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 f6e7e9cd1d9..e62e30c1824 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 @@ -52,7 +52,7 @@ def _get( api, args=args, app_model=app_model, - end_user=Mock(spec=EndUser), + end_user=EndUser(id=str(uuid4()), app_id=app_model.id, tenant_id=app_model.tenant_id), file_id=file_id, ) diff --git a/api/tests/unit_tests/services/agent/test_agent_runtime_config_service.py b/api/tests/unit_tests/services/agent/test_agent_runtime_config_service.py index 2b2e22e8959..8b78be33640 100644 --- a/api/tests/unit_tests/services/agent/test_agent_runtime_config_service.py +++ b/api/tests/unit_tests/services/agent/test_agent_runtime_config_service.py @@ -15,18 +15,12 @@ from models.model import App, Conversation from services.agent.runtime_config_service import AgentRuntimeConfigService -def _app() -> MagicMock: - app = MagicMock(spec=App) - app.id = "app-1" - app.tenant_id = "tenant-1" - return app +def _app() -> App: + return App(id="app-1", tenant_id="tenant-1") -def _conversation(*, binding_id: str | None = None) -> MagicMock: - conversation = MagicMock(spec=Conversation) - conversation.id = "conversation-1" - conversation.agent_workspace_binding_id = binding_id - return conversation +def _conversation(*, binding_id: str | None = None) -> Conversation: + return Conversation(id="conversation-1", agent_workspace_binding_id=binding_id) def _soul(prompt: str) -> AgentSoulConfig: @@ -45,13 +39,13 @@ def _patch_published_soul(monkeypatch: pytest.MonkeyPatch, soul: AgentSoulConfig return roster_service -def test_debug_without_mapping_falls_back_to_published_soul(monkeypatch: pytest.MonkeyPatch) -> None: - session = MagicMock(spec=Session) - session.scalar.return_value = None +def test_debug_without_mapping_falls_back_to_published_soul( + monkeypatch: pytest.MonkeyPatch, sqlite_session: Session +) -> None: published = _soul("published") roster_service = _patch_published_soul(monkeypatch, published) - result = AgentRuntimeConfigService(session).resolve_conversation_soul( + result = AgentRuntimeConfigService(sqlite_session).resolve_conversation_soul( app_model=_app(), conversation=_conversation(), account_id="account-1", @@ -65,16 +59,23 @@ def test_debug_without_mapping_falls_back_to_published_soul(monkeypatch: pytest. ) -def test_debug_without_draft_falls_back_to_published_soul(monkeypatch: pytest.MonkeyPatch) -> None: - session = MagicMock(spec=Session) - debug_conversation = MagicMock(spec=AgentDebugConversation) - debug_conversation.agent_id = "agent-1" - debug_conversation.draft_type = AgentConfigDraftType.DRAFT - session.scalar.side_effect = [debug_conversation, None] +def test_debug_without_draft_falls_back_to_published_soul( + monkeypatch: pytest.MonkeyPatch, sqlite_session: Session +) -> None: + debug_conversation = AgentDebugConversation( + tenant_id="tenant-1", + app_id="app-1", + account_id="account-1", + conversation_id="conversation-1", + agent_id="agent-1", + draft_type=AgentConfigDraftType.DRAFT, + ) + sqlite_session.add(debug_conversation) + sqlite_session.flush() published = _soul("published") _patch_published_soul(monkeypatch, published) - result = AgentRuntimeConfigService(session).resolve_conversation_soul( + result = AgentRuntimeConfigService(sqlite_session).resolve_conversation_soul( app_model=_app(), conversation=_conversation(), account_id="account-1", @@ -84,13 +85,11 @@ def test_debug_without_draft_falls_back_to_published_soul(monkeypatch: pytest.Mo assert result == published -def test_missing_binding_falls_back_to_published_soul(monkeypatch: pytest.MonkeyPatch) -> None: - session = MagicMock(spec=Session) - session.scalar.return_value = None +def test_missing_binding_falls_back_to_published_soul(monkeypatch: pytest.MonkeyPatch, sqlite_session: Session) -> None: published = _soul("published") _patch_published_soul(monkeypatch, published) - result = AgentRuntimeConfigService(session).resolve_conversation_soul( + result = AgentRuntimeConfigService(sqlite_session).resolve_conversation_soul( app_model=_app(), conversation=_conversation(binding_id="binding-1"), account_id=None, @@ -104,17 +103,24 @@ def test_missing_binding_falls_back_to_published_soul(monkeypatch: pytest.Monkey def test_missing_bound_version_falls_back_to_published_soul( version_kind: AgentConfigVersionKind, monkeypatch: pytest.MonkeyPatch, + sqlite_session: Session, ) -> None: - session = MagicMock(spec=Session) - binding = MagicMock(spec=AgentWorkspaceBinding) - binding.agent_id = "agent-1" - binding.agent_config_version_id = "version-1" - binding.agent_config_version_kind = version_kind - session.scalar.side_effect = [binding, None] + binding = AgentWorkspaceBinding( + id="binding-1", + tenant_id="tenant-1", + app_id="app-1", + workspace_id="workspace-1", + backend_binding_ref="binding-ref-1", + agent_id="agent-1", + agent_config_version_id="version-1", + agent_config_version_kind=version_kind, + ) + sqlite_session.add(binding) + sqlite_session.flush() published = _soul("published") _patch_published_soul(monkeypatch, published) - result = AgentRuntimeConfigService(session).resolve_conversation_soul( + result = AgentRuntimeConfigService(sqlite_session).resolve_conversation_soul( app_model=_app(), conversation=_conversation(binding_id="binding-1"), account_id=None, @@ -124,19 +130,31 @@ def test_missing_bound_version_falls_back_to_published_soul( assert result == published -def test_bound_draft_returns_its_soul(monkeypatch: pytest.MonkeyPatch) -> None: - session = MagicMock(spec=Session) - binding = MagicMock(spec=AgentWorkspaceBinding) - binding.agent_id = "agent-1" - binding.agent_config_version_id = "draft-1" - binding.agent_config_version_kind = AgentConfigVersionKind.DRAFT - draft = MagicMock(spec=AgentConfigDraft) +def test_bound_draft_returns_its_soul(monkeypatch: pytest.MonkeyPatch, sqlite_session: Session) -> None: + binding = AgentWorkspaceBinding( + id="binding-1", + tenant_id="tenant-1", + app_id="app-1", + workspace_id="workspace-1", + backend_binding_ref="binding-ref-1", + agent_id="agent-1", + agent_config_version_id="draft-1", + agent_config_version_kind=AgentConfigVersionKind.DRAFT, + ) bound = _soul("bound draft") - draft.config_snapshot_dict = bound.model_dump(mode="json") - session.scalar.side_effect = [binding, draft] + draft = AgentConfigDraft( + id="draft-1", + tenant_id="tenant-1", + agent_id="agent-1", + draft_type=AgentConfigDraftType.DRAFT, + config_snapshot=bound, + ) + sqlite_session.add_all([binding, draft]) + sqlite_session.flush() + sqlite_session.expire_all() roster_service = _patch_published_soul(monkeypatch, _soul("published")) - result = AgentRuntimeConfigService(session).resolve_conversation_soul( + result = AgentRuntimeConfigService(sqlite_session).resolve_conversation_soul( app_model=_app(), conversation=_conversation(binding_id="binding-1"), account_id=None, diff --git a/api/tests/unit_tests/services/agent/test_roster_package_service.py b/api/tests/unit_tests/services/agent/test_roster_package_service.py index 582c3ca4389..c2189cb0b06 100644 --- a/api/tests/unit_tests/services/agent/test_roster_package_service.py +++ b/api/tests/unit_tests/services/agent/test_roster_package_service.py @@ -16,6 +16,8 @@ from sqlalchemy.orm import Session, sessionmaker from sqlalchemy.pool import QueuePool from configs import dify_config +from extensions.storage.storage_type import StorageType +from libs.datetime_utils import naive_utc_now from models.agent import ( Agent, AgentConfigDraft, @@ -29,7 +31,7 @@ from models.agent import ( AgentStatus, ) from models.agent_config_entities import AgentSoulConfig -from models.enums import AppStatus, CustomizeTokenStrategy +from models.enums import AppStatus, CreatorUserRole, CustomizeTokenStrategy from models.model import App, AppMode, IconType, Site from models.skill import AgentSkillBindingSnapshot, Skill, SkillVersion, SkillVersionManifest from models.tools import ToolFile @@ -1396,7 +1398,12 @@ def test_export_download_closes_owned_archive(app: Flask) -> None: ], ) def test_export_preserves_file_metadata_in_dsl( - monkeypatch: pytest.MonkeyPatch, file_kind: str, declared_mime: str | None, stored_mime: str, expected_mime: str + monkeypatch: pytest.MonkeyPatch, + sqlite_session: Session, + file_kind: str, + declared_mime: str | None, + stored_mime: str, + expected_mime: str, ) -> None: from unittest.mock import Mock @@ -1414,7 +1421,20 @@ def test_export_preserves_file_metadata_in_dsl( original_url=None, ) tool_file.id = "source-id" - upload_file = Mock(spec=UploadFile, id="source-id", key="payload", mime_type=stored_mime) + upload_file = UploadFile( + tenant_id="tenant-1", + storage_type=StorageType.LOCAL, + key="payload", + name="original.pdf", + size=1, + extension="pdf", + mime_type=stored_mime, + created_by_role=CreatorUserRole.ACCOUNT, + created_by="account-1", + created_at=naive_utc_now(), + used=False, + ) + upload_file.id = "source-id" monkeypatch.setattr(exporter, "_tool_files", Mock(return_value={"source-id": tool_file})) monkeypatch.setattr(exporter, "_upload_files", Mock(return_value={"source-id": upload_file})) soul = AgentSoulConfig.model_validate( @@ -1425,7 +1445,7 @@ def test_export_preserves_file_metadata_in_dsl( } ) - portable_soul, _, sources = exporter._collect_payloads(session=Mock(spec=Session), tenant_id="tenant-1", soul=soul) + portable_soul, _, sources = exporter._collect_payloads(session=sqlite_session, tenant_id="tenant-1", soul=soul) ref = portable_soul.config_files[0] assert (ref.name, ref.file_kind, ref.mime_type, ref.file_id) == ( diff --git a/api/tests/unit_tests/services/test_human_input_file_upload_service.py b/api/tests/unit_tests/services/test_human_input_file_upload_service.py index 2f1b15cf472..55dcbbaa6d6 100644 --- a/api/tests/unit_tests/services/test_human_input_file_upload_service.py +++ b/api/tests/unit_tests/services/test_human_input_file_upload_service.py @@ -51,7 +51,7 @@ def _upload_context() -> HumanInputUploadContext: form_id="form-1", recipient_id="recipient-1", upload_token_id="token-1", - owner=MagicMock(spec=Account), + owner=Account(name="Upload owner", email="owner@example.com"), ) @@ -136,7 +136,7 @@ def test_validate_upload_token_resolves_delivery_test_owner() -> None: uploads = MagicMock(spec=HumanInputFileUploadRepository) form = _active_form(workflow_run_id=None, form_kind=HumanInputFormKind.DELIVERY_TEST) uploads.get_upload_grant.return_value = HumanInputUploadGrantRecord(upload_token_id="token-1", form=form) - owner = MagicMock(spec=Account) + owner = Account(name="Delivery test owner", email="owner@example.com") uploads.get_delivery_test_upload_owner.return_value = owner workflow_runs = MagicMock()