emergent-security/tests/test_decisions.py

42 lines
1.7 KiB
Python

"""Decision function (canon A3) against the fixture cases."""
from __future__ import annotations
import pytest
from fixture_loading import decision_cases
from emergent_security.decide import decide
from emergent_security.delegation import Delegation
from emergent_security.memory import MemoryEntry
from emergent_security.model import Request
def run(request_dict, context, default_envelope, scales, tenant_context_from):
return decide(
Request.from_dict(request_dict),
envelope=default_envelope,
scales=scales,
registry=[Delegation.from_dict(d) for d in context.get("registry", [])],
tenant=tenant_context_from(context),
memory=[MemoryEntry.from_dict(m) for m in context.get("memory", [])],
)
@pytest.mark.parametrize(("request_dict", "context", "expect"), decision_cases())
def test_decision(request_dict, context, expect, default_envelope, scales, tenant_context_from):
decision = run(request_dict, context, default_envelope, scales, tenant_context_from).to_dict()
actual = {key: decision[key] for key in expect}
assert actual == expect
@pytest.mark.parametrize(("request_dict", "context", "expect"), decision_cases())
def test_every_decision_is_explained(request_dict, context, expect, default_envelope, scales, tenant_context_from):
"""A DENY names a rule; an ESCALATE names its blocking condition and a recipient (A3, A7)."""
decision = run(request_dict, context, default_envelope, scales, tenant_context_from)
if decision.outcome.value == "DENY":
assert decision.rules
if decision.effect == "escalate":
assert decision.route_to
if decision.outcome.value == "ESCALATE":
assert decision.blocking_condition