Files
ctms/backend/tests/test_migrated_endpoints_batch3.py
T
2026-05-26 14:46:01 +08:00

540 lines
18 KiB
Python

"""
第3批模块迁移测试:12个模块,63个端点
测试接口级权限系统在所有第3批模块中的应用
"""
import uuid
import pytest
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.project_permissions import role_has_api_permission
from app.models.api_endpoint_permission import ApiEndpointPermission
# ============================================================================
# 启动管理 (startup) - 19个端点
# ============================================================================
@pytest.mark.asyncio
async def test_startup_ethics_create_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以创建伦理审批"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="POST:/studies/{study_id}/startup/ethics",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/startup/ethics")
assert allowed is True
@pytest.mark.asyncio
async def test_startup_ethics_list_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以查询伦理审批列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="GET:/studies/{study_id}/startup/ethics",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "GET:/studies/{study_id}/startup/ethics")
assert allowed is True
@pytest.mark.asyncio
async def test_startup_feasibility_create_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以创建可行性评估"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="POST:/studies/{study_id}/startup/feasibility",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/startup/feasibility")
assert allowed is True
@pytest.mark.asyncio
async def test_startup_budget_create_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以创建预算评估"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="POST:/studies/{study_id}/startup/budget",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/startup/budget")
assert allowed is True
@pytest.mark.asyncio
async def test_startup_timeline_create_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以创建时间表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="POST:/studies/{study_id}/startup/timeline",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/startup/timeline")
assert allowed is True
# ============================================================================
# 项目权限管理 (project_permissions) - 2个端点
# ============================================================================
@pytest.mark.asyncio
async def test_project_permissions_get_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以查询项目权限矩阵"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="GET:/studies/{study_id}/permissions",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "GET:/studies/{study_id}/permissions")
assert allowed is True
@pytest.mark.asyncio
async def test_project_permissions_update_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以更新项目权限矩阵"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="PUT:/studies/{study_id}/permissions",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "PUT:/studies/{study_id}/permissions")
assert allowed is True
# ============================================================================
# 项目概览 (overview) - 1个端点
# ============================================================================
@pytest.mark.asyncio
async def test_overview_get_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以查询项目概览"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="GET:/studies/{study_id}/overview",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "GET:/studies/{study_id}/overview")
assert allowed is True
# ============================================================================
# 监查问题 (monitoring_visit_issues) - 7个端点
# ============================================================================
@pytest.mark.asyncio
async def test_monitoring_issues_create_with_permission(db_session: AsyncSession):
"""验证有权限的CRA可以创建监查问题"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="POST:/studies/{study_id}/monitoring-visits/{visit_id}/issues",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "POST:/studies/{study_id}/monitoring-visits/{visit_id}/issues")
assert allowed is True
@pytest.mark.asyncio
async def test_monitoring_issues_list_with_permission(db_session: AsyncSession):
"""验证有权限的CRA可以查询监查问题列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="GET:/studies/{study_id}/monitoring-visits/{visit_id}/issues",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "GET:/studies/{study_id}/monitoring-visits/{visit_id}/issues")
assert allowed is True
# ============================================================================
# 药物发货 (drug_shipments) - 5个端点
# ============================================================================
@pytest.mark.asyncio
async def test_drug_shipments_create_with_permission(db_session: AsyncSession):
"""验证有权限的IMP可以创建药物发货"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="IMP",
endpoint_key="POST:/studies/{study_id}/drug-shipments",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "IMP", "POST:/studies/{study_id}/drug-shipments")
assert allowed is True
@pytest.mark.asyncio
async def test_drug_shipments_list_with_permission(db_session: AsyncSession):
"""验证有权限的IMP可以查询药物发货列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="IMP",
endpoint_key="GET:/studies/{study_id}/drug-shipments",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "IMP", "GET:/studies/{study_id}/drug-shipments")
assert allowed is True
# ============================================================================
# 物资管理 (material_equipments) - 5个端点
# ============================================================================
@pytest.mark.asyncio
async def test_materials_create_with_permission(db_session: AsyncSession):
"""验证有权限的IMP可以创建物资"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="IMP",
endpoint_key="POST:/studies/{study_id}/materials",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "IMP", "POST:/studies/{study_id}/materials")
assert allowed is True
@pytest.mark.asyncio
async def test_materials_list_with_permission(db_session: AsyncSession):
"""验证有权限的IMP可以查询物资列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="IMP",
endpoint_key="GET:/studies/{study_id}/materials",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "IMP", "GET:/studies/{study_id}/materials")
assert allowed is True
# ============================================================================
# 参与者PDS (subject_pds) - 4个端点
# ============================================================================
@pytest.mark.asyncio
async def test_subject_pds_create_with_permission(db_session: AsyncSession):
"""验证有权限的CRA可以创建参与者PDS"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="POST:/studies/{study_id}/subjects/{subject_id}/pds",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "POST:/studies/{study_id}/subjects/{subject_id}/pds")
assert allowed is True
@pytest.mark.asyncio
async def test_subject_pds_list_with_permission(db_session: AsyncSession):
"""验证有权限的CRA可以查询参与者PDS列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="GET:/studies/{study_id}/subjects/{subject_id}/pds",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "GET:/studies/{study_id}/subjects/{subject_id}/pds")
assert allowed is True
# ============================================================================
# 审计日志 (audit_logs) - 3个端点
# ============================================================================
@pytest.mark.asyncio
async def test_audit_logs_list_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以查询审计日志列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="GET:/studies/{study_id}/audit-logs",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "GET:/studies/{study_id}/audit-logs")
assert allowed is True
@pytest.mark.asyncio
async def test_audit_logs_export_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以导出审计日志"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="POST:/studies/{study_id}/audit-logs/export",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/audit-logs/export")
assert allowed is True
# ============================================================================
# 访视管理 (visits) - 5个端点
# ============================================================================
@pytest.mark.asyncio
async def test_visits_create_with_permission(db_session: AsyncSession):
"""验证有权限的PV可以创建访视"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PV",
endpoint_key="POST:/studies/{study_id}/visits",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PV", "POST:/studies/{study_id}/visits")
assert allowed is True
@pytest.mark.asyncio
async def test_visits_list_with_permission(db_session: AsyncSession):
"""验证有权限的PV可以查询访视列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PV",
endpoint_key="GET:/studies/{study_id}/visits",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PV", "GET:/studies/{study_id}/visits")
assert allowed is True
# ============================================================================
# 知识库笔记 (knowledge_notes) - 5个端点
# ============================================================================
@pytest.mark.asyncio
async def test_knowledge_notes_create_with_permission(db_session: AsyncSession):
"""验证有权限的MEDICAL_REVIEW可以创建知识库笔记"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="MEDICAL_REVIEW",
endpoint_key="POST:/studies/{study_id}/knowledge-notes",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "MEDICAL_REVIEW", "POST:/studies/{study_id}/knowledge-notes")
assert allowed is True
@pytest.mark.asyncio
async def test_knowledge_notes_list_with_permission(db_session: AsyncSession):
"""验证有权限的MEDICAL_REVIEW可以查询知识库笔记列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="MEDICAL_REVIEW",
endpoint_key="GET:/studies/{study_id}/knowledge-notes",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "MEDICAL_REVIEW", "GET:/studies/{study_id}/knowledge-notes")
assert allowed is True
# ============================================================================
# 参与者历史 (subject_histories) - 5个端点
# ============================================================================
@pytest.mark.asyncio
async def test_subject_histories_list_with_permission(db_session: AsyncSession):
"""验证有权限的CRA可以查询参与者历史列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="GET:/studies/{study_id}/subjects/{subject_id}/history",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "GET:/studies/{study_id}/subjects/{subject_id}/history")
assert allowed is True
@pytest.mark.asyncio
async def test_subject_histories_export_with_permission(db_session: AsyncSession):
"""验证有权限的CRA可以导出参与者历史"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="GET:/studies/{study_id}/subjects/{subject_id}/history/export",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "GET:/studies/{study_id}/subjects/{subject_id}/history/export")
assert allowed is True
# ============================================================================
# 项目里程碑 (project_milestones) - 2个端点
# ============================================================================
@pytest.mark.asyncio
async def test_milestones_list_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以查询项目里程碑列表"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="GET:/studies/{study_id}/milestones",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "GET:/studies/{study_id}/milestones")
assert allowed is True
@pytest.mark.asyncio
async def test_milestones_update_with_permission(db_session: AsyncSession):
"""验证有权限的PM可以更新项目里程碑"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="PM",
endpoint_key="PATCH:/studies/{study_id}/milestones/{id}",
allowed=True,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "PM", "PATCH:/studies/{study_id}/milestones/{id}")
assert allowed is True
# ============================================================================
# 权限拒绝场景
# ============================================================================
@pytest.mark.asyncio
async def test_startup_permission_denied_for_cra(db_session: AsyncSession):
"""验证CRA无法执行启动管理操作"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="POST:/studies/{study_id}/startup/ethics",
allowed=False,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "POST:/studies/{study_id}/startup/ethics")
assert allowed is False
@pytest.mark.asyncio
async def test_project_permissions_denied_for_cra(db_session: AsyncSession):
"""验证CRA无法修改项目权限"""
study_id = uuid.uuid4()
perm = ApiEndpointPermission(
study_id=study_id,
role="CRA",
endpoint_key="PUT:/studies/{study_id}/permissions",
allowed=False,
)
db_session.add(perm)
await db_session.commit()
allowed = await role_has_api_permission(db_session, study_id, "CRA", "PUT:/studies/{study_id}/permissions")
assert allowed is False