feat(destinations): a tap that preserves the suppression sentinel

EES writes 'c' where a figure is withheld and the categories sum to the
cohort, so counts and percentages are emitted as text with the sentinel
intact. safe_numeric must never be pointed at them.

School rows and the England reference need different establishment pins:
at national level selective schools, studios and UTCs are separate
populations rather than labels, so leaving establishment open multiplies
30 rows into 190. Two queries per period, each keeping its own level.

Verified against the live API for 2022/23: 135,240 school records over
4,508 schools, exactly 30 each, no duplicate keys, 31,382 sentinels kept.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvdDKvFFSZuMVDH5fEyTob
This commit is contained in:
TudorandClaude Opus 5 committed 2026-08-28 16:06:37 +01:00
1 parent 7ae9ecdc36
commit 9188626051
13 files changed
+1467 -1

No files matched your search

@@ -0,0 +1,134 @@
"""The tap's one testable job without a network: mapping an API row to a Singer
record without destroying the suppression sentinel."""
from tap_uk_ees_destinations.tap import (
row_to_record,
KS4_DESTINATION_SLUGS,
KS4_PUPIL_GROUP_SLUGS,
)
def test_published_row_keeps_its_numbers_as_text():
row = {
"timePeriod": {"period": "2022/2023"},
"geographicLevel": "SCH",
"locations": {"LA": "u9Oo4", "NAT": "dP0Zw", "SCH": "IXn5B"},
"filters": {"wYXbx": "DCz1Q", "9ss4v": "p9WRS"},
"values": {"Poghe": "264", "1roqi": "182", "dPjk0": "68.9"},
}
rec = row_to_record(row, urn_by_location={"IXn5B": "137083"})
assert rec["urn"] == "137083"
assert rec["time_period"] == "202223"
assert rec["destination_measure"] == "school_sixth_form"
assert rec["pupil_group"] == "all"
assert rec["cohort_pupils"] == "264"
assert rec["pupils_raw"] == "182"
assert rec["percentage_raw"] == "68.9"
def test_suppressed_row_preserves_the_c_sentinel():
row = {
"timePeriod": {"period": "2022/2023"},
"geographicLevel": "SCH",
"locations": {"SCH": "IXn5B"},
"filters": {"wYXbx": "eLsdu", "9ss4v": "OvPnC"},
"values": {"Poghe": "41", "1roqi": "c", "dPjk0": "c"},
}
rec = row_to_record(row, urn_by_location={"IXn5B": "137083"})
assert rec["pupils_raw"] == "c", "the sentinel must survive extraction"
assert rec["percentage_raw"] == "c"
assert rec["pupil_group"] == "disadvantaged"
def test_national_rows_are_kept_with_a_null_urn():
"""The England reference travels in the same response. It is kept, with a
null urn, so fact_destination_national has something to read."""
row = {
"timePeriod": {"period": "2022/2023"},
"geographicLevel": "NAT",
"locations": {"NAT": "dP0Zw"},
"filters": {"wYXbx": "DCz1Q", "9ss4v": "p9WRS"},
"values": {"Poghe": "500000", "1roqi": "190000", "dPjk0": "38.0"},
}
rec = row_to_record(row, urn_by_location={})
assert rec is not None
assert rec["urn"] is None
assert rec["percentage_raw"] == "38.0"
def test_other_geographic_levels_are_dropped():
"""A school row also carries NAT, LA and REG entries for its parents, so
the level has to be read from geographicLevel rather than inferred from
which location keys are present."""
row = {
"timePeriod": {"period": "2022/2023"},
"geographicLevel": "LA",
"locations": {"LA": "u9Oo4", "NAT": "dP0Zw"},
"filters": {"wYXbx": "DCz1Q", "9ss4v": "p9WRS"},
"values": {"Poghe": "1", "1roqi": "1", "dPjk0": "1"},
}
assert row_to_record(row, urn_by_location={}) is None
def test_school_row_with_an_unknown_location_is_dropped():
row = {
"timePeriod": {"period": "2022/2023"},
"geographicLevel": "SCH",
"locations": {"SCH": "unknown"},
"filters": {"wYXbx": "DCz1Q", "9ss4v": "p9WRS"},
"values": {"Poghe": "1", "1roqi": "1", "dPjk0": "1"},
}
assert row_to_record(row, urn_by_location={"IXn5B": "137083"}) is None
def test_rows_without_a_recognised_destination_are_dropped():
row = {
"timePeriod": {"period": "2022/2023"},
"geographicLevel": "SCH",
"locations": {"SCH": "IXn5B"},
"filters": {"wYXbx": "notaslug", "9ss4v": "p9WRS"},
"values": {"Poghe": "1", "1roqi": "1", "dPjk0": "1"},
}
assert row_to_record(row, urn_by_location={"IXn5B": "137083"}) is None
def test_every_slug_maps_to_one_measure():
assert len(set(KS4_DESTINATION_SLUGS.values())) == len(KS4_DESTINATION_SLUGS)
assert set(KS4_PUPIL_GROUP_SLUGS.values()) == {"all", "disadvantaged", "other"}
def test_indicator_ids_are_per_dataset_not_shared():
"""The 16-18 dataset uses different indicator ids for the same concepts.
Reusing the KS4 ids there returns IndicatorsNotFound from the API."""
from tap_uk_ees_destinations.tap import KS4_INDICATORS, KS5_INDICATORS
assert set(KS4_INDICATORS) == set(KS5_INDICATORS) == {"cohort", "pupils", "percentage"}
assert not set(KS4_INDICATORS.values()) & set(KS5_INDICATORS.values())
def test_ks5_rows_are_read_with_the_ks5_indicators():
from tap_uk_ees_destinations.tap import (
KS5_DESTINATION_SLUGS, KS5_PUPIL_GROUP_SLUGS, KS5_INDICATORS,
)
row = {
"timePeriod": {"period": "2022/2023"},
"geographicLevel": "SCH",
"locations": {"SCH": "IXn5B"},
"filters": {"dest": "dkyu0", "dis": "Y0PuH"},
"values": {"5TESd": "176", "tjybE": "98", "fzKfY": "55.7"},
}
rec = row_to_record(
row, {"IXn5B": "137083"},
KS5_DESTINATION_SLUGS, KS5_PUPIL_GROUP_SLUGS, KS5_INDICATORS,
)
assert rec["destination_measure"] == "higher_education"
assert rec["cohort_pupils"] == "176"
assert rec["pupils_raw"] == "98"
assert rec["percentage_raw"] == "55.7"
def test_establishment_dimensions_are_not_pinned():
"""A school row carries its own establishment type, never Total — pinning
Total there returns zero rows for every school."""
from tap_uk_ees_destinations.tap import KS4_PINNED, KS5_PINNED
establishment_totals = {"4369U", "rgHcN", "EfHQq", "S4ROV"}
assert not set(KS4_PINNED) & establishment_totals
assert not set(KS5_PINNED) & establishment_totals