diff --git a/e2e/tests/journeys.spec.ts b/e2e/tests/journeys.spec.ts index 15744d8..ae585ee 100644 --- a/e2e/tests/journeys.spec.ts +++ b/e2e/tests/journeys.spec.ts @@ -309,6 +309,19 @@ test('school type and gender switch straight to another value', async ({ page }) * School type offers six groups a parent recognises, and Faith sits beside it. * Data-invariant: asserts what every returned school is, never how many. */ +// Clear all once dropped the search with the filters, which sent desktop back +// to the home page instead of to the unfiltered results. +test('Clear all removes the filters and keeps the search', async ({ page }) => { + await page.goto('/?search=school&phase=primary'); + const row = page.getByRole('group', { name: 'Filters', exact: true }); + await expect(schoolLinks(page).first()).toBeVisible({ timeout: 15_000 }); + await row.getByRole('button', { name: 'Clear all', exact: true }).click(); + await expect(page).not.toHaveURL(/[?&]phase=/); + await expect(page).toHaveURL(/[?&]search=school(&|$)/); + await expect(schoolLinks(page).first()).toBeVisible(); + await expect(row.getByRole('button', { name: 'Clear all', exact: true })).toHaveCount(0); +}); + test('school type groups and the faith filter narrow to what they name', async ({ page }) => { await page.goto('/?search=school'); const type = page.getByRole('combobox', { name: 'School type', exact: true }); diff --git a/nextjs-app/__tests__/components/ResultsToolbar.test.tsx b/nextjs-app/__tests__/components/ResultsToolbar.test.tsx index 105b9d7..fcd3d44 100644 --- a/nextjs-app/__tests__/components/ResultsToolbar.test.tsx +++ b/nextjs-app/__tests__/components/ResultsToolbar.test.tsx @@ -1,4 +1,4 @@ -import { act, fireEvent, render, screen } from '@testing-library/react'; +import { act, fireEvent, render, screen, within } from '@testing-library/react'; import { HomeView } from '@/components/HomeView'; import { FilterBar } from '@/components/FilterBar'; import { fetchSchools } from '@/lib/api'; @@ -175,3 +175,24 @@ describe('the results list', () => { expect(screen.queryByText('Search: southmead')).not.toBeInTheDocument(); }); }); + +describe('the desktop Clear all', () => { + const row = () => screen.getByRole('group', { name: 'Filters' }); + + it('removes the filters and keeps the search, rather than going home', () => { + params = new URLSearchParams('postcode=SW196AR&radius=3&phase=primary&school_type=council&local_authority=Wandsworth'); + render(); + fireEvent.click(within(row()).getByRole('button', { name: 'Clear all' })); + const pushed = push.mock.calls.at(-1)![0] as string; + const next = new URLSearchParams(pushed.split('?')[1]); + expect(next.get('postcode')).toBe('SW196AR'); + expect(next.get('radius')).toBe('3'); + for (const key of ['phase', 'school_type', 'local_authority']) expect(next.get(key)).toBeNull(); + }); + + it('is not offered when only a search is applied', () => { + params = new URLSearchParams('search=southmead'); + render(); + expect(within(row()).queryByRole('button', { name: /^Clear/ })).not.toBeInTheDocument(); + }); +}); diff --git a/nextjs-app/components/FilterBar.tsx b/nextjs-app/components/FilterBar.tsx index 8474d4e..3c4d30a 100644 --- a/nextjs-app/components/FilterBar.tsx +++ b/nextjs-app/components/FilterBar.tsx @@ -377,31 +377,13 @@ export function FilterBar({ updateURL({ ...cleared, [key]: value }); }; - // Every filter at once, keeping the search and its distance: what "Clear - // all" means beside the applied filters, where the search is not one of them. + // Every filter at once, keeping the search and its distance. The search is + // what the results answer, not a filter on them: clearing it too used to + // send desktop back to the home page. const handleClearFilterValues = () => { updateURL(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""]))); }; - const handleClearFilters = () => { - setOmniValue(""); - pendingQueryRef.current = ""; - startTransition(() => { - router.push(pathname); - }); - }; - - const hasActiveFilters = - currentSearch || - currentLA || - currentType || - currentFaith || - currentPhase || - currentPostcode || - currentGender || - currentAdmissionsPolicy || - currentHasSixthForm; - /* * A filter's options come from the full lists, not from the results: the * results have already been narrowed by that filter, so scoping to them @@ -844,14 +826,14 @@ export function FilterBar({ /> - {hasActiveFilters && ( + {appliedCount > 0 && ( )}