from __future__ import annotations import uuid import pytest from fastapi import HTTPException from sqlalchemy import select, text from sqlalchemy.ext.asyncio import AsyncSession from app.db.base_class import Base 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.user import UserStatus class UserStub: def __init__(self) -> None: self.id = uuid.uuid4() self.is_admin = True self.status = UserStatus.ACTIVE def test_etmf_node_table_is_registered() -> None: import app.db.base # noqa: F401 assert "etmf_nodes" in Base.metadata.tables @pytest.mark.asyncio async def test_document_create_persists_etmf_node_id(db_session: AsyncSession) -> None: from app.models.etmf import EtmfNode from app.schemas.document import DocumentCreate from app.services import document_service study_id = ( await db_session.execute(text("SELECT id FROM studies ORDER BY created_at DESC LIMIT 1")) ).scalar_one() node = EtmfNode( study_id=study_id, code="01.01", name="方案与版本", scope_type=DocumentScopeType.GLOBAL, required=True, sort_order=1, ) db_session.add(node) await db_session.commit() await db_session.refresh(node) doc = await document_service.create_document( db_session, DocumentCreate( trial_id=study_id, doc_no="PROTOCOL-001", doc_type="Protocol", title="研究方案", scope_type=DocumentScopeType.GLOBAL, etmf_node_id=node.id, ), UserStub(), ) assert doc.etmf_node_id == node.id stored = ( await db_session.execute(select(Document).where(Document.id == doc.id)) ).scalar_one() assert stored.etmf_node_id == node.id @pytest.mark.asyncio async def test_site_scoped_etmf_node_requires_site_document(db_session: AsyncSession) -> None: from app.models.etmf import EtmfNode from app.schemas.document import DocumentCreate from app.services import document_service study_id = ( await db_session.execute(text("SELECT id FROM studies ORDER BY created_at DESC LIMIT 1")) ).scalar_one() node = EtmfNode( study_id=study_id, code="03.01", name="中心启动文件", scope_type=DocumentScopeType.SITE, required=True, sort_order=1, ) db_session.add(node) await db_session.commit() await db_session.refresh(node) with pytest.raises(HTTPException) as exc_info: await document_service.create_document( db_session, DocumentCreate( trial_id=study_id, doc_no="SITE-STARTUP-001", doc_type="Startup", title="中心启动文件", scope_type=DocumentScopeType.GLOBAL, etmf_node_id=node.id, ), UserStub(), ) assert exc_info.value.status_code == 422 assert "中心" in str(exc_info.value.detail)