"""集成测试:权限管理API端点""" import pytest import uuid from fastapi.testclient import TestClient from sqlalchemy.ext.asyncio import AsyncSession from app.core.project_permissions import get_api_endpoint_permissions, replace_api_endpoint_permissions from app.models.api_endpoint_permission import ApiEndpointPermission @pytest.mark.asyncio async def test_get_api_endpoint_permissions_empty(db_session: AsyncSession): """测试获取空的权限矩阵""" study_id = uuid.uuid4() result = await get_api_endpoint_permissions(db_session, study_id) # 应该返回所有角色和端点的默认权限 assert isinstance(result, dict) assert len(result) > 0 @pytest.mark.asyncio async def test_get_api_endpoint_permissions_with_custom(db_session: AsyncSession): """测试获取自定义权限矩阵""" study_id = uuid.uuid4() # 创建自定义权限 perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="POST:/subjects", allowed=True, ) db_session.add(perm) await db_session.commit() result = await get_api_endpoint_permissions(db_session, study_id) assert isinstance(result, dict) assert "CRA" in result assert "POST:/subjects" in result["CRA"] assert result["CRA"]["POST:/subjects"]["allowed"] is True @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_single_role(db_session: AsyncSession): """测试替换单个角色的权限""" study_id = uuid.uuid4() payload = { "CRA": { "POST:/subjects": True, "GET:/subjects": True, "PATCH:/subjects/{id}": True, } } result = await replace_api_endpoint_permissions(db_session, study_id, payload) assert isinstance(result, dict) assert "CRA" in result assert result["CRA"]["POST:/subjects"]["allowed"] is True assert result["CRA"]["GET:/subjects"]["allowed"] is True assert result["CRA"]["PATCH:/subjects/{id}"]["allowed"] is True @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_multiple_roles(db_session: AsyncSession): """测试替换多个角色的权限""" study_id = uuid.uuid4() payload = { "CRA": { "POST:/subjects": True, "GET:/subjects": True, }, "PV": { "GET:/subjects": True, "GET:/subjects/{id}": True, } } result = await replace_api_endpoint_permissions(db_session, study_id, payload) assert result["CRA"]["POST:/subjects"]["allowed"] is True assert result["CRA"]["GET:/subjects"]["allowed"] is True assert result["PV"]["GET:/subjects"]["allowed"] is True assert result["PV"]["GET:/subjects/{id}"]["allowed"] is True @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_deny(db_session: AsyncSession): """测试替换权限为拒绝""" study_id = uuid.uuid4() payload = { "PV": { "POST:/subjects": False, } } result = await replace_api_endpoint_permissions(db_session, study_id, payload) assert result["PV"]["POST:/subjects"]["allowed"] is False @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_overwrites_existing(db_session: AsyncSession): """测试替换权限会覆盖现有权限""" study_id = uuid.uuid4() # 创建初始权限 perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="POST:/subjects", allowed=True, ) db_session.add(perm) await db_session.commit() # 替换权限 payload = { "CRA": { "POST:/subjects": False, } } result = await replace_api_endpoint_permissions(db_session, study_id, payload) assert result["CRA"]["POST:/subjects"]["allowed"] is False @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_multiple_endpoints(db_session: AsyncSession): """测试替换多个端点的权限""" study_id = uuid.uuid4() payload = { "CRA": { "POST:/subjects": True, "GET:/subjects": True, "PATCH:/subjects/{id}": True, "DELETE:/subjects/{id}": False, "POST:/risk-issues": True, "GET:/risk-issues": True, } } result = await replace_api_endpoint_permissions(db_session, study_id, payload) assert result["CRA"]["POST:/subjects"]["allowed"] is True assert result["CRA"]["GET:/subjects"]["allowed"] is True assert result["CRA"]["PATCH:/subjects/{id}"]["allowed"] is True assert result["CRA"]["DELETE:/subjects/{id}"]["allowed"] is False assert result["CRA"]["POST:/risk-issues"]["allowed"] is True assert result["CRA"]["GET:/risk-issues"]["allowed"] is True @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_different_studies(db_session: AsyncSession): """测试不同项目的权限独立""" study_id_1 = uuid.uuid4() study_id_2 = uuid.uuid4() payload_1 = { "CRA": { "POST:/subjects": True, } } payload_2 = { "CRA": { "POST:/subjects": False, } } await replace_api_endpoint_permissions(db_session, study_id_1, payload_1) await replace_api_endpoint_permissions(db_session, study_id_2, payload_2) result_1 = await get_api_endpoint_permissions(db_session, study_id_1) result_2 = await get_api_endpoint_permissions(db_session, study_id_2) assert result_1["CRA"]["POST:/subjects"]["allowed"] is True assert result_2["CRA"]["POST:/subjects"]["allowed"] is False @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_empty_payload(db_session: AsyncSession): """测试空的权限替换""" study_id = uuid.uuid4() payload = {} result = await replace_api_endpoint_permissions(db_session, study_id, payload) # 应该返回空结果或默认权限 assert isinstance(result, dict) @pytest.mark.asyncio async def test_replace_api_endpoint_permissions_partial_update(db_session: AsyncSession): """测试部分权限更新""" study_id = uuid.uuid4() # 创建初始权限 perm1 = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="POST:/subjects", allowed=True, ) perm2 = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="GET:/subjects", allowed=True, ) db_session.add(perm1) db_session.add(perm2) await db_session.commit() # 只更新一个权限 payload = { "CRA": { "POST:/subjects": False, } } result = await replace_api_endpoint_permissions(db_session, study_id, payload) # POST权限应该被更新 assert result["CRA"]["POST:/subjects"]["allowed"] is False # GET权限应该保持不变 assert result["CRA"]["GET:/subjects"]["allowed"] is True @pytest.mark.asyncio async def test_get_api_endpoint_permissions_structure(db_session: AsyncSession): """测试权限矩阵的结构""" study_id = uuid.uuid4() # 创建权限 perm = ApiEndpointPermission( study_id=study_id, role="CRA", endpoint_key="POST:/subjects", allowed=True, ) db_session.add(perm) await db_session.commit() result = await get_api_endpoint_permissions(db_session, study_id) # 验证结构 assert isinstance(result, dict) for role, endpoints in result.items(): assert isinstance(role, str) assert isinstance(endpoints, dict) for endpoint_key, permission in endpoints.items(): assert isinstance(endpoint_key, str) assert isinstance(permission, dict) assert "allowed" in permission assert isinstance(permission["allowed"], bool)