fact_performance's total_pupils is the cohort a year's results were measured on. For a secondary that is Year 11 alone, and the list API sent it as the card's "pupils": Burntwood showed 245 in search and 1,462 on its page. The list and place payloads now carry the register's whole-school count, and nothing when the register has none. Map popups and the compare basket read the same field. The header and the wellbeing section fell back to the same results figure when the census had no record. They now fall back to the register count. The shell took yearlyData only for that fallback, so the prop is gone and the results array no longer ships to the client for the chrome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.6 KiB
Python
68 lines
2.6 KiB
Python
"""Cards, map popups and place rows label total_pupils "pupils".
|
|
|
|
fact_performance's total_pupils is the cohort a year's results were measured
|
|
on. For a secondary that is the GCSE year group alone: Burntwood showed 245 in
|
|
search against 1,462 on roll. The list and place payloads therefore carry the
|
|
register's whole-school count, and nothing when the register has none.
|
|
"""
|
|
|
|
import numpy as np
|
|
import pandas as pd
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
def _schools_df() -> pd.DataFrame:
|
|
base = {
|
|
"local_authority": "Essex", "school_type": "Academy converter",
|
|
"year": 202425, "ofsted_grade": 2.0, "ofsted_date": None,
|
|
"town": "Brentwood", "postcode": "CM13 1AA", "status": "Open",
|
|
"address": "1 Test Street", "latitude": 51.6, "longitude": 0.3,
|
|
"gender": "Mixed", "rwm_expected_pct": np.nan, "attainment_8_score": 50.0,
|
|
}
|
|
rows = [
|
|
# Secondary: results cohort 245, register 1,462.
|
|
{**base, "urn": 100001, "school_name": "Alpha High", "phase": "Secondary",
|
|
"total_pupils": 245, "gias_total_pupils": 1462},
|
|
# Register count missing: no count, never the cohort.
|
|
{**base, "urn": 100002, "school_name": "Beta High", "phase": "Secondary",
|
|
"total_pupils": 180, "gias_total_pupils": np.nan},
|
|
]
|
|
# Enough schools in one town for it to have a place page.
|
|
rows += [
|
|
{**base, "urn": 100010 + i, "school_name": f"Gamma High {i}", "phase": "Secondary",
|
|
"total_pupils": 200, "gias_total_pupils": 1000 + i}
|
|
for i in range(5)
|
|
]
|
|
return pd.DataFrame(rows)
|
|
|
|
|
|
@pytest.fixture()
|
|
def client(monkeypatch):
|
|
from backend import app as app_module
|
|
|
|
monkeypatch.setattr(app_module, "load_latest_school_data", _schools_df)
|
|
monkeypatch.setattr(app_module, "load_school_data", _schools_df)
|
|
monkeypatch.setattr(app_module, "_place_registry", None)
|
|
return TestClient(app_module.app, raise_server_exceptions=False)
|
|
|
|
|
|
def _pupils(schools: list[dict]) -> dict[int, object]:
|
|
return {s["urn"]: s.get("total_pupils") for s in schools}
|
|
|
|
|
|
def test_the_list_carries_the_whole_school_count(client):
|
|
resp = client.get("/api/schools?page_size=50")
|
|
assert resp.status_code == 200, resp.text
|
|
pupils = _pupils(resp.json()["schools"])
|
|
assert pupils[100001] == 1462
|
|
assert pupils[100002] is None
|
|
|
|
|
|
def test_a_place_page_carries_the_whole_school_count(client):
|
|
resp = client.get("/api/places/town/brentwood")
|
|
assert resp.status_code == 200, resp.text
|
|
pupils = _pupils(resp.json()["schools"])
|
|
assert pupils[100001] == 1462
|
|
assert pupils[100002] is None
|