Files
giglez/tests/unit/test_decoded_key_identification.py
T
leetcrypt d85d22661b test: cover decoded KEY exact signature-DB matching
10 offline tests for the KEY-file identification path: a named protocol that
is in the DB resolves to the real catalog signature (category + manufacturer)
via match_method 'decoded_key_exact' with frequency-aware confidence
(0.95 consistent / 0.90 off-band); unknown names fall back to the router
('decoded_key', <0.90) yet stay identified; plus _lookup_known_protocol
case-insensitivity and None handling. Values are drawn from the DB itself so
the suite tracks catalog changes. Bare pytest, no server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-21 12:08:05 -07:00

132 lines
5.4 KiB
Python

#!/usr/bin/env python3
"""
Offline unit tests for decoded (KEY) .sub identification against the signature DB.
A Flipper KEY file carries no RAW pulses but *names* a decoded protocol (e.g.
``Protocol: Princeton``). When that name is in our signature database this is the
strongest possible identification -- the capture device already demodulated and
named the protocol and we recognise it -- so it must:
- resolve to the REAL catalog signature (true manufacturer + category), not the
category router's coarser guess (Princeton is a Garage Door Opener in the
catalog, which the router previously mislabelled "Remote Control"), and
- score with high, frequency-aware confidence (exact database match), not the
~0.45 fuzzy-guess confidence it used to get.
Unknown protocol names must still fall back to category routing so an upload is
identified by family rather than silently dropped ("accept any capture ->
identify the device").
Offline / author-time: bare ``pytest`` runs this with no docker, no server, no
network. KEY .sub content is embedded and written to ``tmp_path``.
"""
import pytest
from src.parser.sub_parser import SubFileParser
from src.matcher.engine import SignatureMatcher
from src.matcher.pattern_decoder import PatternDecoder
from src.matcher.protocol_database import get_protocol_database
def _key_sub(protocol: str, frequency: int, bit: int = 24, key: str = "00 00 00 00 00 95 D5 D4") -> str:
return "\n".join([
"Filetype: Flipper SubGhz Key File",
"Version: 1",
f"Frequency: {frequency}",
"Preset: FuriHalSubGhzPresetOok270Async",
f"Protocol: {protocol}",
f"Bit: {bit}",
f"Key: {key}",
"TE: 400",
"",
])
def _write(tmp_path, content, name="k.sub"):
p = tmp_path / name
p.write_text(content)
return str(p)
def _identify(tmp_path, content):
meta = SubFileParser().parse(_write(tmp_path, content))
return meta, SignatureMatcher().match(meta, max_results=5)
# A known catalog protocol and a known one that carries a manufacturer, both
# taken from the DB itself so the tests stay correct if the catalog changes.
_DB = get_protocol_database()
_KNOWN = next(p for p in _DB.get_all())
_KNOWN_WITH_MFR = next((p for p in _DB.get_all() if p.manufacturer), None)
_UNKNOWN_NAME = "ZZ_NOT_A_REAL_PROTOCOL_9999"
class TestKnownProtocolExactMatch:
def test_named_protocol_resolves_to_catalog_signature(self, tmp_path):
meta, matches = _identify(tmp_path, _key_sub(_KNOWN.name, _KNOWN.frequency))
assert meta.file_format == "KEY"
assert meta.is_decoded is True
assert len(matches) >= 1
top = matches[0]
assert top.device_name == _KNOWN.name
assert top.match_method == "decoded_key_exact"
# Category comes from the catalog, not the router's guess.
assert top.match_details.get("device_category") == _KNOWN.category
def test_exact_match_scores_high_when_frequency_consistent(self, tmp_path):
_, matches = _identify(tmp_path, _key_sub(_KNOWN.name, _KNOWN.frequency))
assert matches[0].confidence == pytest.approx(0.95)
assert matches[0].match_details.get("frequency_match") is True
def test_exact_match_still_high_but_lower_on_frequency_mismatch(self, tmp_path):
# Same known name, but a frequency far outside its band.
off_band = _KNOWN.frequency + 50_000_000
_, matches = _identify(tmp_path, _key_sub(_KNOWN.name, off_band))
top = matches[0]
assert top.match_method == "decoded_key_exact"
assert top.confidence == pytest.approx(0.90)
assert top.match_details.get("frequency_match") is False
@pytest.mark.skipif(_KNOWN_WITH_MFR is None, reason="no catalog protocol carries a manufacturer")
def test_real_manufacturer_is_surfaced(self, tmp_path):
_, matches = _identify(
tmp_path, _key_sub(_KNOWN_WITH_MFR.name, _KNOWN_WITH_MFR.frequency, bit=66)
)
assert matches[0].manufacturer == _KNOWN_WITH_MFR.manufacturer
class TestUnknownProtocolFallback:
def test_unknown_name_falls_back_to_router(self, tmp_path):
_, matches = _identify(tmp_path, _key_sub(_UNKNOWN_NAME, 433920000))
assert len(matches) >= 1, "unknown decoded protocol must still be identified by family"
top = matches[0]
assert top.match_method == "decoded_key"
# A routed guess must not masquerade as an exact database match.
assert top.confidence < 0.90
def test_unknown_name_still_names_the_protocol(self, tmp_path):
_, matches = _identify(tmp_path, _key_sub(_UNKNOWN_NAME, 433920000))
assert matches[0].device_name == _UNKNOWN_NAME
class TestLookupHelper:
def test_known_name_case_insensitive(self):
dec = PatternDecoder()
sig = dec._lookup_known_protocol(_KNOWN.name.upper(), _KNOWN.frequency)
assert sig is not None
assert sig.name == _KNOWN.name
def test_unknown_name_returns_none(self):
assert PatternDecoder()._lookup_known_protocol(_UNKNOWN_NAME, 433920000) is None
def test_empty_name_returns_none(self):
assert PatternDecoder()._lookup_known_protocol(None, 433920000) is None
def test_prefers_frequency_matching_candidate(self):
"""If duplicate-named entries exist, the frequency-consistent one wins."""
dec = PatternDecoder()
sig = dec._lookup_known_protocol(_KNOWN.name, _KNOWN.frequency)
assert sig is not None
assert sig.matches_frequency(_KNOWN.frequency)