"""DfE re-publishes earlier years inside later KS4 releases. The 2024/25 results file holds 2022/23, 2023/24 and 2024/25 under current column names. The 2023/24 release's own file, re-issued in March 2026 under older names, was read after it and overwrote every 2023/24 row with blanks (audit C2). For the KS4 results stream the newest release owns every year it contains. """ import importlib.util import re from pathlib import Path import pandas as pd import pytest TAP_DIR = (Path(__file__).resolve().parents[1] / 'plugins' / 'extractors' / 'tap-uk-ees' / 'tap_uk_ees') @pytest.fixture def precedence(): spec = importlib.util.spec_from_file_location( 'release_precedence', TAP_DIR / 'release_precedence.py') module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module def _release(period): return {'id': f'release-{period}', 'time_period': period} def test_releases_are_taken_newest_first_whatever_order_the_api_gives(precedence): releases = [_release('202223'), _release('202425'), _release(None), _release('202324')] ordered = precedence.newest_first(releases) assert [r['time_period'] for r in ordered] == ['202425', '202324', '202223', None] def test_a_year_a_newer_release_supplied_is_dropped_from_an_older_one(precedence): newer = pd.DataFrame({'time_period': ['202425', '202324', '202223'], 'school_urn': ['1'] * 3}) older = pd.DataFrame({'time_period': ['202324', '202324', '201920'], 'school_urn': ['1', '2', '1']}) kept, skipped = precedence.drop_owned_periods(older, precedence.periods_in(newer)) assert list(kept['time_period']) == ['201920'] assert skipped == {'202324': 2} def test_periods_match_despite_surrounding_spaces(precedence): owned = precedence.periods_in(pd.DataFrame({'time_period': [' 202324 ']})) kept, skipped = precedence.drop_owned_periods(pd.DataFrame({'time_period': ['202324']}), owned) assert owned == {'202324'} assert kept.empty assert skipped == {'202324': 1} def test_nothing_is_dropped_before_any_year_is_owned(precedence): df = pd.DataFrame({'time_period': ['202324'], 'school_urn': ['1']}) kept, skipped = precedence.drop_owned_periods(df, set()) assert kept.equals(df) assert skipped == {} def test_a_file_without_time_period_is_left_alone(precedence): df = pd.DataFrame({'school_urn': ['1']}) kept, skipped = precedence.drop_owned_periods(df, {'202324'}) assert kept.equals(df) assert skipped == {} assert precedence.periods_in(df) == set() def test_only_the_ks4_results_stream_opts_in(): # A general rule would wipe KS2: the 2024/25 KS2 file holds 98,448 of the # 955,956 rows the 2023/24 release has for 2023/24. source = (TAP_DIR / 'tap.py').read_text() opted_in = [chunk.split('(')[0] for chunk in source.split('\nclass ')[1:] if re.search(r'_newest_release_owns_period\s*=\s*True', chunk)] assert opted_in == ['EESKS4PerformanceStream'] @pytest.mark.parametrize('slug, period', [ ('2024-25', '202425'), ('2024-25-revised', '202425'), ('2025-26-provisional', '202526'), ('latest', None), ('', None), ]) def test_a_release_slug_gives_its_year_whatever_its_suffix(precedence, slug, period): # KS2 already publishes "2024-25-revised" and "2025-26-provisional". An # unread suffix sent the release last, behind the provisional one for the # same year, which then owned the year and dropped every revised row. assert precedence.slug_to_time_period(slug) == period def test_within_a_year_the_api_order_is_kept(precedence): # The API lists a year's revised release before its first release. releases = [{'id': 'revised', 'time_period': '202526'}, {'id': 'first', 'time_period': '202526'}, {'id': 'older', 'time_period': '202425'}] assert [r['id'] for r in precedence.newest_first(releases)] == ['revised', 'first', 'older']