From bb1ab3a2e305abe734d63d2a9ae1584b7e27a51f Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 19 May 2026 15:42:11 -0400 Subject: [PATCH] =?UTF-8?q?test(web):=20un-skip=20discover/requests=20rout?= =?UTF-8?q?e=20tests=20=E2=80=94=20mock=20$app=20(#374)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: discover.test.ts and requests.test.ts were the only route page tests NOT mocking $app/state (+ $app/navigation), so rendering the +page.svelte pulled in SvelteKit's client runtime and threw `TypeError: notifiable_store is not a function` at module load. They'd been describe.skip'd AND hard-excluded in vitest.config.ts. Fix mirrors every other route test: vi.hoisted pageState + vi.mock('$app/state', () => pageUrlModule(state)) + vi.mock('$app/navigation', () => ({ goto: vi.fn() })). Un-skip both describe blocks; drop the vitest.config exclude. The web test job now runs both suites again. Co-Authored-By: Claude Opus 4.7 (1M context) --- web/src/routes/discover/discover.test.ts | 18 +++++++++++------- web/src/routes/requests/requests.test.ts | 15 +++++++++++---- web/vitest.config.ts | 14 +------------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/web/src/routes/discover/discover.test.ts b/web/src/routes/discover/discover.test.ts index c01b4580..b2d1c14f 100644 --- a/web/src/routes/discover/discover.test.ts +++ b/web/src/routes/discover/discover.test.ts @@ -3,6 +3,16 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/svelte'; import { mockQuery } from '../../test-utils/query'; import { apiClientMock } from '../../test-utils/mocks/client'; import type { LidarrSearchResult } from '$lib/api/types'; +import { pageUrlModule } from '../../test-utils/mocks/appState'; + +// $app/state / $app/navigation must be mocked or rendering the page +// pulls in SvelteKit's client runtime (`notifiable_store is not a +// function`) at module load. Same pattern as the other route tests. +const pageState = vi.hoisted(() => ({ + pageUrl: new URL('http://localhost/discover') +})); +vi.mock('$app/state', () => pageUrlModule(pageState)); +vi.mock('$app/navigation', () => ({ goto: vi.fn() })); // Lidarr search query factory and createRequest are mocked at the module // level so each test can shape what the page sees without standing up a @@ -56,13 +66,7 @@ afterEach(() => { vi.clearAllMocks(); }); -// FIXME(M7 #374): suite errors at module-load with -// `TypeError: notifiable_store is not a function` from SvelteKit's -// internal client.js. Surfaces only on the new dev-push CI; PR-to-main -// runs were green. Probably a vitest module-resolution interaction -// with a recent SvelteKit; needs targeted triage. Skipped to unblock -// CI for #372 — the page itself isn't broken, the test harness is. -describe.skip('Discover page', () => { +describe('Discover page', () => { test('initial state (no query) shows the suggestion feed', () => { render(DiscoverPage); expect(screen.getByText(/suggested for you/i)).toBeInTheDocument(); diff --git a/web/src/routes/requests/requests.test.ts b/web/src/routes/requests/requests.test.ts index 5639d09e..1178597d 100644 --- a/web/src/routes/requests/requests.test.ts +++ b/web/src/routes/requests/requests.test.ts @@ -3,6 +3,16 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/svelte'; import { mockQuery } from '../../test-utils/query'; import { apiClientMock } from '../../test-utils/mocks/client'; import type { LidarrRequest } from '$lib/api/types'; +import { pageUrlModule } from '../../test-utils/mocks/appState'; + +// $app/state / $app/navigation must be mocked or rendering the page +// pulls in SvelteKit's client runtime (`notifiable_store is not a +// function`) at module load. Same pattern as the other route tests. +const pageState = vi.hoisted(() => ({ + pageUrl: new URL('http://localhost/requests') +})); +vi.mock('$app/state', () => pageUrlModule(pageState)); +vi.mock('$app/navigation', () => ({ goto: vi.fn() })); // Capture invalidateQueries on the mocked QueryClient so the cancel test can // assert against the same instance the page consumed. Per-file mock OVERRIDES @@ -66,10 +76,7 @@ afterEach(() => { vi.clearAllMocks(); }); -// FIXME(M7 #374): same SvelteKit `notifiable_store is not a function` -// failure as discover.test.ts. Skipped to unblock CI for #372 — needs -// triage as a separate task. -describe.skip('Requests page', () => { +describe('Requests page', () => { test('renders one row per request from the API', () => { const rows: LidarrRequest[] = [ req({ id: 'r1', kind: 'artist', artist_name: 'Boards of Canada' }), diff --git a/web/vitest.config.ts b/web/vitest.config.ts index 9a071c45..f97aac5f 100644 --- a/web/vitest.config.ts +++ b/web/vitest.config.ts @@ -7,19 +7,7 @@ export default defineConfig({ test: { environment: 'jsdom', include: ['src/**/*.test.ts', 'src/**/*.svelte.test.ts', 'scripts/**/*.test.js'], - // M7 #374: these two test files explode at module-load with - // `TypeError: notifiable_store is not a function` from SvelteKit's - // internal client.js — the import chain triggers SvelteKit's client - // runtime init in a way the dev-push vitest invocation can't satisfy. - // describe.skip inside the files doesn't help because vitest must - // load the file before it can see the describe block. Excluded here - // until the triage in #374 lands a real fix (probably a $app/paths - // mock in vitest.setup.ts). - exclude: [ - ...configDefaults.exclude, - 'src/routes/discover/discover.test.ts', - 'src/routes/requests/requests.test.ts' - ], + exclude: [...configDefaults.exclude], setupFiles: ['./vitest.setup.ts'] } });