"""Tests for the firmware pin + needs-reflash detection (no hardware).""" import asyncio from pm3py._firmware import FirmwarePin, FIRMWARE_PIN, matches from pm3py.core.client import Proxmark3 from pm3py import flash_cli def run(coro): return asyncio.get_event_loop().run_until_complete(coro) # --- matches() --- def test_matches_sha_substring(): pin = FirmwarePin(sha="303bd5873") assert matches("Iceman/main/303bd5873-dirty", pin) is True assert matches("Iceman/main/303bd58-clean", pin) is True # 7-char prefix def test_matches_rejects_other_build(): pin = FirmwarePin(sha="303bd5873") assert matches("Iceman/master/deadbeef", pin) is False def test_matches_empty_is_false(): assert matches("", FirmwarePin(sha="303bd5873")) is False def test_matches_tag(): pin = FirmwarePin(sha="303bd5873", tag="fw-v0.1.0") assert matches("pm3py fw-v0.1.0 build", pin) is True def test_default_pin_is_present(): assert FIRMWARE_PIN.sha # a pin is baked in # --- _probe_firmware wiring --- def _fake_probe(pm3, version_string): async def fake_ping(length=32): return {"success": True} async def fake_version(): return {"version_string": version_string, "chip_id": "0x1", "section_size": 0} pm3.hw.ping = fake_ping pm3.hw.version = fake_version def test_probe_sets_matches_pin_true(): pm3 = Proxmark3("/dev/ttyFAKE") _fake_probe(pm3, f"Iceman/main/{FIRMWARE_PIN.sha}-dirty") run(pm3._probe_firmware()) assert pm3.firmware.matches_pin is True assert pm3.firmware.expected_firmware == FIRMWARE_PIN.sha def test_probe_sets_matches_pin_false_for_stock(): pm3 = Proxmark3("/dev/ttyFAKE") _fake_probe(pm3, "Iceman/master/00000000") run(pm3._probe_firmware()) assert pm3.firmware.matches_pin is False # --- CLI wiring --- def test_cli_help_exits_clean(capsys): try: flash_cli.main(["--help"]) except SystemExit as e: assert e.code == 0 out = capsys.readouterr().out assert "pm3flash" in out