from __future__ import annotations import uuid from types import SimpleNamespace import pytest from sqlalchemy.ext.asyncio import AsyncSession from app.models.document import Document, DocumentScopeType from app.models.document_version import DocumentVersion # noqa: F401 from app.models.distribution import Distribution # noqa: F401 from app.models.acknowledgement import Acknowledgement # noqa: F401 from app.models.etmf import EtmfNode from app.services.etmf_service import calculate_node_status, list_etmf_tree def test_required_node_without_documents_is_missing() -> None: node = SimpleNamespace(is_active=True, required=True) assert calculate_node_status(node, []) == "MISSING" def test_node_with_document_without_effective_version_is_uploaded() -> None: node = SimpleNamespace(is_active=True, required=True) document = SimpleNamespace(current_effective_version_id=None) assert calculate_node_status(node, [document]) == "UPLOADED" def test_node_with_current_effective_version_is_effective() -> None: node = SimpleNamespace(is_active=True, required=True) document = SimpleNamespace(current_effective_version_id=uuid.uuid4()) assert calculate_node_status(node, [document]) == "EFFECTIVE" @pytest.mark.asyncio async def test_etmf_tree_returns_hierarchy_and_status(db_session: AsyncSession) -> None: study_id = uuid.uuid4() parent = EtmfNode( id=uuid.uuid4(), study_id=study_id, code="01", name="项目管理", scope_type=DocumentScopeType.GLOBAL, required=False, sort_order=1, ) child = EtmfNode( id=uuid.uuid4(), study_id=study_id, parent_id=parent.id, code="01.01", name="方案与版本", scope_type=DocumentScopeType.GLOBAL, required=True, sort_order=1, ) db_session.add_all([parent, child]) await db_session.commit() tree = await list_etmf_tree(db_session, study_id=study_id, current_user=None) assert len(tree) == 1 assert tree[0].code == "01" assert tree[0].children[0].code == "01.01" assert tree[0].children[0].status == "MISSING"