42 lines
1.7 KiB
Python
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
|