From 7b63b1cabb817618d8e0b9bf87088ba2c1115489 Mon Sep 17 00:00:00 2001 From: Bujjibabukatta Date: Sun, 9 Aug 2026 12:39:16 +0530 Subject: [PATCH] Move template-field validation out of GoogleCampaignManagerDeleteReportOperator.__init__ --- .../operators/campaign_manager.py | 10 +++---- .../operators/test_campaign_manager.py | 29 +++++++++++++++++++ .../validate_operators_init_exemptions.txt | 1 - 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/providers/google/src/airflow/providers/google/marketing_platform/operators/campaign_manager.py b/providers/google/src/airflow/providers/google/marketing_platform/operators/campaign_manager.py index 4634d58b26ba2..f466079fbe227 100644 --- a/providers/google/src/airflow/providers/google/marketing_platform/operators/campaign_manager.py +++ b/providers/google/src/airflow/providers/google/marketing_platform/operators/campaign_manager.py @@ -84,11 +84,6 @@ def __init__( **kwargs, ) -> None: super().__init__(**kwargs) - if not (report_name or report_id): - raise AirflowException("Please provide `report_name` or `report_id`.") - if report_name and report_id: - raise AirflowException("Please provide only one parameter `report_name` or `report_id`.") - self.profile_id = profile_id self.report_name = report_name self.report_id = report_id @@ -97,6 +92,11 @@ def __init__( self.impersonation_chain = impersonation_chain def execute(self, context: Context) -> None: + if not (self.report_name or self.report_id): + raise AirflowException("Please provide `report_name` or `report_id`.") + if self.report_name and self.report_id: + raise AirflowException("Please provide only one parameter `report_name` or `report_id`.") + hook = GoogleCampaignManagerHook( gcp_conn_id=self.gcp_conn_id, api_version=self.api_version, diff --git a/providers/google/tests/unit/google/marketing_platform/operators/test_campaign_manager.py b/providers/google/tests/unit/google/marketing_platform/operators/test_campaign_manager.py index dca13918d01a8..0d548702e3e88 100644 --- a/providers/google/tests/unit/google/marketing_platform/operators/test_campaign_manager.py +++ b/providers/google/tests/unit/google/marketing_platform/operators/test_campaign_manager.py @@ -24,6 +24,7 @@ import pytest from sqlalchemy import delete +from airflow.exceptions import AirflowException from airflow.models import TaskInstance as TI from airflow.providers.common.compat.sdk import timezone from airflow.providers.google.marketing_platform.operators.campaign_manager import ( @@ -87,6 +88,34 @@ def test_execute(self, mock_base_op, hook_mock): profile_id=PROFILE_ID, report_id=REPORT_ID ) + @mock.patch( + "airflow.providers.google.marketing_platform.operators.campaign_manager.GoogleCampaignManagerHook" + ) + @mock.patch("airflow.providers.google.marketing_platform.operators.campaign_manager.BaseOperator") + def test_execute_raises_when_both_report_name_and_id(self, mock_base_op, hook_mock): + op = GoogleCampaignManagerDeleteReportOperator( + profile_id=PROFILE_ID, + report_name=REPORT_NAME, + report_id=REPORT_ID, + api_version=API_VERSION, + task_id="test_task", + ) + with pytest.raises(AirflowException, match="only one parameter"): + op.execute(context=None) + + @mock.patch( + "airflow.providers.google.marketing_platform.operators.campaign_manager.GoogleCampaignManagerHook" + ) + @mock.patch("airflow.providers.google.marketing_platform.operators.campaign_manager.BaseOperator") + def test_execute_raises_when_neither_report_name_nor_id(self, mock_base_op, hook_mock): + op = GoogleCampaignManagerDeleteReportOperator( + profile_id=PROFILE_ID, + api_version=API_VERSION, + task_id="test_task", + ) + with pytest.raises(AirflowException, match="Please provide"): + op.execute(context=None) + @pytest.mark.db_test class TestGoogleCampaignManagerDownloadReportOperator: diff --git a/scripts/ci/prek/validate_operators_init_exemptions.txt b/scripts/ci/prek/validate_operators_init_exemptions.txt index e6869670a5bea..accd0e274bea3 100644 --- a/scripts/ci/prek/validate_operators_init_exemptions.txt +++ b/scripts/ci/prek/validate_operators_init_exemptions.txt @@ -20,6 +20,5 @@ providers/google/src/airflow/providers/google/cloud/sensors/bigquery_dts.py::Big providers/google/src/airflow/providers/google/cloud/sensors/cloud_composer.py::CloudComposerExternalTaskSensor providers/google/src/airflow/providers/google/cloud/transfers/azure_fileshare_to_gcs.py::AzureFileShareToGCSOperator providers/google/src/airflow/providers/google/cloud/transfers/gcs_to_bigquery.py::GCSToBigQueryOperator -providers/google/src/airflow/providers/google/marketing_platform/operators/campaign_manager.py::GoogleCampaignManagerDeleteReportOperator providers/microsoft/azure/src/airflow/providers/microsoft/azure/transfers/gcs_to_wasb.py::GCSToAzureBlobStorageOperator providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/operators/psrp.py::PsrpOperator