"""/api/compare enrichment for the compare redesign: per-school supplementary blocks, top-level national_averages (shared with the /api/national-averages endpoint) and computed benchmarks — all additive.""" import types import numpy as np import pandas as pd import pytest from fastapi.testclient import TestClient LATEST = 202425 CANNED_SUPPLEMENTARY = { "ofsted": {"overall_effectiveness": 2, "grade_source": "graded", "report_card": {}, "ofsted_page_url": "https://reports.ofsted.gov.uk/provider/21/100140"}, "census": {"year": 202526, "fsm_pct": 29.8}, "admissions": {"year": 202627, "second_preference_offers": 4}, "admissions_history": [{"year": 202627, "second_preference_offers": 4}], "sen_detail": None, "phonics": None, "deprivation": {"idaci_decile": 4}, "finance": None, } def _two_primary_schools_df() -> pd.DataFrame: rows = [] for urn, name, rwm, dis in ((100140, "Plumcroft Primary School", 79.0, 72.0), (138690, "Barclay Primary School", 87.0, 86.0)): rows.append(dict( urn=urn, school_name=name, local_authority="Greenwich", school_type="Community school", address="1 Road", phase="Primary", year=LATEST, rwm_expected_pct=rwm, attainment_8_score=np.nan, eligible_pupils=60, rwm_expected_disadvantaged_pct=dis, eal_pct=20.0, sen_support_pct=14.0, disadvantaged_pct=25.0, total_pupils=1000.0, )) return pd.DataFrame(rows) class _StubNatRow: year = 202425 rwm_expected_pct = 62.1 gps_expected_pct = 72.0 science_expected_pct = 81.0 class _StubSession: def query(self, *a, **k): return self def order_by(self, *a, **k): return self def all(self): return [_StubNatRow()] def close(self): pass @pytest.fixture() def client(monkeypatch): from backend import app as app_module from backend import database as database_module monkeypatch.setattr(app_module, "load_school_data", _two_primary_schools_df) monkeypatch.setattr( app_module, "get_supplementary_data", lambda db, urn: dict(CANNED_SUPPLEMENTARY) ) monkeypatch.setattr(database_module, "SessionLocal", _StubSession) return TestClient(app_module.app, raise_server_exceptions=False) def test_existing_shape_is_preserved(client): body = client.get("/api/compare?urns=100140,138690").json() school = body["comparison"]["100140"] assert school["school_info"]["rwm_expected_pct"] == 79.0 assert school["yearly_data"][0]["year"] == LATEST def test_each_school_gains_supplementary_blocks(client): body = client.get("/api/compare?urns=100140,138690").json() for urn in ("100140", "138690"): school = body["comparison"][urn] assert school["ofsted"]["grade_source"] == "graded" assert school["census"]["fsm_pct"] == 29.8 assert school["admissions"]["second_preference_offers"] == 4 assert school["admissions_history"][0]["year"] == 202627 assert school["deprivation"]["idaci_decile"] == 4 def test_top_level_national_averages_and_benchmarks(client): body = client.get("/api/compare?urns=100140,138690").json() assert body["national_averages"]["year"] == LATEST assert body["benchmarks"]["source"] == "state-school average (computed from our dataset)" # weighted over equal cohorts of 72 and 86 = 79.0 assert body["benchmarks"]["primary"]["disadvantaged_rwm_expected_pct"] == 79.0 def test_supplementary_failure_degrades_not_500(client, monkeypatch): from backend import app as app_module def _boom(db, urn): raise RuntimeError("marts unavailable") monkeypatch.setattr(app_module, "get_supplementary_data", _boom) resp = client.get("/api/compare?urns=100140") assert resp.status_code == 200 school = resp.json()["comparison"]["100140"] assert school["ofsted"] is None assert school["admissions_history"] == [] def test_national_averages_endpoint_exposes_gps_science(client): body = client.get("/api/national-averages").json() latest_primary_by_year = [e["primary"] for e in body["by_year"] if e["primary"]] assert latest_primary_by_year, "expected official by_year rows from the stub" assert latest_primary_by_year[-1]["gps_expected_pct"] == 72.0 assert latest_primary_by_year[-1]["science_expected_pct"] == 81.0