From 654042e2bd131b2e1bc49499477770114ff53b36 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Date: Tue, 24 Jun 2025 19:52:50 +0100 Subject: [PATCH 1/2] Add default conn name to asana provider operators --- .../providers/asana/operators/asana_tasks.py | 8 +-- .../unit/asana/operators/test_asana_tasks.py | 59 +++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/providers/asana/src/airflow/providers/asana/operators/asana_tasks.py b/providers/asana/src/airflow/providers/asana/operators/asana_tasks.py index 39ba24002cc4b..04a44bed9cfb0 100644 --- a/providers/asana/src/airflow/providers/asana/operators/asana_tasks.py +++ b/providers/asana/src/airflow/providers/asana/operators/asana_tasks.py @@ -53,9 +53,9 @@ class AsanaCreateTaskOperator(BaseOperator): def __init__( self, *, - conn_id: str, name: str, task_parameters: dict | None = None, + conn_id: str = "asana_default", **kwargs, ) -> None: super().__init__(**kwargs) @@ -92,9 +92,9 @@ class AsanaUpdateTaskOperator(BaseOperator): def __init__( self, *, - conn_id: str, asana_task_gid: str, task_parameters: dict, + conn_id: str = "asana_default", **kwargs, ) -> None: super().__init__(**kwargs) @@ -124,8 +124,8 @@ class AsanaDeleteTaskOperator(BaseOperator): def __init__( self, *, - conn_id: str, asana_task_gid: str, + conn_id: str = "asana_default", **kwargs, ) -> None: super().__init__(**kwargs) @@ -160,8 +160,8 @@ class AsanaFindTaskOperator(BaseOperator): def __init__( self, *, - conn_id: str, search_parameters: dict | None = None, + conn_id: str = "asana_default", **kwargs, ) -> None: super().__init__(**kwargs) diff --git a/providers/asana/tests/unit/asana/operators/test_asana_tasks.py b/providers/asana/tests/unit/asana/operators/test_asana_tasks.py index f22764520595f..da37bb102bdf2 100644 --- a/providers/asana/tests/unit/asana/operators/test_asana_tasks.py +++ b/providers/asana/tests/unit/asana/operators/test_asana_tasks.py @@ -37,6 +37,22 @@ class TestAsanaTaskOperators: @pytest.fixture(autouse=True) def setup_connections(self, create_connection_without_db): create_connection_without_db(Connection(conn_id="asana_test", conn_type="asana", password="test")) + create_connection_without_db(Connection(conn_id="asana_default", conn_type="asana", password="test")) + + @patch("airflow.providers.asana.hooks.asana.TasksApi", autospec=True, return_value=asana_tasks_api_mock) + def test_asana_create_task_operator_with_default_conn(self, mock_tasks_api): + """ + Tests that the AsanaCreateTaskOperator uses the default connection. + """ + + mock_tasks_api.return_value.create_task.return_value = {"gid": "1"} + create_task = AsanaCreateTaskOperator( + task_id="create_task", + name="test", + task_parameters={"workspace": "1"}, + ) + assert create_task.conn_id == "asana_default" + create_task.run(start_date=DEFAULT_DATE, end_date=DEFAULT_DATE, ignore_ti_state=True) @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") def test_asana_create_task_operator(self, mock_asana_hook): @@ -58,6 +74,19 @@ def test_asana_create_task_operator(self, mock_asana_hook): mock_hook_instance.create_task.assert_called_once_with("test", {"workspace": "1"}) assert result == "1" + @patch("airflow.providers.asana.hooks.asana.TasksApi", autospec=True, return_value=asana_tasks_api_mock) + def test_asana_find_task_operator_with_default_conn(self, mock_tasks_api): + """ + Tests that the AsanaFindTaskOperator uses the default connection. + """ + mock_tasks_api.return_value.tasks.create.return_value = {"gid": "1"} + find_task = AsanaFindTaskOperator( + task_id="find_task", + search_parameters={"project": "test"}, + ) + assert find_task.conn_id == "asana_default" + find_task.run(start_date=DEFAULT_DATE, end_date=DEFAULT_DATE, ignore_ti_state=True) + @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") def test_asana_find_task_operator(self, mock_asana_hook): """ @@ -77,6 +106,19 @@ def test_asana_find_task_operator(self, mock_asana_hook): mock_hook_instance.find_task.assert_called_once_with({"project": "test"}) assert result == {"gid": "1"} + @patch("airflow.providers.asana.hooks.asana.TasksApi", autospec=True, return_value=asana_tasks_api_mock) + def test_asana_update_task_operator_default_conn(self, mock_tasks_api): + """ + Tests that the AsanaUpdateTaskOperator uses the default connection. + """ + update_task = AsanaUpdateTaskOperator( + task_id="update_task", + asana_task_gid="test", + task_parameters={"completed": True}, + ) + assert update_task.conn_id == "asana_default" + assert mock_tasks_api.return_value.update_task.called + @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") def test_asana_update_task_operator(self, mock_asana_hook): """ @@ -93,6 +135,23 @@ def test_asana_update_task_operator(self, mock_asana_hook): update_task.execute({}) mock_hook_instance.update_task.assert_called_once_with("test", {"completed": True}) + @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") + def test_asana_delete_task_operator_with_default_conn(self, mock_asana_hook): + """ + Tests that the AsanaDeleteTaskOperator uses the default connection. + """ + + mock_hook_instance = MagicMock() + mock_asana_hook.return_value = mock_hook_instance + + delete_task = AsanaDeleteTaskOperator( + task_id="delete_task", + asana_task_gid="test", + ) + delete_task.execute({}) + assert delete_task.conn_id == "asana_default" + mock_hook_instance.delete_task.assert_called_once_with("test") + @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") def test_asana_delete_task_operator(self, mock_asana_hook): """ From 519beda2b7b998140fc0dc1bf02833749c52b35b Mon Sep 17 00:00:00 2001 From: Pavan Kumar Date: Tue, 24 Jun 2025 22:19:49 +0100 Subject: [PATCH 2/2] Update tests --- .../unit/asana/operators/test_asana_tasks.py | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/providers/asana/tests/unit/asana/operators/test_asana_tasks.py b/providers/asana/tests/unit/asana/operators/test_asana_tasks.py index da37bb102bdf2..1c1737a5648ea 100644 --- a/providers/asana/tests/unit/asana/operators/test_asana_tasks.py +++ b/providers/asana/tests/unit/asana/operators/test_asana_tasks.py @@ -39,20 +39,25 @@ def setup_connections(self, create_connection_without_db): create_connection_without_db(Connection(conn_id="asana_test", conn_type="asana", password="test")) create_connection_without_db(Connection(conn_id="asana_default", conn_type="asana", password="test")) - @patch("airflow.providers.asana.hooks.asana.TasksApi", autospec=True, return_value=asana_tasks_api_mock) - def test_asana_create_task_operator_with_default_conn(self, mock_tasks_api): + @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") + def test_asana_create_task_operator_with_default_conn(self, mock_asana_hook): """ Tests that the AsanaCreateTaskOperator uses the default connection. """ - mock_tasks_api.return_value.create_task.return_value = {"gid": "1"} + mock_hook_instance = MagicMock() + mock_asana_hook.return_value = mock_hook_instance + mock_hook_instance.create_task.return_value = {"gid": "1"} + create_task = AsanaCreateTaskOperator( task_id="create_task", name="test", task_parameters={"workspace": "1"}, ) + result = create_task.execute({}) assert create_task.conn_id == "asana_default" - create_task.run(start_date=DEFAULT_DATE, end_date=DEFAULT_DATE, ignore_ti_state=True) + mock_hook_instance.create_task.assert_called_once_with("test", {"workspace": "1"}) + assert result == "1" @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") def test_asana_create_task_operator(self, mock_asana_hook): @@ -74,18 +79,25 @@ def test_asana_create_task_operator(self, mock_asana_hook): mock_hook_instance.create_task.assert_called_once_with("test", {"workspace": "1"}) assert result == "1" - @patch("airflow.providers.asana.hooks.asana.TasksApi", autospec=True, return_value=asana_tasks_api_mock) - def test_asana_find_task_operator_with_default_conn(self, mock_tasks_api): + @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") + def test_asana_find_task_operator_with_default_conn(self, mock_asana_hook): """ Tests that the AsanaFindTaskOperator uses the default connection. """ - mock_tasks_api.return_value.tasks.create.return_value = {"gid": "1"} + + mock_hook_instance = MagicMock() + mock_asana_hook.return_value = mock_hook_instance + mock_hook_instance.find_task.return_value = {"gid": "1"} + find_task = AsanaFindTaskOperator( task_id="find_task", search_parameters={"project": "test"}, ) assert find_task.conn_id == "asana_default" - find_task.run(start_date=DEFAULT_DATE, end_date=DEFAULT_DATE, ignore_ti_state=True) + + result = find_task.execute({}) + mock_hook_instance.find_task.assert_called_once_with({"project": "test"}) + assert result == {"gid": "1"} @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") def test_asana_find_task_operator(self, mock_asana_hook): @@ -106,18 +118,22 @@ def test_asana_find_task_operator(self, mock_asana_hook): mock_hook_instance.find_task.assert_called_once_with({"project": "test"}) assert result == {"gid": "1"} - @patch("airflow.providers.asana.hooks.asana.TasksApi", autospec=True, return_value=asana_tasks_api_mock) - def test_asana_update_task_operator_default_conn(self, mock_tasks_api): + @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") + def test_asana_update_task_operator_default_conn(self, mock_asana_hook): """ Tests that the AsanaUpdateTaskOperator uses the default connection. """ + + mock_hook_instance = MagicMock() + mock_asana_hook.return_value = mock_hook_instance update_task = AsanaUpdateTaskOperator( task_id="update_task", asana_task_gid="test", task_parameters={"completed": True}, ) assert update_task.conn_id == "asana_default" - assert mock_tasks_api.return_value.update_task.called + update_task.execute({}) + mock_hook_instance.update_task.assert_called_once_with("test", {"completed": True}) @patch("airflow.providers.asana.operators.asana_tasks.AsanaHook") def test_asana_update_task_operator(self, mock_asana_hook):