diff --git a/nextjs-app/__tests__/components/SchoolRow.test.tsx b/nextjs-app/__tests__/components/SchoolRow.test.tsx new file mode 100644 index 0000000..dcdab0e --- /dev/null +++ b/nextjs-app/__tests__/components/SchoolRow.test.tsx @@ -0,0 +1,36 @@ +/** + * SchoolRow (primary search results): line 2 prints the religious character + * only when the school has one. The register's "None" was printed as a chip. + */ + +import '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/react'; +import { SchoolRow } from '@/components/SchoolRow'; +import type { School } from '@/lib/types'; + +const base = { + urn: 100001, + school_name: 'Alpha Primary School', + local_authority: 'Testshire', + school_type: 'Free schools', + phase: 'Primary', + gender: 'Mixed', + age_range: '4-11', + rwm_expected_pct: 70, +} as unknown as School; + +describe('SchoolRow religious character', () => { + it.each(['None', 'Does not apply', ''])( + 'prints nothing when the register says %p', + (religious_denomination) => { + render(); + expect(screen.queryByText('None')).not.toBeInTheDocument(); + expect(screen.queryByText('Does not apply')).not.toBeInTheDocument(); + }, + ); + + it('prints a religious character the school has', () => { + render(); + expect(screen.getByText('Church of England')).toBeInTheDocument(); + }); +}); diff --git a/nextjs-app/__tests__/components/SecondarySchoolRow.test.tsx b/nextjs-app/__tests__/components/SecondarySchoolRow.test.tsx index a868256..e3a25ac 100644 --- a/nextjs-app/__tests__/components/SecondarySchoolRow.test.tsx +++ b/nextjs-app/__tests__/components/SecondarySchoolRow.test.tsx @@ -65,3 +65,38 @@ describe('SecondarySchoolRow proposed-to-close tag', () => { expect(screen.queryByText(/Proposed to close/)).not.toBeInTheDocument(); }); }); + +describe('SecondarySchoolRow admissions tag', () => { + it('tags a selective school', () => { + render(); + expect(screen.getByText('Selective')).toBeInTheDocument(); + }); + + it('does not tag a non-selective school as selective', () => { + // "Non-selective" contains "selective": a substring test tagged every + // comprehensive (Burntwood, Graveney) as Selective. + render(); + expect(screen.queryByText('Selective')).not.toBeInTheDocument(); + }); + + it.each(['None', 'Does not apply', '', null])( + 'gives no faith tag when the religious character is %p', + (religious_denomination) => { + render( + , + ); + expect(screen.queryByText('Faith priority')).not.toBeInTheDocument(); + }, + ); + + it('tags a school with a religious character', () => { + render( + , + ); + expect(screen.getByText('Faith priority')).toBeInTheDocument(); + }); +}); diff --git a/nextjs-app/components/SchoolRow.tsx b/nextjs-app/components/SchoolRow.tsx index 306363a..fe167b0 100644 --- a/nextjs-app/components/SchoolRow.tsx +++ b/nextjs-app/components/SchoolRow.tsx @@ -9,7 +9,7 @@ */ import type { School } from '@/lib/types'; -import { formatPercentage, calculateTrend, getPhaseStyle, schoolUrl, buildOfstedListBadge, formatAgeRange, isProposedToClose, isSpecialSchool, listRwmValue } from '@/lib/utils'; +import { formatPercentage, calculateTrend, getPhaseStyle, schoolUrl, buildOfstedListBadge, formatAgeRange, hasReligiousCharacter, isProposedToClose, isSpecialSchool, listRwmValue } from '@/lib/utils'; import styles from './SchoolRow.module.css'; interface SchoolRowProps { @@ -34,9 +34,7 @@ export function SchoolRow({ const ofstedBadge = buildOfstedListBadge(school); const showGender = school.gender && school.gender.toLowerCase() !== 'mixed'; - const showDenomination = - school.religious_denomination && - school.religious_denomination !== 'Does not apply'; + const showDenomination = hasReligiousCharacter(school.religious_denomination); // The school's OWN figure and its year-over-year trend are same-school // measures — shown whenever there's a real value (not the all-zero diff --git a/nextjs-app/components/SecondarySchoolRow.tsx b/nextjs-app/components/SecondarySchoolRow.tsx index e10ca0a..762937d 100644 --- a/nextjs-app/components/SecondarySchoolRow.tsx +++ b/nextjs-app/components/SecondarySchoolRow.tsx @@ -11,14 +11,14 @@ 'use client'; import type { School } from '@/lib/types'; -import { buildOfstedListBadge, getPhaseStyle, schoolUrl, formatAgeRange, isProposedToClose, isSpecialSchool } from '@/lib/utils'; +import { buildOfstedListBadge, getPhaseStyle, schoolUrl, formatAgeRange, hasReligiousCharacter, isProposedToClose, isSpecialSchool } from '@/lib/utils'; import styles from './SecondarySchoolRow.module.css'; function detectAdmissionsTag(school: School): string | null { - const policy = school.admissions_policy?.toLowerCase() ?? ''; - if (policy.includes('selective')) return 'Selective'; - const denom = school.religious_denomination ?? ''; - if (denom && denom !== 'Does not apply') return 'Faith priority'; + // Exact match: "Non-selective" contains "selective", so a substring test + // tagged every comprehensive as Selective. + if (school.admissions_policy?.trim().toLowerCase() === 'selective') return 'Selective'; + if (hasReligiousCharacter(school.religious_denomination)) return 'Faith priority'; return null; } diff --git a/nextjs-app/lib/utils.ts b/nextjs-app/lib/utils.ts index 3422edb..09a76c4 100644 --- a/nextjs-app/lib/utils.ts +++ b/nextjs-app/lib/utils.ts @@ -902,6 +902,15 @@ export function isSpecialSchool(school: { school_type?: string | null }): boolea return /\bspecial\b/.test(t) || /pupil referral/.test(t) || /alternative provision/.test(t); } +/** + * Whether GIAS records a religious character. "None" and "Does not apply" are + * the register's two ways of saying it has none, and neither is a faith. + */ +export function hasReligiousCharacter(value: string | null | undefined): boolean { + const v = value?.trim().toLowerCase() ?? ''; + return v !== '' && v !== 'none' && v !== 'does not apply'; +} + /** * The school's combined Reading, Writing & Maths figure, or null when there is * no real one to show.