chore(deps): SvelteKit 3 with adapter-static 4 and TypeScript 6, full-tree npm audit (#5021)
Merges Renovate's kit 3 (PR #149) and adapter-static 4 (PR #148) bumps, plus the migration they need. The mechanical part is `sv migrate sveltekit-3`, run one task at a time and reviewed: - svelte.config.js is gone. Its options move into sveltekit() in vite.config.ts, exported as kitOptions so vitest.config.ts runs the same kit setup, including the $test-utils alias the tests import. - $lib becomes #lib through package.json "imports". There is no src/lib/index, so only the "#lib/*" entry is kept. - tsconfig extends $app/tsconfig. - Peer floors raised to kit 3's requirements: svelte ^5.57.1, vite ^8.0.12, svelte-check ^4.7.5. By hand, from the codemod's list of non-automated tasks: - goto's replaceState option is now replace; keepFocus becomes reset: false. For the search typeahead, reset: false also stops the scroll-to-top, which is wanted while typing. - The test setup mocks drop pushState/replaceState and $app/paths base/assets, which kit 3 removed, and mock refreshAll in place of invalidateAll. - The other flagged files only read page.url or goto internal routes, so they needed no change. TypeScript goes to ^6, not the ^7 Renovate offers: kit 3 declares typescript ^6 as a peer and svelte-check 4.7 accepts ^5 || ^6. Move to 7 once both accept it. With Tailwind 4 and kit 3 in, `npm audit` on the whole tree reports 0, so the web lane now audits every dependency rather than only what ships to browsers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,14 +3,14 @@
|
||||
import { page } from '$app/state';
|
||||
import { goto } from '$app/navigation';
|
||||
import { QueryClientProvider } from '@tanstack/svelte-query';
|
||||
import { queryClient } from '$lib/query/client';
|
||||
import { user } from '$lib/auth/store.svelte';
|
||||
import { isPublicRoute } from '$lib/auth/publicRoutes';
|
||||
import Shell from '$lib/components/Shell.svelte';
|
||||
import QueueDrawer from '$lib/components/QueueDrawer.svelte';
|
||||
import SelectionBar from '$lib/components/SelectionBar.svelte';
|
||||
import ToastHost from '$lib/components/ToastHost.svelte';
|
||||
import { selection, clearSelection } from '$lib/selection/store.svelte';
|
||||
import { queryClient } from '#lib/query/client.js';
|
||||
import { user } from '#lib/auth/store.svelte.js';
|
||||
import { isPublicRoute } from '#lib/auth/publicRoutes.js';
|
||||
import Shell from '#lib/components/Shell.svelte';
|
||||
import QueueDrawer from '#lib/components/QueueDrawer.svelte';
|
||||
import SelectionBar from '#lib/components/SelectionBar.svelte';
|
||||
import ToastHost from '#lib/components/ToastHost.svelte';
|
||||
import { selection, clearSelection } from '#lib/selection/store.svelte.js';
|
||||
import {
|
||||
registerAudioEl,
|
||||
reportTimeUpdate,
|
||||
@@ -20,21 +20,21 @@
|
||||
closeQueueDrawer,
|
||||
consumePendingRestorePosition,
|
||||
deriveFadeScalar
|
||||
} from '$lib/player/store.svelte';
|
||||
import { useMediaSession } from '$lib/player/mediaSession.svelte';
|
||||
import { useEventsDispatcher } from '$lib/player/events.svelte';
|
||||
import { useServerEvents } from '$lib/serverEvents.svelte';
|
||||
import { useGlobalShortcuts } from '$lib/player/shortcuts.svelte';
|
||||
import { applyMetaThemeColor } from '$lib/theme/applyMetaThemeColor.svelte';
|
||||
import { audioLoader } from '$lib/player/audioLoader';
|
||||
import { attachStallRetry } from '$lib/player/stallRetry';
|
||||
} from '#lib/player/store.svelte.js';
|
||||
import { useMediaSession } from '#lib/player/mediaSession.svelte.js';
|
||||
import { useEventsDispatcher } from '#lib/player/events.svelte.js';
|
||||
import { useServerEvents } from '#lib/serverEvents.svelte.js';
|
||||
import { useGlobalShortcuts } from '#lib/player/shortcuts.svelte.js';
|
||||
import { applyMetaThemeColor } from '#lib/theme/applyMetaThemeColor.svelte.js';
|
||||
import { audioLoader } from '#lib/player/audioLoader.js';
|
||||
import { attachStallRetry } from '#lib/player/stallRetry.js';
|
||||
import {
|
||||
applyGain,
|
||||
ensureGains,
|
||||
ensureGraph,
|
||||
gainDbAt,
|
||||
resumeGraph
|
||||
} from '$lib/player/gainStage.svelte';
|
||||
} from '#lib/player/gainStage.svelte.js';
|
||||
import { untrack } from 'svelte';
|
||||
|
||||
let { children } = $props<{ children: import('svelte').Snippet }>();
|
||||
@@ -47,9 +47,9 @@
|
||||
const isPublic = isPublicRoute(path);
|
||||
if (user.value === null && !isPublic) {
|
||||
const returnTo = path + page.url.search;
|
||||
goto('/login?returnTo=' + encodeURIComponent(returnTo), { replaceState: true });
|
||||
goto('/login?returnTo=' + encodeURIComponent(returnTo), { replace: true });
|
||||
} else if (user.value !== null && isPublic) {
|
||||
goto('/', { replaceState: true });
|
||||
goto('/', { replace: true });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { bootstrap, user } from '$lib/auth/store.svelte';
|
||||
import { restoreQueue } from '$lib/player/store.svelte';
|
||||
import { loadNormalization } from '$lib/stores/normalization.svelte';
|
||||
import { bootstrap, user } from '#lib/auth/store.svelte.js';
|
||||
import { restoreQueue } from '#lib/player/store.svelte.js';
|
||||
import { loadNormalization } from '#lib/stores/normalization.svelte.js';
|
||||
|
||||
export const ssr = false; // adapter-static fallback; we're SPA-only
|
||||
export const prerender = false;
|
||||
|
||||
+20
-20
@@ -1,17 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { createHomeQuery } from '$lib/api/home';
|
||||
import HorizontalScrollRow from '$lib/components/HorizontalScrollRow.svelte';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import ArtistCard from '$lib/components/ArtistCard.svelte';
|
||||
import CompactTrackCard from '$lib/components/CompactTrackCard.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import PlaylistCard from '$lib/components/PlaylistCard.svelte';
|
||||
import PlaylistPlaceholderCard from '$lib/components/PlaylistPlaceholderCard.svelte';
|
||||
import { createPlaylistsQuery } from '$lib/api/playlists';
|
||||
import { createSystemPlaylistsStatusQuery } from '$lib/api/me';
|
||||
import type { Playlist } from '$lib/api/types';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { createHomeQuery } from '#lib/api/home.js';
|
||||
import HorizontalScrollRow from '#lib/components/HorizontalScrollRow.svelte';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import ArtistCard from '#lib/components/ArtistCard.svelte';
|
||||
import CompactTrackCard from '#lib/components/CompactTrackCard.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
import PlaylistCard from '#lib/components/PlaylistCard.svelte';
|
||||
import PlaylistPlaceholderCard from '#lib/components/PlaylistPlaceholderCard.svelte';
|
||||
import { createPlaylistsQuery } from '#lib/api/playlists.js';
|
||||
import { createSystemPlaylistsStatusQuery } from '#lib/api/me.js';
|
||||
import type { Playlist } from '#lib/api/types.js';
|
||||
|
||||
const queryStore = createHomeQuery();
|
||||
const query = $derived($queryStore);
|
||||
@@ -212,7 +212,7 @@
|
||||
title="You might like"
|
||||
ariaLabel="You might like albums"
|
||||
>
|
||||
{#snippet item(album: import('$lib/api/types').AlbumRef)}
|
||||
{#snippet item(album: import('#lib/api/types.js').AlbumRef)}
|
||||
<div class="w-40"><AlbumCard {album} /></div>
|
||||
{/snippet}
|
||||
</HorizontalScrollRow>
|
||||
@@ -223,7 +223,7 @@
|
||||
title={data.you_might_like_albums.length === 0 ? 'You might like' : undefined}
|
||||
ariaLabel="You might like artists"
|
||||
>
|
||||
{#snippet item(artist: import('$lib/api/types').ArtistRef)}
|
||||
{#snippet item(artist: import('#lib/api/types.js').ArtistRef)}
|
||||
<div class="w-36"><ArtistCard {artist} /></div>
|
||||
{/snippet}
|
||||
</HorizontalScrollRow>
|
||||
@@ -244,7 +244,7 @@
|
||||
title="Recently added"
|
||||
ariaLabel="Recently added"
|
||||
>
|
||||
{#snippet item(album: import('$lib/api/types').AlbumRef)}
|
||||
{#snippet item(album: import('#lib/api/types.js').AlbumRef)}
|
||||
<div class="w-48"><AlbumCard {album} /></div>
|
||||
{/snippet}
|
||||
</HorizontalScrollRow>
|
||||
@@ -267,7 +267,7 @@
|
||||
title="Rediscover"
|
||||
ariaLabel="Rediscover albums"
|
||||
>
|
||||
{#snippet item(album: import('$lib/api/types').AlbumRef)}
|
||||
{#snippet item(album: import('#lib/api/types.js').AlbumRef)}
|
||||
<!-- Rediscover sits below Recently Added in the size
|
||||
hierarchy. w-40 keeps it readable without competing
|
||||
with the freshest content above. -->
|
||||
@@ -281,7 +281,7 @@
|
||||
title={data.rediscover_albums.length === 0 ? 'Rediscover' : undefined}
|
||||
ariaLabel="Rediscover artists"
|
||||
>
|
||||
{#snippet item(artist: import('$lib/api/types').ArtistRef)}
|
||||
{#snippet item(artist: import('#lib/api/types.js').ArtistRef)}
|
||||
<div class="w-36"><ArtistCard {artist} /></div>
|
||||
{/snippet}
|
||||
</HorizontalScrollRow>
|
||||
@@ -302,7 +302,7 @@
|
||||
title="Most played"
|
||||
ariaLabel="Most played"
|
||||
>
|
||||
{#snippet item(track: import('$lib/api/types').TrackRef, globalIdx: number)}
|
||||
{#snippet item(track: import('#lib/api/types.js').TrackRef, globalIdx: number)}
|
||||
<CompactTrackCard
|
||||
{track}
|
||||
sectionTracks={data.most_played_tracks}
|
||||
@@ -326,7 +326,7 @@
|
||||
title="Last played"
|
||||
ariaLabel="Last played artists"
|
||||
>
|
||||
{#snippet item(artist: import('$lib/api/types').ArtistRef)}
|
||||
{#snippet item(artist: import('#lib/api/types.js').ArtistRef)}
|
||||
<div class="w-36"><ArtistCard {artist} /></div>
|
||||
{/snippet}
|
||||
</HorizontalScrollRow>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import AdminTabs from '$lib/components/AdminTabs.svelte';
|
||||
import AdminTabs from '#lib/components/AdminTabs.svelte';
|
||||
|
||||
let { children } = $props<{ children: import('svelte').Snippet }>();
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { user } from '$lib/auth/store.svelte';
|
||||
import { user } from '#lib/auth/store.svelte.js';
|
||||
import type { LayoutLoad } from './$types';
|
||||
|
||||
// Hard route gate: runs before the layout (and any child page) renders.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Disc3, Album, Music2, Check, X, RotateCcw, Trash2, Cloud, ChevronRight } from 'lucide-svelte';
|
||||
import StageBadge from '$lib/components/StageBadge.svelte';
|
||||
import LoudnessSettingsCard from '$lib/components/LoudnessSettingsCard.svelte';
|
||||
import StageBadge from '#lib/components/StageBadge.svelte';
|
||||
import LoudnessSettingsCard from '#lib/components/LoudnessSettingsCard.svelte';
|
||||
import { stageState } from './stage-state';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import {
|
||||
@@ -20,17 +20,17 @@
|
||||
refetchMissingCovers,
|
||||
triggerScan,
|
||||
researchMissingArt
|
||||
} from '$lib/api/admin';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import { runMutation } from '$lib/util/runMutation';
|
||||
} from '#lib/api/admin.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { errCode } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import { runMutation } from '#lib/util/runMutation.js';
|
||||
import type {
|
||||
AdminQuarantineRow,
|
||||
LidarrRequest,
|
||||
LidarrRequestKind,
|
||||
LidarrQuarantineReason
|
||||
} from '$lib/api/types';
|
||||
} from '#lib/api/types.js';
|
||||
|
||||
// Top-of-admin overview. Shows the connection card + the most recent
|
||||
// 5 of each actionable queue (requests, quarantine) with inline
|
||||
|
||||
@@ -8,7 +8,7 @@ const userState = vi.hoisted(() => ({
|
||||
current: null as { id: string; username: string; is_admin: boolean } | null
|
||||
}));
|
||||
|
||||
vi.mock('$lib/auth/store.svelte', () => ({
|
||||
vi.mock('#lib/auth/store.svelte.js', () => ({
|
||||
user: { get value() { return userState.current; } }
|
||||
}));
|
||||
|
||||
@@ -16,7 +16,7 @@ vi.mock('$app/state', () => ({
|
||||
page: { url: new URL('http://localhost/admin') }
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/admin', async () => {
|
||||
vi.mock('#lib/api/admin.js', async () => {
|
||||
const { readable } = await import('svelte/store');
|
||||
return {
|
||||
createAdminRequestsQuery: vi.fn(),
|
||||
@@ -106,7 +106,7 @@ import {
|
||||
deleteQuarantineFile,
|
||||
deleteQuarantineViaLidarr,
|
||||
researchMissingArt
|
||||
} from '$lib/api/admin';
|
||||
} from '#lib/api/admin.js';
|
||||
import OverviewPage from './+page.svelte';
|
||||
|
||||
function setupOverview(opts: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Copy, Download, Activity } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import {
|
||||
@@ -9,10 +9,10 @@
|
||||
updateUserDebugMode,
|
||||
type AdminDiagnostic,
|
||||
type DiagnosticsFilter
|
||||
} from '$lib/api/admin';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { errMessage } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
} from '#lib/api/admin.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { errMessage } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
|
||||
// Device diagnostics timeline (M9). The operator enables debug-mode on
|
||||
// an account (remotely, here), then watches the account's device(s)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Copy, TriangleAlert } from 'lucide-svelte';
|
||||
import {
|
||||
createDuplicatesQuery,
|
||||
runDuplicateSweep,
|
||||
dismissDuplicateGroup,
|
||||
mergeDuplicateGroup
|
||||
} from '$lib/api/admin';
|
||||
import { errMessage } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import { relativeTime } from '$lib/utils/relativeTime';
|
||||
import type { AdminDuplicateGroup, AdminDuplicateMember } from '$lib/api/types';
|
||||
import FingerprintSettingsCard from '$lib/components/FingerprintSettingsCard.svelte';
|
||||
} from '#lib/api/admin.js';
|
||||
import { errMessage } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import { relativeTime } from '#lib/utils/relativeTime.js';
|
||||
import type { AdminDuplicateGroup, AdminDuplicateMember } from '#lib/api/types.js';
|
||||
import FingerprintSettingsCard from '#lib/components/FingerprintSettingsCard.svelte';
|
||||
|
||||
// Tracks the duplicate sweep believes hold one recording (#3912). Dismissing a
|
||||
// group says "these are not duplicates", and the sweep will not propose that
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { fireEvent, render, screen } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import type { AdminDuplicatesResponse } from '$lib/api/types';
|
||||
import type { AdminDuplicatesResponse } from '#lib/api/types.js';
|
||||
|
||||
vi.mock('$lib/api/admin', () => ({
|
||||
vi.mock('#lib/api/admin.js', () => ({
|
||||
createDuplicatesQuery: vi.fn(),
|
||||
runDuplicateSweep: vi.fn().mockResolvedValue({ started: true }),
|
||||
dismissDuplicateGroup: vi.fn().mockResolvedValue(undefined),
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
dismissDuplicateGroup,
|
||||
mergeDuplicateGroup,
|
||||
runDuplicateSweep
|
||||
} from '$lib/api/admin';
|
||||
} from '#lib/api/admin.js';
|
||||
|
||||
const HOUR = 3_600_000;
|
||||
const ago = (ms: number) => new Date(Date.now() - ms).toISOString();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { tick } from 'svelte';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Save, RefreshCw, Trash2 } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import {
|
||||
@@ -22,16 +22,16 @@
|
||||
type CoverProvider,
|
||||
type TagProvider,
|
||||
type SMTPConfig
|
||||
} from '$lib/api/admin';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import Modal from '$lib/components/Modal.svelte';
|
||||
import AcoustIDCard from '$lib/components/AcoustIDCard.svelte';
|
||||
import NetworkSettingsCard from '$lib/components/NetworkSettingsCard.svelte';
|
||||
import PublicAddressCard from '$lib/components/PublicAddressCard.svelte';
|
||||
import NotificationEmailCard from '$lib/components/NotificationEmailCard.svelte';
|
||||
import type { LidarrConfig, LidarrTestResult } from '$lib/api/types';
|
||||
} from '#lib/api/admin.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { errCode } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import Modal from '#lib/components/Modal.svelte';
|
||||
import AcoustIDCard from '#lib/components/AcoustIDCard.svelte';
|
||||
import NetworkSettingsCard from '#lib/components/NetworkSettingsCard.svelte';
|
||||
import PublicAddressCard from '#lib/components/PublicAddressCard.svelte';
|
||||
import NotificationEmailCard from '#lib/components/NotificationEmailCard.svelte';
|
||||
import type { LidarrConfig, LidarrTestResult } from '#lib/api/types.js';
|
||||
|
||||
// Lidarr connection panel. The "saved api key" is masked as "***" on GET —
|
||||
// never displayed in the input. The input always starts empty; sending an
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor, within } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import type { LidarrConfig } from '$lib/api/types';
|
||||
import type { CoverProvider, TagProvider, SMTPConfig } from '$lib/api/admin';
|
||||
import type { LidarrConfig } from '#lib/api/types.js';
|
||||
import type { CoverProvider, TagProvider, SMTPConfig } from '#lib/api/admin.js';
|
||||
|
||||
// useQueryClient is wrapped so the page can call invalidateQueries() without
|
||||
// a real QueryClient context. Per-file mock OVERRIDES the vitest.setup default
|
||||
@@ -13,7 +13,7 @@ vi.mock('@tanstack/svelte-query', async (orig) => {
|
||||
return { ...actual, useQueryClient: () => ({ invalidateQueries }) };
|
||||
});
|
||||
|
||||
vi.mock('$lib/api/admin', () => ({
|
||||
vi.mock('#lib/api/admin.js', () => ({
|
||||
createLidarrConfigQuery: vi.fn(),
|
||||
createQualityProfilesQuery: vi.fn(),
|
||||
createMetadataProfilesQuery: vi.fn(),
|
||||
@@ -57,7 +57,7 @@ import {
|
||||
createSMTPConfigQuery,
|
||||
updateSMTPConfig,
|
||||
testSMTPConfig
|
||||
} from '$lib/api/admin';
|
||||
} from '#lib/api/admin.js';
|
||||
|
||||
const cfgConnected: LidarrConfig = {
|
||||
enabled: true,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { FolderX, Music2 } from 'lucide-svelte';
|
||||
import { createMissingFilesQuery } from '$lib/api/admin';
|
||||
import { relativeTime, timeUntil } from '$lib/utils/relativeTime';
|
||||
import { coverUrl } from '$lib/media/covers';
|
||||
import ReacquisitionSettingsCard from '$lib/components/ReacquisitionSettingsCard.svelte';
|
||||
import type { AdminMissingGroup } from '$lib/api/types';
|
||||
import { createMissingFilesQuery } from '#lib/api/admin.js';
|
||||
import { relativeTime, timeUntil } from '#lib/utils/relativeTime.js';
|
||||
import { coverUrl } from '#lib/media/covers.js';
|
||||
import ReacquisitionSettingsCard from '#lib/components/ReacquisitionSettingsCard.svelte';
|
||||
import type { AdminMissingGroup } from '#lib/api/types.js';
|
||||
|
||||
// Files the scan looked for and could not find. Read-only on purpose:
|
||||
// a missing file keeps its track row, its play history and its likes,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import type { AdminMissingResponse } from '$lib/api/types';
|
||||
import type { AdminMissingResponse } from '#lib/api/types.js';
|
||||
|
||||
// The page now embeds ReacquisitionSettingsCard, which loads its own settings
|
||||
// from this same module on mount. Stubbing both keeps these tests about the
|
||||
// missing-files list — the card has its own suite.
|
||||
vi.mock('$lib/api/admin', () => ({
|
||||
vi.mock('#lib/api/admin.js', () => ({
|
||||
createMissingFilesQuery: vi.fn(),
|
||||
getReacquisitionSettings: vi.fn().mockResolvedValue({
|
||||
enabled: true,
|
||||
@@ -22,7 +22,7 @@ vi.mock('$lib/api/admin', () => ({
|
||||
}));
|
||||
|
||||
import AdminMissingFilesPage from './+page.svelte';
|
||||
import { createMissingFilesQuery } from '$lib/api/admin';
|
||||
import { createMissingFilesQuery } from '#lib/api/admin.js';
|
||||
|
||||
const DAY = 24 * 3_600_000;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { stageState } from './stage-state';
|
||||
import type { ScanStatus } from '$lib/api/admin';
|
||||
import type { ScanStatus } from '#lib/api/admin.js';
|
||||
|
||||
const FINISHED_AT = '2026-05-06T12:00:00Z';
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Copy, Trash2, CheckCircle2 } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import RowActionsMenu, { type RowAction } from '$lib/components/RowActionsMenu.svelte';
|
||||
import RowActionsMenu, { type RowAction } from '#lib/components/RowActionsMenu.svelte';
|
||||
import {
|
||||
createAdminPlaybackErrorsQuery,
|
||||
resolvePlaybackError,
|
||||
deleteQuarantineFile
|
||||
} from '$lib/api/admin';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { errMessage } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import Modal from '$lib/components/Modal.svelte';
|
||||
import type { AdminPlaybackError, PlaybackErrorResolution } from '$lib/api/types';
|
||||
import { relativeTime } from '$lib/utils/relativeTime';
|
||||
} from '#lib/api/admin.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { errMessage } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import Modal from '#lib/components/Modal.svelte';
|
||||
import type { AdminPlaybackError, PlaybackErrorResolution } from '#lib/api/types.js';
|
||||
import { relativeTime } from '#lib/utils/relativeTime.js';
|
||||
|
||||
// Client-reported playback errors inbox. Two tabs — Unresolved
|
||||
// (default) / Resolved. Per-row: copy details to clipboard, delete
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Music2, RotateCcw, Trash2, Cloud, Play, ChevronRight } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import RowActionsMenu, { type RowAction } from '$lib/components/RowActionsMenu.svelte';
|
||||
import RowActionsMenu, { type RowAction } from '#lib/components/RowActionsMenu.svelte';
|
||||
import {
|
||||
createAdminQuarantineQuery,
|
||||
resolveQuarantine,
|
||||
deleteQuarantineFile,
|
||||
deleteQuarantineViaLidarr
|
||||
} from '$lib/api/admin';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { errMessage } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import { playRadio } from '$lib/player/store.svelte';
|
||||
import { coverUrl } from '$lib/media/covers';
|
||||
import Modal from '$lib/components/Modal.svelte';
|
||||
import type { AdminQuarantineRow, LidarrQuarantineReason } from '$lib/api/types';
|
||||
import { relativeTime } from '$lib/utils/relativeTime';
|
||||
} from '#lib/api/admin.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { errMessage } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import { playRadio } from '#lib/player/store.svelte.js';
|
||||
import { coverUrl } from '#lib/media/covers.js';
|
||||
import Modal from '#lib/components/Modal.svelte';
|
||||
import type { AdminQuarantineRow, LidarrQuarantineReason } from '#lib/api/types.js';
|
||||
import { relativeTime } from '#lib/utils/relativeTime.js';
|
||||
|
||||
// Aggregated triage queue. One row per track, with per-row resolution
|
||||
// actions: Resolve (clears reports), Delete file (Bronze; modal-confirm),
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import type { AdminQuarantineRow } from '$lib/api/types';
|
||||
import type { AdminQuarantineRow } from '#lib/api/types.js';
|
||||
|
||||
// Wrap useQueryClient so the page can call invalidateQueries() without a real
|
||||
// QueryClient context. Everything else from svelte-query passes through.
|
||||
vi.mock('$lib/api/admin', () => ({
|
||||
vi.mock('#lib/api/admin.js', () => ({
|
||||
createAdminQuarantineQuery: vi.fn(),
|
||||
resolveQuarantine: vi.fn(),
|
||||
deleteQuarantineFile: vi.fn(),
|
||||
deleteQuarantineViaLidarr: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playRadio: vi.fn()
|
||||
}));
|
||||
|
||||
@@ -22,8 +22,8 @@ import {
|
||||
resolveQuarantine,
|
||||
deleteQuarantineFile,
|
||||
deleteQuarantineViaLidarr
|
||||
} from '$lib/api/admin';
|
||||
import { playRadio } from '$lib/player/store.svelte';
|
||||
} from '#lib/api/admin.js';
|
||||
import { playRadio } from '#lib/player/store.svelte.js';
|
||||
|
||||
const baseRow: AdminQuarantineRow = {
|
||||
track_id: 't-001',
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Disc3, Album, Music2, Check, X, SlidersHorizontal } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import RowActionsMenu, { type RowAction } from '$lib/components/RowActionsMenu.svelte';
|
||||
import RowActionsMenu, { type RowAction } from '#lib/components/RowActionsMenu.svelte';
|
||||
import {
|
||||
createAdminRequestsQuery,
|
||||
createQualityProfilesQuery,
|
||||
createRootFoldersQuery,
|
||||
approveRequest,
|
||||
rejectRequest
|
||||
} from '$lib/api/admin';
|
||||
import { errMessage } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import StatusPill from '$lib/components/StatusPill.svelte';
|
||||
import Modal from '$lib/components/Modal.svelte';
|
||||
import type { LidarrRequest, LidarrRequestKind, LidarrRequestStatus } from '$lib/api/types';
|
||||
} from '#lib/api/admin.js';
|
||||
import { errMessage } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import StatusPill from '#lib/components/StatusPill.svelte';
|
||||
import Modal from '#lib/components/Modal.svelte';
|
||||
import type { LidarrRequest, LidarrRequestKind, LidarrRequestStatus } from '#lib/api/types.js';
|
||||
|
||||
// Approval queue. Tabs filter by status; rows expose Override/Approve/Reject
|
||||
// per spec. The override modal collapses by default — most requests get the
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import type { LidarrRequest } from '$lib/api/types';
|
||||
import type { LidarrRequest } from '#lib/api/types.js';
|
||||
|
||||
// Wrap useQueryClient so the page can call invalidateQueries() without a
|
||||
// real QueryClient context. Everything else from svelte-query passes through.
|
||||
vi.mock('$lib/api/admin', () => ({
|
||||
vi.mock('#lib/api/admin.js', () => ({
|
||||
createAdminRequestsQuery: vi.fn(),
|
||||
createQualityProfilesQuery: vi.fn(),
|
||||
createRootFoldersQuery: vi.fn(),
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
createRootFoldersQuery,
|
||||
approveRequest,
|
||||
rejectRequest
|
||||
} from '$lib/api/admin';
|
||||
} from '#lib/api/admin.js';
|
||||
|
||||
const baseRow: LidarrRequest = {
|
||||
id: 'r1',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ScanStatus } from '$lib/api/admin';
|
||||
import type { ScanStatus } from '#lib/api/admin.js';
|
||||
|
||||
export type StageState = 'pending' | 'in_progress' | 'done' | 'skipped';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import {
|
||||
getTuning,
|
||||
patchTuning,
|
||||
@@ -14,9 +14,9 @@
|
||||
type TrendsResponse,
|
||||
type TrendSeries,
|
||||
type TrendMarker
|
||||
} from '$lib/api/tuning';
|
||||
import { errMessage } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
} from '#lib/api/tuning.js';
|
||||
import { errMessage } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
|
||||
// The defaults-discovery lab (#1250): DB-backed scoring-weight
|
||||
// profiles + taste-build knobs with live effect. This card exists to
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, test, vi, beforeEach } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
import type { TuningSnapshot, TrendsResponse } from '$lib/api/tuning';
|
||||
import type { TuningSnapshot, TrendsResponse } from '#lib/api/tuning.js';
|
||||
|
||||
vi.mock('$lib/api/tuning', async (orig) => {
|
||||
vi.mock('#lib/api/tuning.js', async (orig) => {
|
||||
const actual = (await orig()) as Record<string, unknown>;
|
||||
return {
|
||||
...actual,
|
||||
@@ -14,10 +14,10 @@ vi.mock('$lib/api/tuning', async (orig) => {
|
||||
});
|
||||
|
||||
const pushToast = vi.fn();
|
||||
vi.mock('$lib/stores/toast.svelte', () => ({ pushToast: (...a: unknown[]) => pushToast(...a) }));
|
||||
vi.mock('#lib/stores/toast.svelte.js', () => ({ pushToast: (...a: unknown[]) => pushToast(...a) }));
|
||||
|
||||
import TuningPage from './+page.svelte';
|
||||
import { getTuning, patchTuning, resetTuning, getTrends } from '$lib/api/tuning';
|
||||
import { getTuning, patchTuning, resetTuning, getTrends } from '#lib/api/tuning.js';
|
||||
|
||||
const weights = (over: Partial<Record<string, number>> = {}) => ({
|
||||
base_weight: 1,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import {
|
||||
updateUserAdmin,
|
||||
createInvite,
|
||||
@@ -15,11 +15,11 @@
|
||||
type AdminUser,
|
||||
type AdminInvite,
|
||||
type CreateUserInput
|
||||
} from '$lib/api/admin';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import Modal from '$lib/components/Modal.svelte';
|
||||
import RowActionsMenu, { type RowAction } from '$lib/components/RowActionsMenu.svelte';
|
||||
} from '#lib/api/admin.js';
|
||||
import { errCode } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import Modal from '#lib/components/Modal.svelte';
|
||||
import RowActionsMenu, { type RowAction } from '#lib/components/RowActionsMenu.svelte';
|
||||
import { Shield, ShieldOff, CheckCircle2, XCircle, KeyRound, Trash2, Copy } from 'lucide-svelte';
|
||||
|
||||
const client = useQueryClient();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import type { AdminUser, AdminInvite } from '$lib/api/admin';
|
||||
import type { AdminUser, AdminInvite } from '#lib/api/admin.js';
|
||||
|
||||
// Wrap useQueryClient so the page can call invalidateQueries() without a real
|
||||
// QueryClient context. Everything else from svelte-query passes through.
|
||||
vi.mock('$lib/api/admin', () => ({
|
||||
vi.mock('#lib/api/admin.js', () => ({
|
||||
createAdminUsersQuery: vi.fn(),
|
||||
createAdminInvitesQuery: vi.fn(),
|
||||
listUsers: vi.fn(),
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
deleteUser,
|
||||
resetUserPassword,
|
||||
updateUserAutoApprove
|
||||
} from '$lib/api/admin';
|
||||
} from '#lib/api/admin.js';
|
||||
|
||||
const alice: AdminUser = {
|
||||
id: 'u1',
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { Play, Shuffle } from 'lucide-svelte';
|
||||
import { page } from '$app/state';
|
||||
import { createAlbumQuery } from '$lib/api/queries';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import TrackRow from '$lib/components/TrackRow.svelte';
|
||||
import LibrarySkeleton from '$lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import LikeButton from '$lib/components/LikeButton.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import { formatDuration } from '$lib/media/duration';
|
||||
import { FALLBACK_COVER } from '$lib/media/covers';
|
||||
import type { ApiError } from '$lib/api/client';
|
||||
import { playQueue } from '$lib/player/store.svelte';
|
||||
import { user } from '$lib/auth/store.svelte';
|
||||
import { refetchAlbumCover } from '$lib/api/admin';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { createAlbumQuery } from '#lib/api/queries.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import TrackRow from '#lib/components/TrackRow.svelte';
|
||||
import LibrarySkeleton from '#lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import LikeButton from '#lib/components/LikeButton.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
import { formatDuration } from '#lib/media/duration.js';
|
||||
import { FALLBACK_COVER } from '#lib/media/covers.js';
|
||||
import type { ApiError } from '#lib/api/client.js';
|
||||
import { playQueue } from '#lib/player/store.svelte.js';
|
||||
import { user } from '#lib/auth/store.svelte.js';
|
||||
import { refetchAlbumCover } from '#lib/api/admin.js';
|
||||
import { errCode } from '#lib/api/errors.js';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
|
||||
const id = $derived(page.params.id ?? '');
|
||||
|
||||
@@ -3,7 +3,7 @@ import { render, screen } from '@testing-library/svelte';
|
||||
import { flushSync } from 'svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import { emptyLikesMock } from '../../../test-utils/mocks/likes';
|
||||
import type { AlbumDetail, TrackRef } from '$lib/api/types';
|
||||
import type { AlbumDetail, TrackRef } from '#lib/api/types.js';
|
||||
import { makeTrack } from '$test-utils/fixtures/track';
|
||||
|
||||
const state = vi.hoisted(() => ({ pageParams: { id: 'xyz' } as Record<string, string> }));
|
||||
@@ -15,15 +15,15 @@ vi.mock('$app/state', () => ({
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
qk: { album: (id: string) => ['album', id] },
|
||||
createAlbumQuery: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
|
||||
import AlbumPage from './+page.svelte';
|
||||
import { createAlbumQuery } from '$lib/api/queries';
|
||||
import { createAlbumQuery } from '#lib/api/queries.js';
|
||||
|
||||
function track(id: string, title: string, number: number, dur: number): TrackRef {
|
||||
return makeTrack({
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
createArtistQuery,
|
||||
createSimilarArtistsQuery,
|
||||
createArtistTopTracksQuery
|
||||
} from '$lib/api/queries';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import ArtistCard from '$lib/components/ArtistCard.svelte';
|
||||
import CompactTrackCard from '$lib/components/CompactTrackCard.svelte';
|
||||
import HorizontalScrollRow from '$lib/components/HorizontalScrollRow.svelte';
|
||||
import LikeButton from '$lib/components/LikeButton.svelte';
|
||||
import LibrarySkeleton from '$lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import { api } from '$lib/api/client';
|
||||
import { playQueue } from '$lib/player/store.svelte';
|
||||
import type { ApiError } from '$lib/api/client';
|
||||
import type { ArtistRef, TrackRef } from '$lib/api/types';
|
||||
} from '#lib/api/queries.js';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import ArtistCard from '#lib/components/ArtistCard.svelte';
|
||||
import CompactTrackCard from '#lib/components/CompactTrackCard.svelte';
|
||||
import HorizontalScrollRow from '#lib/components/HorizontalScrollRow.svelte';
|
||||
import LikeButton from '#lib/components/LikeButton.svelte';
|
||||
import LibrarySkeleton from '#lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
import { api } from '#lib/api/client.js';
|
||||
import { playQueue } from '#lib/player/store.svelte.js';
|
||||
import type { ApiError } from '#lib/api/client.js';
|
||||
import type { ArtistRef, TrackRef } from '#lib/api/types.js';
|
||||
|
||||
const id = $derived(page.params.id ?? '');
|
||||
const queryStore = $derived(createArtistQuery(id));
|
||||
|
||||
@@ -3,7 +3,7 @@ import { render, screen } from '@testing-library/svelte';
|
||||
import { flushSync } from 'svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import { emptyLikesMock } from '../../../test-utils/mocks/likes';
|
||||
import type { ArtistDetail, AlbumRef } from '$lib/api/types';
|
||||
import type { ArtistDetail, AlbumRef } from '#lib/api/types.js';
|
||||
|
||||
const state = vi.hoisted(() => ({ pageParams: { id: 'abc' } as Record<string, string> }));
|
||||
|
||||
@@ -14,21 +14,21 @@ vi.mock('$app/state', () => ({
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
qk: { artist: (id: string) => ['artist', id] },
|
||||
createArtistQuery: vi.fn(),
|
||||
createSimilarArtistsQuery: vi.fn(),
|
||||
createArtistTopTracksQuery: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
|
||||
import ArtistPage from './+page.svelte';
|
||||
import {
|
||||
createArtistQuery,
|
||||
createSimilarArtistsQuery,
|
||||
createArtistTopTracksQuery
|
||||
} from '$lib/api/queries';
|
||||
} from '#lib/api/queries.js';
|
||||
|
||||
function album(id: string, title: string, year?: number): AlbumRef {
|
||||
return {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { createLidarrSearchQuery } from '$lib/api/lidarr';
|
||||
import { createRequest } from '$lib/api/requests';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { createLidarrSearchQuery } from '#lib/api/lidarr.js';
|
||||
import { createRequest } from '#lib/api/requests.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import DiscoverResultCard from '$lib/components/DiscoverResultCard.svelte';
|
||||
import DiscoverTabs from '$lib/components/DiscoverTabs.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import SuggestionFeed from '$lib/components/SuggestionFeed.svelte';
|
||||
import Modal from '$lib/components/Modal.svelte';
|
||||
import DiscoverResultCard from '#lib/components/DiscoverResultCard.svelte';
|
||||
import DiscoverTabs from '#lib/components/DiscoverTabs.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import SuggestionFeed from '#lib/components/SuggestionFeed.svelte';
|
||||
import Modal from '#lib/components/Modal.svelte';
|
||||
import type {
|
||||
LidarrRequestKind,
|
||||
LidarrSearchResult
|
||||
} from '$lib/api/types';
|
||||
} from '#lib/api/types.js';
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
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 type { LidarrSearchResult } from '#lib/api/types.js';
|
||||
import { pageUrlModule } from '../../test-utils/mocks/appState';
|
||||
|
||||
// $app/state / $app/navigation must be mocked or rendering the page
|
||||
@@ -17,7 +17,7 @@ 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
|
||||
// real QueryClient + network.
|
||||
vi.mock('$lib/api/lidarr', () => ({
|
||||
vi.mock('#lib/api/lidarr.js', () => ({
|
||||
createLidarrSearchQuery: vi.fn()
|
||||
}));
|
||||
|
||||
@@ -26,18 +26,18 @@ vi.mock('$lib/api/lidarr', () => ({
|
||||
// snoozing: a factory-shaped module mock must export everything the
|
||||
// component tree imports, or rendering the feed throws before any
|
||||
// assertion runs.
|
||||
vi.mock('$lib/api/suggestions', () => ({
|
||||
vi.mock('#lib/api/suggestions.js', () => ({
|
||||
createSuggestionsQuery: vi.fn(),
|
||||
createSnoozesQuery: vi.fn(),
|
||||
snoozeSuggestion: vi.fn().mockResolvedValue(undefined),
|
||||
unsnoozeSuggestion: vi.fn().mockResolvedValue(undefined)
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/requests', () => ({
|
||||
vi.mock('#lib/api/requests.js', () => ({
|
||||
createRequest: vi.fn().mockResolvedValue({ id: 'r1' })
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
|
||||
// The page calls useQueryClient() to invalidate qk.myRequests() after a
|
||||
// submit (#369); stub it so rendering doesn't require a real QueryClient and
|
||||
@@ -49,9 +49,9 @@ vi.mock('@tanstack/svelte-query', async (importOriginal) => {
|
||||
});
|
||||
|
||||
import DiscoverPage from './+page.svelte';
|
||||
import { createLidarrSearchQuery } from '$lib/api/lidarr';
|
||||
import { createSuggestionsQuery, createSnoozesQuery } from '$lib/api/suggestions';
|
||||
import { createRequest } from '$lib/api/requests';
|
||||
import { createLidarrSearchQuery } from '#lib/api/lidarr.js';
|
||||
import { createSuggestionsQuery, createSnoozesQuery } from '#lib/api/suggestions.js';
|
||||
import { createRequest } from '#lib/api/requests.js';
|
||||
|
||||
const mockedCreateQuery = createLidarrSearchQuery as ReturnType<typeof vi.fn>;
|
||||
const mockedCreateSuggestionsQuery = createSuggestionsQuery as ReturnType<typeof vi.fn>;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { forgotPassword } from '$lib/auth/store.svelte';
|
||||
import { rateLimitMessage } from '$lib/api/client';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { forgotPassword } from '#lib/auth/store.svelte.js';
|
||||
import { rateLimitMessage } from '#lib/api/client.js';
|
||||
|
||||
let email = $state('');
|
||||
let submitted = $state(false);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { render, fireEvent, screen, waitFor } from '@testing-library/svelte';
|
||||
|
||||
vi.mock('$lib/auth/store.svelte', () => ({
|
||||
vi.mock('#lib/auth/store.svelte.js', () => ({
|
||||
forgotPassword: vi.fn(),
|
||||
}));
|
||||
|
||||
import { forgotPassword } from '$lib/auth/store.svelte';
|
||||
import { forgotPassword } from '#lib/auth/store.svelte.js';
|
||||
import ForgotPasswordPage from './+page.svelte';
|
||||
|
||||
describe('/forgot-password page', () => {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { createAlbumsAlphaInfiniteQuery } from '$lib/api/albums';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import AlphabeticalGrid from '$lib/components/AlphabeticalGrid.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import InfiniteScrollSentinel from '$lib/components/InfiniteScrollSentinel.svelte';
|
||||
import QuickFilter from '$lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import type { AlbumRef } from '$lib/api/types';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { createAlbumsAlphaInfiniteQuery } from '#lib/api/albums.js';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import AlphabeticalGrid from '#lib/components/AlphabeticalGrid.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import InfiniteScrollSentinel from '#lib/components/InfiniteScrollSentinel.svelte';
|
||||
import QuickFilter from '#lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '#lib/components/EmptyState.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
import type { AlbumRef } from '#lib/api/types.js';
|
||||
|
||||
const queryStore = createAlbumsAlphaInfiniteQuery();
|
||||
const query = $derived($queryStore);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { readable } from 'svelte/store';
|
||||
import { emptyLikesMock } from '../../../test-utils/mocks/likes';
|
||||
import { apiClientMock } from '../../../test-utils/mocks/client';
|
||||
|
||||
vi.mock('$lib/api/albums', () => ({
|
||||
vi.mock('#lib/api/albums.js', () => ({
|
||||
createAlbumsAlphaInfiniteQuery: () => readable({
|
||||
data: { pages: [{
|
||||
items: [
|
||||
@@ -26,12 +26,12 @@ vi.mock('$lib/api/albums', () => ({
|
||||
}),
|
||||
ALBUM_PAGE_SIZE: 50
|
||||
}));
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
enqueueTracks: vi.fn(),
|
||||
playQueue: vi.fn()
|
||||
}));
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
// 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.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { createArtistsQuery } from '$lib/api/queries';
|
||||
import ArtistCard from '$lib/components/ArtistCard.svelte';
|
||||
import AlphabeticalGrid from '$lib/components/AlphabeticalGrid.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import InfiniteScrollSentinel from '$lib/components/InfiniteScrollSentinel.svelte';
|
||||
import QuickFilter from '$lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import type { ArtistRef } from '$lib/api/types';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { createArtistsQuery } from '#lib/api/queries.js';
|
||||
import ArtistCard from '#lib/components/ArtistCard.svelte';
|
||||
import AlphabeticalGrid from '#lib/components/AlphabeticalGrid.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import InfiniteScrollSentinel from '#lib/components/InfiniteScrollSentinel.svelte';
|
||||
import QuickFilter from '#lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '#lib/components/EmptyState.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
import type { ArtistRef } from '#lib/api/types.js';
|
||||
|
||||
const queryStore = $derived(createArtistsQuery('alpha'));
|
||||
const query = $derived($queryStore);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { readable } from 'svelte/store';
|
||||
import { emptyLikesMock } from '../../../test-utils/mocks/likes';
|
||||
import { apiClientMock } from '../../../test-utils/mocks/client';
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
createArtistsQuery: () => readable({
|
||||
data: { pages: [{
|
||||
items: [
|
||||
@@ -21,15 +21,15 @@ vi.mock('$lib/api/queries', () => ({
|
||||
fetchNextPage: () => {}
|
||||
})
|
||||
}));
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn(),
|
||||
enqueueTracks: vi.fn()
|
||||
}));
|
||||
vi.mock('$lib/api/artists', () => ({
|
||||
vi.mock('#lib/api/artists.js', () => ({
|
||||
listArtistTracks: vi.fn().mockResolvedValue([])
|
||||
}));
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
import Page from './+page.svelte';
|
||||
|
||||
describe('/library/artists', () => {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { ChevronLeft } from 'lucide-svelte';
|
||||
import {
|
||||
createGenresQuery,
|
||||
listAlbumsByGenre,
|
||||
BROWSE_PAGE_SIZE,
|
||||
type GenreCount
|
||||
} from '$lib/api/browse';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import QuickFilter from '$lib/components/QuickFilter.svelte';
|
||||
import type { AlbumRef } from '$lib/api/types';
|
||||
} from '#lib/api/browse.js';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import EmptyState from '#lib/components/EmptyState.svelte';
|
||||
import QuickFilter from '#lib/components/QuickFilter.svelte';
|
||||
import type { AlbumRef } from '#lib/api/types.js';
|
||||
|
||||
const indexStore = createGenresQuery();
|
||||
const index = $derived($indexStore);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { mockQuery } from '$test-utils/query';
|
||||
import { pageUrlModule } from '$test-utils/mocks/appState';
|
||||
import { apiClientMock } from '$test-utils/mocks/client';
|
||||
import { emptyLikesMock } from '$test-utils/mocks/likes';
|
||||
import type { AlbumRef } from '$lib/api/types';
|
||||
import type { AlbumRef } from '#lib/api/types.js';
|
||||
|
||||
const pageState = vi.hoisted(() => ({
|
||||
pageUrl: new URL('http://localhost/library/genres')
|
||||
@@ -12,15 +12,15 @@ const pageState = vi.hoisted(() => ({
|
||||
|
||||
vi.mock('$app/state', () => pageUrlModule(pageState));
|
||||
|
||||
vi.mock('$lib/api/browse', () => ({
|
||||
vi.mock('#lib/api/browse.js', () => ({
|
||||
BROWSE_PAGE_SIZE: 2,
|
||||
createGenresQuery: vi.fn(),
|
||||
listAlbumsByGenre: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn(),
|
||||
playRadio: vi.fn(),
|
||||
enqueueTrack: vi.fn(),
|
||||
@@ -29,7 +29,7 @@ vi.mock('$lib/player/store.svelte', () => ({
|
||||
}));
|
||||
|
||||
import GenresPage from './+page.svelte';
|
||||
import { createGenresQuery, listAlbumsByGenre } from '$lib/api/browse';
|
||||
import { createGenresQuery, listAlbumsByGenre } from '#lib/api/browse.js';
|
||||
|
||||
const asMock = (fn: unknown) => fn as ReturnType<typeof vi.fn>;
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Music2, RotateCcw } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import { createMyQuarantineQuery, unflagTrack } from '$lib/api/quarantine';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import type { LidarrQuarantineMineRow, LidarrQuarantineReason } from '$lib/api/types';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import { coverUrl } from '$lib/media/covers';
|
||||
import { relativeTime } from '$lib/utils/relativeTime';
|
||||
import { createMyQuarantineQuery, unflagTrack } from '#lib/api/quarantine.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import type { LidarrQuarantineMineRow, LidarrQuarantineReason } from '#lib/api/types.js';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import { coverUrl } from '#lib/media/covers.js';
|
||||
import { relativeTime } from '#lib/utils/relativeTime.js';
|
||||
|
||||
const client = useQueryClient();
|
||||
const queryStore = createMyQuarantineQuery();
|
||||
|
||||
@@ -2,14 +2,14 @@ import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
|
||||
vi.mock('$lib/api/quarantine', () => ({
|
||||
vi.mock('#lib/api/quarantine.js', () => ({
|
||||
createMyQuarantineQuery: vi.fn(),
|
||||
unflagTrack: vi.fn().mockResolvedValue(undefined)
|
||||
}));
|
||||
|
||||
import HiddenPage from './+page.svelte';
|
||||
import { createMyQuarantineQuery, unflagTrack } from '$lib/api/quarantine';
|
||||
import type { LidarrQuarantineMineRow } from '$lib/api/types';
|
||||
import { createMyQuarantineQuery, unflagTrack } from '#lib/api/quarantine.js';
|
||||
import type { LidarrQuarantineMineRow } from '#lib/api/types.js';
|
||||
|
||||
const baseRow: LidarrQuarantineMineRow = {
|
||||
track_id: 't1',
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { createHistoryQuery } from '$lib/api/history';
|
||||
import { groupByDay } from '$lib/utils/dayGroup';
|
||||
import HistoryRow from '$lib/components/HistoryRow.svelte';
|
||||
import InfiniteScrollSentinel from '$lib/components/InfiniteScrollSentinel.svelte';
|
||||
import LibrarySkeleton from '$lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import QuickFilter from '$lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { createHistoryQuery } from '#lib/api/history.js';
|
||||
import { groupByDay } from '#lib/utils/dayGroup.js';
|
||||
import HistoryRow from '#lib/components/HistoryRow.svelte';
|
||||
import InfiniteScrollSentinel from '#lib/components/InfiniteScrollSentinel.svelte';
|
||||
import LibrarySkeleton from '#lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import QuickFilter from '#lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '#lib/components/EmptyState.svelte';
|
||||
|
||||
const queryStore = createHistoryQuery();
|
||||
const query = $derived($queryStore);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { render, screen } from '@testing-library/svelte';
|
||||
import HistoryPage from './+page.svelte';
|
||||
import type { HistoryEvent, HistoryResponse } from '$lib/api/history';
|
||||
import type { HistoryEvent, HistoryResponse } from '#lib/api/history.js';
|
||||
import { makeTrack } from '$test-utils/fixtures/track';
|
||||
|
||||
const mkTrack = (id: string) => makeTrack({ id: `track-${id}`, title: `Song ${id}` });
|
||||
@@ -20,9 +20,9 @@ let mockIsFetchingNextPage = false;
|
||||
const mockFetchNextPage = vi.fn();
|
||||
const mockRefetch = vi.fn();
|
||||
|
||||
vi.mock('$lib/api/history', async () => {
|
||||
const actual = await vi.importActual<typeof import('$lib/api/history')>(
|
||||
'$lib/api/history'
|
||||
vi.mock('#lib/api/history.js', async () => {
|
||||
const actual = await vi.importActual<typeof import('#lib/api/history.js')>(
|
||||
'#lib/api/history.js'
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
@@ -44,11 +44,11 @@ vi.mock('$lib/api/history', async () => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/branding', () => ({
|
||||
vi.mock('#lib/branding.js', () => ({
|
||||
pageTitle: (s: string) => `Minstrel · ${s}`
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import {
|
||||
createLikedTracksInfiniteQuery,
|
||||
createLikedAlbumsInfiniteQuery,
|
||||
createLikedArtistsInfiniteQuery
|
||||
} from '$lib/api/likes';
|
||||
import ArtistCard from '$lib/components/ArtistCard.svelte';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import TrackRow from '$lib/components/TrackRow.svelte';
|
||||
import QuickFilter from '$lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
} from '#lib/api/likes.js';
|
||||
import ArtistCard from '#lib/components/ArtistCard.svelte';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import TrackRow from '#lib/components/TrackRow.svelte';
|
||||
import QuickFilter from '#lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '#lib/components/EmptyState.svelte';
|
||||
|
||||
const artistsStore = $derived(createLikedArtistsInfiniteQuery());
|
||||
const albumsStore = $derived(createLikedAlbumsInfiniteQuery());
|
||||
|
||||
@@ -2,11 +2,11 @@ import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent } from '@testing-library/svelte';
|
||||
import { mockInfiniteQuery } from '../../../test-utils/query';
|
||||
import { apiClientMock } from '../../../test-utils/mocks/client';
|
||||
import type { ArtistRef, AlbumRef, TrackRef, Page } from '$lib/api/types';
|
||||
import type { ArtistRef, AlbumRef, TrackRef, Page } from '#lib/api/types.js';
|
||||
import { readable } from 'svelte/store';
|
||||
import { makeTrack } from '$test-utils/fixtures/track';
|
||||
|
||||
vi.mock('$lib/api/likes', () => ({
|
||||
vi.mock('#lib/api/likes.js', () => ({
|
||||
createLikedIdsQuery: () => readable({
|
||||
data: { track_ids: [], album_ids: [], artist_ids: [] },
|
||||
isPending: false,
|
||||
@@ -19,8 +19,8 @@ vi.mock('$lib/api/likes', () => ({
|
||||
unlikeEntity: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn(), enqueueTrack: vi.fn(), enqueueTracks: vi.fn(),
|
||||
player: { current: undefined }
|
||||
}));
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
createLikedTracksInfiniteQuery,
|
||||
createLikedAlbumsInfiniteQuery,
|
||||
createLikedArtistsInfiniteQuery
|
||||
} from '$lib/api/likes';
|
||||
} from '#lib/api/likes.js';
|
||||
|
||||
function page<T>(items: T[], total: number, offset = 0, limit = 50): Page<T> {
|
||||
return { items, total, offset, limit };
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { goto } from '$app/navigation';
|
||||
import { Plus } from 'lucide-svelte';
|
||||
import PlaylistCard from '$lib/components/PlaylistCard.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import QuickFilter from '$lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import { createPlaylistsQuery, createPlaylist } from '$lib/api/playlists';
|
||||
import PlaylistCard from '#lib/components/PlaylistCard.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import QuickFilter from '#lib/components/QuickFilter.svelte';
|
||||
import EmptyState from '#lib/components/EmptyState.svelte';
|
||||
import { createPlaylistsQuery, createPlaylist } from '#lib/api/playlists.js';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
|
||||
const playlistsStore = $derived(createPlaylistsQuery());
|
||||
const playlistsQuery = $derived($playlistsStore);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import type { Playlist } from '$lib/api/types';
|
||||
import type { Playlist } from '#lib/api/types.js';
|
||||
|
||||
vi.mock('$lib/api/playlists', () => ({
|
||||
vi.mock('#lib/api/playlists.js', () => ({
|
||||
createPlaylistsQuery: vi.fn(),
|
||||
createPlaylist: vi.fn().mockResolvedValue({ id: 'p-new', name: 'X' })
|
||||
}));
|
||||
@@ -11,7 +11,7 @@ vi.mock('$lib/api/playlists', () => ({
|
||||
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
|
||||
|
||||
import PlaylistsPage from './+page.svelte';
|
||||
import { createPlaylistsQuery, createPlaylist } from '$lib/api/playlists';
|
||||
import { createPlaylistsQuery, createPlaylist } from '#lib/api/playlists.js';
|
||||
|
||||
const mockedCreatePlaylistsQuery = createPlaylistsQuery as ReturnType<typeof vi.fn>;
|
||||
const mockedCreatePlaylist = createPlaylist as ReturnType<typeof vi.fn>;
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { ChevronLeft } from 'lucide-svelte';
|
||||
import {
|
||||
createAlbumYearsQuery,
|
||||
listAlbumsByYear,
|
||||
BROWSE_PAGE_SIZE,
|
||||
type YearCount
|
||||
} from '$lib/api/browse';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import type { AlbumRef } from '$lib/api/types';
|
||||
} from '#lib/api/browse.js';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import EmptyState from '#lib/components/EmptyState.svelte';
|
||||
import type { AlbumRef } from '#lib/api/types.js';
|
||||
|
||||
const indexStore = createAlbumYearsQuery();
|
||||
const index = $derived($indexStore);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { mockQuery } from '$test-utils/query';
|
||||
import { pageUrlModule } from '$test-utils/mocks/appState';
|
||||
import { apiClientMock } from '$test-utils/mocks/client';
|
||||
import { emptyLikesMock } from '$test-utils/mocks/likes';
|
||||
import type { AlbumRef } from '$lib/api/types';
|
||||
import type { AlbumRef } from '#lib/api/types.js';
|
||||
|
||||
const pageState = vi.hoisted(() => ({
|
||||
pageUrl: new URL('http://localhost/library/years')
|
||||
@@ -12,15 +12,15 @@ const pageState = vi.hoisted(() => ({
|
||||
|
||||
vi.mock('$app/state', () => pageUrlModule(pageState));
|
||||
|
||||
vi.mock('$lib/api/browse', () => ({
|
||||
vi.mock('#lib/api/browse.js', () => ({
|
||||
BROWSE_PAGE_SIZE: 2,
|
||||
createAlbumYearsQuery: vi.fn(),
|
||||
listAlbumsByYear: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn(),
|
||||
playRadio: vi.fn(),
|
||||
enqueueTrack: vi.fn(),
|
||||
@@ -29,7 +29,7 @@ vi.mock('$lib/player/store.svelte', () => ({
|
||||
}));
|
||||
|
||||
import YearsPage from './+page.svelte';
|
||||
import { createAlbumYearsQuery, listAlbumsByYear } from '$lib/api/browse';
|
||||
import { createAlbumYearsQuery, listAlbumsByYear } from '#lib/api/browse.js';
|
||||
|
||||
const asMock = (fn: unknown) => fn as ReturnType<typeof vi.fn>;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { page } from '$app/state';
|
||||
import { goto } from '$app/navigation';
|
||||
import { login } from '$lib/auth/store.svelte';
|
||||
import { rateLimitMessage, type ApiError } from '$lib/api/client';
|
||||
import { login } from '#lib/auth/store.svelte.js';
|
||||
import { rateLimitMessage, type ApiError } from '#lib/api/client.js';
|
||||
|
||||
let username = $state('');
|
||||
let password = $state('');
|
||||
@@ -27,7 +27,7 @@
|
||||
try {
|
||||
await login(username, password);
|
||||
const dest = safeReturnTo(page.url.searchParams.get('returnTo'));
|
||||
goto(dest, { replaceState: true });
|
||||
goto(dest, { replace: true });
|
||||
} catch (err) {
|
||||
const apiErr = err as ApiError;
|
||||
const throttled = rateLimitMessage(err);
|
||||
|
||||
@@ -13,13 +13,13 @@ vi.mock('$app/navigation', () => ({
|
||||
goto: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/auth/store.svelte', () => ({
|
||||
vi.mock('#lib/auth/store.svelte.js', () => ({
|
||||
login: vi.fn(),
|
||||
user: { value: null }
|
||||
}));
|
||||
|
||||
import LoginPage from './+page.svelte';
|
||||
import { login } from '$lib/auth/store.svelte';
|
||||
import { login } from '#lib/auth/store.svelte.js';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
afterEach(() => {
|
||||
@@ -81,7 +81,7 @@ describe('login page', () => {
|
||||
render(LoginPage);
|
||||
await submit();
|
||||
await waitFor(() => {
|
||||
expect(goto).toHaveBeenCalledWith('/artists/abc', { replaceState: true });
|
||||
expect(goto).toHaveBeenCalledWith('/artists/abc', { replace: true });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ describe('login page', () => {
|
||||
render(LoginPage);
|
||||
await submit();
|
||||
await waitFor(() => {
|
||||
expect(goto).toHaveBeenCalledWith('/', { replaceState: true });
|
||||
expect(goto).toHaveBeenCalledWith('/', { replace: true });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@ describe('login page', () => {
|
||||
render(LoginPage);
|
||||
await submit();
|
||||
await waitFor(() => {
|
||||
expect(goto).toHaveBeenCalledWith('/', { replaceState: true });
|
||||
expect(goto).toHaveBeenCalledWith('/', { replace: true });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
togglePlay, skipNext, skipPrev, seekTo, setVolume,
|
||||
toggleShuffle, cycleRepeat,
|
||||
toggleQueueDrawer
|
||||
} from '$lib/player/store.svelte';
|
||||
import { formatDuration } from '$lib/media/duration';
|
||||
import { FALLBACK_COVER, coverUrl } from '$lib/media/covers';
|
||||
import { useSmoothPosition } from '$lib/player/smoothPosition.svelte';
|
||||
import LikeButton from '$lib/components/LikeButton.svelte';
|
||||
import TrackMenu from '$lib/components/TrackMenu.svelte';
|
||||
import QueueList from '$lib/components/QueueList.svelte';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
} from '#lib/player/store.svelte.js';
|
||||
import { formatDuration } from '#lib/media/duration.js';
|
||||
import { FALLBACK_COVER, coverUrl } from '#lib/media/covers.js';
|
||||
import { useSmoothPosition } from '#lib/player/smoothPosition.svelte.js';
|
||||
import LikeButton from '#lib/components/LikeButton.svelte';
|
||||
import TrackMenu from '#lib/components/TrackMenu.svelte';
|
||||
import QueueList from '#lib/components/QueueList.svelte';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
|
||||
const current = $derived(player.current);
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, within } from '@testing-library/svelte';
|
||||
import { readable } from 'svelte/store';
|
||||
import { emptyLikesMock } from '../test-utils/mocks/likes';
|
||||
import type { Playlist } from '$lib/api/types';
|
||||
import type { Playlist } from '#lib/api/types.js';
|
||||
|
||||
// Mock all the queries the home page constructs.
|
||||
vi.mock('$lib/api/home', () => ({
|
||||
vi.mock('#lib/api/home.js', () => ({
|
||||
createHomeQuery: () =>
|
||||
readable({
|
||||
data: {
|
||||
@@ -23,20 +23,20 @@ vi.mock('$lib/api/home', () => ({
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/playlists', () => ({
|
||||
vi.mock('#lib/api/playlists.js', () => ({
|
||||
createPlaylistsQuery: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/me', () => ({
|
||||
vi.mock('#lib/api/me.js', () => ({
|
||||
createSystemPlaylistsStatusQuery: vi.fn()
|
||||
}));
|
||||
|
||||
// LikeButton imports — needed because the home renders cards that may use it.
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
|
||||
import Page from './+page.svelte';
|
||||
import { createPlaylistsQuery } from '$lib/api/playlists';
|
||||
import { createSystemPlaylistsStatusQuery } from '$lib/api/me';
|
||||
import { createPlaylistsQuery } from '#lib/api/playlists.js';
|
||||
import { createSystemPlaylistsStatusQuery } from '#lib/api/me.js';
|
||||
|
||||
const emptyPlaylistsResponse = { owned: [], public: [] };
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
import { page } from '$app/state';
|
||||
import { goto } from '$app/navigation';
|
||||
import { untrack } from 'svelte';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Pencil, Trash2, Link as LinkIcon } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import PlaylistTrackRow from '$lib/components/PlaylistTrackRow.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import PlaylistTrackRow from '#lib/components/PlaylistTrackRow.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import {
|
||||
createPlaylistQuery,
|
||||
updatePlaylist,
|
||||
@@ -15,15 +15,15 @@
|
||||
reorderPlaylist,
|
||||
refreshSystem,
|
||||
systemShuffle
|
||||
} from '$lib/api/playlists';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { user } from '$lib/auth/store.svelte';
|
||||
import { errCode, errMessage } from '$lib/api/errors';
|
||||
import { playQueue } from '$lib/player/store.svelte';
|
||||
import { systemPlaylistRefetch } from '$lib/playlists/systemRefetch';
|
||||
import { systemRebuilt } from '$lib/serverEvents.svelte';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import type { TrackRef } from '$lib/api/types';
|
||||
} from '#lib/api/playlists.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import { user } from '#lib/auth/store.svelte.js';
|
||||
import { errCode, errMessage } from '#lib/api/errors.js';
|
||||
import { playQueue } from '#lib/player/store.svelte.js';
|
||||
import { systemPlaylistRefetch } from '#lib/playlists/systemRefetch.js';
|
||||
import { systemRebuilt } from '#lib/serverEvents.svelte.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import type { TrackRef } from '#lib/api/types.js';
|
||||
|
||||
// SvelteKit types page.params.id as string | undefined (the route
|
||||
// could in principle render with the slot empty); empty-string fallback
|
||||
|
||||
@@ -2,7 +2,7 @@ import { describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
import { mockQuery } from '../../../test-utils/query';
|
||||
import { emptyQuarantineMock } from '../../../test-utils/mocks/quarantine';
|
||||
import type { PlaylistDetail } from '$lib/api/types';
|
||||
import type { PlaylistDetail } from '#lib/api/types.js';
|
||||
|
||||
// Project canonical: $app/state (rune-state), not $app/stores (legacy
|
||||
// reactive store). The page module exports an object with a `params`
|
||||
@@ -13,7 +13,7 @@ vi.mock('$app/state', () => ({
|
||||
|
||||
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
|
||||
|
||||
vi.mock('$lib/api/playlists', () => ({
|
||||
vi.mock('#lib/api/playlists.js', () => ({
|
||||
createPlaylistQuery: vi.fn(),
|
||||
updatePlaylist: vi.fn().mockResolvedValue(undefined),
|
||||
deletePlaylist: vi.fn().mockResolvedValue(undefined),
|
||||
@@ -22,11 +22,11 @@ vi.mock('$lib/api/playlists', () => ({
|
||||
refreshSystem: vi.fn().mockResolvedValue({ playlist_id: 'p1', track_count: 5, track_ids: [] })
|
||||
}));
|
||||
|
||||
vi.mock('$lib/auth/store.svelte', () => ({
|
||||
vi.mock('#lib/auth/store.svelte.js', () => ({
|
||||
user: { value: { id: 'u-self', username: 'me', is_admin: false } }
|
||||
}));
|
||||
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn(),
|
||||
enqueueTracks: vi.fn(),
|
||||
playNext: vi.fn(),
|
||||
@@ -35,15 +35,15 @@ vi.mock('$lib/player/store.svelte', () => ({
|
||||
}));
|
||||
|
||||
// Cascade through PlaylistTrackRow's mocks (LikeButton + TrackMenu transitively).
|
||||
vi.mock('$lib/api/likes', () => ({
|
||||
vi.mock('#lib/api/likes.js', () => ({
|
||||
createLikedIdsQuery: () => ({ subscribe: () => () => {}, data: { track_ids: [], album_ids: [], artist_ids: [] } }),
|
||||
likeEntity: vi.fn(),
|
||||
unlikeEntity: vi.fn()
|
||||
}));
|
||||
vi.mock('$lib/api/quarantine', () => emptyQuarantineMock());
|
||||
vi.mock('#lib/api/quarantine.js', () => emptyQuarantineMock());
|
||||
|
||||
import PlaylistDetailPage from './+page.svelte';
|
||||
import { createPlaylistQuery, deletePlaylist, refreshSystem } from '$lib/api/playlists';
|
||||
import { createPlaylistQuery, deletePlaylist, refreshSystem } from '#lib/api/playlists.js';
|
||||
|
||||
const mockedQuery = createPlaylistQuery as ReturnType<typeof vi.fn>;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { goto } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
import { getSetupStatus, register } from '$lib/auth/store.svelte';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { rateLimitMessage } from '$lib/api/client';
|
||||
import { getSetupStatus, register } from '#lib/auth/store.svelte.js';
|
||||
import { errCode } from '#lib/api/errors.js';
|
||||
import { rateLimitMessage } from '#lib/api/client.js';
|
||||
|
||||
let username = $state('');
|
||||
let password = $state('');
|
||||
@@ -63,7 +63,7 @@
|
||||
setupToken: setupToken.trim() || undefined,
|
||||
displayName: displayName || undefined,
|
||||
});
|
||||
await goto('/', { replaceState: true });
|
||||
await goto('/', { replace: true });
|
||||
} catch (err: unknown) {
|
||||
error = rateLimitMessage(err) ?? errorMessageFor(errCode(err));
|
||||
} finally {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
|
||||
vi.mock('$lib/branding', () => ({
|
||||
vi.mock('#lib/branding.js', () => ({
|
||||
pageTitle: (s: string) => `${s} · Minstrel`
|
||||
}));
|
||||
|
||||
@@ -9,14 +9,14 @@ vi.mock('$app/navigation', () => ({
|
||||
goto: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/auth/store.svelte', () => ({
|
||||
vi.mock('#lib/auth/store.svelte.js', () => ({
|
||||
register: vi.fn(),
|
||||
getSetupStatus: vi.fn().mockResolvedValue({ setup_required: false }),
|
||||
user: { value: null }
|
||||
}));
|
||||
|
||||
import RegisterPage from './+page.svelte';
|
||||
import { getSetupStatus, register } from '$lib/auth/store.svelte';
|
||||
import { getSetupStatus, register } from '#lib/auth/store.svelte.js';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
afterEach(() => {
|
||||
@@ -60,7 +60,7 @@ describe('/register page', () => {
|
||||
}));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(goto).toHaveBeenCalledWith('/', { replaceState: true });
|
||||
expect(goto).toHaveBeenCalledWith('/', { replace: true });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { Disc3, Album, Music2, X } from 'lucide-svelte';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import { createMyRequestsQuery, cancelRequest } from '$lib/api/requests';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import StatusPill from '$lib/components/StatusPill.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import DiscoverTabs from '$lib/components/DiscoverTabs.svelte';
|
||||
import type { LidarrRequest, LidarrRequestKind } from '$lib/api/types';
|
||||
import { createMyRequestsQuery, cancelRequest } from '#lib/api/requests.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
import StatusPill from '#lib/components/StatusPill.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import DiscoverTabs from '#lib/components/DiscoverTabs.svelte';
|
||||
import type { LidarrRequest, LidarrRequestKind } from '#lib/api/types.js';
|
||||
|
||||
const queryStore = createMyRequestsQuery();
|
||||
const query = $derived($queryStore);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
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 type { LidarrRequest } from '#lib/api/types.js';
|
||||
import { pageUrlModule } from '../../test-utils/mocks/appState';
|
||||
|
||||
// $app/state / $app/navigation must be mocked or rendering the page
|
||||
@@ -23,22 +23,22 @@ vi.mock('@tanstack/svelte-query', async (orig) => {
|
||||
return { ...actual, useQueryClient: () => ({ invalidateQueries }) };
|
||||
});
|
||||
|
||||
vi.mock('$lib/api/requests', () => ({
|
||||
vi.mock('#lib/api/requests.js', () => ({
|
||||
createMyRequestsQuery: vi.fn(),
|
||||
cancelRequest: vi.fn().mockResolvedValue({ id: 'r1' })
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
qk: {
|
||||
myRequests: () => ['myRequests']
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
|
||||
import RequestsPage from './+page.svelte';
|
||||
import { createMyRequestsQuery, cancelRequest } from '$lib/api/requests';
|
||||
import { qk } from '$lib/api/queries';
|
||||
import { createMyRequestsQuery, cancelRequest } from '#lib/api/requests.js';
|
||||
import { qk } from '#lib/api/queries.js';
|
||||
|
||||
const mockedCreateMyRequestsQuery = createMyRequestsQuery as ReturnType<typeof vi.fn>;
|
||||
const mockedCancelRequest = cancelRequest as ReturnType<typeof vi.fn>;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/state';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { resetPassword } from '$lib/auth/store.svelte';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { rateLimitMessage } from '$lib/api/client';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { resetPassword } from '#lib/auth/store.svelte.js';
|
||||
import { errCode } from '#lib/api/errors.js';
|
||||
import { rateLimitMessage } from '#lib/api/client.js';
|
||||
|
||||
let newPassword = $state('');
|
||||
let confirmPassword = $state('');
|
||||
@@ -27,7 +27,7 @@
|
||||
submitting = true;
|
||||
try {
|
||||
await resetPassword(token, newPassword);
|
||||
await goto('/login?reset=ok', { replaceState: true });
|
||||
await goto('/login?reset=ok', { replace: true });
|
||||
} catch (e: unknown) {
|
||||
const code = errCode(e);
|
||||
const throttled = rateLimitMessage(e);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { render, fireEvent, screen, waitFor } from '@testing-library/svelte';
|
||||
|
||||
vi.mock('$lib/auth/store.svelte', () => ({
|
||||
vi.mock('#lib/auth/store.svelte.js', () => ({
|
||||
resetPassword: vi.fn(),
|
||||
}));
|
||||
|
||||
@@ -13,7 +13,7 @@ vi.mock('$app/state', () => ({
|
||||
page: { params: { token: 'test-token-abc' } },
|
||||
}));
|
||||
|
||||
import { resetPassword } from '$lib/auth/store.svelte';
|
||||
import { resetPassword } from '#lib/auth/store.svelte.js';
|
||||
import { goto } from '$app/navigation';
|
||||
import ResetPasswordPage from './+page.svelte';
|
||||
|
||||
@@ -36,7 +36,7 @@ describe('/reset-password/[token] page', () => {
|
||||
await fireEvent.input(screen.getByLabelText('Confirm new password'), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.click(screen.getByRole('button', { name: 'Set password' }));
|
||||
expect(resetPassword).toHaveBeenCalledWith('test-token-abc', 'abcd1234');
|
||||
await waitFor(() => expect(goto).toHaveBeenCalledWith('/login?reset=ok', expect.objectContaining({ replaceState: true })));
|
||||
await waitFor(() => expect(goto).toHaveBeenCalledWith('/login?reset=ok', expect.objectContaining({ replace: true })));
|
||||
});
|
||||
|
||||
it('shows clear error on invalid_token', async () => {
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { page } from '$app/state';
|
||||
import { createSearchQuery } from '$lib/api/queries';
|
||||
import ArtistCard from '$lib/components/ArtistCard.svelte';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import TrackRow from '$lib/components/TrackRow.svelte';
|
||||
import SearchSkeleton from '$lib/components/SearchSkeleton.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import { playRadio } from '$lib/player/store.svelte';
|
||||
import type { TrackRef } from '$lib/api/types';
|
||||
import { createSearchQuery } from '#lib/api/queries.js';
|
||||
import ArtistCard from '#lib/components/ArtistCard.svelte';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import TrackRow from '#lib/components/TrackRow.svelte';
|
||||
import SearchSkeleton from '#lib/components/SearchSkeleton.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
import { playRadio } from '#lib/player/store.svelte.js';
|
||||
import type { TrackRef } from '#lib/api/types.js';
|
||||
|
||||
const q = $derived((page.url.searchParams.get('q') ?? '').trim());
|
||||
const queryStore = $derived(q ? createSearchQuery(q) : null);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { page } from '$app/state';
|
||||
import { createSearchAlbumsInfiniteQuery } from '$lib/api/queries';
|
||||
import AlbumCard from '$lib/components/AlbumCard.svelte';
|
||||
import LibrarySkeleton from '$lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import { createSearchAlbumsInfiniteQuery } from '#lib/api/queries.js';
|
||||
import AlbumCard from '#lib/components/AlbumCard.svelte';
|
||||
import LibrarySkeleton from '#lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
|
||||
const q = $derived((page.url.searchParams.get('q') ?? '').trim());
|
||||
const queryStore = $derived(q ? createSearchAlbumsInfiniteQuery(q) : null);
|
||||
|
||||
@@ -4,25 +4,25 @@ import { mockInfiniteQuery } from '../../../test-utils/query';
|
||||
import { emptyLikesMock } from '../../../test-utils/mocks/likes';
|
||||
import { apiClientMock } from '../../../test-utils/mocks/client';
|
||||
import { pageUrlModule } from '$test-utils/mocks/appState';
|
||||
import type { AlbumRef, Page } from '$lib/api/types';
|
||||
import type { AlbumRef, Page } from '#lib/api/types.js';
|
||||
|
||||
const state = vi.hoisted(() => ({ pageUrl: new URL('http://localhost/search/albums?q=miles') }));
|
||||
|
||||
vi.mock('$app/state', () => pageUrlModule(state));
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
createSearchAlbumsInfiniteQuery: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
enqueueTracks: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
|
||||
import AlbumsOverflow from './+page.svelte';
|
||||
import { createSearchAlbumsInfiniteQuery } from '$lib/api/queries';
|
||||
import { createSearchAlbumsInfiniteQuery } from '#lib/api/queries.js';
|
||||
|
||||
function page<T>(items: T[], total: number, offset = 0, limit = 50): Page<T> {
|
||||
return { items, total, offset, limit };
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { page } from '$app/state';
|
||||
import { createSearchArtistsInfiniteQuery } from '$lib/api/queries';
|
||||
import ArtistCard from '$lib/components/ArtistCard.svelte';
|
||||
import LibrarySkeleton from '$lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import { createSearchArtistsInfiniteQuery } from '#lib/api/queries.js';
|
||||
import ArtistCard from '#lib/components/ArtistCard.svelte';
|
||||
import LibrarySkeleton from '#lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
|
||||
const q = $derived((page.url.searchParams.get('q') ?? '').trim());
|
||||
const queryStore = $derived(q ? createSearchArtistsInfiniteQuery(q) : null);
|
||||
|
||||
@@ -3,20 +3,20 @@ import { render, screen, fireEvent } from '@testing-library/svelte';
|
||||
import { mockInfiniteQuery } from '../../../test-utils/query';
|
||||
import { emptyLikesMock } from '../../../test-utils/mocks/likes';
|
||||
import { pageUrlModule } from '$test-utils/mocks/appState';
|
||||
import type { ArtistRef, Page } from '$lib/api/types';
|
||||
import type { ArtistRef, Page } from '#lib/api/types.js';
|
||||
|
||||
const state = vi.hoisted(() => ({ pageUrl: new URL('http://localhost/search/artists?q=miles') }));
|
||||
|
||||
vi.mock('$app/state', () => pageUrlModule(state));
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
createSearchArtistsInfiniteQuery: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
|
||||
import ArtistsOverflow from './+page.svelte';
|
||||
import { createSearchArtistsInfiniteQuery } from '$lib/api/queries';
|
||||
import { createSearchArtistsInfiniteQuery } from '#lib/api/queries.js';
|
||||
|
||||
function page<T>(items: T[], total: number, offset = 0, limit = 50): Page<T> {
|
||||
return { items, total, offset, limit };
|
||||
|
||||
@@ -4,7 +4,7 @@ import { mockQuery } from '../../test-utils/query';
|
||||
import { emptyLikesMock } from '../../test-utils/mocks/likes';
|
||||
import { apiClientMock } from '../../test-utils/mocks/client';
|
||||
import { pageUrlModule } from '$test-utils/mocks/appState';
|
||||
import type { ArtistRef, AlbumRef, SearchResponse } from '$lib/api/types';
|
||||
import type { ArtistRef, AlbumRef, SearchResponse } from '#lib/api/types.js';
|
||||
import { makeTrack } from '$test-utils/fixtures/track';
|
||||
|
||||
const state = vi.hoisted(() => ({
|
||||
@@ -13,11 +13,11 @@ const state = vi.hoisted(() => ({
|
||||
|
||||
vi.mock('$app/state', () => pageUrlModule(state));
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
createSearchQuery: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn(),
|
||||
playRadio: vi.fn(),
|
||||
enqueueTrack: vi.fn(),
|
||||
@@ -25,12 +25,12 @@ vi.mock('$lib/player/store.svelte', () => ({
|
||||
player: { current: undefined }
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/client', () => apiClientMock());
|
||||
vi.mock('#lib/api/client.js', () => apiClientMock());
|
||||
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
|
||||
import SearchPage from './+page.svelte';
|
||||
import { createSearchQuery } from '$lib/api/queries';
|
||||
import { createSearchQuery } from '#lib/api/queries.js';
|
||||
|
||||
function emptyResp(): SearchResponse {
|
||||
return {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { page } from '$app/state';
|
||||
import { createSearchTracksInfiniteQuery } from '$lib/api/queries';
|
||||
import TrackRow from '$lib/components/TrackRow.svelte';
|
||||
import LibrarySkeleton from '$lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '$lib/utils/useDelayed.svelte';
|
||||
import { playRadio } from '$lib/player/store.svelte';
|
||||
import type { TrackRef } from '$lib/api/types';
|
||||
import { createSearchTracksInfiniteQuery } from '#lib/api/queries.js';
|
||||
import TrackRow from '#lib/components/TrackRow.svelte';
|
||||
import LibrarySkeleton from '#lib/components/LibrarySkeleton.svelte';
|
||||
import ApiErrorBanner from '#lib/components/ApiErrorBanner.svelte';
|
||||
import { useDelayed } from '#lib/utils/useDelayed.svelte.js';
|
||||
import { playRadio } from '#lib/player/store.svelte.js';
|
||||
import type { TrackRef } from '#lib/api/types.js';
|
||||
|
||||
const q = $derived((page.url.searchParams.get('q') ?? '').trim());
|
||||
const queryStore = $derived(q ? createSearchTracksInfiniteQuery(q) : null);
|
||||
|
||||
@@ -4,31 +4,31 @@ import { mockInfiniteQuery } from '../../../test-utils/query';
|
||||
import { emptyLikesMock } from '../../../test-utils/mocks/likes';
|
||||
import { emptyQuarantineMock } from '../../../test-utils/mocks/quarantine';
|
||||
import { pageUrlModule } from '$test-utils/mocks/appState';
|
||||
import type { TrackRef, Page } from '$lib/api/types';
|
||||
import type { TrackRef, Page } from '#lib/api/types.js';
|
||||
import { makeTrack } from '$test-utils/fixtures/track';
|
||||
|
||||
const state = vi.hoisted(() => ({ pageUrl: new URL('http://localhost/search/tracks?q=miles') }));
|
||||
|
||||
vi.mock('$app/state', () => pageUrlModule(state));
|
||||
|
||||
vi.mock('$lib/api/queries', () => ({
|
||||
vi.mock('#lib/api/queries.js', () => ({
|
||||
createSearchTracksInfiniteQuery: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/player/store.svelte', () => ({
|
||||
vi.mock('#lib/player/store.svelte.js', () => ({
|
||||
playQueue: vi.fn(),
|
||||
playRadio: vi.fn(),
|
||||
enqueueTrack: vi.fn(),
|
||||
player: { current: undefined }
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/likes', () => emptyLikesMock());
|
||||
vi.mock('#lib/api/likes.js', () => emptyLikesMock());
|
||||
|
||||
vi.mock('$lib/api/quarantine', () => emptyQuarantineMock());
|
||||
vi.mock('#lib/api/quarantine.js', () => emptyQuarantineMock());
|
||||
|
||||
import TracksOverflow from './+page.svelte';
|
||||
import { createSearchTracksInfiniteQuery } from '$lib/api/queries';
|
||||
import { playRadio } from '$lib/player/store.svelte';
|
||||
import { createSearchTracksInfiniteQuery } from '#lib/api/queries.js';
|
||||
import { playRadio } from '#lib/player/store.svelte.js';
|
||||
|
||||
function page<T>(items: T[], total: number, offset = 0, limit = 50): Page<T> {
|
||||
return { items, total, offset, limit };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { pageTitle } from '$lib/branding';
|
||||
import { pageTitle } from '#lib/branding.js';
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import type { CreateQueryResult, CreateMutationResult } from '@tanstack/svelte-query';
|
||||
import {
|
||||
@@ -8,15 +8,15 @@
|
||||
createTokenMutation,
|
||||
createEnabledMutation,
|
||||
type LBStatus
|
||||
} from '$lib/api/listenbrainz';
|
||||
} from '#lib/api/listenbrainz.js';
|
||||
import {
|
||||
createRecommendationMetricsQuery,
|
||||
type RecommendationMetrics,
|
||||
type SurfaceIntent,
|
||||
type MetricDelta
|
||||
} from '$lib/api/metrics';
|
||||
import { theme, setTheme, type ThemePreference } from '$lib/stores/theme.svelte';
|
||||
import { player, setCrossfade } from '$lib/player/store.svelte';
|
||||
} from '#lib/api/metrics.js';
|
||||
import { theme, setTheme, type ThemePreference } from '#lib/stores/theme.svelte.js';
|
||||
import { player, setCrossfade } from '#lib/player/store.svelte.js';
|
||||
import {
|
||||
updateProfile,
|
||||
changePassword,
|
||||
@@ -24,14 +24,14 @@
|
||||
getSubsonicPasswordStatus,
|
||||
generateSubsonicPassword,
|
||||
clearSubsonicPassword
|
||||
} from '$lib/api/me';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { pushToast } from '$lib/stores/toast.svelte';
|
||||
import MobileAppDownload from '$lib/components/MobileAppDownload.svelte';
|
||||
import ServerVersion from '$lib/components/ServerVersion.svelte';
|
||||
import ActiveSessions from '$lib/components/ActiveSessions.svelte';
|
||||
import NormalizationSetting from '$lib/components/NormalizationSetting.svelte';
|
||||
import NotificationSettings from '$lib/components/NotificationSettings.svelte';
|
||||
} from '#lib/api/me.js';
|
||||
import { errCode } from '#lib/api/errors.js';
|
||||
import { pushToast } from '#lib/stores/toast.svelte.js';
|
||||
import MobileAppDownload from '#lib/components/MobileAppDownload.svelte';
|
||||
import ServerVersion from '#lib/components/ServerVersion.svelte';
|
||||
import ActiveSessions from '#lib/components/ActiveSessions.svelte';
|
||||
import NormalizationSetting from '#lib/components/NormalizationSetting.svelte';
|
||||
import NotificationSettings from '#lib/components/NotificationSettings.svelte';
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, test, vi, beforeEach } from 'vitest';
|
||||
import { render, screen, fireEvent } from '@testing-library/svelte';
|
||||
|
||||
vi.mock('$lib/api/listenbrainz', () => {
|
||||
vi.mock('#lib/api/listenbrainz.js', () => {
|
||||
// Mocks must look like a Svelte readable store. The page reads e.g.
|
||||
// $status.isPending, which is shorthand for "subscribe to status,
|
||||
// then read .isPending on the emitted value." Returning an object
|
||||
@@ -27,8 +27,8 @@ vi.mock('$lib/api/listenbrainz', () => {
|
||||
|
||||
// The Notifications section has its own tests (NotificationSettings.test.ts);
|
||||
// here it only needs a settled query so the page renders.
|
||||
vi.mock('$lib/api/notifications', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('$lib/api/notifications')>();
|
||||
vi.mock('#lib/api/notifications.js', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('#lib/api/notifications.js')>();
|
||||
const { mockQuery } = await import('../../test-utils/query');
|
||||
return {
|
||||
...mod,
|
||||
@@ -39,8 +39,8 @@ vi.mock('$lib/api/notifications', async (importOriginal) => {
|
||||
});
|
||||
|
||||
// The Volume leveling setting loads on mount; keep it off the network.
|
||||
vi.mock('$lib/api/normalization', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('$lib/api/normalization')>();
|
||||
vi.mock('#lib/api/normalization.js', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('#lib/api/normalization.js')>();
|
||||
return {
|
||||
...mod,
|
||||
getNormalization: vi.fn().mockResolvedValue(mod.DEFAULT_NORMALIZATION),
|
||||
@@ -48,7 +48,7 @@ vi.mock('$lib/api/normalization', async (importOriginal) => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('$lib/api/metrics', () => ({
|
||||
vi.mock('#lib/api/metrics.js', () => ({
|
||||
createRecommendationMetricsQuery: () => ({
|
||||
subscribe: (run: (v: unknown) => void) => {
|
||||
run({ isPending: false, isError: false, data: { window_days: 30, baseline: null, groups: [] } });
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor, within } from '@testing-library/svelte';
|
||||
import { readable, writable } from 'svelte/store';
|
||||
import type { LBStatus } from '$lib/api/listenbrainz';
|
||||
import type { LBStatus } from '#lib/api/listenbrainz.js';
|
||||
|
||||
vi.mock('$lib/api/listenbrainz', () => ({
|
||||
vi.mock('#lib/api/listenbrainz.js', () => ({
|
||||
createLBStatusQuery: vi.fn(),
|
||||
createTokenMutation: vi.fn(),
|
||||
createEnabledMutation: vi.fn(),
|
||||
@@ -13,8 +13,8 @@ vi.mock('$lib/api/listenbrainz', () => ({
|
||||
|
||||
// The Notifications section has its own tests (NotificationSettings.test.ts);
|
||||
// here it only needs a settled query so the page renders.
|
||||
vi.mock('$lib/api/notifications', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('$lib/api/notifications')>();
|
||||
vi.mock('#lib/api/notifications.js', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('#lib/api/notifications.js')>();
|
||||
const { mockQuery } = await import('../../test-utils/query');
|
||||
return {
|
||||
...mod,
|
||||
@@ -25,8 +25,8 @@ vi.mock('$lib/api/notifications', async (importOriginal) => {
|
||||
});
|
||||
|
||||
// The Volume leveling setting loads on mount; keep it off the network.
|
||||
vi.mock('$lib/api/normalization', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('$lib/api/normalization')>();
|
||||
vi.mock('#lib/api/normalization.js', async (importOriginal) => {
|
||||
const mod = await importOriginal<typeof import('#lib/api/normalization.js')>();
|
||||
return {
|
||||
...mod,
|
||||
getNormalization: vi.fn().mockResolvedValue(mod.DEFAULT_NORMALIZATION),
|
||||
@@ -34,7 +34,7 @@ vi.mock('$lib/api/normalization', async (importOriginal) => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('$lib/api/me', () => ({
|
||||
vi.mock('#lib/api/me.js', () => ({
|
||||
updateProfile: vi.fn(),
|
||||
changePassword: vi.fn(),
|
||||
// Default to a resolved value so the page's $effect doesn't crash
|
||||
@@ -51,7 +51,7 @@ const metricsMock = vi.hoisted(() => ({
|
||||
data: { window_days: 30, baseline: null, groups: [] } as unknown
|
||||
}));
|
||||
|
||||
vi.mock('$lib/api/metrics', () => ({
|
||||
vi.mock('#lib/api/metrics.js', () => ({
|
||||
createRecommendationMetricsQuery: () => ({
|
||||
subscribe: (run: (v: unknown) => void) => {
|
||||
run({ isPending: false, isError: false, data: metricsMock.data });
|
||||
@@ -67,7 +67,7 @@ import {
|
||||
createEnabledMutation,
|
||||
setListenBrainzToken,
|
||||
setListenBrainzEnabled
|
||||
} from '$lib/api/listenbrainz';
|
||||
} from '#lib/api/listenbrainz.js';
|
||||
import {
|
||||
updateProfile,
|
||||
changePassword,
|
||||
@@ -75,7 +75,7 @@ import {
|
||||
getSubsonicPasswordStatus,
|
||||
generateSubsonicPassword,
|
||||
clearSubsonicPassword
|
||||
} from '$lib/api/me';
|
||||
} from '#lib/api/me.js';
|
||||
|
||||
function mockStatusStore(data: LBStatus) {
|
||||
return readable({ data, isPending: false, isError: false });
|
||||
|
||||
Reference in New Issue
Block a user