Files
awoooi/apps/api/tests/test_awooop_tenant_asset_inventory.py
Your Name 0e93566f11
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m27s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
fix(awooop): fail soft readback list endpoints
2026-07-03 08:21:36 +08:00

161 lines
6.0 KiB
Python

from __future__ import annotations
import json
import re
from src.api.v1.platform.tenants import ListTenantsResponse, _tenant_readback_fallback
from src.services.platform_operator_service import build_tenant_asset_inventory
FORBIDDEN_PUBLIC_MARKERS = [
"Vibe" + "Work",
"Agent " + "Bounty " + "Protocol",
"agent-" + "bounty-" + "protocol",
"AWOOOI / " + "AwoooP / " + "IwoooS",
"Tsen" + "Yang Website",
"Bitan " + "Pharmacy",
"repo_owner_namespace_redacted=true",
"raw_repository_namespace_visible=false",
"public_api_raw_repo_namespace_allowed=false",
"read_only_inventory_only=true",
"runtime_execution_authorized=false",
"action_buttons_allowed=false",
]
def test_tenant_asset_inventory_merges_products_routes_and_repos() -> None:
tenants = [
{
"project_id": "awoooi",
"display_name": "AWOOOI",
"migration_mode": "shadow",
"budget_limit_usd": None,
"is_active": True,
"created_at": "2026-06-14T00:00:00+08:00",
}
]
inventory = build_tenant_asset_inventory(tenants)
summary = inventory["summary"]
assert inventory["schema_version"] == "awooop_tenant_asset_inventory_v1"
assert summary["tenant_table_count"] == 1
assert summary["product_surface_count"] >= 16
assert summary["public_route_count"] >= 31
assert summary["source_candidate_repo_count"] == 10
assert summary["source_in_scope_repo_count"] == 9
assert summary["source_primary_ready_count"] == 0
assert summary["owner_response_accepted_count"] == 0
assert summary["runtime_gate_count"] == 0
assert summary["action_button_count"] == 0
product_ids = {item["product_id"] for item in inventory["products"]}
assert {
"PRD-001",
"PRD-002",
"PRD-003",
"PRD-004",
"PRD-005",
"PRD-006",
"PRD-007",
"PRD-008",
"PRD-010",
"PRD-011",
"PRD-012",
"PRD-013",
"PRD-014",
}.issubset(product_ids)
assert all(re.fullmatch(r"PRD-\d{3}", item["project_id"]) for item in inventory["products"])
assert all(item["source_keys"] == [] or all(key.startswith("SRCREF-") for key in item["source_keys"]) for item in inventory["products"])
route_domains = {item["domain"] for item in inventory["public_routes"]}
assert {
"awoooi.wooo.work",
"stock.wooo.work",
"bitan.wooo.work",
"mo.wooo.work",
"vibework.wooo.work",
"agent.wooo.work",
"2026fifa.wooo.work",
"design.wooo.work",
"n8n.wooo.work",
"grist.wooo.work",
"vault.wooo.work",
"ollama.wooo.work",
"tsenyang.com",
"tsenyang.wooo.work",
}.issubset(route_domains)
source_repos = {item["github_repo"] for item in inventory["source_repos"]}
source_scope_ids = {item["source_scope_id"] for item in inventory["source_repos"]}
assert "SRC-008" in source_scope_ids
assert "SRC-009" in source_scope_ids
assert "SRC-010" in source_scope_ids
assert all(re.fullmatch(r"SRC-\d{3}", repo) for repo in source_repos)
assert all(item["source_namespace_redacted"] for item in inventory["source_repos"])
inventory_payload = json.dumps(inventory, ensure_ascii=False)
assert "owenhytsai" not in inventory_payload
assert "nexu-io" not in inventory_payload
assert "blocked_waiting_" not in inventory_payload
assert "observe_scope_review" not in inventory_payload
assert all(marker not in inventory_payload for marker in FORBIDDEN_PUBLIC_MARKERS)
assert "只讀資產台帳" in " ".join(inventory["boundaries"])
assert all("=" not in boundary for boundary in inventory["boundaries"])
assert {item["risk"] for item in inventory["source_repos"]}.issubset(
{"high", "medium", "low", "unknown"}
)
assert {item["readiness_state"] for item in inventory["source_repos"]}.issubset(
{
"need_refs_evidence",
"need_target_decision",
"need_internal_remote_decision",
"need_scope_review",
"need_owner_evidence",
}
)
assert all(item["runtime_gate_count"] == 0 for item in inventory["source_repos"])
assert all(item["action_button_count"] == 0 for item in inventory["public_routes"])
assert all(item["runtime_gate_count"] == 0 for item in inventory["products"])
def test_tenant_response_model_keeps_asset_inventory_contract() -> None:
tenant = {
"project_id": "awoooi",
"display_name": "AWOOOI",
"migration_mode": "shadow",
"budget_limit_usd": None,
"is_active": True,
"created_at": "2026-06-14T00:00:00+08:00",
}
inventory = build_tenant_asset_inventory([tenant])
response = ListTenantsResponse.model_validate(
{
"tenants": [tenant],
"total": 1,
"asset_inventory": inventory,
}
)
assert response.asset_inventory.summary.product_surface_count >= 16
assert response.asset_inventory.summary.runtime_gate_count == 0
assert response.asset_inventory.products[0].runtime_gate_count == 0
response_payload = response.model_dump_json()
assert "owenhytsai" not in response_payload
assert "nexu-io" not in response_payload
assert all(marker not in response_payload for marker in FORBIDDEN_PUBLIC_MARKERS)
assert response.asset_inventory.source_repos[0].source_namespace_redacted is True
def test_tenant_readback_fallback_keeps_response_model_no_write_contract() -> None:
response = ListTenantsResponse.model_validate(_tenant_readback_fallback())
assert response.tenants[0].project_id == "awoooi"
assert response.tenants[0].migration_mode == "readback_degraded"
assert response.asset_inventory.mode == "readback_degraded_ai_controlled_repair"
assert response.asset_inventory.summary.tenant_table_count == 0
assert response.asset_inventory.products == []
assert response.asset_inventory.public_routes == []
assert response.asset_inventory.source_repos == []
assert "does not modify" in " ".join(response.asset_inventory.boundaries)