SPB Git

spb/lou-ka Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

HTML 99.7%
2.2 KB · 61 lines python
Raw Blame History
1# -----------------------------------------------------------------------------2# Lou-Ka — tests de régression des connecteurs (rejeu des fixtures hors-ligne)3#   Ré-enregistrer une fixture après un changement de site :4#   .venv/bin/python run.py record <source>5# -----------------------------------------------------------------------------6import json7import re89import pytest1011from louka.fixtures import FIXTURES_DIR, recorded_sources, replay_connector, snapshot1213SOURCES = recorded_sources()1415pytestmark = pytest.mark.skipif(16    not SOURCES, reason="aucune fixture enregistrée (run.py record <source>)")171819@pytest.fixture(scope="module")20def parsed():21    """Rejoue chaque connecteur une seule fois par session de test."""22    cache = {}2324    def _get(source_id):25        if source_id not in cache:26            cache[source_id] = replay_connector(source_id).fetch()27        return cache[source_id]2829    return _get303132@pytest.mark.parametrize("source_id", SOURCES)33def test_parsing_matches_snapshot(source_id, parsed):34    """Le parsing des fixtures reproduit exactement l'instantané enregistré."""35    expected = json.loads(36        (FIXTURES_DIR / source_id / "expected.json").read_text(encoding="utf-8"))37    actual = snapshot(parsed(source_id))38    assert actual["count"] == expected["count"]39    assert actual["listings"] == expected["listings"]404142@pytest.mark.parametrize("source_id", SOURCES)43def test_listings_are_valid(source_id, parsed):44    """Contraintes de schéma : uid uniques, URLs absolues, prix plausibles."""45    listings = parsed(source_id)46    assert listings, "le connecteur ne retourne aucune annonce depuis la fixture"4748    uids = [l.uid for l in listings]49    assert len(uids) == len(set(uids)), "external_id en double"5051    for l in listings:52        assert l.source == source_id53        assert l.external_id54        assert re.match(r"^https?://", l.url), f"URL non absolue : {l.url!r}"55        assert l.price is None or 100 <= l.price <= 2000056        assert l.area_sqft is None or 80 <= l.area_sqft <= 2000057        for img in l.images:58            assert re.match(r"^https?://", img), f"image non absolue : {img!r}"59        # jamais de valeur inventée : chaîne vide ou None, pas de « N/A »60        assert (l.unit_type or "") not in ("N/A", "n/a", "?")61