"""单元测试:API权限配置""" import pytest from app.core.api_permissions import API_ENDPOINT_PERMISSIONS, MODULE_TO_ENDPOINTS def test_api_endpoint_permissions_structure(): """测试API端点权限配置结构""" for endpoint_key, config in API_ENDPOINT_PERMISSIONS.items(): assert "module" in config, f"Missing 'module' in {endpoint_key}" assert "action" in config, f"Missing 'action' in {endpoint_key}" assert "description" in config, f"Missing 'description' in {endpoint_key}" assert "default_roles" in config, f"Missing 'default_roles' in {endpoint_key}" assert config["action"] in ["read", "write"], f"Invalid action in {endpoint_key}" assert isinstance(config["default_roles"], list), f"default_roles must be list in {endpoint_key}" assert len(config["default_roles"]) > 0, f"default_roles must not be empty in {endpoint_key}" def test_module_to_endpoints_mapping(): """测试模块到端点的映射""" for module, actions in MODULE_TO_ENDPOINTS.items(): assert "read" in actions, f"Missing 'read' in {module}" assert "write" in actions, f"Missing 'write' in {module}" assert isinstance(actions["read"], list), f"read must be list in {module}" assert isinstance(actions["write"], list), f"write must be list in {module}" # 验证所有端点都在API_ENDPOINT_PERMISSIONS中定义 for endpoint_key in actions["read"] + actions["write"]: assert endpoint_key in API_ENDPOINT_PERMISSIONS, f"Endpoint {endpoint_key} not in API_ENDPOINT_PERMISSIONS" def test_subjects_endpoints_configured(): """测试subjects模块的端点配置""" expected_endpoints = [ "POST:/subjects", "GET:/subjects", "GET:/subjects/{id}", "PATCH:/subjects/{id}", "DELETE:/subjects/{id}", "POST:/subjects/{subject_id}/visits", "GET:/subjects/{subject_id}/visits", "GET:/subjects/{subject_id}/visits/{visit_id}", "PATCH:/subjects/{subject_id}/visits/{visit_id}", ] for endpoint_key in expected_endpoints: assert endpoint_key in API_ENDPOINT_PERMISSIONS, f"Missing endpoint {endpoint_key}" assert API_ENDPOINT_PERMISSIONS[endpoint_key]["module"] == "subjects" def test_risk_issues_endpoints_configured(): """测试risk_issues模块的端点配置""" expected_endpoints = [ "POST:/risk-issues", "GET:/risk-issues", "GET:/risk-issues/{id}", "DELETE:/risk-issues/{id}", ] for endpoint_key in expected_endpoints: assert endpoint_key in API_ENDPOINT_PERMISSIONS, f"Missing endpoint {endpoint_key}" assert API_ENDPOINT_PERMISSIONS[endpoint_key]["module"] == "risk_issues" def test_fees_endpoints_configured(): """测试fees模块的端点配置""" expected_endpoints = [ "POST:/fees/contracts", "GET:/fees/contracts", "GET:/fees/contracts/{id}", "PATCH:/fees/contracts/{id}", "DELETE:/fees/contracts/{id}", "POST:/fees/contracts/{id}/payments", "PATCH:/fees/payments/{id}", "DELETE:/fees/payments/{id}", "POST:/finance/contracts", "GET:/finance/contracts", "GET:/finance/contracts/{id}", "PATCH:/finance/contracts/{id}", "DELETE:/finance/contracts/{id}", ] for endpoint_key in expected_endpoints: assert endpoint_key in API_ENDPOINT_PERMISSIONS, f"Missing endpoint {endpoint_key}" assert API_ENDPOINT_PERMISSIONS[endpoint_key]["module"] == "fees" def test_project_members_endpoints_configured(): """测试project_members模块的端点配置""" expected_endpoints = [ "POST:/project-members", "GET:/project-members", "PATCH:/project-members/{id}", ] for endpoint_key in expected_endpoints: assert endpoint_key in API_ENDPOINT_PERMISSIONS, f"Missing endpoint {endpoint_key}" assert API_ENDPOINT_PERMISSIONS[endpoint_key]["module"] == "project_members" def test_sites_endpoints_configured(): """测试sites模块的端点配置""" expected_endpoints = [ "POST:/sites", "GET:/sites", "GET:/sites/{id}", "PATCH:/sites/{id}", ] for endpoint_key in expected_endpoints: assert endpoint_key in API_ENDPOINT_PERMISSIONS, f"Missing endpoint {endpoint_key}" assert API_ENDPOINT_PERMISSIONS[endpoint_key]["module"] == "sites" def test_endpoint_key_format(): """测试端点key格式""" for endpoint_key in API_ENDPOINT_PERMISSIONS.keys(): # 格式应该是 "METHOD:/path" assert ":" in endpoint_key, f"Invalid endpoint_key format: {endpoint_key}" method, path = endpoint_key.split(":", 1) assert method in ["GET", "POST", "PATCH", "DELETE", "PUT"], f"Invalid method in {endpoint_key}" assert path.startswith("/"), f"Invalid path in {endpoint_key}" def test_default_roles_valid(): """测试默认角色有效""" valid_roles = {"PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA", "ADMIN"} for endpoint_key, config in API_ENDPOINT_PERMISSIONS.items(): for role in config["default_roles"]: assert role in valid_roles, f"Invalid role {role} in {endpoint_key}" def test_module_to_endpoints_completeness(): """测试MODULE_TO_ENDPOINTS包含所有模块""" modules_in_config = set() for config in API_ENDPOINT_PERMISSIONS.values(): modules_in_config.add(config["module"]) for module in modules_in_config: assert module in MODULE_TO_ENDPOINTS, f"Module {module} not in MODULE_TO_ENDPOINTS" def test_read_write_endpoints_consistency(): """测试read/write端点的一致性""" for module, actions in MODULE_TO_ENDPOINTS.items(): read_endpoints = set(actions["read"]) write_endpoints = set(actions["write"]) # read和write不应该有重叠 overlap = read_endpoints & write_endpoints assert len(overlap) == 0, f"Overlap between read and write in {module}: {overlap}" # 所有端点都应该在API_ENDPOINT_PERMISSIONS中 all_endpoints = read_endpoints | write_endpoints for endpoint_key in all_endpoints: assert endpoint_key in API_ENDPOINT_PERMISSIONS, f"Endpoint {endpoint_key} not in API_ENDPOINT_PERMISSIONS" config = API_ENDPOINT_PERMISSIONS[endpoint_key] assert config["module"] == module, f"Module mismatch for {endpoint_key}" # 验证action与read/write分类一致 if endpoint_key in read_endpoints: assert config["action"] == "read", f"Action mismatch for {endpoint_key}" else: assert config["action"] == "write", f"Action mismatch for {endpoint_key}" def test_no_duplicate_endpoints(): """测试没有重复的端点""" endpoints = list(API_ENDPOINT_PERMISSIONS.keys()) assert len(endpoints) == len(set(endpoints)), "Duplicate endpoints found" def test_endpoint_descriptions_not_empty(): """测试所有端点都有描述""" for endpoint_key, config in API_ENDPOINT_PERMISSIONS.items(): assert config["description"], f"Empty description for {endpoint_key}" assert len(config["description"]) > 0, f"Empty description for {endpoint_key}"