diff --git a/tests/unit/test_pin_unification.py b/tests/unit/test_pin_unification.py new file mode 100644 index 0000000..9864445 --- /dev/null +++ b/tests/unit/test_pin_unification.py @@ -0,0 +1,45 @@ +"""End-to-end test: the CLI, FSM, and web arm flow all accept the same PIN. + +Regression guard for issue #2 — the three layers previously used three +incompatible hash schemes under two different config keys.""" + +from click.testing import CliRunner + +from vigilar.alerts.pin import hash_pin, verify_pin +from vigilar.cli.cmd_config import config_cmd +from vigilar.config import SecurityConfig, VigilarConfig +from vigilar.events.state import ArmStateFSM +from vigilar.constants import ArmState + + +def test_cli_output_is_accepted_by_fsm(test_db): + """Hash produced by `vigilar config set-pin` must verify against + ArmStateFSM.verify_pin, same config key, same format.""" + runner = CliRunner() + result = runner.invoke(config_cmd, ["set-pin"], input="9876\n9876\n") + assert result.exit_code == 0, result.output + + hash_line = next( + line for line in result.output.splitlines() + if line.strip().startswith("pin_hash") + ) + hash_value = hash_line.split('"')[1] + + cfg = VigilarConfig(security=SecurityConfig(pin_hash=hash_value)) + fsm = ArmStateFSM(test_db, cfg) + + assert fsm.verify_pin("9876") is True + assert fsm.verify_pin("0000") is False + + +def test_fsm_transitions_with_pin_from_alerts_module(test_db): + """The alerts.pin module and ArmStateFSM agree on the hash format.""" + stored = hash_pin("4242") + cfg = VigilarConfig(security=SecurityConfig(pin_hash=stored)) + fsm = ArmStateFSM(test_db, cfg) + + assert fsm.transition(ArmState.ARMED_AWAY, pin="4242", triggered_by="test") is True + assert fsm.state == ArmState.ARMED_AWAY + + # Same stored hash rejects the wrong PIN + assert verify_pin("0000", stored) is False