refactor(web/test): default svelte-query mock in vitest.setup; remove from 34 files (B3)

This commit is contained in:
2026-05-08 11:08:41 -04:00
parent 923b8286ee
commit 3e34f1f7b3
35 changed files with 12 additions and 192 deletions
@@ -41,14 +41,6 @@ const playlistsData = vi.hoisted(() => ({
public: [] as unknown[]
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return {
...actual,
useQueryClient: () => ({ invalidateQueries: vi.fn().mockResolvedValue(undefined) })
};
});
vi.mock('$lib/auth/store.svelte', () => ({
user: { value: { id: 'u-self', username: 'me', is_admin: false } }
}));
-5
View File
@@ -22,11 +22,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
vi.mock('$lib/api/albums', async (orig) => {
-5
View File
@@ -28,11 +28,6 @@ vi.mock('$lib/player/store.svelte', () => ({
enqueueTracks: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
import AlbumMenu from './AlbumMenu.svelte';
import { enqueueTracks } from '$lib/player/store.svelte';
import { listAlbumTracks } from '$lib/api/albums';
@@ -21,11 +21,6 @@ vi.mock('$lib/api/likes', async () => {
unlikeEntity: vi.fn().mockResolvedValue(undefined)
};
});
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
import ArtistCard from './ArtistCard.svelte';
import { api } from '$lib/api/client';
import { playQueue } from '$lib/player/store.svelte';
@@ -27,11 +27,6 @@ vi.mock('$lib/player/store.svelte', () => ({
enqueueTracks: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
import ArtistMenu from './ArtistMenu.svelte';
import { enqueueTracks } from '$lib/player/store.svelte';
import { listArtistTracks } from '$lib/api/artists';
@@ -34,11 +34,6 @@ vi.mock('$lib/auth/store.svelte', () => ({
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
vi.mock('$lib/player/store.svelte', () => ({
playQueue: vi.fn(),
enqueueTrack: vi.fn(),
@@ -12,14 +12,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn().mockResolvedValue(undefined)
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return {
...actual,
useQueryClient: () => ({})
};
});
import LikeButton from './LikeButton.svelte';
import { likeEntity, unlikeEntity } from '$lib/api/likes';
-5
View File
@@ -61,11 +61,6 @@ vi.mock('$lib/api/quarantine', () => ({
createMyQuarantineQuery: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import PlayerBar from './PlayerBar.svelte';
import {
togglePlay, skipNext, skipPrev, seekTo, setVolume,
@@ -7,14 +7,6 @@ vi.mock('$lib/auth/store.svelte', () => ({
user: { value: { id: 'u-self', username: 'me', is_admin: false } }
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return {
...actual,
useQueryClient: () => ({ invalidateQueries: vi.fn().mockResolvedValue(undefined) })
};
});
vi.mock('$lib/api/playlists', () => ({
getPlaylist: vi.fn().mockResolvedValue({
id: 'p-1',
@@ -46,11 +46,6 @@ vi.mock('$lib/player/store.svelte', () => ({
playRadio: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
import PlaylistTrackRow from './PlaylistTrackRow.svelte';
const live: PlaylistTrack = {
-5
View File
@@ -49,11 +49,6 @@ vi.mock('$lib/player/store.svelte', () => ({
enqueueTrack: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
import TrackMenu from './TrackMenu.svelte';
import { playNext, enqueueTrack } from '$lib/player/store.svelte';
-5
View File
@@ -26,11 +26,6 @@ vi.mock('$lib/api/quarantine', () => ({
createMyQuarantineQuery: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import TrackRow from './TrackRow.svelte';
import { playQueue, enqueueTrack, playRadio } from '$lib/player/store.svelte';
-8
View File
@@ -60,14 +60,6 @@ vi.mock('$lib/api/admin', async () => {
};
});
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return {
...actual,
useQueryClient: () => ({ invalidateQueries: vi.fn() })
};
});
afterEach(() => {
cleanup();
vi.clearAllMocks();
@@ -7,11 +7,6 @@ import type { CoverProvider, SMTPConfig } from '$lib/api/admin';
// useQueryClient is wrapped so the page can call invalidateQueries() without
// a real QueryClient context. Everything else from svelte-query passes through.
const invalidateQueries = vi.fn();
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries }) };
});
vi.mock('$lib/api/admin', () => ({
createLidarrConfigQuery: vi.fn(),
createQualityProfilesQuery: vi.fn(),
@@ -5,11 +5,6 @@ import type { AdminQuarantineRow } from '$lib/api/types';
// Wrap useQueryClient so the page can call invalidateQueries() without a real
// QueryClient context. Everything else from svelte-query passes through.
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
vi.mock('$lib/api/admin', () => ({
createAdminQuarantineQuery: vi.fn(),
resolveQuarantine: vi.fn(),
@@ -5,11 +5,6 @@ import type { LidarrRequest } from '$lib/api/types';
// Wrap useQueryClient so the page can call invalidateQueries() without a
// real QueryClient context. Everything else from svelte-query passes through.
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
vi.mock('$lib/api/admin', () => ({
createAdminRequestsQuery: vi.fn(),
createQualityProfilesQuery: vi.fn(),
-5
View File
@@ -5,11 +5,6 @@ import type { AdminUser, AdminInvite } from '$lib/api/admin';
// Wrap useQueryClient so the page can call invalidateQueries() without a real
// QueryClient context. Everything else from svelte-query passes through.
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
vi.mock('$lib/api/admin', () => ({
createAdminUsersQuery: vi.fn(),
createAdminInvitesQuery: vi.fn(),
-5
View File
@@ -29,11 +29,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import AlbumPage from './+page.svelte';
import { createAlbumQuery } from '$lib/api/queries';
@@ -29,11 +29,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import ArtistPage from './+page.svelte';
import { createArtistQuery } from '$lib/api/queries';
-5
View File
@@ -22,11 +22,6 @@ vi.mock('$lib/api/client', () => ({
api: { get: vi.fn(), post: vi.fn(), put: vi.fn(), del: vi.fn() }
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import DiscoverPage from './+page.svelte';
import { createLidarrSearchQuery } from '$lib/api/lidarr';
import { createSuggestionsQuery } from '$lib/api/suggestions';
@@ -40,11 +40,6 @@ vi.mock('$lib/api/likes', () => ({
// AlbumCard renders LikeButton, which calls useQueryClient() to get the
// cache for invalidation. The page test isn't wrapped in a QueryClientProvider,
// so we stub useQueryClient with a noop client.
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import Page from './+page.svelte';
describe('/library/albums', () => {
@@ -33,11 +33,6 @@ vi.mock('$lib/api/likes', () => ({
likeEntity: vi.fn().mockResolvedValue(undefined),
unlikeEntity: vi.fn().mockResolvedValue(undefined)
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
import Page from './+page.svelte';
describe('/library/artists', () => {
@@ -2,11 +2,6 @@ import { afterEach, describe, expect, test, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte';
import { mockQuery } from '../../../test-utils/query';
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
vi.mock('$lib/api/quarantine', () => ({
createMyQuarantineQuery: vi.fn(),
unflagTrack: vi.fn().mockResolvedValue(undefined)
@@ -17,11 +17,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
vi.mock('$lib/api/client', () => ({ api: { get: vi.fn() } }));
vi.mock('$lib/player/store.svelte', () => ({
playQueue: vi.fn(), enqueueTrack: vi.fn(), enqueueTracks: vi.fn()
-5
View File
@@ -36,11 +36,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn().mockResolvedValue(undefined)
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
import Page from './+page.svelte';
import { createPlaylistsQuery } from '$lib/api/playlists';
import { createSystemPlaylistsStatusQuery } from '$lib/api/me';
@@ -21,11 +21,6 @@ vi.mock('$lib/api/playlists', () => ({
refreshDiscover: vi.fn().mockResolvedValue({ playlist_id: 'p1', track_count: 5 })
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn().mockResolvedValue(undefined) }) };
});
vi.mock('$lib/auth/store.svelte', () => ({
user: { value: { id: 'u-self', username: 'me', is_admin: false } }
}));
@@ -8,14 +8,6 @@ vi.mock('$lib/api/playlists', () => ({
createPlaylist: vi.fn().mockResolvedValue({ id: 'p-new', name: 'X' })
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return {
...actual,
useQueryClient: () => ({ invalidateQueries: vi.fn().mockResolvedValue(undefined) })
};
});
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
import PlaylistsPage from './+page.svelte';
-8
View File
@@ -22,14 +22,6 @@ vi.mock('$lib/api/client', () => ({
api: { get: vi.fn(), post: vi.fn(), put: vi.fn(), del: vi.fn() }
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return {
...actual,
useQueryClient: () => ({ invalidateQueries })
};
});
import RequestsPage from './+page.svelte';
import { createMyRequestsQuery, cancelRequest } from '$lib/api/requests';
import { qk } from '$lib/api/queries';
@@ -31,11 +31,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import AlbumsOverflow from './+page.svelte';
import { createSearchAlbumsInfiniteQuery } from '$lib/api/queries';
@@ -24,11 +24,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import ArtistsOverflow from './+page.svelte';
import { createSearchArtistsInfiniteQuery } from '$lib/api/queries';
-5
View File
@@ -37,11 +37,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
import SearchPage from './+page.svelte';
import { createSearchQuery } from '$lib/api/queries';
@@ -30,11 +30,6 @@ vi.mock('$lib/api/likes', () => ({
unlikeEntity: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({}) };
});
vi.mock('$lib/api/quarantine', () => ({
flagTrack: vi.fn(),
unflagTrack: vi.fn(),
@@ -25,11 +25,6 @@ vi.mock('$lib/api/listenbrainz', () => {
};
});
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
beforeEach(() => {
globalThis.localStorage.clear();
document.documentElement.removeAttribute('data-theme');
-8
View File
@@ -20,14 +20,6 @@ vi.mock('$lib/api/me', () => ({
regenerateAPIToken: vi.fn()
}));
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return {
...actual,
useQueryClient: () => ({ invalidateQueries: vi.fn() })
};
});
import SettingsPage from './+page.svelte';
import {
createLBStatusQuery,
+12 -1
View File
@@ -1,9 +1,20 @@
import '@testing-library/jest-dom/vitest';
import { beforeEach, afterEach } from 'vitest';
import { beforeEach, afterEach, vi } from 'vitest';
import { render } from '@testing-library/svelte';
import ToastHost from './src/lib/components/ToastHost.svelte';
import { clearToast } from './src/lib/stores/toast.svelte';
// Default svelte-query mock for the whole test suite. Most component
// tests just need useQueryClient to return SOMETHING — they never assert
// on the result. Tests that need to assert on invalidateQueries (named
// mock pattern) override this with their own per-file vi.mock. The
// override wins because per-file mocks take precedence over setup-file
// mocks in vitest.
vi.mock('@tanstack/svelte-query', async (orig) => {
const actual = (await orig()) as Record<string, unknown>;
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
});
// Node 25 ships a partial localStorage global that lacks getItem/setItem/clear
// unless launched with --localstorage-file. jsdom sees Node's global and skips
// installing its own. Replace with an in-memory Storage-compatible polyfill so