# Trouve-KA — tests du scoring Québec # Author: Simon-Pierre Boucher # Contact: contact@spboucher.ai from trouveka.classifier import score_page from trouveka.types import ParsedPage def _page(**kwargs) -> ParsedPage: defaults = {"url": "https://example.com/page", "title": "", "body": ""} return ParsedPage(**(defaults | kwargs)) def test_quebec_business_scores_high(): page = _page( url="https://plomberiexyz.qc.ca/services", title="Plomberie XYZ — Plombier à Gatineau", description="Service de plomberie résidentielle en Outaouais", body="Plomberie XYZ dessert Gatineau et l'Outaouais. 123 rue Principale, Gatineau (Québec) J8X 3X3. " "Appelez-nous au 819-555-1234. Urgences 24h partout au Québec.", headings=["Plombier Gatineau", "Nos services"], language="fr", ) signals = score_page(page, "plomberiexyz.qc.ca") assert signals.score > 0.7 assert "gatineau" in signals.locations assert "tld_quebec" in signals.reasons assert "code_postal_qc" in signals.reasons def test_ontario_business_scores_low(): page = _page( url="https://ottawaplumbing.ca/", title="Ottawa Plumbing Services", description="Plumbing services in Ottawa, Ontario", body="We serve Ottawa, Kanata and Nepean. 456 Bank Street, Ottawa, ON K1S 3T4. Call 613-555-9999.", headings=["Plumbing Ottawa"], language="en", ) signals = score_page(page, "ottawaplumbing.ca") assert signals.score < 0.2 def test_nyt_article_about_montreal_gets_page_signal(): # Un article international SUR Montréal : le domaine n'est pas québécois, # mais la page a un signal réel (page_quebec_score > 0, sans être maximal). page = _page( url="https://www.nytimes.com/2026/01/01/travel/montreal.html", title="36 Hours in Montreal", description="What to do in Montreal, Quebec's largest city", body="Montreal is the largest city in Quebec. From the Plateau-Mont-Royal to Old Montreal, " "the city offers poutine, festivals and more. Nearby Laval and Longueuil...", headings=["36 Hours in Montreal"], language="en", ) signals = score_page(page, "nytimes.com") assert 0.2 < signals.score < 0.8 assert "montreal" in signals.locations def test_generic_english_page_scores_near_zero(): page = _page( url="https://techblog.com/post", title="Understanding Rust lifetimes", body="Rust lifetimes are a way to express the scope of references in your program. " * 20, language="en", ) signals = score_page(page, "techblog.com") assert signals.score < 0.1 def test_french_alone_is_not_proof(): # Une page française de France ne doit pas passer le seuil sur la langue seule page = _page( url="https://lemonde.fr/article", title="Actualités françaises", body="La France annonce de nouvelles mesures. Paris, Lyon et Marseille concernées. " * 10, language="fr", ) signals = score_page(page, "lemonde.fr") assert signals.score < 0.3 def test_score_saturates_below_one(): body = "Montréal Québec Gatineau Sherbrooke Laval " * 100 + " H2X 1Y6 G1R 4S9 514-555-0000 Hydro-Québec" page = _page(url="https://x.qc.ca/", title="Montréal Québec", body=body, language="fr") signals = score_page(page, "x.qc.ca") assert 0.8 < signals.score <= 1.0