""" 第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) # ============================================================================ @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="startup_ethics:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "startup_ethics:create") 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="startup_ethics:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "startup_ethics:list") assert allowed is True @pytest.mark.asyncio async def test_startup_initiation_create_with_permission(db_session: AsyncSession): """验证有权限的PM可以创建立项记录""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="startup_initiation:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "startup_initiation:create") assert allowed is True @pytest.mark.asyncio async def test_startup_auth_create_with_permission(db_session: AsyncSession): """验证有权限的PM可以创建启动会或培训授权""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="startup_auth:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "startup_auth:create") assert allowed is True @pytest.mark.asyncio async def test_startup_auth_read_with_permission(db_session: AsyncSession): """验证有权限的CRA可以查询启动会或培训授权""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="startup_auth:read", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "startup_auth:read") assert allowed is True # ============================================================================ # 项目权限管理已迁移为系统级权限 # ============================================================================ def test_project_permissions_are_not_project_matrix_permissions(): """项目权限配置由 system:permissions:project_config 控制,不再进入项目矩阵。""" from app.core.api_permissions import API_ENDPOINT_PERMISSIONS, SYSTEM_PERMISSIONS assert "permissions:read" not in API_ENDPOINT_PERMISSIONS assert "permissions:update" not in API_ENDPOINT_PERMISSIONS assert "system:permissions:project_config" in SYSTEM_PERMISSIONS # ============================================================================ # 项目概览 (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="project_overview:read", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "project_overview:read") assert allowed is True # ============================================================================ # 监查访视问题汇总 (monitoring_visit_issues) # ============================================================================ @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="monitoring_issues:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "monitoring_issues:list") assert allowed is True # ============================================================================ # 药物发货 (drug_shipments) - 5个端点 # ============================================================================ @pytest.mark.asyncio async def test_drug_shipments_create_with_permission(db_session: AsyncSession): """验证有权限的CTA可以创建药物发货""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CTA", endpoint_key="drug_shipments:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CTA", "drug_shipments:create") assert allowed is True @pytest.mark.asyncio async def test_drug_shipments_list_with_permission(db_session: AsyncSession): """验证有权限的CTA可以查询药物发货列表""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CTA", endpoint_key="drug_shipments:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CTA", "drug_shipments:list") assert allowed is True # ============================================================================ # 设备管理 (material_equipments) - 5个端点 # ============================================================================ @pytest.mark.asyncio async def test_material_equipments_create_with_permission(db_session: AsyncSession): """验证有权限的CRA可以创建设备""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="material_equipments:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "material_equipments:create") assert allowed is True @pytest.mark.asyncio async def test_material_equipments_list_with_permission(db_session: AsyncSession): """验证有权限的CTA可以查询设备列表""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CTA", endpoint_key="material_equipments:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CTA", "material_equipments:list") assert allowed is True # ============================================================================ # 参与者PD (subject_pds) - 4个端点 # ============================================================================ @pytest.mark.asyncio async def test_subject_pds_create_with_permission(db_session: AsyncSession): """验证有权限的CRA可以创建参与者PD""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="subject_pds:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "subject_pds:create") assert allowed is True @pytest.mark.asyncio async def test_subject_pds_list_with_permission(db_session: AsyncSession): """验证有权限的CRA可以查询参与者PD列表""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="subject_pds:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "subject_pds:list") 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="audit_logs:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "audit_logs:list") 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="audit_logs:export", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "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="visits:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PV", "visits:create") 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="visits:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PV", "visits:list") assert allowed is True # ============================================================================ # 注意事项 (precautions) - 5个端点 # ============================================================================ @pytest.mark.asyncio async def test_precautions_create_with_permission(db_session: AsyncSession): """验证有权限的QA可以创建注意事项""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="QA", endpoint_key="precautions:create", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "QA", "precautions:create") assert allowed is True @pytest.mark.asyncio async def test_precautions_list_with_permission(db_session: AsyncSession): """验证有权限的QA可以查询注意事项列表""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="QA", endpoint_key="precautions:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "QA", "precautions:list") assert allowed is True # ============================================================================ # 病史记录 (subject_histories) # ============================================================================ @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="subject_histories:list", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "subject_histories:list") assert allowed is True @pytest.mark.asyncio async def test_subject_histories_read_with_permission(db_session: AsyncSession): """验证有权限的CRA可以查询病史记录详情""" study_id = uuid.uuid4() perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="subject_histories:read", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "subject_histories:read") 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="project_milestones:read", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "project_milestones:read") 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="project_milestones:update", allowed=True, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "PM", "project_milestones:update") 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="startup_ethics:create", allowed=False, ) db_session.add(perm) await db_session.commit() allowed = await role_has_api_permission(db_session, study_id, "CRA", "startup_ethics:create") assert allowed is False @pytest.mark.asyncio async def test_removed_project_permissions_are_denied_for_project_roles(db_session: AsyncSession): """项目角色不能再通过 permissions:update 这种残留 key 获得权限管理能力。""" study_id = uuid.uuid4() allowed = await role_has_api_permission(db_session, study_id, "CRA", "permissions:update") assert allowed is False