Files
reuse-surface/tests/test_statehub_bridge.py
tegwick e72966a658
Some checks failed
ci / validate-registry (push) Has been cancelled
REUSE-WP-0018 T01/T02/T04/T06: plan-check deterministic matching + State Hub bridge
T01: specs/PlanCheck.md design doc, plan-check-result.schema.json and
reuse-event.schema.json (the latter shared with WP-0019's reuse telemetry).

T02: reuse_surface/plan_check.py + 'reuse-surface plan-check' CLI command.
Deterministic token-Jaccard matching against registry/indexes/federated.yaml
(reuses overlaps.py's TOKEN_RE rather than a second scoring method), with
reuse/extend/new verdicts, markdown and --format json output, staleness
warning, and --record-outcome JSONL telemetry.

T04: reuse_surface/statehub_bridge.py bridges plan-check 'new' verdicts to
State Hub capability requests (--file-request) and surfaces open requests
with no matching capability (report gaps --check-capability-requests, opt-in
to stay offline-safe). Verified against the live local State Hub API;
status field (not catalog_entry_id presence) is the correct open/closed
signal, and the list endpoint needs a longer timeout than the health check
(~7s observed with 5 rows).

T06: docs (tools/README.md, RegistryFederation.md, SCOPE.md,
IntentScopeGapAnalysis.md priority 29) and an informational CI smoke step.

T03 (LLM rerank) not started -- llm-connect isn't running on this
workstation. T05 (ecosystem rollout) remains blocked: WP-0017 has drafted
entries for all 61 repos but they're still local-only pending its own T05
push/publish pass, so the federated index isn't yet worth rolling out
plan-check as ecosystem convention.

16 new tests, all mocked -- no network calls in the default test run.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 00:57:18 +02:00

67 lines
2.5 KiB
Python

from __future__ import annotations
import urllib.error
from reuse_surface import statehub_bridge
def test_state_hub_reachable_true(monkeypatch):
monkeypatch.setattr(statehub_bridge, "_request", lambda *a, **k: {"status": "ok"})
assert statehub_bridge.state_hub_reachable() is True
def test_state_hub_reachable_false_on_error(monkeypatch):
def raise_error(*args, **kwargs):
raise urllib.error.URLError("no route")
monkeypatch.setattr(statehub_bridge, "_request", raise_error)
assert statehub_bridge.state_hub_reachable() is False
def test_file_capability_request_skips_when_unreachable(monkeypatch):
monkeypatch.setattr(statehub_bridge, "state_hub_reachable", lambda base_url=None: False)
result = statehub_bridge.file_capability_request(
title="t", description="d", requesting_domain="infotech", requesting_agent="a"
)
assert result is None
def test_file_capability_request_posts_body(monkeypatch):
captured = {}
def fake_request(method, path, base_url, *, body=None, params=None, timeout=None):
captured["method"] = method
captured["path"] = path
captured["body"] = body
return {"id": "abc-123", **body}
monkeypatch.setattr(statehub_bridge, "state_hub_reachable", lambda base_url=None: True)
monkeypatch.setattr(statehub_bridge, "_request", fake_request)
result = statehub_bridge.file_capability_request(
title="Need X", description="desc", requesting_domain="infotech", requesting_agent="reuse-surface"
)
assert captured["method"] == "POST"
assert captured["path"] == "/capability-requests/"
assert captured["body"]["title"] == "Need X"
assert result["id"] == "abc-123"
def test_list_open_capability_requests_filters_terminal_status(monkeypatch):
monkeypatch.setattr(statehub_bridge, "state_hub_reachable", lambda base_url=None: True)
monkeypatch.setattr(
statehub_bridge,
"_request",
lambda *a, **k: [
{"id": "1", "status": "requested"},
{"id": "2", "status": "completed"},
{"id": "3", "status": "requested", "catalog_entry_id": "routed-but-open"},
],
)
result = statehub_bridge.list_open_capability_requests()
assert {r["id"] for r in result} == {"1", "3"}
def test_list_open_capability_requests_none_when_unreachable(monkeypatch):
monkeypatch.setattr(statehub_bridge, "state_hub_reachable", lambda base_url=None: False)
assert statehub_bridge.list_open_capability_requests() is None