from __future__ import annotations import time import pytest from .conftest import SeededUser, TenantSeed from .helpers import ReleaseApiClient @pytest.mark.release def test_g5_rule_sets_are_globally_readable_but_bindings_and_groups_follow_tenant_scope( admin_client: ReleaseApiClient, tenant_admin_api: ReleaseApiClient, common_api_a: ReleaseApiClient, ) -> None: admin_rule_sets = ReleaseApiClient.json_data(admin_client.get("/api/rule-sets")) tenant_rule_sets = ReleaseApiClient.json_data(tenant_admin_api.get("/api/rule-sets")) common_rule_sets = ReleaseApiClient.json_data(common_api_a.get("/api/rule-sets")) assert len(admin_rule_sets) > 0 assert len(tenant_rule_sets) == len(admin_rule_sets) assert len(common_rule_sets) == len(admin_rule_sets) admin_bindings = ReleaseApiClient.json_data(admin_client.get("/api/rule-sets/bindings")) tenant_bindings = ReleaseApiClient.json_data(tenant_admin_api.get("/api/rule-sets/bindings")) common_bindings = ReleaseApiClient.json_data(common_api_a.get("/api/rule-sets/bindings")) assert isinstance(admin_bindings, list) assert len(admin_bindings) > 0 assert tenant_bindings == [] assert common_bindings == [] admin_groups = admin_client.get("/api/v3/evaluation-point-groups/all") tenant_groups = tenant_admin_api.get("/api/v3/evaluation-point-groups/all") common_groups = common_api_a.get("/api/v3/evaluation-point-groups/all") assert ReleaseApiClient.json_data(admin_groups) != [] assert ReleaseApiClient.json_data(tenant_groups) == [] assert ReleaseApiClient.json_data(common_groups) == [] @pytest.mark.release def test_g5_group_detail_and_children_follow_same_scope_boundary( admin_client: ReleaseApiClient, tenant_admin_api: ReleaseApiClient, common_api_a: ReleaseApiClient, ) -> None: admin_groups = ReleaseApiClient.json_data(admin_client.get("/api/v3/evaluation-point-groups/all")) assert admin_groups != [] target_group = admin_groups[0] target_group_id = int(target_group["id"]) admin_detail = ReleaseApiClient.json_data( admin_client.get(f"/api/v3/evaluation-point-groups/{target_group_id}") ) assert int(admin_detail["id"]) == target_group_id admin_children = admin_client.get( f"/api/v3/evaluation-point-groups/{target_group_id}/children?page=1&page_size=20" ).json() assert isinstance(admin_children, dict) assert "data" in admin_children tenant_detail = tenant_admin_api.get( f"/api/v3/evaluation-point-groups/{target_group_id}", expected_status=404, ) assert "规则分组不存在" in tenant_detail.text tenant_children = tenant_admin_api.get( f"/api/v3/evaluation-point-groups/{target_group_id}/children?page=1&page_size=20", expected_status=404, ) assert "规则分组不存在" in tenant_children.text common_detail = common_api_a.get( f"/api/v3/evaluation-point-groups/{target_group_id}", expected_status=404, ) assert "规则分组不存在" in common_detail.text @pytest.mark.release def test_g5_cross_review_rejects_cross_tenant_documents_and_members( tenant_admin_api: ReleaseApiClient, common_api_b: ReleaseApiClient, tenant_a: TenantSeed, tenant_b: TenantSeed, tenant_common_user_a: SeededUser, tenant_common_user_b: SeededUser, make_release_document, ) -> None: doc_a = make_release_document( client=tenant_admin_api, tenant=tenant_a, file_name=f"pytest-cross-a-{int(time.time())}.txt", ) doc_b = make_release_document( client=common_api_b, tenant=tenant_b, file_name=f"pytest-cross-b-{int(time.time())}.txt", ) same_tenant = tenant_admin_api.post( "/api/v3/cross-review/tasks", json={ "taskName": f"Pytest Cross Same {int(time.time())}", "taskType": "CITY", "memberUserIds": [tenant_common_user_a.user_id], "principalUserIds": [], "documentIds": [doc_a.document_id], }, expected_status=200, ) same_tenant_data = ReleaseApiClient.json_data(same_tenant) assert int(same_tenant_data["documentCount"]) == 1 cross_doc = tenant_admin_api.post( "/api/v3/cross-review/tasks", json={ "taskName": f"Pytest Cross Doc {int(time.time())}", "taskType": "CITY", "memberUserIds": [tenant_common_user_a.user_id], "principalUserIds": [], "documentIds": [doc_b.document_id], }, expected_status=403, ) assert "其他租户文档" in cross_doc.text cross_member = tenant_admin_api.post( "/api/v3/cross-review/tasks", json={ "taskName": f"Pytest Cross Member {int(time.time())}", "taskType": "CITY", "memberUserIds": [tenant_common_user_b.user_id], "principalUserIds": [], "documentIds": [doc_a.document_id], }, expected_status=403, ) assert "其他租户用户" in cross_member.text @pytest.mark.release def test_g5_cross_review_task_visibility_progress_and_documents_follow_member_scope( tenant_admin_api: ReleaseApiClient, tenant_admin_api_b: ReleaseApiClient, tenant_a: TenantSeed, tenant_common_user_a: SeededUser, make_release_document, ) -> None: doc_a = make_release_document( client=tenant_admin_api, tenant=tenant_a, file_name=f"pytest-cross-query-{int(time.time())}.txt", ) created = tenant_admin_api.post( "/api/v3/cross-review/tasks", json={ "taskName": f"Pytest Query Task {int(time.time())}", "taskType": "CITY", "memberUserIds": [tenant_common_user_a.user_id], "principalUserIds": [], "documentIds": [doc_a.document_id], }, expected_status=200, ) created_data = ReleaseApiClient.json_data(created) task_id = int(created_data["taskId"]) queried = ReleaseApiClient.json_data( tenant_admin_api.post( "/api/v3/cross-review/tasks/query", json={"page": 1, "pageSize": 50, "keyword": "Pytest Query Task"}, expected_status=200, ) ) task_ids = {int(item["taskId"]) for item in queried["items"]} assert task_id in task_ids created_item = next(item for item in queried["items"] if int(item["taskId"]) == task_id) evaluation_tenant_codes = {str(item.get("tenantCode") or "") for item in created_item.get("evaluationTenants") or []} assert tenant_a.tenant_code in evaluation_tenant_codes progress = ReleaseApiClient.json_data( tenant_admin_api.get(f"/api/v3/cross-review/tasks/{task_id}/progress", expected_status=200) ) assert int(progress["taskId"]) == task_id assert int(progress["totalDocuments"]) == 1 documents = ReleaseApiClient.json_data( tenant_admin_api.get( f"/api/v3/cross-review/tasks/{task_id}/documents?page=1&pageSize=20", expected_status=200, ) ) assert int(documents["taskId"]) == task_id returned_document_ids = {int(item["documentId"]) for item in documents["items"]} assert doc_a.document_id in returned_document_ids cross_tenant_query = ReleaseApiClient.json_data( tenant_admin_api_b.post( "/api/v3/cross-review/tasks/query", json={"page": 1, "pageSize": 50, "keyword": "Pytest Query Task"}, expected_status=200, ) ) cross_tenant_task_ids = {int(item["taskId"]) for item in cross_tenant_query["items"]} assert task_id not in cross_tenant_task_ids cross_tenant_progress = tenant_admin_api_b.get( f"/api/v3/cross-review/tasks/{task_id}/progress", expected_status=403, ) assert "当前用户不是交叉评查任务成员" in cross_tenant_progress.text cross_tenant_documents = tenant_admin_api_b.get( f"/api/v3/cross-review/tasks/{task_id}/documents?page=1&pageSize=20", expected_status=403, ) assert "当前用户不是交叉评查任务成员" in cross_tenant_documents.text