"""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