diff --git a/api/tests/test_containers_integration_tests/controllers/console/test_apikey.py b/api/tests/test_containers_integration_tests/controllers/console/test_apikey.py index 7df63aae1a..b55eaa1d58 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/test_apikey.py +++ b/api/tests/test_containers_integration_tests/controllers/console/test_apikey.py @@ -5,6 +5,7 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest +from flask import Flask from flask.testing import FlaskClient from sqlalchemy import delete from sqlalchemy.orm import Session @@ -126,7 +127,7 @@ class TestAppApiKeyResource: def test_delete_forbidden_for_non_admin( self, - flask_app_with_containers, + flask_app_with_containers: Flask, ) -> None: """A non-admin member cannot delete API keys via the controller permission check.""" from werkzeug.exceptions import Forbidden diff --git a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py index e41adccf3c..e155b711a7 100644 --- a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py +++ b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py @@ -575,7 +575,7 @@ class TestTriggerSubscriptionVerifyApi: assert method(api, "github", "s1") == {"ok": True} @pytest.mark.parametrize("raised_exception", [ValueError("bad"), Exception("boom")]) - def test_verify_errors(self, app, raised_exception): + def test_verify_errors(self, app: Flask, raised_exception): api = TriggerSubscriptionVerifyApi() method = unwrap(api.post) diff --git a/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py b/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py index 0a4e495f36..1bc4253cb9 100644 --- a/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py +++ b/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py @@ -277,7 +277,7 @@ class TestDecodeJwtToken: mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app, + app: Flask, ) -> None: non_existent_id = str(uuid4()) mock_extract.return_value = "jwt-token" diff --git a/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py b/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py index e71079829f..9d588d4c73 100644 --- a/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py +++ b/api/tests/test_containers_integration_tests/services/auth/test_api_key_auth_service.py @@ -5,6 +5,7 @@ from unittest.mock import Mock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy.orm import Session from models.source import DataSourceApiKeyAuthBinding @@ -45,7 +46,7 @@ class TestApiKeyAuthService: return binding def test_get_provider_auth_list_success( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, category, provider ): self._create_binding(db_session_with_containers, tenant_id=tenant_id, category=category, provider=provider) db_session_with_containers.expire_all() @@ -58,7 +59,7 @@ class TestApiKeyAuthService: assert tenant_results[0].provider == provider def test_get_provider_auth_list_empty( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id ): result = ApiKeyAuthService.get_provider_auth_list(tenant_id) @@ -66,7 +67,7 @@ class TestApiKeyAuthService: assert tenant_results == [] def test_get_provider_auth_list_filters_disabled( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, category, provider ): self._create_binding( db_session_with_containers, tenant_id=tenant_id, category=category, provider=provider, disabled=True @@ -84,7 +85,7 @@ class TestApiKeyAuthService: self, mock_encrypter, mock_factory, - flask_app_with_containers, + flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, mock_args, @@ -106,7 +107,7 @@ class TestApiKeyAuthService: @patch("services.auth.api_key_auth_service.ApiKeyAuthFactory") def test_create_provider_auth_validation_failed( - self, mock_factory, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_args + self, mock_factory, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, mock_args ): mock_auth_instance = Mock() mock_auth_instance.validate_credentials.return_value = False @@ -124,7 +125,7 @@ class TestApiKeyAuthService: self, mock_encrypter, mock_factory, - flask_app_with_containers, + flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, mock_args, @@ -144,7 +145,7 @@ class TestApiKeyAuthService: def test_get_auth_credentials_success( self, - flask_app_with_containers, + flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, category, @@ -165,14 +166,14 @@ class TestApiKeyAuthService: assert result == mock_credentials def test_get_auth_credentials_not_found( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, category, provider ): result = ApiKeyAuthService.get_auth_credentials(tenant_id, category, provider) assert result is None def test_get_auth_credentials_json_parsing( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, category, provider ): special_credentials = {"auth_type": "api_key", "config": {"api_key": "key_with_中文_and_special_chars_!@#$%"}} self._create_binding( @@ -190,7 +191,7 @@ class TestApiKeyAuthService: assert result["config"]["api_key"] == "key_with_中文_and_special_chars_!@#$%" def test_delete_provider_auth_success( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, category, provider + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id, category, provider ): binding = self._create_binding( db_session_with_containers, tenant_id=tenant_id, category=category, provider=provider @@ -205,7 +206,7 @@ class TestApiKeyAuthService: assert remaining is None def test_delete_provider_auth_not_found( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id ): # Should not raise when binding not found ApiKeyAuthService.delete_provider_auth(tenant_id, str(uuid4())) @@ -275,7 +276,7 @@ class TestApiKeyAuthService: @patch("services.auth.api_key_auth_service.ApiKeyAuthFactory") @patch("services.auth.api_key_auth_service.encrypter") def test_create_provider_auth_database_error_handling( - self, mock_encrypter, mock_factory, flask_app_with_containers, tenant_id, mock_args + self, mock_encrypter, mock_factory, flask_app_with_containers: Flask, tenant_id, mock_args ): mock_auth_instance = Mock() mock_auth_instance.validate_credentials.return_value = True diff --git a/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py b/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py index e78fa27976..1de9ce38a0 100644 --- a/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py +++ b/api/tests/test_containers_integration_tests/services/auth/test_auth_integration.py @@ -10,6 +10,7 @@ from uuid import uuid4 import httpx import pytest +from flask import Flask from sqlalchemy.orm import Session from models.source import DataSourceApiKeyAuthBinding @@ -45,8 +46,8 @@ class TestAuthIntegration: self, mock_encrypt, mock_http, - flask_app_with_containers, - db_session_with_containers, + flask_app_with_containers: Flask, + db_session_with_containers: Session, tenant_id_1, category, firecrawl_credentials, @@ -86,8 +87,8 @@ class TestAuthIntegration: mock_jina_http, mock_fc_http, mock_encrypt, - flask_app_with_containers, - db_session_with_containers, + flask_app_with_containers: Flask, + db_session_with_containers: Session, tenant_id_1, tenant_id_2, category, @@ -115,7 +116,7 @@ class TestAuthIntegration: assert result2[0].tenant_id == tenant_id_2 def test_cross_tenant_access_prevention( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id_2, category + self, flask_app_with_containers: Flask, db_session_with_containers: Session, tenant_id_2, category ): result = ApiKeyAuthService.get_auth_credentials(tenant_id_2, category, AuthType.FIRECRAWL) @@ -139,8 +140,8 @@ class TestAuthIntegration: self, mock_encrypt, mock_http, - flask_app_with_containers, - db_session_with_containers, + flask_app_with_containers: Flask, + db_session_with_containers: Session, tenant_id_1, category, firecrawl_credentials, @@ -201,8 +202,8 @@ class TestAuthIntegration: def test_network_failure_recovery( self, mock_http, - flask_app_with_containers, - db_session_with_containers, + flask_app_with_containers: Flask, + db_session_with_containers: Session, tenant_id_1, category, firecrawl_credentials, @@ -239,8 +240,8 @@ class TestAuthIntegration: self, mock_http, mock_encrypt, - flask_app_with_containers, - db_session_with_containers, + flask_app_with_containers: Flask, + db_session_with_containers: Session, tenant_id_1, category, firecrawl_credentials, diff --git a/api/tests/test_containers_integration_tests/services/dataset_service_update_delete.py b/api/tests/test_containers_integration_tests/services/dataset_service_update_delete.py index 02c3d1a80e..1cffc43658 100644 --- a/api/tests/test_containers_integration_tests/services/dataset_service_update_delete.py +++ b/api/tests/test_containers_integration_tests/services/dataset_service_update_delete.py @@ -14,7 +14,7 @@ from sqlalchemy.orm import Session from werkzeug.exceptions import NotFound from core.rag.index_processor.constant.index_type import IndexTechniqueType -from models import Account, Tenant, TenantAccountJoin, TenantAccountRole +from models import Account, AccountStatus, Tenant, TenantAccountJoin, TenantAccountRole, TenantStatus from models.dataset import AppDatasetJoin, Dataset, DatasetPermissionEnum from models.enums import DataSourceType from models.model import App @@ -38,13 +38,13 @@ class DatasetUpdateDeleteTestDataFactory: email=f"{uuid4()}@example.com", name=f"user-{uuid4()}", interface_language="en-US", - status="active", + status=AccountStatus.ACTIVE, ) db_session_with_containers.add(account) db_session_with_containers.commit() if tenant is None: - tenant = Tenant(name=f"tenant-{uuid4()}", status="normal") + tenant = Tenant(name=f"tenant-{uuid4()}", status=TenantStatus.NORMAL) db_session_with_containers.add(tenant) db_session_with_containers.commit() diff --git a/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py b/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py index e73c2afe7f..075f43d63a 100644 --- a/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py +++ b/api/tests/test_containers_integration_tests/services/enterprise/test_account_deletion_sync.py @@ -10,6 +10,7 @@ from unittest.mock import patch from uuid import uuid4 import pytest +from flask import Flask from redis import RedisError from sqlalchemy.orm import Session @@ -123,7 +124,7 @@ class TestSyncAccountDeletion: mock_queue_task.assert_not_called() def test_sync_account_deletion_multiple_workspaces( - self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task + self, flask_app_with_containers: Flask, db_session_with_containers: Session, mock_queue_task ): account_id = str(uuid4()) tenant_ids = [str(uuid4()) for _ in range(3)] @@ -145,7 +146,7 @@ class TestSyncAccountDeletion: assert queued_workspace_ids == set(tenant_ids) def test_sync_account_deletion_no_workspaces( - self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task + self, flask_app_with_containers: Flask, db_session_with_containers: Session, mock_queue_task ): with patch("services.enterprise.account_deletion_sync.dify_config") as mock_config: mock_config.ENTERPRISE_ENABLED = True @@ -156,7 +157,7 @@ class TestSyncAccountDeletion: mock_queue_task.assert_not_called() def test_sync_account_deletion_partial_failure( - self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task + self, flask_app_with_containers: Flask, db_session_with_containers: Session, mock_queue_task ): account_id = str(uuid4()) tenant_ids = [str(uuid4()) for _ in range(3)] @@ -181,7 +182,7 @@ class TestSyncAccountDeletion: assert mock_queue_task.call_count == 3 def test_sync_account_deletion_all_failures( - self, flask_app_with_containers, db_session_with_containers: Session, mock_queue_task + self, flask_app_with_containers: Flask, db_session_with_containers: Session, mock_queue_task ): account_id = str(uuid4()) tenant_id = str(uuid4()) diff --git a/api/tests/test_containers_integration_tests/services/plugin/test_plugin_parameter_service.py b/api/tests/test_containers_integration_tests/services/plugin/test_plugin_parameter_service.py index ce9f10e207..48830c0f43 100644 --- a/api/tests/test_containers_integration_tests/services/plugin/test_plugin_parameter_service.py +++ b/api/tests/test_containers_integration_tests/services/plugin/test_plugin_parameter_service.py @@ -11,6 +11,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from core.plugin.entities.plugin_daemon import CredentialType from models.tools import BuiltinToolProvider @@ -49,8 +50,8 @@ class TestGetDynamicSelectOptionsTool: mock_tool_mgr, mock_encrypter_fn, mock_client_cls, - flask_app_with_containers, - db_session_with_containers, + flask_app_with_containers: Flask, + db_session_with_containers: Session, ): tenant_id = str(uuid4()) provider_ctrl = MagicMock() @@ -91,8 +92,8 @@ class TestGetDynamicSelectOptionsTool: self, mock_tool_mgr, mock_encrypter_fn, - flask_app_with_containers, - db_session_with_containers, + flask_app_with_containers: Flask, + db_session_with_containers: Session, ): provider_ctrl = MagicMock() provider_ctrl.need_credentials = True diff --git a/api/tests/test_containers_integration_tests/services/plugin/test_plugin_service.py b/api/tests/test_containers_integration_tests/services/plugin/test_plugin_service.py index 0cdae572fb..0fa4d9043b 100644 --- a/api/tests/test_containers_integration_tests/services/plugin/test_plugin_service.py +++ b/api/tests/test_containers_integration_tests/services/plugin/test_plugin_service.py @@ -11,10 +11,13 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy import select +from sqlalchemy.orm import Session from core.plugin.entities.plugin import PluginInstallationSource from core.plugin.entities.plugin_daemon import PluginVerification +from models import ProviderType from models.provider import Provider, ProviderCredential, TenantPreferredModelProvider from services.errors.plugin import PluginInstallationForbiddenError from services.feature_service import PluginInstallationScope @@ -346,7 +349,7 @@ class TestUninstall: @patch("services.plugin.plugin_service.PluginInstaller") def test_cleans_credentials_when_plugin_found( - self, mock_installer_cls, flask_app_with_containers, db_session_with_containers + self, mock_installer_cls, flask_app_with_containers: Flask, db_session_with_containers: Session ): tenant_id = str(uuid4()) plugin_id = "org/myplugin" @@ -374,7 +377,7 @@ class TestUninstall: pref = TenantPreferredModelProvider( tenant_id=tenant_id, provider_name=provider_name, - preferred_provider_type="custom", + preferred_provider_type=ProviderType.CUSTOM, ) db_session_with_containers.add(pref) db_session_with_containers.commit() diff --git a/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py b/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py index 11e864176a..e4a106694b 100644 --- a/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py +++ b/api/tests/test_containers_integration_tests/services/recommend_app/test_database_retrieval.py @@ -3,6 +3,7 @@ from __future__ import annotations from unittest.mock import patch from uuid import uuid4 +from flask import Flask from sqlalchemy.orm import Session from models.model import App, RecommendedApp, Site @@ -10,7 +11,7 @@ from services.recommend_app.database.database_retrieval import DatabaseRecommend from services.recommend_app.recommend_app_type import RecommendAppType -def _create_app(db_session, *, tenant_id: str, is_public: bool = True) -> App: +def _create_app(db_session: Session, *, tenant_id: str, is_public: bool = True) -> App: app = App( tenant_id=tenant_id, name=f"app-{uuid4()}", @@ -25,7 +26,7 @@ def _create_app(db_session, *, tenant_id: str, is_public: bool = True) -> App: return app -def _create_site(db_session, *, app_id: str) -> Site: +def _create_site(db_session: Session, *, app_id: str) -> Site: site = Site( app_id=app_id, title=f"site-{uuid4()}", @@ -95,7 +96,9 @@ class TestDatabaseRecommendAppRetrieval: class TestFetchRecommendedAppsFromDb: - def test_returns_apps_and_sorted_categories(self, flask_app_with_containers, db_session_with_containers: Session): + def test_returns_apps_and_sorted_categories( + self, flask_app_with_containers: Flask, db_session_with_containers: Session + ): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) _create_site(db_session_with_containers, app_id=app1.id) @@ -116,7 +119,7 @@ class TestFetchRecommendedAppsFromDb: assert "writing" in result["categories"] def test_returns_multiple_categories_for_one_app( - self, flask_app_with_containers, db_session_with_containers: Session + self, flask_app_with_containers: Flask, db_session_with_containers: Session ): tenant_id = str(uuid4()) created_app = _create_app(db_session_with_containers, tenant_id=tenant_id) @@ -139,7 +142,7 @@ class TestFetchRecommendedAppsFromDb: def test_ignores_legacy_category_when_categories_are_empty( self, - flask_app_with_containers, + flask_app_with_containers: Flask, db_session_with_containers: Session, ): legacy_category = f"legacy-empty-{uuid4()}" @@ -163,7 +166,7 @@ class TestFetchRecommendedAppsFromDb: assert legacy_category not in result["categories"] def test_falls_back_to_default_language_when_empty( - self, flask_app_with_containers, db_session_with_containers: Session + self, flask_app_with_containers: Flask, db_session_with_containers: Session ): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) @@ -177,7 +180,7 @@ class TestFetchRecommendedAppsFromDb: app_ids = {r["app_id"] for r in result["recommended_apps"]} assert app1.id in app_ids - def test_skips_non_public_apps(self, flask_app_with_containers, db_session_with_containers: Session): + def test_skips_non_public_apps(self, flask_app_with_containers: Flask, db_session_with_containers: Session): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id, is_public=False) _create_site(db_session_with_containers, app_id=app1.id) @@ -190,7 +193,7 @@ class TestFetchRecommendedAppsFromDb: app_ids = {r["app_id"] for r in result["recommended_apps"]} assert app1.id not in app_ids - def test_skips_apps_without_site(self, flask_app_with_containers, db_session_with_containers: Session): + def test_skips_apps_without_site(self, flask_app_with_containers: Flask, db_session_with_containers: Session): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) _create_recommended_app(db_session_with_containers, app_id=app1.id) @@ -204,12 +207,14 @@ class TestFetchRecommendedAppsFromDb: class TestFetchRecommendedAppDetailFromDb: - def test_returns_none_when_not_listed(self, flask_app_with_containers, db_session_with_containers: Session): + def test_returns_none_when_not_listed(self, flask_app_with_containers: Flask, db_session_with_containers: Session): result = DatabaseRecommendAppRetrieval.fetch_recommended_app_detail_from_db(str(uuid4())) assert result is None - def test_returns_none_when_app_not_public(self, flask_app_with_containers, db_session_with_containers: Session): + def test_returns_none_when_app_not_public( + self, flask_app_with_containers: Flask, db_session_with_containers: Session + ): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id, is_public=False) _create_recommended_app(db_session_with_containers, app_id=app1.id) @@ -221,7 +226,9 @@ class TestFetchRecommendedAppDetailFromDb: assert result is None @patch("services.recommend_app.database.database_retrieval.AppDslService") - def test_returns_detail_on_success(self, mock_dsl, flask_app_with_containers, db_session_with_containers: Session): + def test_returns_detail_on_success( + self, mock_dsl, flask_app_with_containers: Flask, db_session_with_containers: Session + ): tenant_id = str(uuid4()) app1 = _create_app(db_session_with_containers, tenant_id=tenant_id) _create_site(db_session_with_containers, app_id=app1.id) diff --git a/api/tests/test_containers_integration_tests/services/test_agent_service.py b/api/tests/test_containers_integration_tests/services/test_agent_service.py index 670b4d00da..27e793915a 100644 --- a/api/tests/test_containers_integration_tests/services/test_agent_service.py +++ b/api/tests/test_containers_integration_tests/services/test_agent_service.py @@ -6,7 +6,7 @@ from faker import Faker from sqlalchemy.orm import Session from core.plugin.impl.exc import PluginDaemonClientSideError -from models import Account, CreatorUserRole +from models import Account, AppMode, CreatorUserRole from models.enums import ConversationFromSource, MessageFileBelongsTo from models.model import AppModelConfig, Conversation, EndUser, Message, MessageAgentThought from services.account_service import AccountService, TenantService @@ -134,7 +134,7 @@ class TestAgentService: app = app_service.create_app(tenant.id, app_args, account) # Update the app model config to set agent_mode for agent-chat mode - if app.mode == "agent-chat" and app.app_model_config: + if app.mode == AppMode.AGENT_CHAT and app.app_model_config: app.app_model_config.agent_mode = json.dumps({"enabled": True, "strategy": "react", "tools": []}) db_session_with_containers.commit() @@ -272,7 +272,7 @@ class TestAgentService: tool_input=json.dumps({"dataset_tool": {"query": "test_query"}}), observation=json.dumps({"dataset_tool": {"results": "test_results"}}), tokens=30, - created_by_role="account", + created_by_role=CreatorUserRole.ACCOUNT, created_by=message.from_account_id, ) db_session_with_containers.add(thought2) diff --git a/api/tests/test_containers_integration_tests/services/test_api_token_service.py b/api/tests/test_containers_integration_tests/services/test_api_token_service.py index a2028d3ed3..9d0082a421 100644 --- a/api/tests/test_containers_integration_tests/services/test_api_token_service.py +++ b/api/tests/test_containers_integration_tests/services/test_api_token_service.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from werkzeug.exceptions import Unauthorized import services.api_token_service as api_token_service_module @@ -14,7 +15,7 @@ from services.api_token_service import ApiTokenCache, CachedApiToken class TestQueryTokenFromDb: def test_should_return_api_token_and_cache_when_token_exists( - self, flask_app_with_containers, db_session_with_containers + self, flask_app_with_containers: Flask, db_session_with_containers ): tenant_id = str(uuid4()) app_id = str(uuid4()) @@ -41,7 +42,7 @@ class TestQueryTokenFromDb: mock_record_usage.assert_called_once_with(token_value, "app") def test_should_cache_null_and_raise_unauthorized_when_token_not_found( - self, flask_app_with_containers, db_session_with_containers + self, flask_app_with_containers: Flask, db_session_with_containers ): with ( patch.object(api_token_service_module.ApiTokenCache, "set") as mock_cache_set, diff --git a/api/tests/test_containers_integration_tests/services/test_file_service_zip_and_lookup.py b/api/tests/test_containers_integration_tests/services/test_file_service_zip_and_lookup.py index 4e0a726cc7..1101d834a0 100644 --- a/api/tests/test_containers_integration_tests/services/test_file_service_zip_and_lookup.py +++ b/api/tests/test_containers_integration_tests/services/test_file_service_zip_and_lookup.py @@ -15,6 +15,7 @@ from uuid import uuid4 from zipfile import ZipFile import pytest +from sqlalchemy.orm import Session import services.file_service as file_service_module from extensions.storage.storage_type import StorageType @@ -23,7 +24,7 @@ from models.model import UploadFile from services.file_service import FileService -def _create_upload_file(db_session, *, tenant_id: str, key: str, name: str) -> UploadFile: +def _create_upload_file(db_session: Session, *, tenant_id: str, key: str, name: str) -> UploadFile: upload_file = UploadFile( tenant_id=tenant_id, storage_type=StorageType.OPENDAL, @@ -66,12 +67,12 @@ def test_build_upload_files_zip_tempfile_sanitizes_and_dedupes_names(monkeypatch assert zf.read("b (2).txt") == b"three" -def test_get_upload_files_by_ids_returns_empty_when_no_ids(db_session_with_containers) -> None: +def test_get_upload_files_by_ids_returns_empty_when_no_ids(db_session_with_containers: Session) -> None: """Ensure empty input returns an empty mapping without hitting the database.""" assert FileService.get_upload_files_by_ids(str(uuid4()), []) == {} -def test_get_upload_files_by_ids_returns_id_keyed_mapping(db_session_with_containers) -> None: +def test_get_upload_files_by_ids_returns_id_keyed_mapping(db_session_with_containers: Session) -> None: """Ensure batch lookup returns a dict keyed by stringified UploadFile ids.""" tenant_id = str(uuid4()) file1 = _create_upload_file(db_session_with_containers, tenant_id=tenant_id, key="k1", name="file1.txt") @@ -84,7 +85,7 @@ def test_get_upload_files_by_ids_returns_id_keyed_mapping(db_session_with_contai assert result[file2.id].id == file2.id -def test_get_upload_files_by_ids_filters_by_tenant(db_session_with_containers) -> None: +def test_get_upload_files_by_ids_filters_by_tenant(db_session_with_containers: Session) -> None: """Ensure files from other tenants are not returned.""" tenant_a = str(uuid4()) tenant_b = str(uuid4()) diff --git a/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py b/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py index bfc2af6509..454b8096d1 100644 --- a/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py +++ b/api/tests/test_containers_integration_tests/services/test_human_input_delivery_test_service.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy.engine import Engine from sqlalchemy.orm import Session @@ -89,7 +90,7 @@ class TestDeliveryTestRegistry: with pytest.raises(DeliveryTestUnsupportedError, match="Delivery method does not support test send."): registry.dispatch(context=context, method=method) - def test_default(self, flask_app_with_containers, db_session_with_containers: Session): + def test_default(self, flask_app_with_containers: Flask, db_session_with_containers: Session): registry = DeliveryTestRegistry.default() assert len(registry._handlers) == 1 assert isinstance(registry._handlers[0], EmailDeliveryTestHandler) @@ -261,7 +262,7 @@ class TestEmailDeliveryTestHandler: ) assert handler._resolve_recipients(tenant_id="t1", method=method) == ["ext@example.com"] - def test_resolve_recipients_member(self, flask_app_with_containers, db_session_with_containers: Session): + def test_resolve_recipients_member(self, flask_app_with_containers: Flask, db_session_with_containers: Session): tenant_id = str(uuid4()) account = Account(name="Test User", email="member@example.com") db_session_with_containers.add(account) @@ -283,7 +284,9 @@ class TestEmailDeliveryTestHandler: ) assert handler._resolve_recipients(tenant_id=tenant_id, method=method) == ["member@example.com"] - def test_resolve_recipients_whole_workspace(self, flask_app_with_containers, db_session_with_containers: Session): + def test_resolve_recipients_whole_workspace( + self, flask_app_with_containers: Flask, db_session_with_containers: Session + ): tenant_id = str(uuid4()) account1 = Account(name="User 1", email=f"u1-{uuid4()}@example.com") account2 = Account(name="User 2", email=f"u2-{uuid4()}@example.com") diff --git a/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py b/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py index fffa82bf5c..f3ab9eb3da 100644 --- a/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py +++ b/api/tests/test_containers_integration_tests/services/test_metadata_partial_update.py @@ -4,6 +4,7 @@ from unittest.mock import Mock, patch from uuid import uuid4 import pytest +from flask import Flask from sqlalchemy import select from sqlalchemy.orm import Session @@ -17,7 +18,7 @@ from services.entities.knowledge_entities.knowledge_entities import ( from services.metadata_service import MetadataService -def _create_dataset(db_session, *, tenant_id: str, built_in_field_enabled: bool = False) -> Dataset: +def _create_dataset(db_session: Session, *, tenant_id: str, built_in_field_enabled: bool = False) -> Dataset: dataset = Dataset( tenant_id=tenant_id, name=f"dataset-{uuid4()}", @@ -31,7 +32,9 @@ def _create_dataset(db_session, *, tenant_id: str, built_in_field_enabled: bool return dataset -def _create_document(db_session, *, dataset_id: str, tenant_id: str, doc_metadata: dict | None = None) -> Document: +def _create_document( + db_session: Session, *, dataset_id: str, tenant_id: str, doc_metadata: dict | None = None +) -> Document: document = Document( tenant_id=tenant_id, dataset_id=dataset_id, @@ -66,7 +69,11 @@ class TestMetadataPartialUpdate: yield account def test_partial_update_merges_metadata( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_current_account + self, + flask_app_with_containers: Flask, + db_session_with_containers: Session, + tenant_id: str, + mock_current_account, ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( @@ -93,7 +100,11 @@ class TestMetadataPartialUpdate: assert updated_doc.doc_metadata["new_key"] == "new_value" def test_full_update_replaces_metadata( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_current_account + self, + flask_app_with_containers: Flask, + db_session_with_containers: Session, + tenant_id: str, + mock_current_account, ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( @@ -120,7 +131,12 @@ class TestMetadataPartialUpdate: assert "existing_key" not in updated_doc.doc_metadata def test_partial_update_skips_existing_binding( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, user_id, mock_current_account + self, + flask_app_with_containers: Flask, + db_session_with_containers: Session, + tenant_id, + user_id, + mock_current_account, ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( @@ -160,7 +176,11 @@ class TestMetadataPartialUpdate: assert len(bindings) == 1 def test_rollback_called_on_commit_failure( - self, flask_app_with_containers, db_session_with_containers: Session, tenant_id, mock_current_account + self, + flask_app_with_containers: Flask, + db_session_with_containers: Session, + tenant_id: str, + mock_current_account, ): dataset = _create_dataset(db_session_with_containers, tenant_id=tenant_id) document = _create_document( diff --git a/api/tests/unit_tests/controllers/console/app/test_app_import_api.py b/api/tests/unit_tests/controllers/console/app/test_app_import_api.py index 9c4678aed3..e690968ffb 100644 --- a/api/tests/unit_tests/controllers/console/app/test_app_import_api.py +++ b/api/tests/unit_tests/controllers/console/app/test_app_import_api.py @@ -6,6 +6,7 @@ from types import SimpleNamespace from unittest.mock import MagicMock import pytest +from flask import Flask from controllers.console.app import app_import as app_import_module from services.app_dsl_service import ImportStatus @@ -48,7 +49,9 @@ class TestAppImportApi: def api(self): return app_import_module.AppImportApi() - def test_import_post_returns_failed_status_and_rolls_back(self, api, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_returns_failed_status_and_rolls_back( + self, api, app: Flask, monkeypatch: pytest.MonkeyPatch + ) -> None: method = _unwrap(api.post) _install_features(monkeypatch, enabled=False) @@ -68,7 +71,9 @@ class TestAppImportApi: assert status == 400 assert response["status"] == ImportStatus.FAILED - def test_import_post_returns_pending_status_and_commits(self, api, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_returns_pending_status_and_commits( + self, api, app: Flask, monkeypatch: pytest.MonkeyPatch + ) -> None: method = _unwrap(api.post) _install_features(monkeypatch, enabled=False) @@ -88,7 +93,9 @@ class TestAppImportApi: assert status == 202 assert response["status"] == ImportStatus.PENDING - def test_import_post_updates_webapp_auth_when_enabled(self, api, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_import_post_updates_webapp_auth_when_enabled( + self, api, app: Flask, monkeypatch: pytest.MonkeyPatch + ) -> None: method = _unwrap(api.post) _install_features(monkeypatch, enabled=True) @@ -118,7 +125,7 @@ class TestAppImportConfirmApi: return app_import_module.AppImportConfirmApi() def test_import_confirm_returns_failed_status_and_rolls_back( - self, api, app, monkeypatch: pytest.MonkeyPatch + self, api, app: Flask, monkeypatch: pytest.MonkeyPatch ) -> None: method = _unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/app/test_conversation_variables_api.py b/api/tests/unit_tests/controllers/console/app/test_conversation_variables_api.py index 1a412aff29..71b6a1aa37 100644 --- a/api/tests/unit_tests/controllers/console/app/test_conversation_variables_api.py +++ b/api/tests/unit_tests/controllers/console/app/test_conversation_variables_api.py @@ -5,6 +5,7 @@ from datetime import UTC, datetime from types import SimpleNamespace import pytest +from flask import Flask from pydantic import ValidationError from controllers.console.app import conversation_variables as conversation_variables_module @@ -20,7 +21,7 @@ def _unwrap(func): return func -def test_get_conversation_variables_returns_paginated_response(app, monkeypatch: pytest.MonkeyPatch) -> None: +def test_get_conversation_variables_returns_paginated_response(app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: api = conversation_variables_module.ConversationVariablesApi() method = _unwrap(api.get) @@ -63,7 +64,9 @@ def test_get_conversation_variables_returns_paginated_response(app, monkeypatch: assert response["data"][0]["updated_at"] == int(updated_at.timestamp()) -def test_get_conversation_variables_normalizes_value_type_and_value(app, monkeypatch: pytest.MonkeyPatch) -> None: +def test_get_conversation_variables_normalizes_value_type_and_value( + app: Flask, monkeypatch: pytest.MonkeyPatch +) -> None: api = conversation_variables_module.ConversationVariablesApi() method = _unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/app/test_workflow_pause_details_api.py b/api/tests/unit_tests/controllers/console/app/test_workflow_pause_details_api.py index f265a4f68d..58274f1688 100644 --- a/api/tests/unit_tests/controllers/console/app/test_workflow_pause_details_api.py +++ b/api/tests/unit_tests/controllers/console/app/test_workflow_pause_details_api.py @@ -20,8 +20,11 @@ from models.workflow import WorkflowRun def _make_account() -> Account: - account = Account(name="tester", email="tester@example.com") - account.status = AccountStatus.ACTIVE + account = Account( + name="tester", + email="tester@example.com", + status=AccountStatus.ACTIVE, + ) account.role = TenantAccountRole.OWNER account.id = "account-123" # type: ignore[assignment] account._current_tenant = SimpleNamespace(id="tenant-123") # type: ignore[attr-defined] diff --git a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_draft_variable.py b/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_draft_variable.py index 63950736c5..8a65c4bbe5 100644 --- a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_draft_variable.py +++ b/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_draft_variable.py @@ -1,7 +1,7 @@ from unittest.mock import MagicMock, patch import pytest -from flask import Response +from flask import Flask, Response from controllers.console import console_ns from controllers.console.app.error import DraftWorkflowNotExist @@ -46,7 +46,7 @@ def restx_config(app): class TestRagPipelineVariableCollectionApi: - def test_get_variables_success(self, app, fake_db, editor_user, restx_config): + def test_get_variables_success(self, app: Flask, fake_db, editor_user, restx_config): api = RagPipelineVariableCollectionApi() method = unwrap(api.get) @@ -80,7 +80,7 @@ class TestRagPipelineVariableCollectionApi: assert result["items"] == [] - def test_get_variables_workflow_not_exist(self, app, fake_db, editor_user): + def test_get_variables_workflow_not_exist(self, app: Flask, fake_db, editor_user): api = RagPipelineVariableCollectionApi() method = unwrap(api.get) @@ -101,7 +101,7 @@ class TestRagPipelineVariableCollectionApi: with pytest.raises(DraftWorkflowNotExist): method(api, pipeline) - def test_delete_variables_success(self, app, fake_db, editor_user): + def test_delete_variables_success(self, app: Flask, fake_db, editor_user): api = RagPipelineVariableCollectionApi() method = unwrap(api.delete) @@ -120,7 +120,7 @@ class TestRagPipelineVariableCollectionApi: class TestRagPipelineNodeVariableCollectionApi: - def test_get_node_variables_success(self, app, fake_db, editor_user, restx_config): + def test_get_node_variables_success(self, app: Flask, fake_db, editor_user, restx_config): api = RagPipelineNodeVariableCollectionApi() method = unwrap(api.get) @@ -146,7 +146,7 @@ class TestRagPipelineNodeVariableCollectionApi: assert result["items"] == [] - def test_get_node_variables_invalid_node(self, app, editor_user): + def test_get_node_variables_invalid_node(self, app: Flask, editor_user): api = RagPipelineNodeVariableCollectionApi() method = unwrap(api.get) @@ -159,7 +159,7 @@ class TestRagPipelineNodeVariableCollectionApi: class TestRagPipelineVariableApi: - def test_get_variable_not_found(self, app, fake_db, editor_user): + def test_get_variable_not_found(self, app: Flask, fake_db, editor_user): api = RagPipelineVariableApi() method = unwrap(api.get) @@ -178,7 +178,7 @@ class TestRagPipelineVariableApi: with pytest.raises(NotFoundError): method(api, MagicMock(), "v1") - def test_patch_variable_invalid_file_payload(self, app, fake_db, editor_user): + def test_patch_variable_invalid_file_payload(self, app: Flask, fake_db, editor_user): api = RagPipelineVariableApi() method = unwrap(api.patch) @@ -203,7 +203,7 @@ class TestRagPipelineVariableApi: with pytest.raises(InvalidArgumentError): method(api, pipeline, "v1") - def test_delete_variable_success(self, app, fake_db, editor_user): + def test_delete_variable_success(self, app: Flask, fake_db, editor_user): api = RagPipelineVariableApi() method = unwrap(api.delete) @@ -228,7 +228,7 @@ class TestRagPipelineVariableApi: class TestRagPipelineVariableResetApi: - def test_reset_variable_success(self, app, fake_db, editor_user): + def test_reset_variable_success(self, app: Flask, fake_db, editor_user): api = RagPipelineVariableResetApi() method = unwrap(api.put) @@ -266,7 +266,7 @@ class TestRagPipelineVariableResetApi: class TestSystemAndEnvironmentVariablesApi: - def test_system_variables_success(self, app, fake_db, editor_user, restx_config): + def test_system_variables_success(self, app: Flask, fake_db, editor_user, restx_config): api = RagPipelineSystemVariableCollectionApi() method = unwrap(api.get) @@ -292,7 +292,7 @@ class TestSystemAndEnvironmentVariablesApi: assert result["items"] == [] - def test_environment_variables_success(self, app, editor_user): + def test_environment_variables_success(self, app: Flask, editor_user): api = RagPipelineEnvironmentVariableCollectionApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py b/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py index ff9e1736d2..c77895d940 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_datasets_document.py @@ -95,7 +95,7 @@ def patch_permission(): class TestGetProcessRuleApi: - def test_get_default_success(self, app, patch_tenant): + def test_get_default_success(self, app: Flask, patch_tenant): api = GetProcessRuleApi() method = unwrap(api.get) @@ -104,7 +104,7 @@ class TestGetProcessRuleApi: assert "rules" in response - def test_get_with_document_dataset_not_found(self, app, patch_tenant): + def test_get_with_document_dataset_not_found(self, app: Flask, patch_tenant): api = GetProcessRuleApi() method = unwrap(api.get) @@ -126,7 +126,7 @@ class TestGetProcessRuleApi: class TestDatasetDocumentListApi: - def test_get_with_fetch_true_counts_segments(self, app, patch_tenant, patch_dataset, patch_permission): + def test_get_with_fetch_true_counts_segments(self, app: Flask, patch_tenant, patch_dataset, patch_permission): api = DatasetDocumentListApi() method = unwrap(api.get) @@ -158,7 +158,9 @@ class TestDatasetDocumentListApi: assert resp["data"] - def test_get_with_search_status_and_created_at_sort(self, app, patch_tenant, patch_dataset, patch_permission): + def test_get_with_search_status_and_created_at_sort( + self, app: Flask, patch_tenant, patch_dataset, patch_permission + ): api = DatasetDocumentListApi() method = unwrap(api.get) @@ -187,7 +189,7 @@ class TestDatasetDocumentListApi: assert resp["total"] == 1 - def test_get_success(self, app, patch_tenant, patch_dataset, patch_permission): + def test_get_success(self, app: Flask, patch_tenant, patch_dataset, patch_permission): api = DatasetDocumentListApi() method = unwrap(api.get) @@ -212,7 +214,7 @@ class TestDatasetDocumentListApi: assert response["total"] == 1 - def test_post_success(self, app, patch_tenant, patch_dataset, patch_permission): + def test_post_success(self, app: Flask, patch_tenant, patch_dataset, patch_permission): api = DatasetDocumentListApi() method = unwrap(api.post) @@ -261,7 +263,7 @@ class TestDatasetDocumentListApi: with pytest.raises(Forbidden): method(api, "ds-1") - def test_get_with_fetch_true_and_invalid_fetch(self, app, patch_tenant, patch_dataset, patch_permission): + def test_get_with_fetch_true_and_invalid_fetch(self, app: Flask, patch_tenant, patch_dataset, patch_permission): api = DatasetDocumentListApi() method = unwrap(api.get) @@ -286,7 +288,7 @@ class TestDatasetDocumentListApi: assert response["total"] == 1 - def test_get_sort_hit_count(self, app, patch_tenant, patch_dataset, patch_permission): + def test_get_sort_hit_count(self, app: Flask, patch_tenant, patch_dataset, patch_permission): api = DatasetDocumentListApi() method = unwrap(api.get) @@ -309,7 +311,7 @@ class TestDatasetDocumentListApi: class TestDocumentApi: - def test_get_success(self, app, patch_tenant): + def test_get_success(self, app: Flask, patch_tenant): api = DocumentApi() method = unwrap(api.get) @@ -327,7 +329,7 @@ class TestDocumentApi: assert status == 200 - def test_get_invalid_metadata(self, app, patch_tenant): + def test_get_invalid_metadata(self, app: Flask, patch_tenant): api = DocumentApi() method = unwrap(api.get) @@ -335,7 +337,7 @@ class TestDocumentApi: with pytest.raises(InvalidMetadataError): method(api, "ds-1", "doc-1") - def test_delete_success(self, app, patch_tenant, patch_dataset): + def test_delete_success(self, app: Flask, patch_tenant, patch_dataset): api = DocumentApi() method = unwrap(api.delete) @@ -355,7 +357,7 @@ class TestDocumentApi: assert status == 204 - def test_delete_indexing_error(self, app, patch_tenant, patch_dataset): + def test_delete_indexing_error(self, app: Flask, patch_tenant, patch_dataset): api = DocumentApi() method = unwrap(api.delete) @@ -376,7 +378,7 @@ class TestDocumentApi: class TestDocumentDownloadApi: - def test_download_success(self, app, patch_tenant): + def test_download_success(self, app: Flask, patch_tenant): api = DocumentDownloadApi() method = unwrap(api.get) @@ -413,7 +415,7 @@ class TestDocumentProcessingApi: with pytest.raises(Forbidden): method(api, "ds-1", "doc-1", "pause") - def test_resume_from_error_state(self, app, patch_tenant): + def test_resume_from_error_state(self, app: Flask, patch_tenant): api = DocumentProcessingApi() method = unwrap(api.patch) @@ -431,7 +433,7 @@ class TestDocumentProcessingApi: assert status == 200 - def test_resume_success(self, app, patch_tenant): + def test_resume_success(self, app: Flask, patch_tenant): api = DocumentProcessingApi() method = unwrap(api.patch) @@ -449,7 +451,7 @@ class TestDocumentProcessingApi: assert status == 200 - def test_pause_success(self, app, patch_tenant): + def test_pause_success(self, app: Flask, patch_tenant): api = DocumentProcessingApi() method = unwrap(api.patch) @@ -467,7 +469,7 @@ class TestDocumentProcessingApi: assert status == 200 - def test_pause_invalid(self, app, patch_tenant): + def test_pause_invalid(self, app: Flask, patch_tenant): api = DocumentProcessingApi() method = unwrap(api.patch) @@ -479,7 +481,7 @@ class TestDocumentProcessingApi: class TestDocumentMetadataApi: - def test_put_metadata_schema_filtering(self, app, patch_tenant): + def test_put_metadata_schema_filtering(self, app: Flask, patch_tenant): api = DocumentMetadataApi() method = unwrap(api.put) @@ -508,7 +510,7 @@ class TestDocumentMetadataApi: assert doc.doc_metadata == {"amount": 10} - def test_put_success(self, app, patch_tenant): + def test_put_success(self, app: Flask, patch_tenant): api = DocumentMetadataApi() method = unwrap(api.put) @@ -532,7 +534,7 @@ class TestDocumentMetadataApi: assert status == 200 - def test_put_invalid_payload(self, app, patch_tenant): + def test_put_invalid_payload(self, app: Flask, patch_tenant): api = DocumentMetadataApi() method = unwrap(api.put) @@ -540,7 +542,7 @@ class TestDocumentMetadataApi: with pytest.raises(ValueError): method(api, "ds-1", "doc-1") - def test_put_invalid_doc_type(self, app, patch_tenant): + def test_put_invalid_doc_type(self, app: Flask, patch_tenant): api = DocumentMetadataApi() method = unwrap(api.put) @@ -559,7 +561,7 @@ class TestDocumentMetadataApi: class TestDocumentStatusApi: - def test_patch_success(self, app, patch_tenant, patch_dataset): + def test_patch_success(self, app: Flask, patch_tenant, patch_dataset): api = DocumentStatusApi() method = unwrap(api.patch) @@ -582,7 +584,7 @@ class TestDocumentStatusApi: assert status == 200 - def test_patch_invalid_action(self, app, patch_tenant, patch_dataset): + def test_patch_invalid_action(self, app: Flask, patch_tenant, patch_dataset): api = DocumentStatusApi() method = unwrap(api.patch) @@ -606,7 +608,7 @@ class TestDocumentStatusApi: class TestDocumentRetryApi: - def test_retry_archived_document_skipped(self, app, patch_tenant, patch_dataset): + def test_retry_archived_document_skipped(self, app: Flask, patch_tenant, patch_dataset): api = DocumentRetryApi() method = unwrap(api.post) @@ -634,7 +636,7 @@ class TestDocumentRetryApi: assert status == 204 retry_mock.assert_called_once_with("ds-1", []) - def test_retry_success(self, app, patch_tenant, patch_dataset): + def test_retry_success(self, app: Flask, patch_tenant, patch_dataset): api = DocumentRetryApi() method = unwrap(api.post) @@ -663,7 +665,7 @@ class TestDocumentRetryApi: assert status == 204 retry_mock.assert_called_once_with("ds-1", [document]) - def test_retry_skips_completed_document(self, app, patch_tenant, patch_dataset): + def test_retry_skips_completed_document(self, app: Flask, patch_tenant, patch_dataset): api = DocumentRetryApi() method = unwrap(api.post) @@ -690,7 +692,7 @@ class TestDocumentRetryApi: class TestDocumentPipelineExecutionLogApi: - def test_get_log_success(self, app, patch_tenant, patch_dataset): + def test_get_log_success(self, app: Flask, patch_tenant, patch_dataset): api = DocumentPipelineExecutionLogApi() method = unwrap(api.get) @@ -718,7 +720,7 @@ class TestDocumentPipelineExecutionLogApi: class TestDocumentGenerateSummaryApi: - def test_generate_summary_missing_documents(self, app, patch_tenant, patch_permission): + def test_generate_summary_missing_documents(self, app: Flask, patch_tenant, patch_permission): api = DocumentGenerateSummaryApi() method = unwrap(api.post) @@ -744,7 +746,7 @@ class TestDocumentGenerateSummaryApi: with pytest.raises(NotFound): method(api, "ds-1") - def test_generate_not_enabled(self, app, patch_tenant, patch_permission): + def test_generate_not_enabled(self, app: Flask, patch_tenant, patch_permission): api = DocumentGenerateSummaryApi() method = unwrap(api.post) @@ -763,7 +765,7 @@ class TestDocumentGenerateSummaryApi: with pytest.raises(ValueError): method(api, "ds-1") - def test_generate_summary_success_with_qa_skip(self, app, patch_tenant, patch_permission): + def test_generate_summary_success_with_qa_skip(self, app: Flask, patch_tenant, patch_permission): api = DocumentGenerateSummaryApi() method = unwrap(api.post) @@ -799,7 +801,7 @@ class TestDocumentGenerateSummaryApi: class TestDocumentSummaryStatusApi: - def test_get_success(self, app, patch_tenant, patch_permission): + def test_get_success(self, app: Flask, patch_tenant, patch_permission): api = DocumentSummaryStatusApi() method = unwrap(api.get) @@ -820,7 +822,7 @@ class TestDocumentSummaryStatusApi: class TestDocumentIndexingEstimateApi: - def test_indexing_estimate_file_not_found(self, app, patch_tenant): + def test_indexing_estimate_file_not_found(self, app: Flask, patch_tenant): api = DocumentIndexingEstimateApi() method = unwrap(api.get) @@ -844,7 +846,7 @@ class TestDocumentIndexingEstimateApi: with pytest.raises(NotFound): method(api, "ds-1", "doc-1") - def test_indexing_estimate_generic_exception(self, app, patch_tenant): + def test_indexing_estimate_generic_exception(self, app: Flask, patch_tenant): api = DocumentIndexingEstimateApi() method = unwrap(api.get) @@ -881,7 +883,7 @@ class TestDocumentIndexingEstimateApi: with pytest.raises(IndexingEstimateError): method(api, "ds-1", "doc-1") - def test_get_finished(self, app, patch_tenant): + def test_get_finished(self, app: Flask, patch_tenant): api = DocumentIndexingEstimateApi() method = unwrap(api.get) @@ -893,7 +895,7 @@ class TestDocumentIndexingEstimateApi: class TestDocumentBatchDownloadZipApi: - def test_post_no_documents(self, app, patch_tenant): + def test_post_no_documents(self, app: Flask, patch_tenant): api = DocumentBatchDownloadZipApi() method = unwrap(api.post) @@ -905,7 +907,7 @@ class TestDocumentBatchDownloadZipApi: class TestDatasetDocumentListApiDelete: - def test_delete_success(self, app, patch_tenant, patch_dataset): + def test_delete_success(self, app: Flask, patch_tenant, patch_dataset): """Test successful deletion of documents""" api = DatasetDocumentListApi() method = unwrap(api.delete) @@ -925,7 +927,7 @@ class TestDatasetDocumentListApiDelete: assert status == 204 - def test_delete_indexing_error(self, app, patch_tenant, patch_dataset): + def test_delete_indexing_error(self, app: Flask, patch_tenant, patch_dataset): """Test deletion with indexing error""" api = DatasetDocumentListApi() method = unwrap(api.delete) @@ -944,7 +946,7 @@ class TestDatasetDocumentListApiDelete: with pytest.raises(DocumentIndexingError): method(api, "ds-1") - def test_delete_dataset_not_found(self, app, patch_tenant): + def test_delete_dataset_not_found(self, app: Flask, patch_tenant): """Test deletion when dataset not found""" api = DatasetDocumentListApi() method = unwrap(api.delete) @@ -961,7 +963,7 @@ class TestDatasetDocumentListApiDelete: class TestDocumentBatchIndexingEstimateApi: - def test_batch_indexing_estimate_website(self, app, patch_tenant): + def test_batch_indexing_estimate_website(self, app: Flask, patch_tenant): api = DocumentBatchIndexingEstimateApi() method = unwrap(api.get) @@ -990,7 +992,7 @@ class TestDocumentBatchIndexingEstimateApi: assert status == 200 - def test_batch_indexing_estimate_notion(self, app, patch_tenant): + def test_batch_indexing_estimate_notion(self, app: Flask, patch_tenant): api = DocumentBatchIndexingEstimateApi() method = unwrap(api.get) @@ -1018,7 +1020,7 @@ class TestDocumentBatchIndexingEstimateApi: assert status == 200 - def test_batch_estimate_unsupported_datasource(self, app, patch_tenant): + def test_batch_estimate_unsupported_datasource(self, app: Flask, patch_tenant): api = DocumentBatchIndexingEstimateApi() method = unwrap(api.get) @@ -1033,7 +1035,7 @@ class TestDocumentBatchIndexingEstimateApi: with pytest.raises(ValueError): method(api, "ds-1", "batch-1") - def test_get_batch_estimate_invalid_batch(self, app, patch_tenant): + def test_get_batch_estimate_invalid_batch(self, app: Flask, patch_tenant): """Test batch estimation with invalid batch""" api = DocumentBatchIndexingEstimateApi() method = unwrap(api.get) @@ -1044,7 +1046,7 @@ class TestDocumentBatchIndexingEstimateApi: class TestDocumentBatchIndexingStatusApi: - def test_get_batch_status_invalid_batch(self, app, patch_tenant): + def test_get_batch_status_invalid_batch(self, app: Flask, patch_tenant): """Test batch status with invalid batch""" api = DocumentBatchIndexingStatusApi() method = unwrap(api.get) @@ -1055,7 +1057,7 @@ class TestDocumentBatchIndexingStatusApi: class TestDocumentIndexingStatusApi: - def test_get_status_document_not_found(self, app, patch_tenant): + def test_get_status_document_not_found(self, app: Flask, patch_tenant): """Test getting status for non-existent document""" api = DocumentIndexingStatusApi() method = unwrap(api.get) @@ -1066,7 +1068,7 @@ class TestDocumentIndexingStatusApi: class TestDocumentApiMetadata: - def test_get_with_only_option(self, app, patch_tenant): + def test_get_with_only_option(self, app: Flask, patch_tenant): """Test get with 'only' metadata option""" api = DocumentApi() method = unwrap(api.get) @@ -1085,7 +1087,7 @@ class TestDocumentApiMetadata: assert status == 200 - def test_get_with_without_option(self, app, patch_tenant): + def test_get_with_without_option(self, app: Flask, patch_tenant): """Test get with 'without' metadata option""" api = DocumentApi() method = unwrap(api.get) @@ -1106,7 +1108,7 @@ class TestDocumentApiMetadata: class TestDocumentGenerateSummaryApiSuccess: - def test_generate_not_enabled_high_quality(self, app, patch_tenant, patch_permission): + def test_generate_not_enabled_high_quality(self, app: Flask, patch_tenant, patch_permission): """Test summary generation on non-high-quality dataset""" api = DocumentGenerateSummaryApi() method = unwrap(api.post) @@ -1128,7 +1130,7 @@ class TestDocumentGenerateSummaryApiSuccess: class TestDocumentProcessingApiResume: - def test_resume_invalid_status(self, app, patch_tenant): + def test_resume_invalid_status(self, app: Flask, patch_tenant): """Test resume on non-paused document""" api = DocumentProcessingApi() method = unwrap(api.patch) @@ -1141,7 +1143,7 @@ class TestDocumentProcessingApiResume: class TestDocumentPermissionCases: - def test_document_batch_get_permission_denied(self, app, patch_tenant): + def test_document_batch_get_permission_denied(self, app: Flask, patch_tenant): api = DocumentBatchIndexingEstimateApi() method = unwrap(api.get) @@ -1159,7 +1161,7 @@ class TestDocumentPermissionCases: with pytest.raises(Forbidden): method(api, "ds-1", "batch-1") - def test_document_batch_get_documents_not_found(self, app, patch_tenant): + def test_document_batch_get_documents_not_found(self, app: Flask, patch_tenant): api = DocumentBatchIndexingEstimateApi() method = unwrap(api.get) @@ -1218,7 +1220,7 @@ class TestDocumentPermissionCases: with pytest.raises(Forbidden): method(api, "ds-1", "doc-1") - def test_process_rule_get_by_document_success(self, app, patch_tenant): + def test_process_rule_get_by_document_success(self, app: Flask, patch_tenant): api = GetProcessRuleApi() method = unwrap(api.get) @@ -1284,7 +1286,7 @@ class TestDocumentPermissionCases: class TestDocumentListAdvancedCases: - def test_document_list_with_multiple_sort_options(self, app, patch_tenant, patch_dataset, patch_permission): + def test_document_list_with_multiple_sort_options(self, app: Flask, patch_tenant, patch_dataset, patch_permission): """Test document list with different sort options""" api = DatasetDocumentListApi() method = unwrap(api.get) @@ -1310,7 +1312,7 @@ class TestDocumentListAdvancedCases: assert response["total"] == 1 - def test_document_metadata_with_schema_validation(self, app, patch_tenant): + def test_document_metadata_with_schema_validation(self, app: Flask, patch_tenant): """Test document metadata update with schema validation""" api = DocumentMetadataApi() method = unwrap(api.put) @@ -1342,7 +1344,7 @@ class TestDocumentListAdvancedCases: class TestDocumentIndexingEdgeCases: - def test_document_indexing_with_extraction_setting(self, app, patch_tenant): + def test_document_indexing_with_extraction_setting(self, app: Flask, patch_tenant): api = DocumentIndexingEstimateApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_external.py b/api/tests/unit_tests/controllers/console/datasets/test_external.py index 7254bf7670..186b379cbc 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_external.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_external.py @@ -292,7 +292,7 @@ class TestBedrockRetrievalApi: class TestExternalApiTemplateListApiAdvanced: - def test_post_duplicate_name_error(self, app, mock_auth, current_user): + def test_post_duplicate_name_error(self, app: Flask, mock_auth, current_user): api = ExternalApiTemplateListApi() method = unwrap(api.post) @@ -310,7 +310,7 @@ class TestExternalApiTemplateListApiAdvanced: with pytest.raises(DatasetNameDuplicateError): method(api) - def test_get_with_pagination(self, app, mock_auth, current_user): + def test_get_with_pagination(self, app: Flask, mock_auth, current_user): api = ExternalApiTemplateListApi() method = unwrap(api.get) @@ -331,7 +331,7 @@ class TestExternalApiTemplateListApiAdvanced: class TestExternalDatasetCreateApiAdvanced: - def test_create_forbidden(self, app, mock_auth, current_user): + def test_create_forbidden(self, app: Flask, mock_auth, current_user): """Test creating external dataset without permission""" api = ExternalDatasetCreateApi() method = unwrap(api.post) @@ -351,7 +351,7 @@ class TestExternalDatasetCreateApiAdvanced: class TestExternalKnowledgeHitTestingApiAdvanced: - def test_hit_testing_dataset_not_found(self, app, mock_auth, current_user): + def test_hit_testing_dataset_not_found(self, app: Flask, mock_auth, current_user): """Test hit testing on non-existent dataset""" api = ExternalKnowledgeHitTestingApi() method = unwrap(api.post) @@ -372,7 +372,7 @@ class TestExternalKnowledgeHitTestingApiAdvanced: with pytest.raises(NotFound): method(api, "ds-1") - def test_hit_testing_with_custom_retrieval_model(self, app, mock_auth, current_user): + def test_hit_testing_with_custom_retrieval_model(self, app: Flask, mock_auth, current_user): api = ExternalKnowledgeHitTestingApi() method = unwrap(api.post) @@ -402,7 +402,7 @@ class TestExternalKnowledgeHitTestingApiAdvanced: class TestBedrockRetrievalApiAdvanced: - def test_bedrock_retrieval_with_invalid_setting(self, app, mock_auth, current_user): + def test_bedrock_retrieval_with_invalid_setting(self, app: Flask, mock_auth, current_user): api = BedrockRetrievalApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_metadata.py b/api/tests/unit_tests/controllers/console/datasets/test_metadata.py index 4042190ff6..6322133536 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_metadata.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_metadata.py @@ -82,7 +82,7 @@ def bypass_decorators(mocker: MockerFixture): class TestDatasetMetadataCreateApi: - def test_create_metadata_success(self, app, current_user, dataset, dataset_id): + def test_create_metadata_success(self, app: Flask, current_user, dataset, dataset_id): api = DatasetMetadataCreateApi() method = unwrap(api.post) @@ -125,7 +125,7 @@ class TestDatasetMetadataCreateApi: assert status == 201 assert result["name"] == "author" - def test_create_metadata_dataset_not_found(self, app, current_user, dataset_id): + def test_create_metadata_dataset_not_found(self, app: Flask, current_user, dataset_id): api = DatasetMetadataCreateApi() method = unwrap(api.post) @@ -162,7 +162,7 @@ class TestDatasetMetadataCreateApi: class TestDatasetMetadataGetApi: - def test_get_metadata_success(self, app, dataset, dataset_id): + def test_get_metadata_success(self, app: Flask, dataset, dataset_id): api = DatasetMetadataCreateApi() method = unwrap(api.get) @@ -184,7 +184,7 @@ class TestDatasetMetadataGetApi: assert status == 200 assert isinstance(result, list) - def test_get_metadata_dataset_not_found(self, app, dataset_id): + def test_get_metadata_dataset_not_found(self, app: Flask, dataset_id): api = DatasetMetadataCreateApi() method = unwrap(api.get) @@ -201,7 +201,7 @@ class TestDatasetMetadataGetApi: class TestDatasetMetadataApi: - def test_update_metadata_success(self, app, current_user, dataset, dataset_id, metadata_id): + def test_update_metadata_success(self, app: Flask, current_user, dataset, dataset_id, metadata_id): api = DatasetMetadataApi() method = unwrap(api.patch) @@ -239,7 +239,7 @@ class TestDatasetMetadataApi: assert status == 200 assert result["name"] == "updated-name" - def test_delete_metadata_success(self, app, current_user, dataset, dataset_id, metadata_id): + def test_delete_metadata_success(self, app: Flask, current_user, dataset, dataset_id, metadata_id): api = DatasetMetadataApi() method = unwrap(api.delete) @@ -289,7 +289,7 @@ class TestDatasetMetadataBuiltInFieldApi: class TestDatasetMetadataBuiltInFieldActionApi: - def test_enable_built_in_field(self, app, current_user, dataset, dataset_id): + def test_enable_built_in_field(self, app: Flask, current_user, dataset, dataset_id): api = DatasetMetadataBuiltInFieldActionApi() method = unwrap(api.post) @@ -320,7 +320,7 @@ class TestDatasetMetadataBuiltInFieldActionApi: class TestDocumentMetadataEditApi: - def test_update_document_metadata_success(self, app, current_user, dataset, dataset_id): + def test_update_document_metadata_success(self, app: Flask, current_user, dataset, dataset_id): api = DocumentMetadataEditApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_website.py b/api/tests/unit_tests/controllers/console/datasets/test_website.py index 9991a0d345..5c7b857c20 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_website.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_website.py @@ -49,7 +49,7 @@ def bypass_auth_and_setup(mocker: MockerFixture): class TestWebsiteCrawlApi: - def test_crawl_success(self, app, mocker: MockerFixture): + def test_crawl_success(self, app: Flask, mocker: MockerFixture): api = WebsiteCrawlApi() method = unwrap(api.post) @@ -86,7 +86,7 @@ class TestWebsiteCrawlApi: assert status == 200 assert result["job_id"] == "job-1" - def test_crawl_invalid_payload(self, app, mocker: MockerFixture): + def test_crawl_invalid_payload(self, app: Flask, mocker: MockerFixture): api = WebsiteCrawlApi() method = unwrap(api.post) @@ -114,7 +114,7 @@ class TestWebsiteCrawlApi: with pytest.raises(WebsiteCrawlError, match="invalid payload"): method(api) - def test_crawl_service_error(self, app, mocker: MockerFixture): + def test_crawl_service_error(self, app: Flask, mocker: MockerFixture): api = WebsiteCrawlApi() method = unwrap(api.post) @@ -151,7 +151,7 @@ class TestWebsiteCrawlApi: class TestWebsiteCrawlStatusApi: - def test_get_status_success(self, app, mocker: MockerFixture): + def test_get_status_success(self, app: Flask, mocker: MockerFixture): api = WebsiteCrawlStatusApi() method = unwrap(api.get) @@ -182,7 +182,7 @@ class TestWebsiteCrawlStatusApi: assert status == 200 assert result["status"] == "completed" - def test_get_status_invalid_provider(self, app, mocker: MockerFixture): + def test_get_status_invalid_provider(self, app: Flask, mocker: MockerFixture): api = WebsiteCrawlStatusApi() method = unwrap(api.get) @@ -204,7 +204,7 @@ class TestWebsiteCrawlStatusApi: with pytest.raises(WebsiteCrawlError, match="invalid provider"): method(api, job_id) - def test_get_status_service_error(self, app, mocker: MockerFixture): + def test_get_status_service_error(self, app: Flask, mocker: MockerFixture): api = WebsiteCrawlStatusApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/explore/test_audio.py b/api/tests/unit_tests/controllers/console/explore/test_audio.py index b4b57022e2..a6642f8582 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_audio.py +++ b/api/tests/unit_tests/controllers/console/explore/test_audio.py @@ -2,6 +2,7 @@ from io import BytesIO from unittest.mock import MagicMock, patch import pytest +from flask import Flask from werkzeug.exceptions import InternalServerError import controllers.console.explore.audio as audio_module @@ -52,7 +53,7 @@ class TestChatAudioApi: self.api = audio_module.ChatAudioApi() self.method = unwrap(self.api.post) - def test_post_success(self, app, installed_app, audio_file): + def test_post_success(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -69,7 +70,7 @@ class TestChatAudioApi: assert resp == {"text": "ok"} - def test_app_unavailable(self, app, installed_app, audio_file): + def test_app_unavailable(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -85,7 +86,7 @@ class TestChatAudioApi: with pytest.raises(AppUnavailableError): self.method(installed_app) - def test_no_audio_uploaded(self, app, installed_app, audio_file): + def test_no_audio_uploaded(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -101,7 +102,7 @@ class TestChatAudioApi: with pytest.raises(NoAudioUploadedError): self.method(installed_app) - def test_audio_too_large(self, app, installed_app, audio_file): + def test_audio_too_large(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -117,7 +118,7 @@ class TestChatAudioApi: with pytest.raises(AudioTooLargeError): self.method(installed_app) - def test_provider_quota_exceeded(self, app, installed_app, audio_file): + def test_provider_quota_exceeded(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -133,7 +134,7 @@ class TestChatAudioApi: with pytest.raises(ProviderQuotaExceededError): self.method(installed_app) - def test_unknown_exception(self, app, installed_app, audio_file): + def test_unknown_exception(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -149,7 +150,7 @@ class TestChatAudioApi: with pytest.raises(InternalServerError): self.method(installed_app) - def test_unsupported_audio_type(self, app, installed_app, audio_file): + def test_unsupported_audio_type(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -165,7 +166,7 @@ class TestChatAudioApi: with pytest.raises(audio_module.UnsupportedAudioTypeError): self.method(installed_app) - def test_provider_not_support_speech_to_text(self, app, installed_app, audio_file): + def test_provider_not_support_speech_to_text(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -181,7 +182,7 @@ class TestChatAudioApi: with pytest.raises(audio_module.ProviderNotSupportSpeechToTextError): self.method(installed_app) - def test_provider_not_initialized(self, app, installed_app, audio_file): + def test_provider_not_initialized(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -197,7 +198,7 @@ class TestChatAudioApi: with pytest.raises(ProviderNotInitializeError): self.method(installed_app) - def test_model_currently_not_supported(self, app, installed_app, audio_file): + def test_model_currently_not_supported(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -213,7 +214,7 @@ class TestChatAudioApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): self.method(installed_app) - def test_invoke_error_asr(self, app, installed_app, audio_file): + def test_invoke_error_asr(self, app: Flask, installed_app, audio_file): with ( app.test_request_context( "/", @@ -235,7 +236,7 @@ class TestChatTextApi: self.api = audio_module.ChatTextApi() self.method = unwrap(self.api.post) - def test_post_success(self, app, installed_app): + def test_post_success(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -251,7 +252,7 @@ class TestChatTextApi: assert resp == {"audio": "ok"} - def test_provider_not_initialized(self, app, installed_app): + def test_provider_not_initialized(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -266,7 +267,7 @@ class TestChatTextApi: with pytest.raises(ProviderNotInitializeError): self.method(installed_app) - def test_model_not_supported(self, app, installed_app): + def test_model_not_supported(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -281,7 +282,7 @@ class TestChatTextApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): self.method(installed_app) - def test_invoke_error(self, app, installed_app): + def test_invoke_error(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -296,7 +297,7 @@ class TestChatTextApi: with pytest.raises(CompletionRequestError): self.method(installed_app) - def test_unknown_exception(self, app, installed_app): + def test_unknown_exception(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -311,7 +312,7 @@ class TestChatTextApi: with pytest.raises(InternalServerError): self.method(installed_app) - def test_app_unavailable_tts(self, app, installed_app): + def test_app_unavailable_tts(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -326,7 +327,7 @@ class TestChatTextApi: with pytest.raises(AppUnavailableError): self.method(installed_app) - def test_no_audio_uploaded_tts(self, app, installed_app): + def test_no_audio_uploaded_tts(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -341,7 +342,7 @@ class TestChatTextApi: with pytest.raises(NoAudioUploadedError): self.method(installed_app) - def test_audio_too_large_tts(self, app, installed_app): + def test_audio_too_large_tts(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -356,7 +357,7 @@ class TestChatTextApi: with pytest.raises(AudioTooLargeError): self.method(installed_app) - def test_unsupported_audio_type_tts(self, app, installed_app): + def test_unsupported_audio_type_tts(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -371,7 +372,7 @@ class TestChatTextApi: with pytest.raises(audio_module.UnsupportedAudioTypeError): self.method(installed_app) - def test_provider_not_support_speech_to_text_tts(self, app, installed_app): + def test_provider_not_support_speech_to_text_tts(self, app: Flask, installed_app): with ( app.test_request_context( "/", @@ -386,7 +387,7 @@ class TestChatTextApi: with pytest.raises(audio_module.ProviderNotSupportSpeechToTextError): self.method(installed_app) - def test_quota_exceeded_tts(self, app, installed_app): + def test_quota_exceeded_tts(self, app: Flask, installed_app): with ( app.test_request_context( "/", diff --git a/api/tests/unit_tests/controllers/console/explore/test_completion.py b/api/tests/unit_tests/controllers/console/explore/test_completion.py index 1dd16f3c59..eac93b1c46 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_completion.py +++ b/api/tests/unit_tests/controllers/console/explore/test_completion.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock, PropertyMock, patch import pytest +from flask import Flask from werkzeug.exceptions import InternalServerError import controllers.console.explore.completion as completion_module @@ -51,7 +52,7 @@ def payload_patch(payload_data): class TestCompletionApi: - def test_post_success(self, app, completion_app, user, payload_patch): + def test_post_success(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -83,7 +84,7 @@ class TestCompletionApi: with pytest.raises(NotCompletionAppError): method(installed_app) - def test_conversation_completed(self, app, completion_app, user, payload_patch): + def test_conversation_completed(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -100,7 +101,7 @@ class TestCompletionApi: with pytest.raises(ConversationCompletedError): method(completion_app) - def test_internal_error(self, app, completion_app, user, payload_patch): + def test_internal_error(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -117,7 +118,7 @@ class TestCompletionApi: with pytest.raises(InternalServerError): method(completion_app) - def test_conversation_not_exists(self, app, completion_app, user, payload_patch): + def test_conversation_not_exists(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -134,7 +135,7 @@ class TestCompletionApi: with pytest.raises(completion_module.NotFound): method(completion_app) - def test_app_unavailable(self, app, completion_app, user, payload_patch): + def test_app_unavailable(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -151,7 +152,7 @@ class TestCompletionApi: with pytest.raises(completion_module.AppUnavailableError): method(completion_app) - def test_provider_not_initialized(self, app, completion_app, user, payload_patch): + def test_provider_not_initialized(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -168,7 +169,7 @@ class TestCompletionApi: with pytest.raises(completion_module.ProviderNotInitializeError): method(completion_app) - def test_quota_exceeded(self, app, completion_app, user, payload_patch): + def test_quota_exceeded(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -185,7 +186,7 @@ class TestCompletionApi: with pytest.raises(completion_module.ProviderQuotaExceededError): method(completion_app) - def test_model_not_supported(self, app, completion_app, user, payload_patch): + def test_model_not_supported(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -202,7 +203,7 @@ class TestCompletionApi: with pytest.raises(completion_module.ProviderModelCurrentlyNotSupportError): method(completion_app) - def test_invoke_error(self, app, completion_app, user, payload_patch): + def test_invoke_error(self, app: Flask, completion_app, user, payload_patch): api = completion_module.CompletionApi() method = unwrap(api.post) @@ -247,7 +248,7 @@ class TestCompletionStopApi: class TestChatApi: - def test_post_success(self, app, chat_app, user, payload_patch): + def test_post_success(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -279,7 +280,7 @@ class TestChatApi: with pytest.raises(NotChatAppError): method(installed_app) - def test_rate_limit_error(self, app, chat_app, user, payload_patch): + def test_rate_limit_error(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -296,7 +297,7 @@ class TestChatApi: with pytest.raises(InvokeRateLimitHttpError): method(chat_app) - def test_conversation_completed_chat(self, app, chat_app, user, payload_patch): + def test_conversation_completed_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -313,7 +314,7 @@ class TestChatApi: with pytest.raises(ConversationCompletedError): method(chat_app) - def test_conversation_not_exists_chat(self, app, chat_app, user, payload_patch): + def test_conversation_not_exists_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -330,7 +331,7 @@ class TestChatApi: with pytest.raises(completion_module.NotFound): method(chat_app) - def test_app_unavailable_chat(self, app, chat_app, user, payload_patch): + def test_app_unavailable_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -347,7 +348,7 @@ class TestChatApi: with pytest.raises(completion_module.AppUnavailableError): method(chat_app) - def test_provider_not_initialized_chat(self, app, chat_app, user, payload_patch): + def test_provider_not_initialized_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -364,7 +365,7 @@ class TestChatApi: with pytest.raises(completion_module.ProviderNotInitializeError): method(chat_app) - def test_quota_exceeded_chat(self, app, chat_app, user, payload_patch): + def test_quota_exceeded_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -381,7 +382,7 @@ class TestChatApi: with pytest.raises(completion_module.ProviderQuotaExceededError): method(chat_app) - def test_model_not_supported_chat(self, app, chat_app, user, payload_patch): + def test_model_not_supported_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -398,7 +399,7 @@ class TestChatApi: with pytest.raises(completion_module.ProviderModelCurrentlyNotSupportError): method(chat_app) - def test_invoke_error_chat(self, app, chat_app, user, payload_patch): + def test_invoke_error_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) @@ -415,7 +416,7 @@ class TestChatApi: with pytest.raises(completion_module.CompletionRequestError): method(chat_app) - def test_internal_error_chat(self, app, chat_app, user, payload_patch): + def test_internal_error_chat(self, app: Flask, chat_app, user, payload_patch): api = completion_module.ChatApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/explore/test_installed_app.py b/api/tests/unit_tests/controllers/console/explore/test_installed_app.py index 93652e75d2..ec82803be4 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_installed_app.py +++ b/api/tests/unit_tests/controllers/console/explore/test_installed_app.py @@ -2,6 +2,7 @@ from datetime import datetime from unittest.mock import MagicMock, PropertyMock, patch import pytest +from flask import Flask from werkzeug.exceptions import BadRequest, Forbidden, NotFound import controllers.console.explore.installed_app as module @@ -51,7 +52,7 @@ def payload_patch(): class TestInstalledAppsListApi: - def test_get_installed_apps(self, app, current_user, tenant_id, installed_app): + def test_get_installed_apps(self, app: Flask, current_user, tenant_id, installed_app): api = module.InstalledAppsListApi() method = unwrap(api.get) @@ -75,7 +76,7 @@ class TestInstalledAppsListApi: assert result["installed_apps"][0]["editable"] is True assert result["installed_apps"][0]["uninstallable"] is False - def test_get_installed_apps_with_app_id_filter(self, app, current_user, tenant_id): + def test_get_installed_apps_with_app_id_filter(self, app: Flask, current_user, tenant_id): api = module.InstalledAppsListApi() method = unwrap(api.get) @@ -97,7 +98,7 @@ class TestInstalledAppsListApi: assert result == {"installed_apps": []} - def test_get_installed_apps_with_webapp_auth_enabled(self, app, current_user, tenant_id, installed_app): + def test_get_installed_apps_with_webapp_auth_enabled(self, app: Flask, current_user, tenant_id, installed_app): """Test filtering when webapp_auth is enabled.""" api = module.InstalledAppsListApi() method = unwrap(api.get) @@ -133,7 +134,7 @@ class TestInstalledAppsListApi: assert len(result["installed_apps"]) == 1 - def test_get_installed_apps_with_webapp_auth_user_denied(self, app, current_user, tenant_id, installed_app): + def test_get_installed_apps_with_webapp_auth_user_denied(self, app: Flask, current_user, tenant_id, installed_app): """Test filtering when user doesn't have access.""" api = module.InstalledAppsListApi() method = unwrap(api.get) @@ -169,7 +170,7 @@ class TestInstalledAppsListApi: assert result["installed_apps"] == [] - def test_get_installed_apps_with_sso_verified_access(self, app, current_user, tenant_id, installed_app): + def test_get_installed_apps_with_sso_verified_access(self, app: Flask, current_user, tenant_id, installed_app): """Test that sso_verified access mode apps are skipped in filtering.""" api = module.InstalledAppsListApi() method = unwrap(api.get) @@ -200,7 +201,7 @@ class TestInstalledAppsListApi: assert len(result["installed_apps"]) == 0 - def test_get_installed_apps_filters_null_apps(self, app, current_user, tenant_id): + def test_get_installed_apps_filters_null_apps(self, app: Flask, current_user, tenant_id): """Test that installed apps with null app are filtered out.""" api = module.InstalledAppsListApi() method = unwrap(api.get) @@ -226,7 +227,7 @@ class TestInstalledAppsListApi: assert result["installed_apps"] == [] - def test_get_installed_apps_current_tenant_none(self, app, tenant_id, installed_app): + def test_get_installed_apps_current_tenant_none(self, app: Flask, tenant_id, installed_app): """Test error when current_user.current_tenant is None.""" api = module.InstalledAppsListApi() method = unwrap(api.get) @@ -247,7 +248,7 @@ class TestInstalledAppsListApi: class TestInstalledAppsCreateApi: - def test_post_success(self, app, tenant_id, payload_patch): + def test_post_success(self, app: Flask, tenant_id, payload_patch): api = module.InstalledAppsListApi() method = unwrap(api.post) @@ -276,7 +277,7 @@ class TestInstalledAppsCreateApi: assert result == {"message": "App installed successfully"} assert recommended.install_count == 1 - def test_post_recommended_not_found(self, app, payload_patch): + def test_post_recommended_not_found(self, app: Flask, payload_patch): api = module.InstalledAppsListApi() method = unwrap(api.post) @@ -291,7 +292,7 @@ class TestInstalledAppsCreateApi: with pytest.raises(NotFound): method(api) - def test_post_app_not_public(self, app, tenant_id, payload_patch): + def test_post_app_not_public(self, app: Flask, tenant_id, payload_patch): api = module.InstalledAppsListApi() method = unwrap(api.post) @@ -315,7 +316,7 @@ class TestInstalledAppsCreateApi: class TestInstalledAppApi: - def test_delete_success(self, tenant_id, installed_app): + def test_delete_success(self, tenant_id: str, installed_app): api = module.InstalledAppApi() method = unwrap(api.delete) @@ -328,7 +329,7 @@ class TestInstalledAppApi: assert status == 204 assert resp["result"] == "success" - def test_delete_owned_by_current_tenant(self, tenant_id): + def test_delete_owned_by_current_tenant(self, tenant_id: str): api = module.InstalledAppApi() method = unwrap(api.delete) @@ -338,7 +339,7 @@ class TestInstalledAppApi: with pytest.raises(BadRequest): method(installed_app) - def test_patch_update_pin(self, app, payload_patch, installed_app): + def test_patch_update_pin(self, app: Flask, payload_patch, installed_app): api = module.InstalledAppApi() method = unwrap(api.patch) @@ -352,7 +353,7 @@ class TestInstalledAppApi: assert installed_app.is_pinned is True assert result["result"] == "success" - def test_patch_no_change(self, app, payload_patch, installed_app): + def test_patch_no_change(self, app: Flask, payload_patch, installed_app): api = module.InstalledAppApi() method = unwrap(api.patch) diff --git a/api/tests/unit_tests/controllers/console/explore/test_saved_message.py b/api/tests/unit_tests/controllers/console/explore/test_saved_message.py index 71241890e9..49e5695e60 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_saved_message.py +++ b/api/tests/unit_tests/controllers/console/explore/test_saved_message.py @@ -82,7 +82,7 @@ class TestSavedMessageListApi: with pytest.raises(NotCompletionAppError): method(installed_app) - def test_post_success(self, app, payload_patch): + def test_post_success(self, app: Flask, payload_patch): api = module.SavedMessageListApi() method = unwrap(api.post) @@ -102,7 +102,7 @@ class TestSavedMessageListApi: save_mock.assert_called_once() assert result == {"result": "success"} - def test_post_message_not_exists(self, app, payload_patch): + def test_post_message_not_exists(self, app: Flask, payload_patch): api = module.SavedMessageListApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/explore/test_trial.py b/api/tests/unit_tests/controllers/console/explore/test_trial.py index 82a063307b..641209d1de 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_trial.py +++ b/api/tests/unit_tests/controllers/console/explore/test_trial.py @@ -102,7 +102,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(NotWorkflowAppError): method(api, MagicMock(mode=AppMode.CHAT)) - def test_success(self, app, trial_app_workflow, account): + def test_success(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -116,7 +116,7 @@ class TestTrialAppWorkflowRunApi: assert result is not None - def test_workflow_provider_not_init(self, app, trial_app_workflow, account): + def test_workflow_provider_not_init(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -132,7 +132,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ProviderNotInitializeError): method(api, trial_app_workflow) - def test_workflow_quota_exceeded(self, app, trial_app_workflow, account): + def test_workflow_quota_exceeded(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -148,7 +148,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ProviderQuotaExceededError): method(api, trial_app_workflow) - def test_workflow_model_not_support(self, app, trial_app_workflow, account): + def test_workflow_model_not_support(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -164,7 +164,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, trial_app_workflow) - def test_workflow_invoke_error(self, app, trial_app_workflow, account): + def test_workflow_invoke_error(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -180,7 +180,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(CompletionRequestError): method(api, trial_app_workflow) - def test_workflow_rate_limit_error(self, app, trial_app_workflow, account): + def test_workflow_rate_limit_error(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -196,7 +196,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(InvokeRateLimitHttpError): method(api, trial_app_workflow) - def test_workflow_value_error(self, app, trial_app_workflow, account): + def test_workflow_value_error(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -212,7 +212,7 @@ class TestTrialAppWorkflowRunApi: with pytest.raises(ValueError): method(api, trial_app_workflow) - def test_workflow_generic_exception(self, app, trial_app_workflow, account): + def test_workflow_generic_exception(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowRunApi() method = unwrap(api.post) @@ -238,7 +238,7 @@ class TestTrialChatApi: with pytest.raises(NotChatAppError): method(api, MagicMock(mode="completion")) - def test_success(self, app, trial_app_chat, account): + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -252,7 +252,7 @@ class TestTrialChatApi: assert result is not None - def test_chat_conversation_not_exists(self, app, trial_app_chat, account): + def test_chat_conversation_not_exists(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -268,7 +268,7 @@ class TestTrialChatApi: with pytest.raises(NotFound): method(api, trial_app_chat) - def test_chat_conversation_completed(self, app, trial_app_chat, account): + def test_chat_conversation_completed(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -284,7 +284,7 @@ class TestTrialChatApi: with pytest.raises(ConversationCompletedError): method(api, trial_app_chat) - def test_chat_app_config_broken(self, app, trial_app_chat, account): + def test_chat_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -300,7 +300,7 @@ class TestTrialChatApi: with pytest.raises(AppUnavailableError): method(api, trial_app_chat) - def test_chat_provider_not_init(self, app, trial_app_chat, account): + def test_chat_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -316,7 +316,7 @@ class TestTrialChatApi: with pytest.raises(ProviderNotInitializeError): method(api, trial_app_chat) - def test_chat_quota_exceeded(self, app, trial_app_chat, account): + def test_chat_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -332,7 +332,7 @@ class TestTrialChatApi: with pytest.raises(ProviderQuotaExceededError): method(api, trial_app_chat) - def test_chat_model_not_support(self, app, trial_app_chat, account): + def test_chat_model_not_support(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -348,7 +348,7 @@ class TestTrialChatApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, trial_app_chat) - def test_chat_invoke_error(self, app, trial_app_chat, account): + def test_chat_invoke_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -364,7 +364,7 @@ class TestTrialChatApi: with pytest.raises(CompletionRequestError): method(api, trial_app_chat) - def test_chat_rate_limit_error(self, app, trial_app_chat, account): + def test_chat_rate_limit_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -380,7 +380,7 @@ class TestTrialChatApi: with pytest.raises(InvokeRateLimitHttpError): method(api, trial_app_chat) - def test_chat_value_error(self, app, trial_app_chat, account): + def test_chat_value_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -396,7 +396,7 @@ class TestTrialChatApi: with pytest.raises(ValueError): method(api, trial_app_chat) - def test_chat_generic_exception(self, app, trial_app_chat, account): + def test_chat_generic_exception(self, app: Flask, trial_app_chat, account): api = module.TrialChatApi() method = unwrap(api.post) @@ -422,7 +422,7 @@ class TestTrialCompletionApi: with pytest.raises(NotCompletionAppError): method(api, MagicMock(mode=AppMode.CHAT)) - def test_success(self, app, trial_app_completion, account): + def test_success(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -436,7 +436,7 @@ class TestTrialCompletionApi: assert result is not None - def test_completion_app_config_broken(self, app, trial_app_completion, account): + def test_completion_app_config_broken(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -452,7 +452,7 @@ class TestTrialCompletionApi: with pytest.raises(AppUnavailableError): method(api, trial_app_completion) - def test_completion_provider_not_init(self, app, trial_app_completion, account): + def test_completion_provider_not_init(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -468,7 +468,7 @@ class TestTrialCompletionApi: with pytest.raises(ProviderNotInitializeError): method(api, trial_app_completion) - def test_completion_quota_exceeded(self, app, trial_app_completion, account): + def test_completion_quota_exceeded(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -484,7 +484,7 @@ class TestTrialCompletionApi: with pytest.raises(ProviderQuotaExceededError): method(api, trial_app_completion) - def test_completion_model_not_support(self, app, trial_app_completion, account): + def test_completion_model_not_support(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -500,7 +500,7 @@ class TestTrialCompletionApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, trial_app_completion) - def test_completion_invoke_error(self, app, trial_app_completion, account): + def test_completion_invoke_error(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -516,7 +516,7 @@ class TestTrialCompletionApi: with pytest.raises(CompletionRequestError): method(api, trial_app_completion) - def test_completion_rate_limit_error(self, app, trial_app_completion, account): + def test_completion_rate_limit_error(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -532,7 +532,7 @@ class TestTrialCompletionApi: with pytest.raises(InternalServerError): method(api, trial_app_completion) - def test_completion_value_error(self, app, trial_app_completion, account): + def test_completion_value_error(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -548,7 +548,7 @@ class TestTrialCompletionApi: with pytest.raises(ValueError): method(api, trial_app_completion) - def test_completion_generic_exception(self, app, trial_app_completion, account): + def test_completion_generic_exception(self, app: Flask, trial_app_completion, account): api = module.TrialCompletionApi() method = unwrap(api.post) @@ -574,7 +574,7 @@ class TestTrialMessageSuggestedQuestionApi: with pytest.raises(NotChatAppError): method(MagicMock(mode="completion"), str(uuid4())) - def test_success(self, app, trial_app_chat, account): + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialMessageSuggestedQuestionApi() method = unwrap(api.get) @@ -591,7 +591,7 @@ class TestTrialMessageSuggestedQuestionApi: assert result == {"data": ["q1", "q2"]} - def test_conversation_not_exists(self, app, trial_app_chat, account): + def test_conversation_not_exists(self, app: Flask, trial_app_chat, account): api = module.TrialMessageSuggestedQuestionApi() method = unwrap(api.get) @@ -643,7 +643,7 @@ class TestTrialAppParameterApi: class TestTrialChatAudioApi: - def test_success(self, app, trial_app_chat, account): + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -662,7 +662,7 @@ class TestTrialChatAudioApi: assert result == {"text": "hello"} - def test_app_config_broken(self, app, trial_app_chat, account): + def test_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -683,7 +683,7 @@ class TestTrialChatAudioApi: with pytest.raises(module.AppUnavailableError): method(api, trial_app_chat) - def test_no_audio_uploaded(self, app, trial_app_chat, account): + def test_no_audio_uploaded(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -704,7 +704,7 @@ class TestTrialChatAudioApi: with pytest.raises(module.NoAudioUploadedError): method(api, trial_app_chat) - def test_audio_too_large(self, app, trial_app_chat, account): + def test_audio_too_large(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -725,7 +725,7 @@ class TestTrialChatAudioApi: with pytest.raises(module.AudioTooLargeError): method(api, trial_app_chat) - def test_unsupported_audio_type(self, app, trial_app_chat, account): + def test_unsupported_audio_type(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -746,7 +746,7 @@ class TestTrialChatAudioApi: with pytest.raises(module.UnsupportedAudioTypeError): method(api, trial_app_chat) - def test_provider_not_support_tts(self, app, trial_app_chat, account): + def test_provider_not_support_tts(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -767,7 +767,7 @@ class TestTrialChatAudioApi: with pytest.raises(module.ProviderNotSupportSpeechToTextError): method(api, trial_app_chat) - def test_provider_not_init(self, app, trial_app_chat, account): + def test_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -784,7 +784,7 @@ class TestTrialChatAudioApi: with pytest.raises(ProviderNotInitializeError): method(api, trial_app_chat) - def test_quota_exceeded(self, app, trial_app_chat, account): + def test_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -803,7 +803,7 @@ class TestTrialChatAudioApi: class TestTrialChatTextApi: - def test_success(self, app, trial_app_chat, account): + def test_success(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -817,7 +817,7 @@ class TestTrialChatTextApi: assert result == {"audio": "base64_data"} - def test_app_config_broken(self, app, trial_app_chat, account): + def test_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -833,7 +833,7 @@ class TestTrialChatTextApi: with pytest.raises(module.AppUnavailableError): method(api, trial_app_chat) - def test_provider_not_support(self, app, trial_app_chat, account): + def test_provider_not_support(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -849,7 +849,7 @@ class TestTrialChatTextApi: with pytest.raises(module.ProviderNotSupportSpeechToTextError): method(api, trial_app_chat) - def test_audio_too_large(self, app, trial_app_chat, account): + def test_audio_too_large(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -865,7 +865,7 @@ class TestTrialChatTextApi: with pytest.raises(module.AudioTooLargeError): method(api, trial_app_chat) - def test_no_audio_uploaded(self, app, trial_app_chat, account): + def test_no_audio_uploaded(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -881,7 +881,7 @@ class TestTrialChatTextApi: with pytest.raises(module.NoAudioUploadedError): method(api, trial_app_chat) - def test_provider_not_init(self, app, trial_app_chat, account): + def test_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -893,7 +893,7 @@ class TestTrialChatTextApi: with pytest.raises(ProviderNotInitializeError): method(api, trial_app_chat) - def test_quota_exceeded(self, app, trial_app_chat, account): + def test_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -905,7 +905,7 @@ class TestTrialChatTextApi: with pytest.raises(ProviderQuotaExceededError): method(api, trial_app_chat) - def test_model_not_support(self, app, trial_app_chat, account): + def test_model_not_support(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -917,7 +917,7 @@ class TestTrialChatTextApi: with pytest.raises(ProviderModelCurrentlyNotSupportError): method(api, trial_app_chat) - def test_invoke_error(self, app, trial_app_chat, account): + def test_invoke_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -931,7 +931,7 @@ class TestTrialChatTextApi: class TestTrialAppWorkflowTaskStopApi: - def test_not_workflow_app(self, app, trial_app_chat): + def test_not_workflow_app(self, app: Flask, trial_app_chat): api = module.TrialAppWorkflowTaskStopApi() method = unwrap(api.post) @@ -939,7 +939,7 @@ class TestTrialAppWorkflowTaskStopApi: with pytest.raises(NotWorkflowAppError): method(api, trial_app_chat, str(uuid4())) - def test_success(self, app, trial_app_workflow, account): + def test_success(self, app: Flask, trial_app_workflow, account): api = module.TrialAppWorkflowTaskStopApi() method = unwrap(api.post) @@ -1009,7 +1009,7 @@ class TestTrialSitApi: class TestTrialChatAudioApiExceptionHandlers: - def test_provider_not_init(self, app, trial_app_chat, account): + def test_provider_not_init(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -1030,7 +1030,7 @@ class TestTrialChatAudioApiExceptionHandlers: with pytest.raises(ProviderNotInitializeError): method(api, trial_app_chat) - def test_quota_exceeded(self, app, trial_app_chat, account): + def test_quota_exceeded(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -1051,7 +1051,7 @@ class TestTrialChatAudioApiExceptionHandlers: with pytest.raises(ProviderQuotaExceededError): method(api, trial_app_chat) - def test_invoke_error(self, app, trial_app_chat, account): + def test_invoke_error(self, app: Flask, trial_app_chat, account): api = module.TrialChatAudioApi() method = unwrap(api.post) @@ -1074,7 +1074,7 @@ class TestTrialChatAudioApiExceptionHandlers: class TestTrialChatTextApiExceptionHandlers: - def test_app_config_broken(self, app, trial_app_chat, account): + def test_app_config_broken(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) @@ -1090,7 +1090,7 @@ class TestTrialChatTextApiExceptionHandlers: with pytest.raises(module.AppUnavailableError): method(api, trial_app_chat) - def test_unsupported_audio_type(self, app, trial_app_chat, account): + def test_unsupported_audio_type(self, app: Flask, trial_app_chat, account): api = module.TrialChatTextApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/explore/test_workflow.py b/api/tests/unit_tests/controllers/console/explore/test_workflow.py index 445f887fd3..3a01925204 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_workflow.py +++ b/api/tests/unit_tests/controllers/console/explore/test_workflow.py @@ -57,7 +57,7 @@ def payload(): class TestInstalledAppWorkflowRunApi: - def test_not_workflow_app(self, app, non_workflow_installed_app): + def test_not_workflow_app(self, app: Flask, non_workflow_installed_app): api = InstalledAppWorkflowRunApi() method = unwrap(api.post) @@ -71,7 +71,7 @@ class TestInstalledAppWorkflowRunApi: with pytest.raises(NotWorkflowAppError): method(non_workflow_installed_app) - def test_success(self, app, installed_workflow_app, user, payload): + def test_success(self, app: Flask, installed_workflow_app, user, payload): api = InstalledAppWorkflowRunApi() method = unwrap(api.post) @@ -91,7 +91,7 @@ class TestInstalledAppWorkflowRunApi: generate_mock.assert_called_once() assert result is not None - def test_rate_limit_error(self, app, installed_workflow_app, user, payload): + def test_rate_limit_error(self, app: Flask, installed_workflow_app, user, payload): api = InstalledAppWorkflowRunApi() method = unwrap(api.post) @@ -109,7 +109,7 @@ class TestInstalledAppWorkflowRunApi: with pytest.raises(InvokeRateLimitHttpError): method(installed_workflow_app) - def test_unexpected_exception(self, app, installed_workflow_app, user, payload): + def test_unexpected_exception(self, app: Flask, installed_workflow_app, user, payload): api = InstalledAppWorkflowRunApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/tag/test_tags.py b/api/tests/unit_tests/controllers/console/tag/test_tags.py index b44706c566..f4916f013c 100644 --- a/api/tests/unit_tests/controllers/console/tag/test_tags.py +++ b/api/tests/unit_tests/controllers/console/tag/test_tags.py @@ -101,7 +101,7 @@ class TestTagListApi: assert status == 200 assert result == [{"id": "1", "name": "tag", "type": "knowledge", "binding_count": "1"}] - def test_post_success(self, app, admin_user, tag, payload_patch): + def test_post_success(self, app: Flask, admin_user, tag, payload_patch): api = TagListApi() method = unwrap(api.post) @@ -144,7 +144,7 @@ class TestTagListApi: class TestTagUpdateDeleteApi: - def test_patch_success(self, app, admin_user, tag, payload_patch): + def test_patch_success(self, app: Flask, admin_user, tag, payload_patch): api = TagUpdateDeleteApi() method = unwrap(api.patch) @@ -191,7 +191,7 @@ class TestTagUpdateDeleteApi: with pytest.raises(Forbidden): method(api, "tag-1") - def test_delete_success(self, app, admin_user): + def test_delete_success(self, app: Flask, admin_user): api = TagUpdateDeleteApi() method = unwrap(api.delete) @@ -210,7 +210,7 @@ class TestTagUpdateDeleteApi: class TestTagBindingCollectionApi: - def test_create_success(self, app, admin_user, payload_patch): + def test_create_success(self, app: Flask, admin_user, payload_patch): api = TagBindingCollectionApi() method = unwrap(api.post) @@ -252,7 +252,7 @@ class TestTagBindingCollectionApi: class TestTagBindingRemoveApi: - def test_remove_success(self, app, admin_user, payload_patch): + def test_remove_success(self, app: Flask, admin_user, payload_patch): api = TagBindingRemoveApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/test_files.py b/api/tests/unit_tests/controllers/console/test_files.py index acae081b98..9274f6cf61 100644 --- a/api/tests/unit_tests/controllers/console/test_files.py +++ b/api/tests/unit_tests/controllers/console/test_files.py @@ -95,7 +95,7 @@ class TestFileApiGet: class TestFileApiPost: - def test_no_file_uploaded(self, app, mock_account_context): + def test_no_file_uploaded(self, app: Flask, mock_account_context): api = FileApi() post_method = unwrap(api.post) @@ -103,7 +103,7 @@ class TestFileApiPost: with pytest.raises(NoFileUploadedError): post_method(api) - def test_too_many_files(self, app, mock_account_context): + def test_too_many_files(self, app: Flask, mock_account_context): api = FileApi() post_method = unwrap(api.post) @@ -120,7 +120,7 @@ class TestFileApiPost: with pytest.raises(TooManyFilesError): post_method(api) - def test_filename_missing(self, app, mock_account_context): + def test_filename_missing(self, app: Flask, mock_account_context): api = FileApi() post_method = unwrap(api.post) @@ -132,7 +132,7 @@ class TestFileApiPost: with pytest.raises(FilenameNotExistsError): post_method(api) - def test_dataset_upload_without_permission(self, app, mock_current_user): + def test_dataset_upload_without_permission(self, app: Flask, mock_current_user): mock_current_user.is_dataset_editor = False with patch( @@ -151,7 +151,7 @@ class TestFileApiPost: with pytest.raises(Forbidden): post_method(api) - def test_successful_upload(self, app, mock_account_context, mock_file_service): + def test_successful_upload(self, app: Flask, mock_account_context, mock_file_service): api = FileApi() post_method = unwrap(api.post) @@ -185,7 +185,7 @@ class TestFileApiPost: assert response["id"] == "file-id-123" assert response["name"] == "test.txt" - def test_upload_with_invalid_source(self, app, mock_account_context, mock_file_service): + def test_upload_with_invalid_source(self, app: Flask, mock_account_context, mock_file_service): """Test that invalid source parameter gets normalized to None""" api = FileApi() post_method = unwrap(api.post) @@ -225,7 +225,7 @@ class TestFileApiPost: call_kwargs = mock_file_service.upload_file.call_args[1] assert call_kwargs["source"] is None - def test_file_too_large_error(self, app, mock_account_context, mock_file_service): + def test_file_too_large_error(self, app: Flask, mock_account_context, mock_file_service): api = FileApi() post_method = unwrap(api.post) @@ -242,7 +242,7 @@ class TestFileApiPost: with pytest.raises(FileTooLargeError): post_method(api) - def test_unsupported_file_type(self, app, mock_account_context, mock_file_service): + def test_unsupported_file_type(self, app: Flask, mock_account_context, mock_file_service): api = FileApi() post_method = unwrap(api.post) @@ -259,7 +259,7 @@ class TestFileApiPost: with pytest.raises(UnsupportedFileTypeError): post_method(api) - def test_blocked_extension(self, app, mock_account_context, mock_file_service): + def test_blocked_extension(self, app: Flask, mock_account_context, mock_file_service): api = FileApi() post_method = unwrap(api.post) @@ -278,7 +278,7 @@ class TestFileApiPost: class TestFilePreviewApi: - def test_get_preview(self, app, mock_account_context, mock_file_service): + def test_get_preview(self, app: Flask, mock_account_context, mock_file_service): api = FilePreviewApi() get_method = unwrap(api.get) mock_file_service.get_file_preview.return_value = "preview text" diff --git a/api/tests/unit_tests/controllers/console/workspace/test_accounts.py b/api/tests/unit_tests/controllers/console/workspace/test_accounts.py index 064726da05..df0d2bda49 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_accounts.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_accounts.py @@ -114,7 +114,7 @@ class TestAccountUpdateApis: (AccountTimezoneApi, {"timezone": "UTC"}), ], ) - def test_update_success(self, app, api_cls, payload): + def test_update_success(self, app: Flask, api_cls, payload): api = api_cls() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_plugin.py b/api/tests/unit_tests/controllers/console/workspace/test_plugin.py index d01bf7d668..83915a0b74 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_plugin.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_plugin.py @@ -302,7 +302,7 @@ class TestPluginFetchPermissionApi: class TestPluginFetchDynamicSelectOptionsApi: - def test_fetch_dynamic_options(self, app, user): + def test_fetch_dynamic_options(self, app: Flask, user): api = PluginFetchDynamicSelectOptionsApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/service_api/app/test_annotation.py b/api/tests/unit_tests/controllers/service_api/app/test_annotation.py index b16ad38c7c..2ab5547cd4 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_annotation.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_annotation.py @@ -17,6 +17,7 @@ from types import SimpleNamespace from unittest.mock import Mock import pytest +from flask import Flask from flask_restx.api import HTTPStatus from controllers.service_api.app.annotation import ( @@ -163,7 +164,7 @@ class TestAnnotationErrorPatterns: class TestAnnotationReplyActionApi: - def test_enable(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_enable(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: enable_mock = Mock() monkeypatch.setattr(AppAnnotationService, "enable_app_annotation", enable_mock) @@ -181,7 +182,7 @@ class TestAnnotationReplyActionApi: assert status == 200 enable_mock.assert_called_once() - def test_disable(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_disable(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: disable_mock = Mock() monkeypatch.setattr(AppAnnotationService, "disable_app_annotation", disable_mock) @@ -231,7 +232,7 @@ class TestAnnotationReplyActionStatusApi: class TestAnnotationListApi: - def test_get(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_get(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: annotation = SimpleNamespace(id="a1", question="q", content="a", created_at=0) monkeypatch.setattr( AppAnnotationService, @@ -248,7 +249,7 @@ class TestAnnotationListApi: assert response["total"] == 1 - def test_create(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_create(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: annotation = SimpleNamespace(id="a1", question="q", content="a", created_at=0) monkeypatch.setattr( AppAnnotationService, @@ -268,7 +269,7 @@ class TestAnnotationListApi: class TestAnnotationUpdateDeleteApi: - def test_update_delete(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_update_delete(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: annotation = SimpleNamespace(id="a1", question="q", content="a", created_at=0) monkeypatch.setattr( AppAnnotationService, diff --git a/api/tests/unit_tests/controllers/service_api/app/test_completion.py b/api/tests/unit_tests/controllers/service_api/app/test_completion.py index 259741937f..a60b3b18bd 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_completion.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_completion.py @@ -415,7 +415,7 @@ class TestChatRequestPayloadController: class TestCompletionApiController: - def test_wrong_mode(self, app) -> None: + def test_wrong_mode(self, app: Flask) -> None: api = CompletionApi() handler = _unwrap(api.post) app_model = SimpleNamespace(mode=AppMode.CHAT.value) @@ -425,7 +425,7 @@ class TestCompletionApiController: with pytest.raises(AppUnavailableError): handler(api, app_model=app_model, end_user=end_user) - def test_conversation_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_conversation_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AppGenerateService, "generate", @@ -443,7 +443,7 @@ class TestCompletionApiController: class TestCompletionStopApiController: - def test_wrong_mode(self, app) -> None: + def test_wrong_mode(self, app: Flask) -> None: api = CompletionStopApi() handler = _unwrap(api.post) app_model = SimpleNamespace(mode=AppMode.CHAT.value) @@ -453,7 +453,7 @@ class TestCompletionStopApiController: with pytest.raises(AppUnavailableError): handler(api, app_model=app_model, end_user=end_user, task_id="t1") - def test_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: stop_mock = Mock() monkeypatch.setattr(AppTaskService, "stop_task", stop_mock) @@ -470,7 +470,7 @@ class TestCompletionStopApiController: class TestChatApiController: - def test_wrong_mode(self, app) -> None: + def test_wrong_mode(self, app: Flask) -> None: api = ChatApi() handler = _unwrap(api.post) app_model = SimpleNamespace(mode=AppMode.COMPLETION.value) @@ -480,7 +480,7 @@ class TestChatApiController: with pytest.raises(NotChatAppError): handler(api, app_model=app_model, end_user=end_user) - def test_workflow_not_found(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_workflow_not_found(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AppGenerateService, "generate", @@ -496,7 +496,7 @@ class TestChatApiController: with pytest.raises(NotFound): handler(api, app_model=app_model, end_user=end_user) - def test_draft_workflow(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_draft_workflow(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( AppGenerateService, "generate", @@ -514,10 +514,10 @@ class TestChatApiController: class TestChatStopApiController: - def test_wrong_mode(self, app) -> None: + def test_wrong_mode(self, app: Flask) -> None: api = ChatStopApi() handler = _unwrap(api.post) - app_model = SimpleNamespace(mode=AppMode.COMPLETION.value) + app_model = SimpleNamespace(mode=AppMode.COMPLETION) end_user = SimpleNamespace(id="u1") with app.test_request_context("/chat-messages/1/stop", method="POST"): diff --git a/api/tests/unit_tests/controllers/service_api/app/test_conversation.py b/api/tests/unit_tests/controllers/service_api/app/test_conversation.py index 74c13d50f6..52a7aa2189 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_conversation.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_conversation.py @@ -495,7 +495,7 @@ class TestConversationPayloadsController: class TestConversationApiController: - def test_list_not_chat(self, app) -> None: + def test_list_not_chat(self, app: Flask) -> None: api = ConversationApi() handler = _unwrap(api.get) app_model = SimpleNamespace(mode=AppMode.COMPLETION) @@ -543,7 +543,7 @@ class TestConversationApiController: class TestConversationDetailApiController: - def test_delete_not_chat(self, app) -> None: + def test_delete_not_chat(self, app: Flask) -> None: api = ConversationDetailApi() handler = _unwrap(api.delete) app_model = SimpleNamespace(mode=AppMode.COMPLETION) @@ -593,7 +593,7 @@ class TestConversationRenameApiController: class TestConversationVariablesApiController: - def test_not_chat(self, app) -> None: + def test_not_chat(self, app: Flask) -> None: api = ConversationVariablesApi() handler = _unwrap(api.get) app_model = SimpleNamespace(mode=AppMode.COMPLETION) diff --git a/api/tests/unit_tests/controllers/service_api/app/test_file.py b/api/tests/unit_tests/controllers/service_api/app/test_file.py index 2615c3edac..88ebe955a8 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_file.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_file.py @@ -238,7 +238,7 @@ class TestFileApiPost: self, mock_db, mock_file_svc_cls, - app, + app: Flask, mock_app_model, mock_end_user, ): @@ -342,7 +342,7 @@ class TestFileApiPost: self, mock_db, mock_file_svc_cls, - app, + app: Flask, mock_app_model, mock_end_user, ): @@ -374,7 +374,7 @@ class TestFileApiPost: self, mock_db, mock_file_svc_cls, - app, + app: Flask, mock_app_model, mock_end_user, ): diff --git a/api/tests/unit_tests/controllers/service_api/app/test_file_preview.py b/api/tests/unit_tests/controllers/service_api/app/test_file_preview.py index d83c22f2cf..f5e8453c5c 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_file_preview.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_file_preview.py @@ -66,7 +66,7 @@ class TestFilePreviewApi: return message def test_validate_file_ownership_success( - self, file_preview_api, mock_app, mock_upload_file, mock_message_file, mock_message + self, file_preview_api: FilePreviewApi, mock_app, mock_upload_file, mock_message_file, mock_message ): """Test successful file ownership validation""" file_id = str(uuid.uuid4()) @@ -97,7 +97,7 @@ class TestFilePreviewApi: assert result_message_file == mock_message_file assert result_upload_file == mock_upload_file - def test_validate_file_ownership_file_not_found(self, file_preview_api): + def test_validate_file_ownership_file_not_found(self, file_preview_api: FilePreviewApi): """Test file ownership validation when MessageFile not found""" file_id = str(uuid.uuid4()) app_id = str(uuid.uuid4()) @@ -112,7 +112,7 @@ class TestFilePreviewApi: assert "File not found in message context" in str(exc_info.value) - def test_validate_file_ownership_access_denied(self, file_preview_api, mock_message_file): + def test_validate_file_ownership_access_denied(self, file_preview_api: FilePreviewApi, mock_message_file): """Test file ownership validation when Message not owned by app""" file_id = str(uuid.uuid4()) app_id = str(uuid.uuid4()) @@ -130,7 +130,9 @@ class TestFilePreviewApi: assert "not owned by requesting app" in str(exc_info.value) - def test_validate_file_ownership_upload_file_not_found(self, file_preview_api, mock_message_file, mock_message): + def test_validate_file_ownership_upload_file_not_found( + self, file_preview_api: FilePreviewApi, mock_message_file, mock_message + ): """Test file ownership validation when UploadFile not found""" file_id = str(uuid.uuid4()) app_id = str(uuid.uuid4()) @@ -151,7 +153,7 @@ class TestFilePreviewApi: assert "Upload file record not found" in str(exc_info.value) def test_validate_file_ownership_tenant_mismatch( - self, file_preview_api, mock_app, mock_upload_file, mock_message_file, mock_message + self, file_preview_api: FilePreviewApi, mock_app, mock_upload_file, mock_message_file, mock_message ): """Test file ownership validation with tenant mismatch""" file_id = str(uuid.uuid4()) @@ -182,7 +184,7 @@ class TestFilePreviewApi: assert "tenant mismatch" in str(exc_info.value) - def test_validate_file_ownership_invalid_input(self, file_preview_api): + def test_validate_file_ownership_invalid_input(self, file_preview_api: FilePreviewApi): """Test file ownership validation with invalid input""" # Test with empty file_id @@ -195,7 +197,7 @@ class TestFilePreviewApi: file_preview_api._validate_file_ownership("file_id", "") assert "Invalid file or app identifier" in str(exc_info.value) - def test_build_file_response_basic(self, file_preview_api, mock_upload_file): + def test_build_file_response_basic(self, file_preview_api: FilePreviewApi, mock_upload_file): """Test basic file response building""" mock_generator = Mock() @@ -207,7 +209,7 @@ class TestFilePreviewApi: assert response.headers["Content-Length"] == str(mock_upload_file.size) assert "Cache-Control" in response.headers - def test_build_file_response_as_attachment(self, file_preview_api, mock_upload_file): + def test_build_file_response_as_attachment(self, file_preview_api: FilePreviewApi, mock_upload_file): """Test file response building with attachment flag""" mock_generator = Mock() @@ -218,7 +220,7 @@ class TestFilePreviewApi: assert mock_upload_file.name in response.headers["Content-Disposition"] assert response.headers["Content-Type"] == "application/octet-stream" - def test_build_file_response_html_forces_attachment(self, file_preview_api, mock_upload_file): + def test_build_file_response_html_forces_attachment(self, file_preview_api: FilePreviewApi, mock_upload_file): """Test HTML files are forced to download""" mock_generator = Mock() mock_upload_file.mime_type = "text/html" @@ -231,7 +233,7 @@ class TestFilePreviewApi: assert response.headers["Content-Type"] == "application/octet-stream" assert response.headers["X-Content-Type-Options"] == "nosniff" - def test_build_file_response_audio_video(self, file_preview_api, mock_upload_file): + def test_build_file_response_audio_video(self, file_preview_api: FilePreviewApi, mock_upload_file): """Test file response building for audio/video files""" mock_generator = Mock() mock_upload_file.mime_type = "video/mp4" @@ -241,7 +243,7 @@ class TestFilePreviewApi: # Check Range support for media files assert response.headers["Accept-Ranges"] == "bytes" - def test_build_file_response_no_size(self, file_preview_api, mock_upload_file): + def test_build_file_response_no_size(self, file_preview_api: FilePreviewApi, mock_upload_file): """Test file response building when size is unknown""" mock_generator = Mock() mock_upload_file.size = 0 # Unknown size @@ -253,7 +255,14 @@ class TestFilePreviewApi: @patch("controllers.service_api.app.file_preview.storage") def test_get_method_integration( - self, mock_storage, file_preview_api, mock_app, mock_end_user, mock_upload_file, mock_message_file, mock_message + self, + mock_storage, + file_preview_api: FilePreviewApi, + mock_app, + mock_end_user, + mock_upload_file, + mock_message_file, + mock_message, ): """Test the full GET method integration (without decorator)""" file_id = str(uuid.uuid4()) @@ -295,7 +304,13 @@ class TestFilePreviewApi: @patch("controllers.service_api.app.file_preview.storage") def test_storage_error_handling( - self, mock_storage, file_preview_api, mock_app, mock_upload_file, mock_message_file, mock_message + self, + mock_storage, + file_preview_api: FilePreviewApi, + mock_app, + mock_upload_file, + mock_message_file, + mock_message, ): """Test storage error handling in the core logic""" file_id = str(uuid.uuid4()) @@ -334,7 +349,7 @@ class TestFilePreviewApi: assert "Storage error" in str(exc_info.value) @patch("controllers.service_api.app.file_preview.logger") - def test_validate_file_ownership_unexpected_error_logging(self, mock_logger, file_preview_api): + def test_validate_file_ownership_unexpected_error_logging(self, mock_logger, file_preview_api: FilePreviewApi): """Test that unexpected errors are logged properly""" file_id = str(uuid.uuid4()) app_id = str(uuid.uuid4()) diff --git a/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py b/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py index 38c403a9c4..ff668ac60a 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_hitl_service_api.py @@ -249,7 +249,9 @@ def _build_resumption_context(task_id: str) -> WorkflowResumptionContext: class TestHitlServiceApi: # Service API event-stream continuation - def test_workflow_events_continue_on_pause_keeps_stream_open(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_workflow_events_continue_on_pause_keeps_stream_open( + self, app: Flask, monkeypatch: pytest.MonkeyPatch + ) -> None: workflow_run = SimpleNamespace( id="run-1", app_id="app-1", diff --git a/api/tests/unit_tests/controllers/service_api/app/test_human_input_form.py b/api/tests/unit_tests/controllers/service_api/app/test_human_input_form.py index 531f722ceb..5d1c4b4e26 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_human_input_form.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_human_input_form.py @@ -9,6 +9,7 @@ from types import SimpleNamespace from unittest.mock import Mock import pytest +from flask import Flask from werkzeug.exceptions import NotFound from controllers.service_api.app.human_input_form import WorkflowHumanInputFormApi @@ -17,7 +18,7 @@ from tests.unit_tests.controllers.service_api.conftest import _unwrap class TestWorkflowHumanInputFormApi: - def test_get_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_get_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: definition = SimpleNamespace( model_dump=lambda: { "rendered_content": "Rendered form content", @@ -57,7 +58,7 @@ class TestWorkflowHumanInputFormApi: service_mock.get_form_by_token.assert_called_once_with("token-1") service_mock.ensure_form_active.assert_called_once_with(form) - def test_get_form_not_in_app(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_get_form_not_in_app(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: form = SimpleNamespace( app_id="another-app", tenant_id="tenant-1", @@ -87,7 +88,7 @@ class TestWorkflowHumanInputFormApi: ], ) def test_get_rejects_non_service_api_recipient_types( - self, app, monkeypatch: pytest.MonkeyPatch, recipient_type: RecipientType + self, app: Flask, monkeypatch: pytest.MonkeyPatch, recipient_type: RecipientType ) -> None: form = SimpleNamespace( app_id="app-1", @@ -111,7 +112,7 @@ class TestWorkflowHumanInputFormApi: service_mock.ensure_form_active.assert_not_called() - def test_post_success(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + def test_post_success(self, app: Flask, monkeypatch: pytest.MonkeyPatch) -> None: form = SimpleNamespace( app_id="app-1", tenant_id="tenant-1", @@ -155,7 +156,7 @@ class TestWorkflowHumanInputFormApi: ], ) def test_post_rejects_non_service_api_recipient_types( - self, app, monkeypatch: pytest.MonkeyPatch, recipient_type: RecipientType + self, app: Flask, monkeypatch: pytest.MonkeyPatch, recipient_type: RecipientType ) -> None: form = SimpleNamespace( app_id="app-1", diff --git a/api/tests/unit_tests/controllers/service_api/app/test_message.py b/api/tests/unit_tests/controllers/service_api/app/test_message.py index 2bc9771862..d44e92ce66 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_message.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_message.py @@ -381,7 +381,7 @@ class TestMessageService: class TestMessageListApi: - def test_not_chat_app(self, app) -> None: + def test_not_chat_app(self, app: Flask) -> None: api = MessageListApi() handler = _unwrap(api.get) app_model = SimpleNamespace(mode=AppMode.COMPLETION.value) @@ -467,7 +467,7 @@ class TestAppGetFeedbacksApi: class TestMessageSuggestedApi: - def test_not_chat(self, app) -> None: + def test_not_chat(self, app: Flask) -> None: api = MessageSuggestedApi() handler = _unwrap(api.get) app_model = SimpleNamespace(mode=AppMode.COMPLETION.value) diff --git a/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py b/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py index b3edc2ecd8..a1aca06570 100644 --- a/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py +++ b/api/tests/unit_tests/controllers/service_api/app/test_workflow_events.py @@ -32,7 +32,7 @@ def _mock_repo_for_run(monkeypatch: pytest.MonkeyPatch, workflow_run): class TestWorkflowEventsApi: - def test_wrong_app_mode(self, app) -> None: + def test_wrong_app_mode(self, app: Flask) -> None: api = WorkflowEventsApi() handler = _unwrap(api.get) app_model = SimpleNamespace(mode=AppMode.CHAT.value) diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_document.py b/api/tests/unit_tests/controllers/service_api/dataset/test_document.py index 738238d10a..61ec397193 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_document.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_document.py @@ -19,6 +19,7 @@ import uuid from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden, NotFound from controllers.service_api.dataset.document import ( @@ -550,7 +551,7 @@ class TestDocumentApiGet: @patch("controllers.service_api.dataset.document.DatasetService") @patch("controllers.service_api.dataset.document.DocumentService") def test_get_document_success_with_all_metadata( - self, mock_doc_svc, mock_dataset_svc, app, mock_tenant, mock_doc_detail + self, mock_doc_svc, mock_dataset_svc, app: Flask, mock_tenant, mock_doc_detail ): """Test successful document retrieval with metadata='all'.""" # Arrange @@ -579,7 +580,7 @@ class TestDocumentApiGet: assert "doc_metadata" in response @patch("controllers.service_api.dataset.document.DocumentService") - def test_get_document_not_found(self, mock_doc_svc, app, mock_tenant): + def test_get_document_not_found(self, mock_doc_svc, app: Flask, mock_tenant): """Test 404 when document is not found.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -599,7 +600,7 @@ class TestDocumentApiGet: api.get(tenant_id=mock_tenant.id, dataset_id=dataset_id, document_id="nonexistent") @patch("controllers.service_api.dataset.document.DocumentService") - def test_get_document_forbidden_wrong_tenant(self, mock_doc_svc, app, mock_tenant, mock_doc_detail): + def test_get_document_forbidden_wrong_tenant(self, mock_doc_svc, app: Flask, mock_tenant, mock_doc_detail): """Test 403 when document tenant doesn't match request tenant.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -620,7 +621,7 @@ class TestDocumentApiGet: api.get(tenant_id=mock_tenant.id, dataset_id=dataset_id, document_id=mock_doc_detail.id) @patch("controllers.service_api.dataset.document.DocumentService") - def test_get_document_metadata_only(self, mock_doc_svc, app, mock_tenant, mock_doc_detail): + def test_get_document_metadata_only(self, mock_doc_svc, app: Flask, mock_tenant, mock_doc_detail): """Test document retrieval with metadata='only'.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -647,7 +648,9 @@ class TestDocumentApiGet: @patch("controllers.service_api.dataset.document.DatasetService") @patch("controllers.service_api.dataset.document.DocumentService") - def test_get_document_metadata_without(self, mock_doc_svc, mock_dataset_svc, app, mock_tenant, mock_doc_detail): + def test_get_document_metadata_without( + self, mock_doc_svc, mock_dataset_svc, app: Flask, mock_tenant, mock_doc_detail + ): """Test document retrieval with metadata='without'.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -674,7 +677,7 @@ class TestDocumentApiGet: assert "name" in response @patch("controllers.service_api.dataset.document.DocumentService") - def test_get_document_invalid_metadata_value(self, mock_doc_svc, app, mock_tenant, mock_doc_detail): + def test_get_document_invalid_metadata_value(self, mock_doc_svc, app: Flask, mock_tenant, mock_doc_detail): """Test error when metadata parameter has invalid value.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -713,7 +716,7 @@ class TestDocumentApiDelete: @patch("controllers.service_api.dataset.document.DocumentService") @patch("controllers.service_api.dataset.document.db") - def test_delete_document_success(self, mock_db, mock_doc_svc, app, mock_tenant, mock_document): + def test_delete_document_success(self, mock_db, mock_doc_svc, app: Flask, mock_tenant, mock_document): """Test successful document deletion.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -741,7 +744,7 @@ class TestDocumentApiDelete: @patch("controllers.service_api.dataset.document.DocumentService") @patch("controllers.service_api.dataset.document.db") - def test_delete_document_not_found(self, mock_db, mock_doc_svc, app, mock_tenant): + def test_delete_document_not_found(self, mock_db, mock_doc_svc, app: Flask, mock_tenant): """Test 404 when document not found.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -763,7 +766,7 @@ class TestDocumentApiDelete: @patch("controllers.service_api.dataset.document.DocumentService") @patch("controllers.service_api.dataset.document.db") - def test_delete_document_archived_forbidden(self, mock_db, mock_doc_svc, app, mock_tenant, mock_document): + def test_delete_document_archived_forbidden(self, mock_db, mock_doc_svc, app: Flask, mock_tenant, mock_document): """Test ArchivedDocumentImmutableError when deleting archived document.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -785,7 +788,7 @@ class TestDocumentApiDelete: @patch("controllers.service_api.dataset.document.DocumentService") @patch("controllers.service_api.dataset.document.db") - def test_delete_document_dataset_not_found(self, mock_db, mock_doc_svc, app, mock_tenant): + def test_delete_document_dataset_not_found(self, mock_db, mock_doc_svc, app: Flask, mock_tenant): """Test ValueError when dataset not found.""" # Arrange dataset_id = str(uuid.uuid4()) @@ -808,7 +811,7 @@ class TestDocumentListApi: @patch("controllers.service_api.dataset.document.marshal") @patch("controllers.service_api.dataset.document.DocumentService") @patch("controllers.service_api.dataset.document.db") - def test_list_documents_success(self, mock_db, mock_doc_svc, mock_marshal, app, mock_tenant, mock_dataset): + def test_list_documents_success(self, mock_db, mock_doc_svc, mock_marshal, app: Flask, mock_tenant, mock_dataset): """Test successful document list retrieval.""" # Arrange mock_db.session.scalar.return_value = mock_dataset @@ -837,7 +840,7 @@ class TestDocumentListApi: assert response["total"] == 2 @patch("controllers.service_api.dataset.document.db") - def test_list_documents_dataset_not_found(self, mock_db, app, mock_tenant, mock_dataset): + def test_list_documents_dataset_not_found(self, mock_db, app: Flask, mock_tenant, mock_dataset): """Test 404 when dataset not found.""" # Arrange mock_db.session.scalar.return_value = None @@ -858,7 +861,9 @@ class TestDocumentIndexingStatusApi: @patch("controllers.service_api.dataset.document.marshal") @patch("controllers.service_api.dataset.document.DocumentService") @patch("controllers.service_api.dataset.document.db") - def test_get_indexing_status_success(self, mock_db, mock_doc_svc, mock_marshal, app, mock_tenant, mock_dataset): + def test_get_indexing_status_success( + self, mock_db, mock_doc_svc, mock_marshal, app: Flask, mock_tenant, mock_dataset + ): """Test successful indexing status retrieval.""" # Arrange batch_id = "batch_123" @@ -894,7 +899,7 @@ class TestDocumentIndexingStatusApi: assert len(response["data"]) == 1 @patch("controllers.service_api.dataset.document.db") - def test_get_indexing_status_dataset_not_found(self, mock_db, app, mock_tenant, mock_dataset): + def test_get_indexing_status_dataset_not_found(self, mock_db, app: Flask, mock_tenant, mock_dataset): """Test 404 when dataset not found.""" # Arrange batch_id = "batch_123" @@ -911,7 +916,9 @@ class TestDocumentIndexingStatusApi: @patch("controllers.service_api.dataset.document.DocumentService") @patch("controllers.service_api.dataset.document.db") - def test_get_indexing_status_documents_not_found(self, mock_db, mock_doc_svc, app, mock_tenant, mock_dataset): + def test_get_indexing_status_documents_not_found( + self, mock_db, mock_doc_svc, app: Flask, mock_tenant, mock_dataset + ): """Test 404 when no documents found for batch.""" # Arrange batch_id = "batch_empty" @@ -978,7 +985,7 @@ class TestDocumentAddByTextApi: mock_knowledge_config, mock_doc_svc, mock_marshal, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1029,7 +1036,7 @@ class TestDocumentAddByTextApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.dataset.document.db") def test_create_document_dataset_not_found( - self, mock_db, mock_validate_token, mock_feature_svc, app, mock_tenant, mock_dataset + self, mock_db, mock_validate_token, mock_feature_svc, app: Flask, mock_tenant, mock_dataset ): """Test ValueError when dataset not found.""" # Arrange — neutralise billing decorators @@ -1052,7 +1059,7 @@ class TestDocumentAddByTextApi: @patch("controllers.service_api.wraps.validate_and_get_api_token") @patch("controllers.service_api.dataset.document.db") def test_create_document_missing_indexing_technique( - self, mock_db, mock_validate_token, mock_feature_svc, app, mock_tenant, mock_dataset + self, mock_db, mock_validate_token, mock_feature_svc, app: Flask, mock_tenant, mock_dataset ): """Test error when both dataset and payload lack indexing_technique. @@ -1161,7 +1168,7 @@ class TestDocumentUpdateByTextApiPost: mock_file_svc_cls, mock_doc_svc, mock_marshal, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1206,7 +1213,7 @@ class TestDocumentUpdateByTextApiPost: mock_validate_token, mock_feature_svc, mock_db, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1245,7 +1252,7 @@ class TestDocumentAddByFileApiPost: mock_validate_token, mock_feature_svc, mock_db, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1275,7 +1282,7 @@ class TestDocumentAddByFileApiPost: mock_validate_token, mock_feature_svc, mock_db, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1306,7 +1313,7 @@ class TestDocumentAddByFileApiPost: mock_validate_token, mock_feature_svc, mock_db, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1338,7 +1345,7 @@ class TestDocumentAddByFileApiPost: mock_validate_token, mock_feature_svc, mock_db, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1381,7 +1388,7 @@ class TestDocumentUpdateByFileApiPatch: mock_feature_svc, mock_update_document_by_file, route_name, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1418,7 +1425,7 @@ class TestDocumentUpdateByFileApiPatch: mock_validate_token, mock_feature_svc, mock_db, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1453,7 +1460,7 @@ class TestDocumentUpdateByFileApiPatch: mock_validate_token, mock_feature_svc, mock_db, - app, + app: Flask, mock_tenant, mock_dataset, ): @@ -1497,7 +1504,7 @@ class TestDocumentUpdateByFileApiPatch: mock_file_svc_cls, mock_doc_svc, mock_marshal, - app, + app: Flask, mock_tenant, mock_dataset, ): diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py b/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py index c02416e5fe..38fcb55fc0 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py @@ -18,6 +18,7 @@ import uuid from unittest.mock import Mock, patch import pytest +from flask import Flask from werkzeug.exceptions import Forbidden, NotFound import services @@ -91,7 +92,7 @@ class TestHitTestingApiPost: mock_hit_svc, mock_marshal, mock_ns, - app, + app: Flask, ): """Test successful hit testing request.""" dataset_id = str(uuid.uuid4()) @@ -129,7 +130,7 @@ class TestHitTestingApiPost: mock_hit_svc, mock_marshal, mock_ns, - app, + app: Flask, ): """Test hit testing with custom retrieval model.""" dataset_id = str(uuid.uuid4()) @@ -183,7 +184,7 @@ class TestHitTestingApiPost: mock_hit_svc, mock_marshal, mock_ns, - app, + app: Flask, ): """Service API retrieval payload should not drop metadata filters.""" dataset_id = str(uuid.uuid4()) @@ -239,7 +240,7 @@ class TestHitTestingApiPost: mock_hit_svc, mock_marshal, mock_ns, - app, + app: Flask, ): """Test service API prepares nullable list fields from marshalled records.""" dataset_id = str(uuid.uuid4()) @@ -286,7 +287,7 @@ class TestHitTestingApiPost: mock_current_user, mock_dataset_svc, mock_ns, - app, + app: Flask, ): """Test hit testing with non-existent dataset.""" dataset_id = str(uuid.uuid4()) @@ -308,7 +309,7 @@ class TestHitTestingApiPost: mock_current_user, mock_dataset_svc, mock_ns, - app, + app: Flask, ): """Test hit testing when user lacks dataset permission.""" dataset_id = str(uuid.uuid4()) diff --git a/api/tests/unit_tests/controllers/service_api/test_index.py b/api/tests/unit_tests/controllers/service_api/test_index.py index 8441118181..c4074c14dd 100644 --- a/api/tests/unit_tests/controllers/service_api/test_index.py +++ b/api/tests/unit_tests/controllers/service_api/test_index.py @@ -54,7 +54,7 @@ class TestIndexApi: assert isinstance(response["server_version"], str) @pytest.mark.parametrize("version", ["0.0.1", "1.0.0", "2.0.0-beta", "1.11.4"]) - def test_get_returns_correct_version(self, app, version): + def test_get_returns_correct_version(self, app: Flask, version): """Test that server_version matches config version.""" # Arrange mock_config = MagicMock() diff --git a/api/tests/unit_tests/controllers/web/test_web_login.py b/api/tests/unit_tests/controllers/web/test_web_login.py index 13b953c04d..839939367c 100644 --- a/api/tests/unit_tests/controllers/web/test_web_login.py +++ b/api/tests/unit_tests/controllers/web/test_web_login.py @@ -44,7 +44,7 @@ class TestEmailCodeLoginSendEmailApi: self, mock_get_user, mock_send_email, - app, + app: Flask, ): mock_account = MagicMock() mock_get_user.return_value = mock_account @@ -75,7 +75,7 @@ class TestEmailCodeLoginApi: mock_get_user, mock_login, mock_reset_login_rate, - app, + app: Flask, ): mock_get_token_data.return_value = {"email": "User@Example.com", "code": "123456"} mock_get_user.return_value = MagicMock() diff --git a/packages/contracts/README.md b/packages/contracts/README.md index ae682faa53..e9320c921d 100644 --- a/packages/contracts/README.md +++ b/packages/contracts/README.md @@ -8,14 +8,14 @@ Snapshot generated from `packages/contracts/generated/api/readiness.json` after running `pnpm -C packages/contracts gen-api-contract-from-openapi`. -Are we OpenAPI ready? **No.** Current generated API contracts are **16.6% ready**. +Are we OpenAPI ready? **No.** Current generated API contracts are **16.7% ready**. | Surface | Ready | Not ready | Total | Ready % | | --------- | ------: | --------: | ------: | --------: | -| console | 95 | 475 | 570 | 16.7% | +| console | 96 | 474 | 570 | 16.8% | | service | 16 | 72 | 88 | 18.2% | | web | 5 | 36 | 41 | 12.2% | -| **total** | **116** | **583** | **699** | **16.6%** | +| **total** | **117** | **582** | **699** | **16.7%** | Readiness here means the generated contract operation is not marked with: diff --git a/packages/contracts/generated/api/console/apps/orpc.gen.ts b/packages/contracts/generated/api/console/apps/orpc.gen.ts index 2eea4f13c4..a1a0faaefd 100644 --- a/packages/contracts/generated/api/console/apps/orpc.gen.ts +++ b/packages/contracts/generated/api/console/apps/orpc.gen.ts @@ -426,16 +426,10 @@ export const imports = { /** * Get workflow online users - * - * Generated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate. - * - * @deprecated */ export const post3 = oc .route({ - deprecated: true, - description: - 'Get workflow online users\n\nGenerated contract types may be inaccurate because backend OpenAPI annotations are incomplete. Do not migrate callers until the generated contract is accurate.', + description: 'Get workflow online users', inputStructure: 'detailed', method: 'POST', operationId: 'postAppsWorkflowsOnlineUsers', diff --git a/packages/contracts/generated/api/readiness.json b/packages/contracts/generated/api/readiness.json index af86c7646e..78fed3ccfa 100644 --- a/packages/contracts/generated/api/readiness.json +++ b/packages/contracts/generated/api/readiness.json @@ -1,7 +1,7 @@ { "surfaces": { "console": { - "notReady": 475, + "notReady": 474, "total": 570 }, "service": {