feat(places): name every authority a place sits in
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m33s
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m33s
SW19 is mostly Merton but partly Wandsworth, and the page said only Merton. The cause was one field doing two jobs: _parent_authority takes the modal authority, which is right for a 301 target and wrong as a statement about where a place is. This is not a corner case. A quarter of viable outcodes (425 of 1,760) and a third of viable towns (263 of 783) cross an authority boundary — Bedford the town spans Bedford and Central Bedfordshire. Place now carries `authorities`, every authority holding at least a tenth of the schools and at least two of them, largest first. parent_authority stays single and unchanged, because a redirect still needs one target. The share threshold exists because GIAS carries postcode errors: EN6 lists two Shropshire schools among fourteen in Hertfordshire, and a bare "any authority present" rule would print those as though they were real. A place too small or too fragmented to clear the threshold still names its largest, so the page never goes silent about where it is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
This commit is contained in:
1 parent
9545aec7f4
commit
93a0a3c26f
7 files changed
+214
-6
No files matched your search
@@ -168,3 +168,47 @@ describe('PlaceView presentation', () => {
|
||||
.not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('PlaceView authorities', () => {
|
||||
const straddling: PlaceDetail = {
|
||||
place: { kind: 'outcode', slug: 'sw19', name: 'SW19', count: 33,
|
||||
parent_authority: 'Merton', phases: ['primary'],
|
||||
authorities: [
|
||||
{ name: 'Merton', slug: 'merton', count: 26 },
|
||||
{ name: 'Wandsworth', slug: 'wandsworth', count: 7 },
|
||||
] },
|
||||
schools: [
|
||||
{ urn: 1, school_name: 'Alpha Primary', phase: 'Primary',
|
||||
rwm_expected_pct: 82, attainment_8_score: null } as never,
|
||||
],
|
||||
averages: { rwm_expected_pct: 63, attainment_8_score: null },
|
||||
};
|
||||
|
||||
it('names every authority the place straddles, not just the largest', () => {
|
||||
// SW19 is mostly Merton but partly Wandsworth. Naming one asserts
|
||||
// something false about a quarter of outcodes.
|
||||
render(<PlaceView detail={straddling} englandAverage={61} neighbours={[]} />);
|
||||
expect(screen.getByRole('link', { name: 'Merton' }))
|
||||
.toHaveAttribute('href', '/schools/authority/merton');
|
||||
expect(screen.getByRole('link', { name: 'Wandsworth' }))
|
||||
.toHaveAttribute('href', '/schools/authority/wandsworth');
|
||||
});
|
||||
|
||||
it('joins them readably rather than as a bare list', () => {
|
||||
// Asserted on the summary line's whole text: a loose /and/ matcher also
|
||||
// hits "Wandsworth".
|
||||
const { container } = render(<PlaceView detail={straddling}
|
||||
englandAverage={61} neighbours={[]} />);
|
||||
const summary = container.querySelector('header p');
|
||||
expect(summary?.textContent).toContain('Merton and Wandsworth');
|
||||
});
|
||||
|
||||
it('falls back to the single parent when the field is absent', () => {
|
||||
// A cached API response predating the authorities field must not blank
|
||||
// the line entirely.
|
||||
const legacy = { ...straddling,
|
||||
place: { ...straddling.place, authorities: undefined } };
|
||||
render(<PlaceView detail={legacy} englandAverage={61} neighbours={[]} />);
|
||||
expect(screen.getByRole('link', { name: 'Merton' })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user