""" 第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