From bbb7dd425eec0cae22cd65d2537094d831545478 Mon Sep 17 00:00:00 2001 From: luisllaver <94252605+luisllaver@users.noreply.github.com> Date: Wed, 20 May 2026 13:40:24 -0300 Subject: [PATCH] Add opt-in AURA trust-check adapter (integrations/aura) --- integrations/aura/tests/test_adapter.py | 120 ++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 integrations/aura/tests/test_adapter.py diff --git a/integrations/aura/tests/test_adapter.py b/integrations/aura/tests/test_adapter.py new file mode 100644 index 00000000..92a41c08 --- /dev/null +++ b/integrations/aura/tests/test_adapter.py @@ -0,0 +1,120 @@ +""" +Offline tests for the AURA trust-check adapter. + +Runs with plain `pytest` (or `python -m pytest`). No network: every call +replays a recorded /check body via the `_fetch` injection seam. + +Coverage: + - one assertion per verdict class (trusted / caution / high_risk / new / unknown) + - the before_settle gate: allow-list pass/reject, custom allow, fail_open + - the network-failure path (fail-closed by default, pass with fail_open) + - input validation +""" + +from __future__ import annotations + +import urllib.error + +import pytest + +from aura.adapter import AuraUntrusted, aura_verdict, before_settle +from aura.tests.fixtures import make_fetch, raising_fetch + +FETCH = make_fetch() + + +# ── verdict classes ───────────────────────────────────────────────────────── + +@pytest.mark.parametrize( + "did,expected,ok", + [ + ("did:aura:trusted-bot", "trusted", True), + ("did:aura:caution-bot", "caution", True), + ("did:aura:risky-bot", "high_risk", False), + ("did:aura:fresh-bot", "new", False), + ("did:aura:ghost-bot", "unknown", False), + ], +) +def test_verdict_classes(did, expected, ok): + v = aura_verdict(did, _fetch=FETCH) + assert v.verdict == expected + assert v.ok is ok + assert v.did == did + assert isinstance(v.reason, str) and v.reason + + +def test_minimal_dict_contract(): + v = aura_verdict("did:aura:trusted-bot", _fetch=FETCH) + d = v.as_dict() + assert set(d) >= {"verdict", "reason", "score"} + assert d["verdict"] == "trusted" + assert d["score"] == 0.86 + + +def test_dimensions_exposed_for_history(): + v = aura_verdict("did:aura:risky-bot", _fetch=FETCH) + assert v.has_history is True + assert v.dimensions["financial_integrity"] == 0.12 + + +def test_new_agent_has_no_score(): + v = aura_verdict("did:aura:fresh-bot", _fetch=FETCH) + assert v.score is None + assert v.has_history is False + + +# ── the before_settle gate ─────────────────────────────────────────────────── + +def test_gate_allows_trusted(): + v = before_settle("did:aura:trusted-bot", _fetch=FETCH) + assert v.verdict == "trusted" + + +def test_gate_allows_caution_and_new_by_default(): + assert before_settle("did:aura:caution-bot", _fetch=FETCH).verdict == "caution" + assert before_settle("did:aura:fresh-bot", _fetch=FETCH).verdict == "new" + + +def test_gate_rejects_high_risk(): + with pytest.raises(AuraUntrusted) as ei: + before_settle("did:aura:risky-bot", _fetch=FETCH) + assert ei.value.verdict.verdict == "high_risk" + + +def test_gate_rejects_unknown_by_default(): + with pytest.raises(AuraUntrusted): + before_settle("did:aura:ghost-bot", _fetch=FETCH) + + +def test_strict_allow_rejects_new(): + with pytest.raises(AuraUntrusted): + before_settle("did:aura:fresh-bot", allow=("trusted", "caution"), _fetch=FETCH) + + +# ── network-failure path ────────────────────────────────────────────────────── + +def test_unreachable_returns_unknown_not_raise(): + fetch = raising_fetch(urllib.error.URLError("connection refused")) + v = aura_verdict("did:aura:trusted-bot", _fetch=fetch) + assert v.verdict == "unknown" + assert "unreachable" in v.reason.lower() + + +def test_gate_fail_closed_on_unreachable(): + fetch = raising_fetch(urllib.error.URLError("connection refused")) + with pytest.raises(AuraUntrusted): + before_settle("did:aura:trusted-bot", _fetch=fetch) + + +def test_gate_fail_open_passes_on_unreachable(): + fetch = raising_fetch(urllib.error.URLError("connection refused")) + v = before_settle("did:aura:trusted-bot", fail_open=True, _fetch=fetch) + assert v.verdict == "unknown" + + +# ── input validation ────────────────────────────────────────────────────────── + +@pytest.mark.parametrize("bad", ["", "not-a-did", "z6Mk-no-prefix", None]) +def test_rejects_bad_did(bad): + with pytest.raises(ValueError): + aura_verdict(bad, _fetch=FETCH)