import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) import products # noqa: E402 def test_table_is_complete(): """Acht Geraete mal zwei Varianten, minus das EVK, das keine eigene Dev-ID hat.""" assert len(products.PRODUCTS) == 15 targets = {p.target for p in products.PRODUCTS.values()} assert targets == {"evk", "e27_rgb", "e14_rgb", "gu10_rgb", "e27_cw", "e14_cw", "gu10_cw", "g95_cw"} def test_production_id_maps_to_prod_variant(): p = products.PRODUCTS["-klyqa.lighting.rgb-cw-ww.gu10"] assert (p.target, p.variant) == ("gu10_rgb", "prod") assert p.name == "Klyqa GU10 RGB CW/WW" def test_dev_suffix_selects_dev_variant(): p = products.PRODUCTS["-klyqa.lighting.cw-ww.g95-dev"] assert (p.target, p.variant) == ("g95_cw", "dev") def test_parses_real_request_from_g95(): """Am 2026-09-13 an einer echten G95 protokolliert.""" r = products.parse_request( "/qcx_firmware_-klyqa.lighting.cw-ww.g95-dev_V1.1.1.1800-dev_ota_light.img") assert r is not None assert r.product_id == "-klyqa.lighting.cw-ww.g95-dev" assert r.lamp_version == "V1.1.1.1800-dev" assert r.product.target == "g95_cw" assert r.product.variant == "dev" def test_parses_real_request_from_gu10(): r = products.parse_request( "/qcx_firmware_-klyqa.lighting.rgb-cw-ww.gu10_V1.1.0.1138_ota_light.img") assert r.product.target == "gu10_rgb" assert r.product.variant == "prod" assert r.lamp_version == "V1.1.0.1138" def test_unknown_product_id_parses_but_has_no_product(): r = products.parse_request( "/qcx_firmware_-acme.lightbulb.xxl_V9.9_ota_light.img") assert r is not None assert r.product is None assert r.product_id == "-acme.lightbulb.xxl" def test_non_matching_paths(): for p in ("/", "/ninlight_evk_ota.img", "/qcx_firmware_.img", "/qcx_firmware_-klyqa.lighting.cw-ww.g95_ota_light.img", "/x/qcx_firmware_-klyqa.lighting.cw-ww.g95_V1_ota_light.img"): assert products.parse_request(p) is None, p def test_path_traversal_is_not_parseable(): assert products.parse_request( "/qcx_firmware_../../etc/passwd_V1_ota_light.img") is None def test_websafe_transform(): assert products.websafe("@klyqa.lighting.cw-ww.g95") == "-klyqa.lighting.cw-ww.g95" assert products.websafe("a b/c") == "a-b-c" assert products.websafe("keep+all-_.09Az") == "keep+all-_.09Az"