# flake8: noqa # mypy: ignore-errors """Tests of killswitch behavior.""" from __future__ import annotations import copy import pytest import semantic_version import killswitch TEST_SET = killswitch.KillSwitchSet( [ killswitch.KillSwitches( version=semantic_version.SimpleSpec("1.0.0"), kills={ "no-actions": killswitch.SingleKill("no-actions", "test"), "delete-action": killswitch.SingleKill( "delete-action", "remove stuff", delete_fields=["a", "b.c"] ), "delete-action-l": killswitch.SingleKill( "delete-action-l", "remove stuff", delete_fields=["2", "0"] ), "set-action": killswitch.SingleKill( "set-action", "set stuff", set_fields={"a": False, "b.c": True} ), "redact-action": killswitch.SingleKill( "redact-action", "redact stuff", redact_fields=["a", "b.c"] ), }, ) ] ) @pytest.mark.parametrize( ("input", "kill", "should_pass", "result", "version"), [ ([], "doesnt-exist", True, None, "1.0.0"), # should fail, attempts to use 'a' to index a list (["a", "b", "c"], "delete-action", False, ["a", "b", "c"], "1.0.0"), (["a", "b", "c"], "delete-action-l", True, ["b"], "1.0.0"), ( set(), "delete-action-l", False, None, "1.0.0", ), # set should be thrown out because it cant be indext ( ["a", "b"], "delete-action-l", True, ["b"], "1.0.0", ), # has a missing value, but that's fine for delete (["a", "b"], "delete-action-l", True, ["a", "b"], "1.1.0"), # wrong version ], ) def test_killswitch( input: killswitch.UPDATABLE_DATA, kill: str, should_pass: bool, result: killswitch.UPDATABLE_DATA | None, version: str, ) -> None: """Simple killswitch tests.""" should_return, res = TEST_SET.check_killswitch(kill, input, version=version) assert ( not should_return ) == should_pass, f'expected to {"pass" if should_pass else "fail"}, but {"passed" if not should_pass else "failed"}' if result is None: return # we didn't expect any result assert res == result @pytest.mark.parametrize( ("kill_dict", "input", "result"), [ ({"set_fields": {"test": None}}, {}, {"test": None}), ({"set_fields": {"test": None}, "delete_fields": ["test"]}, {}, {}), ( {"set_fields": {"test": None}, "redact_fields": ["test"]}, {}, {"test": "REDACTED"}, ), ( { "set_fields": {"test": None}, "redact_fields": ["test"], "delete_fields": ["test"], }, {}, {}, ), ], ) def test_operator_precedence( kill_dict: killswitch.SingleKillSwitchJSON, input: killswitch.UPDATABLE_DATA, result: killswitch.UPDATABLE_DATA, ) -> None: """Ensure that operators are being applied in the correct order.""" kill = killswitch.SingleKill( "", "", kill_dict.get("redact_fields"), kill_dict.get("delete_fields"), kill_dict.get("set_fields"), ) cpy = copy.deepcopy(input) kill.apply_rules(cpy) assert cpy == result @pytest.mark.parametrize( ("names", "input", "result", "expected_return"), [ (["no-actions", "delete-action"], {"a": 1}, {"a": 1}, True), # this is true because delete-action keyerrors, thus causing failsafe (["delete-action"], {"a": 1}, {"a": 1}, True), (["delete-action"], {"a": 1, "b": {"c": 2}}, {"b": {}}, False), ], ) def test_check_multiple( names: list[str], input: killswitch.UPDATABLE_DATA, result: killswitch.UPDATABLE_DATA, expected_return: bool, ) -> None: """Check that order is correct when checking multiple killswitches.""" should_return, data = TEST_SET.check_multiple_killswitches( input, *names, version="1.0.0" ) assert should_return == expected_return assert data == result