Files
school_compare/nextjs-app/__tests__/support/schoolFixtures.ts
T
TudorandClaude Opus 5.5 9ef48da4b1 fix(school): the Ofsted section shows the grade still in force and the latest visit
The section is dated by the latest visit and headlines the grade still in force with the inspection that awarded or confirmed it, or 'No overall grade'. A later visit that isn't the grade's source gets its own line, with an ungraded outcome such as 'Standards maintained'. The primary and secondary no-grade branches merge, so the secondary page no longer drops the sixth-form and early-years judgements (audit M2), and 'Not rated' goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 16:31:26 +01:00

345 lines
12 KiB
TypeScript

/**
* Fixtures for the school detail characterization tests.
*
* Four shapes, each pinning a branch the detail views take:
* primary — KS2 results, legacy OEIF Ofsted, 3 years of admissions
* (enough for the year/trend toggle)
* secondary — KS4 results, Report Card Ofsted, 1 admissions year
* (no toggle)
* allThrough — BOTH KS2 and KS4, so the primary content is gated back on
* special — a special school with an all-zero KS2 row, where the
* England comparison must be suppressed
*
* Field names come from lib/types.ts. If TypeScript rejects something here,
* the fixture is wrong — never widen the type to accommodate a fixture.
*/
import type {
School, SchoolResult, AbsenceData, OfstedInspection, SchoolCensus,
SchoolAdmissions, SchoolDeprivation, SchoolFinance, NationalAverages,
} from '@/lib/types';
// ---------------------------------------------------------------------------
// Builders — SchoolResult has 57 required nullable fields, so every fixture
// starts from an all-null row and overrides only what it is testing.
// ---------------------------------------------------------------------------
const emptyResult: SchoolResult = {
school_id: 1,
year: 2024,
total_pupils: null, eligible_pupils: null,
rwm_expected_pct: null, reading_expected_pct: null, writing_expected_pct: null,
maths_expected_pct: null, gps_expected_pct: null, science_expected_pct: null,
rwm_high_pct: null, reading_high_pct: null, writing_high_pct: null,
maths_high_pct: null, gps_high_pct: null,
reading_progress: null, writing_progress: null, maths_progress: null,
reading_avg_score: null, maths_avg_score: null, gps_avg_score: null,
disadvantaged_pct: null, eal_pct: null, sen_support_pct: null, sen_ehcp_pct: null,
stability_pct: null,
reading_absence_pct: null, gps_absence_pct: null, maths_absence_pct: null,
writing_absence_pct: null, science_absence_pct: null,
rwm_expected_boys_pct: null, rwm_expected_girls_pct: null,
rwm_high_boys_pct: null, rwm_high_girls_pct: null,
rwm_expected_disadvantaged_pct: null, rwm_expected_non_disadvantaged_pct: null,
disadvantaged_gap: null,
rwm_expected_3yr_pct: null, reading_avg_3yr: null, maths_avg_3yr: null,
attainment_8_score: null, progress_8_score: null,
progress_8_lower_ci: null, progress_8_upper_ci: null,
progress_8_english: null, progress_8_maths: null,
progress_8_ebacc: null, progress_8_open: null,
english_maths_strong_pass_pct: null, english_maths_standard_pass_pct: null,
ebacc_entry_pct: null, ebacc_strong_pass_pct: null, ebacc_standard_pass_pct: null,
ebacc_avg_score: null, gcse_grade_91_pct: null, prior_attainment_avg: null,
};
export function makeResult(overrides: Partial<SchoolResult> = {}): SchoolResult {
return { ...emptyResult, ...overrides };
}
function makeSchool(overrides: Partial<School> = {}): School {
return {
urn: 123456,
school_name: 'Test Primary School',
local_authority: 'Westshire',
local_authority_code: 900,
school_type: 'Community school',
school_type_code: 'CY',
religious_denomination: 'None',
age_range: '4-11',
address1: '1 Test Lane',
address2: null,
town: 'Testville',
postcode: 'TE1 1ST',
address: '1 Test Lane, Testville, TE1 1ST',
latitude: 51.5,
longitude: -0.12,
phase: 'Primary',
gender: 'Mixed',
...overrides,
};
}
const emptyOfsted: OfstedInspection = {
framework: null,
inspection_date: null,
inspection_type: null,
overall_effectiveness: null,
quality_of_education: null,
behaviour_attitudes: null,
personal_development: null,
leadership_management: null,
early_years_provision: null,
previous_overall: null,
rc_safeguarding_met: null,
rc_inclusion: null,
rc_curriculum_teaching: null,
rc_achievement: null,
rc_attendance_behaviour: null,
rc_personal_development: null,
rc_leadership_governance: null,
rc_early_years: null,
rc_sixth_form: null,
report_url: null,
};
function makeOfsted(overrides: Partial<OfstedInspection> = {}): OfstedInspection {
return { ...emptyOfsted, ...overrides };
}
function makeAdmissions(overrides: Partial<SchoolAdmissions> = {}): SchoolAdmissions {
return {
year: 2024,
places_offered: 60,
total_applications: 210,
first_preference_applications: 90,
first_preference_offers: 54,
first_preference_offer_pct: 60,
oversubscribed: true,
...overrides,
};
}
const census: SchoolCensus = {
year: 2024,
total_pupils: 420,
female_pupils: 205,
male_pupils: 215,
fsm_pct: 18.4,
eal_pct: 22.1,
};
const absence: AbsenceData = {
overall_absence_rate: 5.2,
persistent_absence_rate: 14.8,
};
const deprivation: SchoolDeprivation = {
lsoa_code: 'E01000001',
idaci_score: 0.21,
idaci_decile: 4,
};
const finance: SchoolFinance = {
year: 2024,
per_pupil_spend: 5400,
staff_cost_pct: 72.5,
teacher_cost_pct: 51.2,
support_staff_cost_pct: 21.3,
premises_cost_pct: 6.1,
};
// ---------------------------------------------------------------------------
// National averages
// ---------------------------------------------------------------------------
export const nationalAveragesFixture: NationalAverages = {
year: 2024,
primary: { rwm_expected_pct: 61, rwm_high_pct: 8, reading_expected_pct: 74 },
secondary: { attainment_8_score: 45.9, progress_8_score: 0, ebacc_entry_pct: 39 },
by_year: [
{ year: 2023, primary: { rwm_expected_pct: 60 }, secondary: { attainment_8_score: 44.4 } },
{ year: 2024, primary: { rwm_expected_pct: 61 }, secondary: { attainment_8_score: 45.9 } },
],
};
// ---------------------------------------------------------------------------
// Fixture 1: ordinary primary — KS2 results, legacy OEIF, 3 admissions years
// ---------------------------------------------------------------------------
export const primaryFixture = {
schoolInfo: makeSchool(),
yearlyData: [
makeResult({ year: 2022, rwm_expected_pct: 54, reading_expected_pct: 68, writing_expected_pct: 62, maths_expected_pct: 65, total_pupils: 58 }),
makeResult({ year: 2023, rwm_expected_pct: 56, reading_expected_pct: 70, writing_expected_pct: 64, maths_expected_pct: 67, total_pupils: 60 }),
makeResult({
year: 2024,
rwm_expected_pct: 58, rwm_high_pct: 9,
reading_expected_pct: 72, writing_expected_pct: 66, maths_expected_pct: 69,
reading_progress: 0.4, writing_progress: -0.2, maths_progress: 1.1,
disadvantaged_pct: 24.5, eal_pct: 22.1, sen_support_pct: 13.2,
total_pupils: 60,
}),
],
absenceData: absence,
ofsted: makeOfsted({
framework: 'OEIF',
inspection_date: '2023-05-17',
inspection_type: 'Section 5',
overall_effectiveness: 2,
quality_of_education: 2,
behaviour_attitudes: 1,
personal_development: 2,
leadership_management: 2,
previous_overall: 3,
current_grade: { grade: 2, date: '2023-05-17', basis: 'graded' },
latest_visit: { date: '2023-05-17', kind: 'graded', outcome: null },
}),
census,
admissions: makeAdmissions({ year: 2024 }),
admissionsHistory: [
makeAdmissions({ year: 2022, first_preference_offer_pct: 71 }),
makeAdmissions({ year: 2023, first_preference_offer_pct: 65 }),
makeAdmissions({ year: 2024, first_preference_offer_pct: 60 }),
],
deprivation,
finance,
};
// ---------------------------------------------------------------------------
// Fixture 2: secondary — KS4 results, Report Card Ofsted, single admissions year
// ---------------------------------------------------------------------------
export const secondaryFixture = {
schoolInfo: makeSchool({
urn: 234567,
school_name: 'Test Secondary School',
phase: 'Secondary',
age_range: '11-16',
school_type: 'Academy converter',
school_type_code: 'AC',
}),
yearlyData: [
makeResult({ year: 2023, attainment_8_score: 44.8, progress_8_score: 0.18 }),
makeResult({
year: 2024,
attainment_8_score: 46.2, progress_8_score: 0.31,
progress_8_banding: 'Above average',
english_maths_standard_pass_pct: 68.4,
english_maths_strong_pass_pct: 47.1,
ebacc_entry_pct: 41.2, ebacc_standard_pass_pct: 28.6,
ebacc_strong_pass_pct: 19.4, ebacc_avg_score: 4.31,
disadvantaged_pct: 27.8, eal_pct: 19.3, sen_support_pct: 11.7,
}),
],
absenceData: absence,
ofsted: makeOfsted({
framework: 'ReportCard',
inspection_date: '2025-11-20',
rc_inspection_date: '2025-11-20',
// isReportCard keys off a non-empty report_card record, NOT the rc_*
// fields — the rc_* numbers supply the values once the layout is chosen.
report_card: {
inclusion: { code: 2, label: 'Strong' },
curriculum_teaching: { code: 2, label: 'Strong' },
achievement: { code: 3, label: 'Expected standard' },
attendance_behaviour: { code: 2, label: 'Strong' },
personal_development: { code: 1, label: 'Exceptional' },
leadership_governance: { code: 2, label: 'Strong' },
},
rc_safeguarding_met: true,
rc_inclusion: 2,
rc_curriculum_teaching: 2,
rc_achievement: 3,
rc_attendance_behaviour: 2,
rc_personal_development: 1,
rc_leadership_governance: 2,
}),
census,
admissions: makeAdmissions({ year: 2024, school_phase: 'Secondary' }),
admissionsHistory: [makeAdmissions({ year: 2024, school_phase: 'Secondary' })],
deprivation,
finance,
};
// ---------------------------------------------------------------------------
// Fixture 3: all-through — BOTH key stages on the same row.
// The highest-value fixture: isAllThrough gates the KS2 content back on for a
// school that also has KS4 data, and this is the case most likely to break.
// ---------------------------------------------------------------------------
export const allThroughFixture = {
schoolInfo: makeSchool({
urn: 345678,
school_name: 'Test All-Through School',
phase: 'All-through',
age_range: '4-18',
has_sixth_form: true,
}),
yearlyData: [
makeResult({ year: 2023, rwm_expected_pct: 55, attainment_8_score: 45.0 }),
makeResult({
year: 2024,
rwm_expected_pct: 63, reading_expected_pct: 76,
writing_expected_pct: 70, maths_expected_pct: 71,
attainment_8_score: 48.7, progress_8_score: 0.42,
english_maths_standard_pass_pct: 71.2,
disadvantaged_pct: 20.1, eal_pct: 17.5, sen_support_pct: 9.8,
}),
],
absenceData: absence,
ofsted: makeOfsted({
framework: 'OEIF',
inspection_date: '2022-10-04',
inspection_type: 'Section 5',
overall_effectiveness: 1,
quality_of_education: 1,
behaviour_attitudes: 1,
personal_development: 1,
leadership_management: 1,
current_grade: { grade: 1, date: '2022-10-04', basis: 'graded' },
latest_visit: { date: '2022-10-04', kind: 'graded', outcome: null },
}),
census,
admissions: makeAdmissions({ year: 2024, school_phase: 'Secondary' }),
admissionsHistory: [
makeAdmissions({ year: 2023, school_phase: 'Secondary', first_preference_offer_pct: 58 }),
makeAdmissions({ year: 2024, school_phase: 'Secondary', first_preference_offer_pct: 52 }),
],
deprivation,
finance,
};
// ---------------------------------------------------------------------------
// Fixture 4: special school — all-zero KS2 row.
// Guards the PR #70 regression: special/PRU/AP schools must not be shown an
// England comparison, because their pupils sit the same tests but very few
// reach the mainstream "expected standard".
// ---------------------------------------------------------------------------
export const specialFixture = {
schoolInfo: makeSchool({
urn: 456789,
school_name: 'Test Special School',
school_type: 'Community special school',
school_type_code: 'CYS',
age_range: '2-19',
}),
yearlyData: [
makeResult({
year: 2024,
rwm_expected_pct: 0,
reading_expected_pct: 0,
writing_expected_pct: 0,
maths_expected_pct: 0,
total_pupils: 12,
}),
],
absenceData: absence,
ofsted: null,
census,
admissions: null,
admissionsHistory: [],
deprivation,
finance,
};