fix(classification): harden registration updates
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 26s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
This commit is contained in:
tegwick 2026-08-23 11:30:36 +02:00
parent fb79d0d68d
commit 57c3e08103
7 changed files with 152 additions and 14 deletions

View file

@ -8,6 +8,8 @@ from pathlib import Path
import pytest
from api.classification import ClassificationData
REPO_ROOT = Path(__file__).resolve().parent.parent
SCRIPT = REPO_ROOT / "scripts" / "register_from_classification.py"
@ -68,4 +70,58 @@ def test_json_report_shape():
assert payload["summary"]["invalid"] == 0
assert "summary" in payload
assert "results" in payload
assert set(payload["summary"]) == {"registered", "updated", "skipped", "invalid"}
assert set(payload["summary"]) == {"registered", "updated", "skipped", "invalid"}
def test_git_fingerprint_uses_one_root(monkeypatch, tmp_path):
from scripts import register_from_classification as registration
first = "a" * 40
second = "b" * 40
monkeypatch.setattr(
registration,
"_git_value",
lambda _path, _args: f"{first}\n{second}",
)
assert registration._git_fingerprint(tmp_path) == first
@pytest.mark.asyncio
async def test_api_update_separates_classification_from_identity(monkeypatch, tmp_path):
from scripts import register_from_classification as registration
calls = []
def fake_api_request(method, path, *, api_base, body=None):
calls.append((method, path, body))
if method == "GET":
return 200, {"slug": "example"}
return 200, {"slug": "example"}
monkeypatch.setattr(registration, "_api_request", fake_api_request)
monkeypatch.setattr(registration, "_git_root", lambda path: path)
monkeypatch.setattr(registration, "_git_value", lambda _path, _args: "origin")
monkeypatch.setattr(registration, "_git_fingerprint", lambda _path: "a" * 40)
report = registration.RegistrationReport()
data = ClassificationData(
category="infrastructure",
domain="infotech",
capability_tags=["infrastructure.state"],
)
await registration._upsert_via_api(
slug="example",
repo_path=tmp_path,
data=data,
dry_run=False,
api_base="http://state-hub.test",
report=report,
)
patch = next(call for call in calls if call[:2] == ("PATCH", "/repos/example"))
assert patch[2]["domain_slug"] == "infotech"
assert "local_path" not in patch[2]
assert "remote_url" not in patch[2]
assert "git_fingerprint" not in patch[2]
assert ("POST", "/repos/example/paths") in [call[:2] for call in calls]

View file

@ -108,6 +108,29 @@ class TestRepos:
assert r.status_code == 201
assert r.json()["host_paths"] == {"workstation": "/srv/hosted-repo"}
async def test_patch_reclassifies_primary_domain(self, client):
await _create_domain(client, slug="infotech", name="Infotech")
await _create_domain(client, slug="financials", name="Financials")
await _create_repo(client, domain_slug="infotech", slug="reclassified-repo")
r = await client.patch(
"/repos/reclassified-repo",
json={
"domain_slug": "financials",
"category": "product",
"secondary_domains": [],
"capability_tags": ["accounting"],
"business_stake": [],
"business_mechanics": [],
"classified_at": "2026-08-23",
"classified_by": "human",
"standard_version": "1.0",
},
)
assert r.status_code == 200, r.text
assert r.json()["domain_slug"] == "financials"
# ---------------------------------------------------------------------------
# Topic tests