Resto·Ka — tous les restaurants du Québec, menus complets et prix réels (famille ·Ka)
Python 69.3%
TypeScript 16.7%
CSS 7.9%
JavaScript 4.7%
HTML 1.4%
1# ==============================================================================2# Author: Simon-Pierre Boucher <contact@spboucher.ai>3# File: tests/test_permits.py4# Desc: Enrichissement RACJ (permis d'alcool) — regroupement des lignes CSV5# par établissement, croisement CONSERVATEUR avec les restaurants6# (nom+lieu, adresse+nom, jamais de fusion hasardeuse) et écriture7# de details.permis_alcool. Tout HORS LIGNE (aucun téléchargement).8# ==============================================================================9import json1011from restoka import permits12from restoka import db as rdb13from restoka.schema import Restaurant1415RECORDS = [16 { # établissement 1 : deux lignes (salle + terrasse), deux permis17 "NoEtablissement": "22723", "RaisonSociale": "Chez Mamy",18 "Titulaire": "9312-5581 Québec Inc.", "Neq": "1170486295",19 "Adresse": "1999 Rue Sainte-Famille ", "CodeVille": "94068",20 "Ville": "Saguenay", "CodePostal": "G7X4X5", "RegAdmin": "02",21 "NoPermis": "100000067-1", "Categorie": "Restaurant pour vendre",22 "TypeLocal": "Autre", "Capacite": "80",23 },24 {25 "NoEtablissement": "22723", "RaisonSociale": "Chez Mamy",26 "Titulaire": "9312-5581 Québec Inc.", "Neq": "1170486295",27 "Adresse": "1999 Rue Sainte-Famille ", "CodeVille": "94068",28 "Ville": "Saguenay", "CodePostal": "G7X4X5", "RegAdmin": "02",29 "NoPermis": "100000068-1", "Categorie": "Bar",30 "TypeLocal": "Terrasse", "Capacite": "40",31 },32 { # établissement 2 : croisement par postal + civique + nom similaire33 "NoEtablissement": "31000", "RaisonSociale": "Resto-Bar Pizza Bella",34 "Titulaire": "Gestion Pizza Bella Inc.", "Neq": "",35 "Adresse": "300 Rue Principale", "CodeVille": "23027",36 "Ville": "Québec", "CodePostal": "G1K3Y2", "RegAdmin": "03",37 "NoPermis": "200000001-1", "Categorie": "Restaurant pour servir",38 "TypeLocal": "Autre", "Capacite": "120",39 },40 { # piège : homonyme dans une AUTRE ville — ne doit RIEN croiser41 "NoEtablissement": "40000", "RaisonSociale": "Chez Mamy",42 "Titulaire": "8888-0000 Québec Inc.", "Neq": "",43 "Adresse": "714 Rang Ouest", "CodeVille": "11111",44 "Ville": "Saint-Jean-de-Dieu", "CodePostal": "G0L3M0",45 "RegAdmin": "01", "NoPermis": "300000001-1", "Categorie": "Bar",46 "TypeLocal": "Autre", "Capacite": "60",47 },48]495051def _seed(con):52 restos = [53 Restaurant(source="osm", external_id="node/1", name="Chez Mamy",54 address="1999 Rue Sainte-Famille", city="Saguenay",55 postal_code="G7X 4X5", lat=48.42, lng=-71.06),56 Restaurant(source="osm", external_id="node/2", name="Bella Pizza Resto",57 address="300 Rue Principale", city="Québec",58 postal_code="G1K 3Y2", lat=46.81, lng=-71.21),59 # piège : même nom mais autre ville (le permis 40000 ne doit pas venir ici)60 Restaurant(source="osm", external_id="node/3", name="Chez Mamy",61 address="12 Rue Untel", city="Gatineau",62 postal_code="J8X 1A1", lat=45.47, lng=-75.70),63 ]64 rdb.sync_source(con, "osm", [r.finalize() for r in restos])656667def test_group_establishments():68 ests = permits.group_establishments(RECORDS)69 assert len(ests) == 370 e = next(x for x in ests if x["no"] == "22723")71 assert e["categories"] == {"Restaurant pour vendre", "Bar"}72 assert e["capacite"] == 120 # 80 + 40 (salle + terrasse)73 assert len(e["permis"]) == 274 assert e["postal"] == "G7X4X5"757677def test_match_conservateur(con):78 _seed(con)79 stats = permits.match(con, permits.group_establishments(RECORDS))80 assert stats["matched"] == 2 and stats["with_permit"] == 28182 # nom+lieu -> le Chez Mamy de Saguenay, jamais celui de Gatineau83 d1 = json.loads(con.execute(84 "SELECT details FROM restaurants WHERE uid='osm:node/1'")85 .fetchone()["details"])86 pa = d1["permis_alcool"]87 assert pa["categories"] == ["Bar", "Restaurant pour vendre"]88 assert pa["capacite"] == 120 and pa["nb_permis"] == 289 assert pa["matched_by"] == "nom+lieu"9091 # adresse+nom (CP + civique + token « pizza/bella » partagé)92 d2 = json.loads(con.execute(93 "SELECT details FROM restaurants WHERE uid='osm:node/2'")94 .fetchone()["details"])95 assert d2["permis_alcool"]["matched_by"] == "adresse+nom"96 assert d2["permis_alcool"]["categories"] == ["Restaurant pour servir"]9798 # l'homonyme d'une autre ville n'est PAS épinglé sur le resto de Gatineau99 d3 = json.loads(con.execute(100 "SELECT details FROM restaurants WHERE uid='osm:node/3'")101 .fetchone()["details"] or "{}")102 assert "permis_alcool" not in d3103