/** * 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 { return { ...emptyResult, ...overrides }; } function makeSchool(overrides: Partial = {}): 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 { return { ...emptyOfsted, ...overrides }; } function makeAdmissions(overrides: Partial = {}): 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, grade_source: 'graded', }), 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, grade_source: 'graded', }), 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, };