# ----------------------------------------------------------------------------- # Rent-Ka — relevance-gate tests (quality.relevance_reason) # Un stationnement/garage/local commercial à louer ne doit jamais être publié ; # un logement qui INCLUT un stationnement doit rester publié. # ----------------------------------------------------------------------------- from rentka.quality import evaluate, relevance_reason def _reason(**kw): d = {"title": "", "description": "", "price": None, "unit_type": None, "bedrooms": None} d.update(kw) return relevance_reason(d) # ---- hors sujet : doivent être mis en quarantaine --------------------------- def test_parking_titre(): assert _reason(title="Parking à louer", price=200.0) assert _reason(title="Stationnement extérieur privé à louer – près du métro", price=100.0) assert _reason(title="Espace d'entreposage chauffé et éclairé", price=150.0) def test_garage_description_titre_trompeur(): # logisquebec : « Appartement Garage à Louer » à 195 $ = un garage assert _reason( title="Costebelle-Banville Appartement Garage à Louer Duberger", description="Grand garage/entrepôt de 8 pieds par 20 pieds, situé au " "cœur d'un quartier tranquille.", price=195.0, unit_type="3½") def test_stationnement_titre_adresse(): # titre-adresse, la description révèle la case de stationnement assert _reason(title="P158 1400 Boul Rene Levesque O", description="1 Stationnement intérieur #158 à vendre.", price=250.0) def test_local_commercial(): assert _reason(title="LOCAL COMMERCIAL À LOUER – CLÉ EN MAIN", price=3650.0) assert _reason(title="302 600 Rue Sherbrooke E", description="Espace de bureau lumineux et fonctionnel de " "290 pi², au centre-ville.", price=800.0) def test_prix_de_case_sans_signal_logement(): assert _reason(title="1288 Rue St-Antoine O. app. P3-151", description="Un dépot de $100 pour le ouvre garage.", price=280.0, unit_type="Condo") def test_location_a_la_nuit(): assert _reason(title="44, Perron O, Ste-Anne-Des-Monts à louer", description="Location court terme seulement. Tarif par nuit " "et non par mois.", price=210.0, unit_type="Maison") # ---- logements légitimes : doivent rester publiés --------------------------- def test_logement_avec_stationnement_inclus(): assert _reason(title="4½ NDG Stationnement + rangement inclus", price=1150.0, unit_type="4½") is None assert _reason(title="Grand 2 1/2 avec électros/internet/stationnement", price=995.0, unit_type="Studio") is None def test_logement_titre_garage_prix_plausible(): # vrai 4½ dont le titre vante le garage assert _reason(title="Garage Intérieur Chauffé", description="Magnifique logement 4 1/2, lumineux, doté d'un " "balcon, d'un ascenseur.", price=2250.0, unit_type="4½") is None def test_immeuble_mixte_residentiel(): assert _reason(title="4 Boulevard Cartier O., app. 717", description="Des résidences exquises et des espaces " "commerciaux au rez-de-chaussée.", price=2150.0, unit_type="4½") is None def test_nom_de_rue_bureau(): assert _reason(title="3220 Av Jacques Bureau", description="Magnifique logement de 2 chambres.", price=1200.0) is None def test_chambre_pas_chere_reste_publiee(): assert _reason(title="Grande Chambre ($600/mois), tout inclus + parking", price=600.0, unit_type="Room") is None def test_evaluate_integre_la_pertinence(): score, ok, reasons = evaluate({ "title": "Parking à louer", "price": 200.0, "address": "123 rue X", "city": "Toronto", "province": "ON", "description": "Belle place de stationnement " * 10, "images": ["a.jpg"], "url": "https://x"}) assert not ok assert any("off-topic" in r for r in reasons) # ---- English vocabulary + territorial scope (Rent-Ka) ------------------------ def test_parking_title_english(): assert _reason(title="Parking spot for rent downtown", price=150.0) assert _reason(title="Storage locker available", price=90.0) assert _reason(title="Office space for lease", price=900.0) def test_english_listing_stays_published(): assert _reason(title="Bright 2 bedroom apartment with parking included", price=1850.0, unit_type="2 bedrooms") is None assert _reason(title="Room in shared house near campus", price=650.0, unit_type="Room") is None def test_quebec_rows_are_quarantined(): score, ok, reasons = evaluate({ "title": "Grand 4½ lumineux", "price": 1200.0, "address": "555 rue Exemple", "city": "Montréal", "province": "QC", "description": "Superbe logement rénové avec balcon. " * 5, "images": ["a.jpg"], "url": "https://x"}) assert not ok assert "outside-scope-quebec" in reasons def test_ontario_rows_publish(): score, ok, reasons = evaluate({ "title": "2 bedroom apartment", "price": 1900.0, "address": "200 Bay St", "city": "Toronto", "province": "ON", "description": "Bright two bedroom apartment with balcony. " * 5, "images": ["a.jpg", "b.jpg"], "url": "https://x", "unit_type": "2 bedrooms"}) assert ok, reasons