fix(search): match primary phases by their words, not exact labels
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m14s
PR Checks / Backend Smoke (pull_request) Successful in 10s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m20s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 12s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 18s
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m14s
PR Checks / Backend Smoke (pull_request) Successful in 10s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m20s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 12s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 18s
The secondary-only filters were hidden for an exact set of lowercased labels, so a change of case, hyphen or spacing in a GIAS phase label would have left them showing. Phases are now matched on their words, as compareGroups already reads "primary". The E2E journey no longer counts school types: it asserts that choosing one leaves the same list on offer, whatever the data holds. A test now pins that a filter with no options is left out, not shown with only its "any" option. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0cc4f52816
commit
68452681f8
3 files changed
+26
-9
No files matched your search
@@ -296,11 +296,13 @@ test('school type and gender switch straight to another value', async ({ page })
|
||||
await gender.selectOption('boys');
|
||||
await expect(page).toHaveURL(/[?&]gender=boys(&|$)/);
|
||||
|
||||
// Whatever types the data holds, choosing one leaves the same list on offer.
|
||||
const type = page.getByRole('combobox', { name: 'School type', exact: true });
|
||||
const [first] = (await type.locator('option').allTextContents()).slice(1);
|
||||
await type.selectOption(first);
|
||||
const offered = await type.locator('option').allTextContents();
|
||||
expect(offered.length, 'no school type to choose').toBeGreaterThan(1);
|
||||
await type.selectOption(offered[1]);
|
||||
await expect(page).toHaveURL(/[?&]school_type=/);
|
||||
await expect.poll(() => type.locator('option').count()).toBeGreaterThan(2);
|
||||
await expect.poll(() => type.locator('option').allTextContents()).toEqual(offered);
|
||||
});
|
||||
|
||||
test('a phase outside primary/secondary filters to that phase, not to everything', async ({ page }) => {
|
||||
|
||||
@@ -87,13 +87,19 @@ describe('the secondary-only filters', () => {
|
||||
expect(shown(openSheet())).toEqual(secondaryOnly);
|
||||
});
|
||||
|
||||
it.each(['primary', 'nursery', 'middle deemed primary'])('hide for the %s phase', (phase) => {
|
||||
it.each(['primary', 'nursery', 'middle deemed primary', 'Middle-deemed Primary'])(
|
||||
'hide for the %s phase', (phase) => {
|
||||
params = new URLSearchParams(`postcode=SW196AR&radius=1&phase=${encodeURIComponent(phase)}`);
|
||||
render(<FilterBar filters={filters} />);
|
||||
expect(shown(openSheet())).toEqual([]);
|
||||
});
|
||||
|
||||
it.each(['secondary', 'all-through'])('show for the %s phase', (phase) => {
|
||||
it('leave out a filter with no options, rather than show only its "any"', () => {
|
||||
render(<FilterBar filters={{ ...filters, genders: [], admissions_policies: [] }} />);
|
||||
expect(shown(openSheet())).toEqual(['Sixth form']);
|
||||
});
|
||||
|
||||
it.each(['secondary', 'all-through', 'middle deemed secondary', '16 plus'])('show for the %s phase', (phase) => {
|
||||
params = new URLSearchParams(`postcode=SW196AR&radius=1&phase=${phase}`);
|
||||
render(<FilterBar filters={filters} />);
|
||||
expect(shown(openSheet())).toEqual(secondaryOnly);
|
||||
|
||||
@@ -69,10 +69,19 @@ type FilterKey = (typeof FILTER_KEYS)[number];
|
||||
/** Filters that only mean something for schools teaching beyond primary. */
|
||||
const SECONDARY_ONLY_KEYS = ["gender", "has_sixth_form", "admissions_policy"] as const;
|
||||
|
||||
/** Phases with no secondary-age pupils, for which those filters are hidden. */
|
||||
const PRIMARY_PHASES = new Set(["primary", "nursery", "middle deemed primary"]);
|
||||
|
||||
const hasSecondaryFilters = (phase: string) => !PRIMARY_PHASES.has(phase.toLowerCase());
|
||||
/**
|
||||
* False for a phase with no secondary-age pupils, for which those filters are
|
||||
* hidden: Primary, Nursery and Middle deemed primary. Matched on the words,
|
||||
* not exact labels, so a change of case, hyphen or spacing in the GIAS label
|
||||
* cannot leave them showing. The same reading of "primary" as
|
||||
* compareGroups in lib/compareLogic.ts. The API's PHASE_GROUPS answers a
|
||||
* different question (which phases a phase filter returns: primary includes
|
||||
* all-through), so it is not this list.
|
||||
*/
|
||||
function hasSecondaryFilters(phase: string): boolean {
|
||||
const p = phase.toLowerCase().replace(/[^a-z]+/g, " ").trim();
|
||||
return !(p === "nursery" || (p.includes("primary") && !p.includes("secondary")));
|
||||
}
|
||||
|
||||
function SlidersIcon() {
|
||||
return (
|
||||
|
||||
Reference in new issue
Block a user