SPB Git forge

spb/resto-ka

Public

Resto·Ka — tous les restaurants du Québec, menus complets et prix réels (famille ·Ka)

52commits 1branches 0releases
11.6 MBsize
maindefault branch
19 days agolast push
Python 69.3% TypeScript 16.7% CSS 7.9% JavaScript 4.7% HTML 1.4%
3.7 KB · 100 lines python
Raw Blame History
1# ==============================================================================2# Author: Simon-Pierre Boucher <contact@spboucher.ai>3# File:   tests/test_doordash.py4# Desc:   Connecteur DoorDash (enrichissement livraison) — parsing JSON-LD5#         (Restaurant + Menu, sections imbriquées, prix « $X.XX »), croisement6#         CONSERVATEUR verify_store (gps+nom / civique+ville+nom, jamais de7#         fusion hasardeuse), slugs candidats par préfixe.8# ==============================================================================9import json1011from restoka.connectors.doordash import (DoorDashConnector, build_menu,12                                         parse_ldjson, slugify, verify_store)1314LD_RESTO = {15    "@type": "Restaurant",16    "name": "Chez Test",17    "address": {"streetAddress": "123 Rue Principale",18                "addressLocality": "Montréal", "addressRegion": "QC"},19    "geo": {"latitude": "45.5200", "longitude": "-73.5800"},20    "servesCuisine": ["Pizza"],21    "priceRange": "$$",22    "aggregateRating": {"ratingValue": 4.6, "reviewCount": 210},23}2425LD_MENU = {26    "@type": "Menu",27    "hasMenuSection": [[{28        "name": "Pizzas",29        "hasMenuItem": [30            {"name": "Margherita", "description": "Tomate, basilic",31             "offers": {"price": "$16.50"}},32            {"name": "Sans prix", "offers": {}},33        ],34    }, {35        "name": "Pizzas",                          # doublon : ignoré36        "hasMenuItem": [{"name": "Dup", "offers": {"price": "$1.00"}}],37    }]],38}394041def _page(*blocks) -> str:42    return "".join(43        f'<script type="application/ld+json">{json.dumps(b)}</script>'44        for b in blocks)454647def test_parse_ldjson_et_build_menu():48    resto, menu = parse_ldjson(_page(LD_RESTO, LD_MENU))49    assert resto["name"] == "Chez Test"50    m = build_menu(menu, "2026-08-25T00:00:00Z")51    assert m["price_context"] == "delivery" and m["price_source"] == "doordash"52    assert len(m["sections"]) == 1                # doublon de section écarté53    items = m["sections"][0]["items"]54    assert items[0]["price"] == 16.5055    assert items[1]["price"] is None              # prix absent toléré56    assert build_menu({}, "x") is None575859def test_parse_ldjson_page_sans_blocs():60    assert parse_ldjson("<html>rien</html>") == (None, None)616263def _row(**over):64    base = {"uid": "osm:1", "name": "Chez Test",65            "address": "123 Rue Principale", "city": "Montréal",66            "postal_code": "H2X1Y4", "phone": "",67            "lat": 45.5201, "lng": -73.5801}68    base.update(over)69    return base707172def test_verify_store_gps_nom():73    assert verify_store(_row(), LD_RESTO) == "gps+nom"747576def test_verify_store_civique_ville_nom():77    # GPS absent côté base : retombe sur civique + ville + nom78    assert verify_store(_row(lat=None, lng=None), LD_RESTO) \79        == "civique+ville+nom"808182def test_verify_store_rejets():83    # autre resto au même endroit : nom différent -> rejet84    autre = dict(LD_RESTO, name="Pizzeria Autre Chose Complètement")85    assert verify_store(_row(), autre) == ""86    # même nom mais loin (>120 m) et civique différent -> rejet87    loin = dict(LD_RESTO, geo={"latitude": "45.60", "longitude": "-73.70"},88                address={"streetAddress": "999 Autre Rue",89                         "addressLocality": "Laval"})90    assert verify_store(_row(), loin) == ""919293def test_slugify_et_candidats():94    assert slugify("Café L'Époque & Fils") == "cafe-lepoque-fils"95    slugs = sorted(["chez-test-montreal-123", "chez-test-laval-456",96                    "chez-testeur-999", "autre-resto-1"])97    cand = DoorDashConnector.candidates_for("Chez Test", slugs)98    assert set(cand) == {"chez-test-montreal-123", "chez-test-laval-456"}99    assert DoorDashConnector.candidates_for("Ab", slugs) == []   # trop court100