Toutes les sorties et tous les événements du Québec, un seul endroit — 7 connecteurs, fiches SSR, design Groupe KA.
1# ==============================================================================2# Author: Simon-Pierre Boucher <contact@spboucher.ai>3# File: tests/test_normalize.py4# Desc: Tests de la couche de normalisation (dates, prix, catégories, régions)5# ==============================================================================6from __future__ import annotations78from sortika.normalize import (clean_city, clean_text, map_categories,9 parse_date_iso, parse_latlng, parse_price)10from sortika.regions import region_from_city, region_from_tourist11from sortika.schema import Event121314def test_parse_date_iso():15 assert parse_date_iso("2026-09-11T00:00:00") == "2026-09-11"16 assert parse_date_iso("2026-09-11") == "2026-09-11"17 assert parse_date_iso("") is None18 assert parse_date_iso("demain") is None19 assert parse_date_iso("0001-99-99") is None202122def test_parse_price():23 assert parse_price("Gratuit") == (True, None, "Gratuit")24 assert parse_price("Entrée libre") == (True, None, "Entrée libre")25 free, amt, _ = parse_price("Adulte 25 $, enfant 12,50 $")26 assert free is False and amt == 12.5027 assert parse_price("Payant")[0] is False28 assert parse_price("")[0] is None293031def test_map_categories():32 assert map_categories(["Festival"]) == ["festival"]33 assert map_categories(["Manifestation sportive"]) == ["sport"]34 assert map_categories(["Chanson", "Sports et plein air"]) == ["musique", "sport"]35 assert map_categories(["Conseil et comité"]) == ["communautaire"]36 assert map_categories(["Zzz-inconnu"]) == ["autre"]37 assert map_categories([]) == ["autre"]383940def test_regions():41 assert region_from_tourist("Cantons-de-l'Est") == "Estrie"42 assert region_from_tourist("Charlevoix") == "Capitale-Nationale"43 assert region_from_tourist("Québec") == "Capitale-Nationale"44 assert region_from_city("Lévis") == "Chaudière-Appalaches"45 assert region_from_city("Gatineau") == "Outaouais"46 assert region_from_city("Ville-Inconnue") == ""474849def test_clean():50 assert clean_city("Montréal (Québec)") == "Montréal"51 assert clean_text("a <b>b</b> c") == "a b c"525354def test_parse_latlng():55 assert parse_latlng("45.5", "-73.5") == (45.5, -73.5)56 assert parse_latlng("0", "0") == (None, None)57 assert parse_latlng(None, None) == (None, None)585960def test_event_finalize_and_dedup():61 a = Event(source="sitq", external_id="X1", url="https://a",62 title=" Festival d'été ", city="Québec (Québec)",63 tourist_region="Québec", raw_categories=["Festival"],64 start_date="2026-07-01T00:00:00", price_label="Gratuit").finalize()65 b = Event(source="montreal", external_id="Y2", url="https://b",66 title="Festival d'été", city="Québec",67 start_date="2026-07-01").finalize()68 assert a.title == "Festival d'été"69 assert a.region == "Capitale-Nationale"70 assert a.categories == ["festival"]71 assert a.is_free is True72 assert a.end_date == "2026-07-01"73 assert a.dedup_key() == b.dedup_key()74