jsdom provides neither IntersectionObserver nor scrollTo; both detail views use them. Adds four fixtures (primary, secondary, all-through, special) covering the branches the characterization tests will pin. SchoolResult carries 57 required nullable fields, so fixtures are built from an all-null base row and override only what they exercise. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
333 lines
11 KiB
TypeScript
333 lines
11 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,
|
|
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',
|
|
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,
|
|
};
|