BuyingAgent/backend/tests/unit/test_discovery_identity.py
Lars b276758ee1
All checks were successful
Deploy Development / deploy (push) Successful in 1m19s
Test Suite / pytest-backend (push) Successful in 31s
Test Suite / smoke-dev (push) Successful in 0s
Test Suite / frontend-checks (push) Successful in 28s
Stelle den Frontend-MVP und die v0.3-API auf develop bereit, damit Dev API und PWA zusammen deployen.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 13:04:59 +02:00

84 lines
3.0 KiB
Python

from app.discovery.enums import MatchStatus
from app.discovery.identity import IdentitySignals, decide_identity, spec_fingerprint
def _sig(**overrides) -> IdentitySignals:
base = IdentitySignals(
source_external_id="gh-1",
gtin_ean="4000000000001",
manufacturer_sku="EM13-32",
source_url="https://geizhals.de/a.html",
title="Example Mobile 13",
manufacturer="Example",
model="Mobile 13",
fingerprint=spec_fingerprint({"manufacturer": "Example", "model": "Mobile 13", "ram": 32}),
)
return IdentitySignals(**{**base.__dict__, **overrides})
def test_sku_and_ean_and_url_match():
known = [("a", _sig())]
assert decide_identity(_sig(), known).reason == "source_external_id"
assert decide_identity(_sig(source_external_id="other"), known).reason == "gtin_ean"
assert decide_identity(_sig(source_external_id="other", gtin_ean="x"), known).reason == "manufacturer_sku"
assert decide_identity(
_sig(source_external_id="other", gtin_ean="x", manufacturer_sku="y"),
known,
).reason == "source_url"
def test_title_plus_fingerprint_matches_stable_specs():
known = [("a", _sig(source_external_id=None, gtin_ean=None, manufacturer_sku=None, source_url=None))]
incoming = _sig(
source_external_id=None,
gtin_ean=None,
manufacturer_sku=None,
source_url=None,
title="Example Mobile 13",
)
decision = decide_identity(incoming, known)
assert decision.match_status == MatchStatus.MATCHED
assert decision.reason == "title+fingerprint"
def test_title_only_is_uncertain_and_never_merges():
known = [("a", _sig(source_external_id=None, gtin_ean=None, manufacturer_sku=None, source_url=None))]
incoming = _sig(
source_external_id=None,
gtin_ean=None,
manufacturer_sku=None,
source_url=None,
fingerprint="different",
manufacturer="Other",
model="Other",
)
decision = decide_identity(incoming, known)
assert decision.match_status == MatchStatus.MATCH_UNCERTAIN
assert decision.existing_id is None
assert decision.reason == "title only"
def test_fingerprint_uses_observed_keys_only():
left = spec_fingerprint({"capacity_l": 2, "color": "black"})
right = spec_fingerprint({"capacity_l": 5, "color": "black"})
assert left != right
assert "capacity_l=2" in left
assert "ram_gb" not in left
assert spec_fingerprint({"title": "ignored", "html": "<b>", "noise": 1}) == "noise=1"
def test_similar_names_do_not_merge():
known = [("a", _sig(source_external_id=None, gtin_ean=None, manufacturer_sku=None, source_url=None))]
incoming = _sig(
source_external_id=None,
gtin_ean=None,
manufacturer_sku=None,
source_url=None,
title="Example Mobile 14",
fingerprint="other",
manufacturer="Example",
model="Mobile 14",
)
decision = decide_identity(incoming, known)
assert decision.match_status == MatchStatus.NEW_REFERENCE