From 40df83de660d19b17d9674821e82aa2bd4b61a49 Mon Sep 17 00:00:00 2001 From: Asuka Minato Date: Tue, 14 Jul 2026 23:56:22 +0900 Subject: [PATCH] test: move trigger provider coverage to unit tests (#38942) --- .../workspace/test_trigger_provider_apis.py} | 72 +------------------ .../workspace/test_trigger_providers.py | 61 ++++++++++++++++ 2 files changed, 62 insertions(+), 71 deletions(-) rename api/tests/{test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py => unit_tests/controllers/console/workspace/test_trigger_provider_apis.py} (87%) create mode 100644 api/tests/unit_tests/controllers/console/workspace/test_trigger_providers.py diff --git a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py b/api/tests/unit_tests/controllers/console/workspace/test_trigger_provider_apis.py similarity index 87% rename from api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py rename to api/tests/unit_tests/controllers/console/workspace/test_trigger_provider_apis.py index 31d625ac91d..6eca14aa273 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_trigger_provider_apis.py @@ -1,4 +1,4 @@ -"""Testcontainers integration tests for controllers.console.workspace.trigger_providers endpoints.""" +"""Unit tests for controllers.console.workspace.trigger_providers endpoints.""" from __future__ import annotations @@ -24,7 +24,6 @@ from controllers.console.workspace.trigger_providers import ( TriggerSubscriptionBuilderLogsApi, TriggerSubscriptionBuilderUpdateApi, TriggerSubscriptionBuilderVerifyApi, - TriggerSubscriptionDeleteApi, TriggerSubscriptionListApi, TriggerSubscriptionUpdateApi, TriggerSubscriptionVerifyApi, @@ -83,10 +82,6 @@ def request_log() -> RequestLog: class TestTriggerProviderApis: - @pytest.fixture - def app(self, flask_app_with_containers: Flask) -> Flask: - return flask_app_with_containers - def test_icon_success(self, app: Flask) -> None: api = TriggerProviderIconApi() method = unwrap(api.get) @@ -128,10 +123,6 @@ class TestTriggerProviderApis: class TestTriggerSubscriptionListApi: - @pytest.fixture - def app(self, flask_app_with_containers: Flask) -> Flask: - return flask_app_with_containers - def test_list_success(self, app: Flask) -> None: api = TriggerSubscriptionListApi() method = unwrap(api.get) @@ -161,10 +152,6 @@ class TestTriggerSubscriptionListApi: class TestTriggerSubscriptionBuilderApis: - @pytest.fixture - def app(self, flask_app_with_containers: Flask) -> Flask: - return flask_app_with_containers - def test_create_builder(self, app: Flask) -> None: api = TriggerSubscriptionBuilderCreateApi() method = unwrap(api.post) @@ -261,10 +248,6 @@ class TestTriggerSubscriptionBuilderApis: class TestTriggerSubscriptionCrud: - @pytest.fixture - def app(self, flask_app_with_containers: Flask) -> Flask: - return flask_app_with_containers - def test_update_rename_only(self, app: Flask) -> None: api = TriggerSubscriptionUpdateApi() method = unwrap(api.post) @@ -319,53 +302,8 @@ class TestTriggerSubscriptionCrud: ): assert method(api, "t1", "s1") == {"result": "success"} - def test_delete_subscription(self, app: Flask) -> None: - api = TriggerSubscriptionDeleteApi() - method = unwrap(api.post) - - mock_session = MagicMock() - - with ( - app.test_request_context("/"), - patch("controllers.console.workspace.trigger_providers.db") as mock_db, - patch("controllers.console.workspace.trigger_providers.sessionmaker") as mock_session_cls, - patch("controllers.console.workspace.trigger_providers.TriggerProviderService.delete_trigger_provider"), - patch( - "controllers.console.workspace.trigger_providers.TriggerSubscriptionOperatorService.delete_plugin_trigger_by_subscription" - ), - ): - mock_db.engine = MagicMock() - mock_session_cls.return_value.begin.return_value.__enter__.return_value = mock_session - - result = method(api, "t1", "sub1") - - assert result["result"] == "success" - - def test_delete_subscription_value_error(self, app: Flask) -> None: - api = TriggerSubscriptionDeleteApi() - method = unwrap(api.post) - - with ( - app.test_request_context("/"), - patch("controllers.console.workspace.trigger_providers.db") as mock_db, - patch("controllers.console.workspace.trigger_providers.sessionmaker") as session_cls, - patch( - "controllers.console.workspace.trigger_providers.TriggerProviderService.delete_trigger_provider", - side_effect=ValueError("bad"), - ), - ): - mock_db.engine = MagicMock() - session_cls.return_value.begin.return_value.__enter__.return_value = MagicMock() - - with pytest.raises(BadRequest): - method(api, "t1", "sub1") - class TestTriggerOAuthApis: - @pytest.fixture - def app(self, flask_app_with_containers: Flask) -> Flask: - return flask_app_with_containers - def test_oauth_authorize_success(self, app: Flask) -> None: api = TriggerOAuthAuthorizeApi() method = unwrap(api.get) @@ -498,10 +436,6 @@ class TestTriggerOAuthApis: class TestTriggerOAuthClientManageApi: - @pytest.fixture - def app(self, flask_app_with_containers: Flask) -> Flask: - return flask_app_with_containers - def test_get_client(self, app: Flask) -> None: api = TriggerOAuthClientManageApi() method = unwrap(api.get) @@ -570,10 +504,6 @@ class TestTriggerOAuthClientManageApi: class TestTriggerSubscriptionVerifyApi: - @pytest.fixture - def app(self, flask_app_with_containers: Flask) -> Flask: - return flask_app_with_containers - def test_verify_success(self, app: Flask) -> None: api = TriggerSubscriptionVerifyApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_trigger_providers.py b/api/tests/unit_tests/controllers/console/workspace/test_trigger_providers.py new file mode 100644 index 00000000000..6464abcfa60 --- /dev/null +++ b/api/tests/unit_tests/controllers/console/workspace/test_trigger_providers.py @@ -0,0 +1,61 @@ +"""Unit tests for trigger-provider controller transaction boundaries.""" + +from collections.abc import Iterator +from importlib import import_module +from inspect import unwrap +from unittest.mock import patch + +import pytest +from flask import Flask +from sqlalchemy.engine import Engine +from werkzeug.exceptions import BadRequest + +from controllers.console.workspace.trigger_providers import TriggerSubscriptionDeleteApi +from models.engine import db + +trigger_provider_module = import_module("controllers.console.workspace.trigger_providers") + + +@pytest.fixture +def flask_sqlite_engine() -> Iterator[Engine]: + app = Flask(__name__) + app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:" + db.init_app(app) + + with app.app_context(): + yield db.engine + + +def test_delete_subscription_uses_sqlite_transaction(flask_sqlite_engine: Engine) -> None: + api = TriggerSubscriptionDeleteApi() + method = unwrap(api.post) + + with ( + patch.object(trigger_provider_module.TriggerProviderService, "delete_trigger_provider") as delete_provider, + patch.object( + trigger_provider_module.TriggerSubscriptionOperatorService, + "delete_plugin_trigger_by_subscription", + ) as delete_triggers, + ): + result = method(api, "t1", "sub1") + + assert result == {"result": "success"} + provider_session = delete_provider.call_args.kwargs["session"] + trigger_session = delete_triggers.call_args.kwargs["session"] + assert provider_session is trigger_session + assert provider_session.get_bind() is flask_sqlite_engine + + +def test_delete_subscription_translates_value_error(flask_sqlite_engine: Engine) -> None: + api = TriggerSubscriptionDeleteApi() + method = unwrap(api.post) + + with ( + patch.object( + trigger_provider_module.TriggerProviderService, + "delete_trigger_provider", + side_effect=ValueError("bad"), + ), + pytest.raises(BadRequest, match="bad"), + ): + method(api, "t1", "sub1")