"""Unit tests for the low-level series-ID builders in bls_client.series. These lock the exact encodings against known-good BLS series IDs. They run offline (no network) and are the regression guard for the encoding bugs that were fixed in June 2026 (JOLTS width, OES area code, ECI component/estimate, productivity sector/measure widths, QCEW form). """ import pytest from bls_client import series as S # (callable, kwargs) -> exact expected series ID. Every value here has been # confirmed to return data from the live BLS API. GOLDEN = [ # LAUS — 20 chars (S.laus_state, dict(state_fips=11, measure="rate"), "LAUST110000000000003"), (S.laus_state, dict(state_fips=11, measure="rate", seasonal=True), "LASST110000000000003"), (S.laus_county, dict(state_fips=11, county_fips=1, measure="rate"), "LAUCN110010000000003"), (S.laus_msa, dict(state_fips=11, cbsa_code=47900, measure="rate"),"LAUMT114790000000003"), # CES national / state (S.ces_national, dict(), "CES0000000001"), (S.ces_national, dict(industry="manufacturing"), "CES3000000001"), (S.ces_state, dict(state_fips=11), "SMS11000000000000001"), # CPI / PPI (S.cpi, dict(), "CUUR0000SA0"), (S.cpi, dict(item="core", seasonal=True), "CUSR0000SA0L1E"), (S.ppi_commodity,dict(), "WPU00000000"), # OES — 25 chars, national area 0000000 (was the 0000400 bug) (S.oes_national, dict(), "OEUN000000000000000000001"), (S.oes_national, dict(occupation_code="151252", data_type="annual_median"), "OEUN000000000000015125213"), # JOLTS — 21 chars / 15 zeros (was 18 chars / 12 zeros) (S.jolts, dict(), "JTS000000000000000JOL"), (S.jolts, dict(element="quits", rate_level="R"), "JTS000000000000000QUR"), (S.jolts, dict(element="hires", seasonal=False), "JTU000000000000000HIL"), # ECI — 17 chars, unadjusted, component 10/20/30, estimate A (S.eci, dict(), "CIU1010000000000A"), (S.eci, dict(component="20"), "CIU1020000000000A"), (S.eci, dict(component="30"), "CIU1030000000000A"), (S.eci, dict(owner="20"), "CIU2010000000000A"), # Productivity — 11 chars, 4-digit sector + 4-digit measure (S.productivity, dict(), "PRS85006092"), (S.productivity, dict(sector="manufacturing", measure="unit_labor_cost"), "PRS30006112"), (S.productivity, dict(sector="business"), "PRS84006092"), ] @pytest.mark.parametrize("fn,kwargs,expected", GOLDEN, ids=[f"{f.__name__}-{e}" for f, _, e in GOLDEN]) def test_builder_exact_id(fn, kwargs, expected): assert fn(**kwargs) == expected # --- Format invariants (catch width regressions even for un-goldened inputs) --- def test_jolts_is_21_chars(): for elem in ("job_openings", "hires", "quits", "layoffs", "total_separations"): sid = S.jolts(elem) assert len(sid) == 21, f"{sid} should be 21 chars" assert sid.startswith("JTS") def test_oes_is_25_chars_national(): sid = S.oes_national() assert len(sid) == 25 assert sid.startswith("OEUN0000000"), "national area code must be 0000000" def test_eci_is_17_chars_and_unadjusted_by_default(): sid = S.eci() assert len(sid) == 17 assert sid.startswith("CIU"), "12-month % change ECI is published unadjusted (CIU)" def test_productivity_is_11_chars(): sid = S.productivity() assert len(sid) == 11 assert sid.startswith("PRS") def test_laus_state_is_20_chars(): assert len(S.laus_state(48, "rate")) == 20 def test_seasonal_flag_flips_adjustment_char(): assert S.cpi(seasonal=False).startswith("CUU") assert S.cpi(seasonal=True).startswith("CUS") assert S.jolts(seasonal=False).startswith("JTU") assert S.jolts(seasonal=True).startswith("JTS")