"""`talk.decide`, the one function behind every talk rule, as a table. Pure -- plain values in, a verdict out -- so every combination is asserted here with no database, and the admin matrix, which calls the same function, cannot disagree with what is enforced. """ from __future__ import annotations import pytest from lembas.services import talk from lembas.services.talk import Rule, decide, match ALLOW = Rule("main", "target", "allow") DENY = Rule("main", "target", "deny") def _v(**kwargs): kwargs.setdefault("instance_mode", talk.MODE_OPEN) kwargs.setdefault("instance_rule", None) return decide(**kwargs) # --- The instance's layer ------------------------------------------------------------ @pytest.mark.parametrize( ("mode", "rule", "offered"), [ (talk.MODE_OPEN, None, True), (talk.MODE_OPEN, DENY, False), (talk.MODE_OPEN, ALLOW, True), (talk.MODE_CLOSED, None, False), (talk.MODE_CLOSED, ALLOW, True), (talk.MODE_CLOSED, DENY, False), ], ) def test_the_instance_mode_and_its_rules(mode, rule, offered): verdict = _v(instance_mode=mode, instance_rule=rule) assert verdict.offered is offered assert verdict.addable is offered def test_another_data_group_is_a_deny_only_an_explicit_allow_opens(): assert _v(same_group=False).offered is False assert _v(same_group=False).why == talk.WHY_GROUP assert _v(same_group=False, instance_rule=ALLOW).offered is True # An open mode is not an explicit allow. assert _v(same_group=False, instance_mode=talk.MODE_OPEN).offered is False # --- A person without the override can only narrow --------------------------------- def test_a_persons_own_deny_takes_it_off_what_is_offered_but_not_off_what_is_addable(): verdict = _v(user_rule=DENY) assert verdict.offered is False assert verdict.addable is True assert verdict.why == talk.WHY_YOUR_RULE def test_a_persons_closed_mode_narrows_too(): verdict = _v(user_mode=talk.MODE_CLOSED) assert (verdict.offered, verdict.addable, verdict.why) == (False, True, talk.WHY_YOUR_CLOSED) def test_without_the_override_a_persons_allow_cannot_widen(): verdict = _v(instance_rule=DENY, user_rule=ALLOW) assert (verdict.offered, verdict.addable) == (False, False) assert verdict.why == talk.WHY_INSTANCE_RULE def test_without_the_override_open_mode_cannot_widen_a_closed_instance(): verdict = _v(instance_mode=talk.MODE_CLOSED, user_mode=talk.MODE_OPEN) assert (verdict.offered, verdict.addable) == (False, False) # --- With the override, the person's layer wins --------------------------------------- def test_with_the_override_a_persons_allow_beats_the_instances_deny(): verdict = _v(instance_rule=DENY, user_rule=ALLOW, override=True) assert (verdict.offered, verdict.addable) == (True, True) def test_with_the_override_a_persons_rule_opens_another_group(): assert _v(same_group=False, user_rule=ALLOW, override=True).offered is True def test_with_the_override_open_mode_widens_a_closed_instance_but_not_across_groups(): assert _v(instance_mode=talk.MODE_CLOSED, user_mode=talk.MODE_OPEN, override=True).offered across = _v(same_group=False, user_mode=talk.MODE_OPEN, override=True) assert across.offered is False and across.why == talk.WHY_GROUP # ...unless some rule explicitly allows it. assert _v( same_group=False, user_mode=talk.MODE_OPEN, override=True, instance_rule=ALLOW ).offered def test_with_the_override_and_no_layer_of_their_own_the_instance_decides(): assert _v(instance_rule=DENY, override=True).offered is False def test_with_the_override_anything_may_be_added_by_hand(): assert _v(instance_rule=DENY, override=True).addable is True assert _v(same_group=False, override=True).addable is True # --- Specificity ------------------------------------------------------------------------- def test_the_most_specific_rule_wins(): rules = [ Rule("*", "*", "deny"), Rule("*", "b", "allow"), Rule("a", "*", "deny"), Rule("a", "b", "allow"), ] assert match(rules, "a", "b").effect == "allow" assert match(rules, "a", "c") == Rule("a", "*", "deny") assert match(rules, "x", "b") == Rule("*", "b", "allow") assert match(rules, "x", "y") == Rule("*", "*", "deny") assert match([], "a", "b") is None def test_a_verdict_says_why_in_english_for_a_model(): assert "forbids" in _v(instance_rule=DENY).reason assert _v().reason == ""