""" 第2批模块迁移测试:members 和 sites 模块 测试接口级权限系统在 members 和 sites 模块中的应用 """ 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 from app.models.study_role_permission import StudyRolePermission @pytest.mark.asyncio async def test_add_member_with_permission(db_session: AsyncSession): """验证有权限的PM可以添加项目成员""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="POST:/studies/{study_id}/members", 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}/members") assert allowed is True @pytest.mark.asyncio async def test_add_member_without_permission(db_session: AsyncSession): """验证无权限的CRA无法添加项目成员""" study_id = uuid.uuid4() # 创建权限(拒绝) perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="POST:/studies/{study_id}/members", 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}/members") assert allowed is False @pytest.mark.asyncio async def test_list_members_with_permission(db_session: AsyncSession): """验证有权限的PM可以查询项目成员列表""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="GET:/studies/{study_id}/members", 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}/members") assert allowed is True @pytest.mark.asyncio async def test_update_member_with_permission(db_session: AsyncSession): """验证有权限的PM可以更新项目成员""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="PATCH:/studies/{study_id}/members/{member_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}/members/{member_id}") assert allowed is True @pytest.mark.asyncio async def test_delete_member_with_permission(db_session: AsyncSession): """验证有权限的PM可以删除项目成员""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="DELETE:/studies/{study_id}/members/{member_id}", allowed=True, ) db_session.add(perm) await db_session.commit() # 验证权限检查 allowed = await role_has_api_permission(db_session, study_id, "PM", "DELETE:/studies/{study_id}/members/{member_id}") assert allowed is True @pytest.mark.asyncio async def test_list_member_candidates_with_permission(db_session: AsyncSession): """验证有权限的PM可以查询项目成员候选人""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="GET:/studies/{study_id}/members/candidates", 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}/members/candidates") assert allowed is True @pytest.mark.asyncio async def test_create_site_with_permission(db_session: AsyncSession): """验证有权限的PM可以创建中心""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="POST:/studies/{study_id}/sites", 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}/sites") assert allowed is True @pytest.mark.asyncio async def test_list_sites_with_permission(db_session: AsyncSession): """验证有权限的PM可以查询中心列表""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="GET:/studies/{study_id}/sites", 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}/sites") assert allowed is True @pytest.mark.asyncio async def test_list_sites_cra_with_permission(db_session: AsyncSession): """验证有权限的CRA可以查询中心列表""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="GET:/studies/{study_id}/sites", 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}/sites") assert allowed is True @pytest.mark.asyncio async def test_update_site_with_permission(db_session: AsyncSession): """验证有权限的PM可以更新中心""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="PATCH:/studies/{study_id}/sites/{site_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}/sites/{site_id}") assert allowed is True @pytest.mark.asyncio async def test_delete_site_with_permission(db_session: AsyncSession): """验证有权限的PM可以删除中心""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="DELETE:/studies/{study_id}/sites/{site_id}", allowed=True, ) db_session.add(perm) await db_session.commit() # 验证权限检查 allowed = await role_has_api_permission(db_session, study_id, "PM", "DELETE:/studies/{study_id}/sites/{site_id}") assert allowed is True @pytest.mark.asyncio async def test_members_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}/members", 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}/members") assert allowed is False @pytest.mark.asyncio async def test_sites_permission_denied_for_cra_write(db_session: AsyncSession): """验证CRA无法执行中心写操作""" study_id = uuid.uuid4() # 创建权限(拒绝) perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="POST:/studies/{study_id}/sites", 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}/sites") assert allowed is False @pytest.mark.asyncio async def test_backward_compatibility_members_module_level(db_session: AsyncSession): """验证members模块的模块级权限回退仍然有效""" study_id = uuid.uuid4() # 设置模块级权限(不设置接口级权限) db_session.add(StudyRolePermission( study_id=study_id, role="PM", module="project_members", can_read=True, can_write=True, )) await db_session.commit() # 验证权限检查会回退到模块级权限 allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/members") assert allowed is True @pytest.mark.asyncio async def test_backward_compatibility_sites_module_level(db_session: AsyncSession): """验证sites模块的模块级权限回退仍然有效""" study_id = uuid.uuid4() # 设置模块级权限(不设置接口级权限) db_session.add(StudyRolePermission( study_id=study_id, role="PM", module="sites", can_read=True, can_write=True, )) await db_session.commit() # 验证权限检查会回退到模块级权限 allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/sites") assert allowed is True @pytest.mark.asyncio async def test_api_permission_priority_over_module_members(db_session: AsyncSession): """验证members模块的接口级权限优先于模块级权限""" study_id = uuid.uuid4() # 设置模块级权限为允许 db_session.add(StudyRolePermission( study_id=study_id, role="PM", module="project_members", can_read=True, can_write=True, )) # 设置接口级权限为拒绝(优先级更高) db_session.add(ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="POST:/studies/{study_id}/members", allowed=False, )) await db_session.commit() # 验证接口级权限优先 allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/members") assert allowed is False @pytest.mark.asyncio async def test_api_permission_priority_over_module_sites(db_session: AsyncSession): """验证sites模块的接口级权限优先于模块级权限""" study_id = uuid.uuid4() # 设置模块级权限为允许 db_session.add(StudyRolePermission( study_id=study_id, role="PM", module="sites", can_read=True, can_write=True, )) # 设置接口级权限为拒绝(优先级更高) db_session.add(ApiEndpointPermission( study_id=study_id, role="PM", endpoint_key="POST:/studies/{study_id}/sites", allowed=False, )) await db_session.commit() # 验证接口级权限优先 allowed = await role_has_api_permission(db_session, study_id, "PM", "POST:/studies/{study_id}/sites") assert allowed is False