Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59ea8a4bdd |
No files matched your search
@@ -410,6 +410,29 @@ test('search and the school page agree on how many pupils a secondary has', asyn
|
||||
expect(school.total_pupils).toBe(detail.school_info.total_pupils);
|
||||
});
|
||||
|
||||
test('a secondary search row compares its Attainment 8 with the LA average', async ({ page }) => {
|
||||
// The comparison vanished unnoticed: the averages were fetched with
|
||||
// force-cache, so one stored failure hid it in that browser for good.
|
||||
// Playwright disables the HTTP cache when it intercepts requests, so this
|
||||
// guards the comparison itself; the unit test pins the cache mode.
|
||||
const la = await (await page.request.get('/api/la-averages')).json();
|
||||
const averages: Record<string, number> = la.secondary?.attainment_8_by_la ?? {};
|
||||
const res = await page.request.get('/api/schools?search=school&phase=secondary&page_size=50');
|
||||
expect(res.ok()).toBeTruthy();
|
||||
const school = ((await res.json()).schools ?? []).find(
|
||||
(s: { attainment_8_score?: number | null; local_authority?: string; school_type?: string }) =>
|
||||
s.attainment_8_score != null && s.local_authority != null && averages[s.local_authority] != null
|
||||
&& !/special|pupil referral|alternative provision/i.test(s.school_type ?? ''));
|
||||
test.skip(!school, 'no mainstream secondary with an LA average here');
|
||||
|
||||
await searchByName(page, school.school_name);
|
||||
const link = page.locator(`a[href^="/school/${school.urn}-"]`).first();
|
||||
await expect(link).toBeVisible({ timeout: 15_000 });
|
||||
const stats = link.locator('xpath=ancestor::div[contains(@class, "__rowContent")][1]')
|
||||
.locator('[class*="__line3"]');
|
||||
await expect(stats.getByText(/vs LA avg/)).toBeVisible();
|
||||
});
|
||||
|
||||
test('a phase outside primary/secondary filters to that phase, not to everything', async ({ page }) => {
|
||||
// The search page offers every GIAS phase, but the API only knew the grouped
|
||||
// ones and silently dropped the rest — so "Nursery" returned primaries.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import { HomeView } from '@/components/HomeView';
|
||||
import { fetchSchools } from '@/lib/api';
|
||||
import { fetchLAaverages, fetchSchools } from '@/lib/api';
|
||||
import { primaryFixture } from '../support/schoolFixtures';
|
||||
import type { SchoolsResponse, School } from '@/lib/types';
|
||||
|
||||
@@ -84,3 +84,23 @@ test('failed map requests can be retried by reopening the map', async () => {
|
||||
expect(fetchSchools).toHaveBeenCalledTimes(2);
|
||||
expect(screen.getByTestId('map')).toHaveTextContent('Retry result');
|
||||
});
|
||||
|
||||
test('LA averages are not fetched with force-cache, so one failure is not replayed for good', async () => {
|
||||
// force-cache serves any stored response, however old, without asking the
|
||||
// server. A request that failed once (a staging deploy restart, the July
|
||||
// proxy outage) was stored and replayed on every later visit, and the
|
||||
// "vs LA avg" delta vanished from every secondary row in that browser.
|
||||
// The default mode honours the API's Cache-Control and never reuses an
|
||||
// error.
|
||||
params = new URLSearchParams('search=high');
|
||||
const secondary: SchoolsResponse = {
|
||||
...response('Alpha High'),
|
||||
schools: [{ ...primaryFixture.schoolInfo, school_name: 'Alpha High', phase: 'Secondary', attainment_8_score: 50 }],
|
||||
};
|
||||
render(<HomeView initialSchools={secondary} filters={filters} />);
|
||||
await act(async () => {});
|
||||
expect(fetchLAaverages).toHaveBeenCalled();
|
||||
for (const [options] of jest.mocked(fetchLAaverages).mock.calls) {
|
||||
expect(options?.cache).not.toBe('force-cache');
|
||||
}
|
||||
});
|
||||
@@ -358,10 +358,14 @@ export function HomeView({ initialSchools, filters, totalSchools, howItWorks, ed
|
||||
return () => controller.abort();
|
||||
}, [resultsView, searchParams, initialSchools.schools]);
|
||||
|
||||
// Fetch LA averages when secondary or mixed schools are visible
|
||||
// Fetch LA averages when secondary or mixed schools are visible. Default
|
||||
// cache mode, never force-cache: force-cache replays any stored response
|
||||
// without asking the server, so one failed request (a deploy restart) hid
|
||||
// every "vs LA avg" delta in that browser for good. The API's Cache-Control
|
||||
// already lets the browser reuse a good answer for five minutes.
|
||||
useEffect(() => {
|
||||
if (!isSecondaryView && !isMixedView) return;
|
||||
fetchLAaverages({ cache: 'force-cache' })
|
||||
fetchLAaverages()
|
||||
.then(data => setLaAverages(data.secondary.attainment_8_by_la))
|
||||
.catch(() => {});
|
||||
}, [isSecondaryView, isMixedView]);
|
||||
|
||||
Reference in new issue
Block a user