SPB Git forge

spb/countryatlas

Public
20commits 1branches 0releases
268.3 MBsize
maindefault branch
12 days agolast push
TypeScript 57% Python 38.6% JavaScript 3.6% CSS 0.6%
3.6 KB · 78 lines python
Raw Blame History
1"""ILOSTAT connector — offline tests on a trimmed DF_UNE_2EAP_SEX_AGE_RT CSV (CAN, FRA, SOM, X01), plus live smoke."""2from __future__ import annotations34from datetime import date56import pytest78from countryatlas.connectors.ilo import ILOConnector9from countryatlas.models import IndicatorSourceSpec10from tests.connectors._helpers import install_fake_get, raw_from_file111213@pytest.fixture14def fake_get(monkeypatch):15    return install_fake_get(monkeypatch)161718SPEC =IndicatorSourceSpec(indicator_id="unemployment-rate", connector="ilo", dataset="DF_UNE_2EAP_SEX_AGE_RT",19                           code=".A..SEX_T.AGE_YTHADULT_YGE15", frequency="A", priority=4)202122def _raw(fixtures_dir, **meta):23    return raw_from_file("ilo", SPEC.dataset, SPEC.code, fixtures_dir / "ilo" / "DF_UNE_2EAP_SEX_AGE_RT.csv", "text/csv", **meta)242526def test_normalize_drops_aggregates_flags_projections_and_imputations(fixtures_dir):27    conn = ILOConnector()28    rows = conn.normalize(_raw(fixtures_dir, dataflow_meta={"release_year": 2025, "name": "… Nov. 2025"}), SPEC)29    assert {r.country_id for r in rows} == {"CAN", "FRA", "SOM"}  # X01 aggregate dropped30    can = {r.year: r for r in rows if r.country_id == "CAN"}31    assert can[2024].is_estimate is False and can[2024].is_forecast is False  # OBS_STATUS = R32    assert can[2025].is_estimate is True and can[2025].is_forecast is False  # nowcast (blank status), release year33    assert can[2026].is_forecast is True and can[2027].is_forecast is True34    assert can[2025].value == pytest.approx(6.907)  # = WB SL.UEM.TOTL.ZS 202535    som = {r.year: r for r in rows if r.country_id == "SOM"}36    assert som[2024].is_estimate is True and som[2024].metadata["low"] == pytest.approx(4.737)37    assert all(r.frequency == "A" and r.period == date(r.year, 1, 1) and r.unit == "% of labour force" for r in rows)38    assert conn.validate(rows).quarantine_dataset is False394041def test_release_year_fallback_is_current_year(fixtures_dir):42    from datetime import UTC, datetime4344    rows = ILOConnector().normalize(_raw(fixtures_dir), SPEC)  # no dataflow_meta → years > now.year are forecasts45    y = datetime.now(UTC).year46    assert all(r.is_forecast == (r.year > y) for r in rows)474849def test_fetch_builds_verified_url_and_parses_release_year(fixtures_dir, fake_get):50    conn = ILOConnector()51    csv_body = (fixtures_dir / "ilo" / "DF_UNE_2EAP_SEX_AGE_RT.csv").read_bytes()52    flow = (fixtures_dir / "ilo" / "dataflow.json").read_bytes()5354    def router(url, params):55        if "/dataflow/ILO/" in url:56            return flow, "application/vnd.sdmx.structure+json"57        return csv_body, "text/csv"5859    calls = fake_get(conn, router)60    p = conn.fetch(SPEC)61    assert calls[0]["url"] == "https://sdmx.ilo.org/rest/dataflow/ILO/DF_UNE_2EAP_SEX_AGE_RT"62    assert calls[1]["url"] == "https://sdmx.ilo.org/rest/data/ILO,DF_UNE_2EAP_SEX_AGE_RT/.A..SEX_T.AGE_YTHADULT_YGE15"63    assert calls[1]["params"] == {"format": "csv"}64    assert p.meta["dataflow_meta"]["release_year"] == 202565    assert "Nov. 2025" in p.meta["dataflow_meta"]["name"]66    rows = conn.normalize(p, SPEC)67    assert {r.year for r in rows if r.is_forecast} == {2026, 2027}686970@pytest.mark.live71def test_live_youth_unemployment():72    conn = ILOConnector()73    spec = SPEC.model_copy(update={"indicator_id": "youth-unemployment-rate", "code": ".A..SEX_T.AGE_YTHADULT_Y15-24",74                                   "params": {"startPeriod": "2023"}})75    rows = conn.normalize(conn.fetch(spec), spec)76    assert len({r.country_id for r in rows}) >= 150 and "CAN" in {r.country_id for r in rows}77    assert conn.validate(rows).quarantine_dataset is False78