| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- from __future__ import annotations
- ACTOR_UID = "01900000-0000-7000-8000-000000000101"
- PLAN_UID = "01900000-0000-7000-8000-000000000201"
- ASSET_UID = "01900000-0000-7000-8000-000000000301"
- CORRECTION_UID = "01900000-0000-7000-8000-000000000401"
- class FakeService:
- def __init__(self):
- self.calls = []
- def list_plans(self):
- return [{"uid": PLAN_UID, "name": "主动发现"}]
- def create_plan(self, payload, *, actor_uid):
- self.calls.append(("create_plan", payload, actor_uid))
- return {"uid": PLAN_UID, **payload}
- def execute(self, plan_uid, payload, *, batch_key, actor_uid):
- self.calls.append(("execute", plan_uid, batch_key, actor_uid))
- return {"uid": "run-1", "status": "completed"}
- def list_assets(self, source_uid):
- return [{"uid": ASSET_UID, "source_uid": source_uid}]
- def list_runs(self, plan_uid):
- return [{"uid": "run-1", "plan_uid": plan_uid}]
- def list_changes(self, run_uid):
- return [{"run_uid": run_uid, "change_type": "field_changed"}]
- def list_lineage(self, run_uid):
- return [{"run_uid": run_uid, "parse_status": "resolved"}]
- def list_health_signals(self, run_uid):
- return [{"run_uid": run_uid, "signal_type": "quality"}]
- def list_corrections(self, asset_uid=None):
- return [{"uid": CORRECTION_UID, "asset_uid": asset_uid}]
- def submit_correction(self, asset_uid, payload, *, actor_uid):
- return {"uid": CORRECTION_UID, "asset_uid": asset_uid, "status": "pending"}
- def resolve_correction(self, correction_uid, **kwargs):
- self.calls.append(("resolve", correction_uid, kwargs))
- return {"uid": correction_uid, "status": "resolved", "current_version": 2}
- def _headers(role, **extra):
- return {"Authorization": f"Bearer {role}", **extra}
- def test_active_metadata_read_operate_and_admin_permissions(monkeypatch):
- from app import create_app
- from app.api.meta_data import active_metadata
- service = FakeService()
- monkeypatch.setattr(active_metadata, "_service", lambda: service)
- monkeypatch.setattr(
- "app.core.system.auth.load_identity_from_token",
- lambda token, secret: (
- {"id": ACTOR_UID, "username": token, "roles": [token]}
- if token in {"viewer", "editor", "admin"}
- else None
- ),
- )
- app = create_app()
- app.config.update(TESTING=True)
- client = app.test_client()
- assert client.get(
- "/api/meta/active-metadata/plans", headers=_headers("viewer")
- ).status_code == 200
- assert client.post(
- "/api/meta/active-metadata/plans",
- json={"name": "plan"},
- headers=_headers("editor"),
- ).status_code == 403
- assert client.post(
- "/api/meta/active-metadata/plans",
- json={"name": "plan"},
- headers=_headers("admin"),
- ).status_code == 201
- assert client.post(
- f"/api/meta/active-metadata/plans/{PLAN_UID}/runs",
- json={"snapshot": {"assets": []}},
- headers=_headers("viewer", **{"Idempotency-Key": "batch-1"}),
- ).status_code == 403
- executed = client.post(
- f"/api/meta/active-metadata/plans/{PLAN_UID}/runs",
- json={"snapshot": {"assets": []}},
- headers=_headers("editor", **{"Idempotency-Key": "batch-1"}),
- )
- assert executed.status_code == 200
- assert service.calls[-1] == ("execute", PLAN_UID, "batch-1", ACTOR_UID)
- resolved = client.post(
- f"/api/meta/active-metadata/corrections/{CORRECTION_UID}/resolve",
- json={
- "expected_version": 1,
- "decision": "accept",
- "resolution": {"comment": "accepted"},
- },
- headers=_headers("editor"),
- )
- assert resolved.status_code == 200
- def test_active_metadata_paths_have_dedicated_policy():
- from app.core.system.permissions import (
- ACTIVE_METADATA_MANAGE,
- ACTIVE_METADATA_OPERATE,
- ACTIVE_METADATA_READ,
- permission_for_request,
- )
- base = "/api/meta/active-metadata"
- assert permission_for_request(f"{base}/plans", "GET") == (ACTIVE_METADATA_READ,)
- assert permission_for_request(f"{base}/plans", "POST") == (
- ACTIVE_METADATA_MANAGE,
- )
- assert permission_for_request(f"{base}/plans/{PLAN_UID}/runs", "POST") == (
- ACTIVE_METADATA_OPERATE,
- )
- assert permission_for_request(f"{base}/runs/run-1/lineage", "GET") == (
- ACTIVE_METADATA_READ,
- )
|