# ----------------------------------------------------------------------------- # Lou-Ka — Agrégateur de logements à louer (province de Québec) # Auteur : Simon-Pierre Boucher — contact@spboucher.ai # test_search.py : /api/search — la recherche unifiée liste + carte. # Règle d'or : total == len(points), quelles que soient les contraintes. # ----------------------------------------------------------------------------- import pytest from fastapi.testclient import TestClient @pytest.fixture(scope="module") def client(): from louka import web return TestClient(web.app) def _get(client, **params): r = client.get("/api/search", params=params) assert r.status_code == 200, r.text return r.json() def test_regle_dor_total_egale_points(client): d = _get(client, page_size=5) assert d["total"] == len(d["points"]) assert len(d["listings"]) <= 5 # points triés comme la liste : le 1er point est la 1re annonce if d["listings"]: assert d["points"][0][0] == d["listings"][0]["uid"] def test_bbox_restreint_et_conserve_egalite(client): tout = _get(client, page_size=1) zone = _get(client, bbox="-71.45,46.70,-71.10,46.92", page_size=1) assert zone["total"] <= tout["total"] assert zone["total"] == len(zone["points"]) for _uid, lng, lat, _p, _v in zone["points"]: assert -71.45 <= lng <= -71.10 and 46.70 <= lat <= 46.92 def test_polygone_sous_ensemble_de_son_emprise(client): poly = "-71.24,46.80;-71.20,46.82;-71.24,46.83" dedans = _get(client, poly=poly, page_size=1) emprise = _get(client, bbox="-71.24,46.80,-71.20,46.83", page_size=1) assert dedans["total"] == len(dedans["points"]) assert dedans["total"] <= emprise["total"] def test_polygone_invalide(client): r = client.get("/api/search", params={"poly": "abc"}) assert r.status_code == 400 r = client.get("/api/search", params={"poly": "-71,46;-71.2,46.2"}) assert r.status_code == 400 # 2 sommets def test_tris(client): asc = _get(client, sort="prix", page_size=10, bbox="-71.45,46.70,-71.10,46.92") prix = [p[3] for p in asc["points"] if p[3] is not None] assert prix == sorted(prix) desc = _get(client, sort="prix_desc", page_size=10, bbox="-71.45,46.70,-71.10,46.92") prix_d = [p[3] for p in desc["points"] if p[3] is not None] assert prix_d == sorted(prix_d, reverse=True) def test_tri_inconnu(client): r = client.get("/api/search", params={"sort": "alea"}) assert r.status_code == 400 def test_page_ramenee_dans_les_bornes(client): d = _get(client, page=99999, page_size=50, bbox="-71.45,46.70,-71.10,46.92") assert d["page"] == max(1, -(-d["total"] // 50)) def test_include_liste_sans_points(client): d = _get(client, include="liste", page_size=5) assert d["points"] is None assert d["total"] > 0 or d["listings"] == [] def test_filtre_deal_et_verdicts(client): d = _get(client, deal="sous", page_size=5) assert d["total"] == len(d["points"]) assert all(p[4] == "s" for p in d["points"])