BuyingAgent/backend/tests/unit/test_geizhals_taxonomy_parser.py
Lars 46857715df
Some checks failed
Deploy Development / deploy (push) Successful in 1m49s
Test Suite / pytest-backend (push) Failing after 32s
Test Suite / smoke-dev (push) Successful in 0s
Test Suite / frontend-checks (push) Successful in 30s
Lerne Taxonomie und Trefferliste live von Geizhals, damit Wizard und Kandidaten echte Quelldaten nutzen.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 14:53:08 +02:00

77 lines
3.0 KiB
Python

from pathlib import Path
from app.discovery.urlgen import generate_search_url
from app.sources.geizhals.taxonomy_parser import parse_taxonomy_html
HTML = (Path(__file__).resolve().parents[2] / "fixtures" / "geizhals" / "nb-category.html").read_text(
encoding="utf-8"
)
def test_parser_reads_href_filters_and_price_inputs() -> None:
payload = parse_taxonomy_html(
HTML,
category_ref="nb",
source_url="https://geizhals.de/?cat=nb",
)
keys = {item["external_filter_key"] for item in payload["filters"]}
assert {"12", "17023", "price", "12128", "7436", "82", "asuch"} <= keys
assert len(payload["filters"]) >= 12
live_ram = next(item for item in payload["filters"] if item["external_filter_key"] == "17023")
assert live_ram["label"] == "RAM"
ram = next(item for item in payload["filters"] if item["external_filter_key"] == "12")
assert ram["label"] == "RAM ab"
assert ram["filter_type"] == "NUMERIC_THRESHOLD"
assert any(option["source_value"] == "ab 16GB" for option in ram["options"])
assert ram["encoding"]["options"]["ab 16GB"] == "16384"
price = next(item for item in payload["filters"] if item["external_filter_key"] == "price")
assert price["filter_type"] == "NUMERIC_RANGE"
assert price["encoding"]["min_parameter"] == "bpmin"
assert price["encoding"]["max_parameter"] == "bpmax"
def test_learned_ram_and_price_encode_observed_geizhals_query() -> None:
payload = parse_taxonomy_html(
HTML,
category_ref="nb",
source_url="https://geizhals.de/?cat=nb",
)
ram = next(item for item in payload["filters"] if item["external_filter_key"] == "12")
price = next(item for item in payload["filters"] if item["external_filter_key"] == "price")
url, internal = generate_search_url(
category_url="https://geizhals.de/?cat=nb",
criteria_items=[
{"criterion": "geizhals:nb:12", "operator": ">=", "value": 16},
{"criterion": "geizhals:nb:price", "operator": "<=", "value": 1700},
],
mappings=[
{
"criterion_key": "geizhals:nb:12",
"external_filter_key": "12",
"source_value": "16384",
"encoding": ram["encoding"],
"status": "VERIFIED",
},
{
"criterion_key": "geizhals:nb:price",
"external_filter_key": "price",
"source_value": None,
"encoding": price["encoding"],
"status": "VERIFIED",
},
],
)
assert internal == []
assert "xf=12_16384" in url
assert "bpmax=1700" in url
def test_challenge_html_is_not_treated_as_taxonomy() -> None:
payload = parse_taxonomy_html(
"<html><body>Enable JavaScript and cookies to continue</body></html>",
category_ref="nb",
source_url="https://geizhals.de/?cat=nb",
)
assert payload["blocked"] is True
assert payload["filters"] == []