refactor(web): sweep 24 test files to use makeTrack/makeTracks fixtures (#375)

Replaces inline TrackRef literal redefinitions with calls to the
test-utils helper. Tests that asserted on default field values
(e.g. track titles, artist names rendered in the DOM) keep explicit
overrides; tests that only need a stub for shape now use makeTrack()
with no overrides.

PlaylistCard.test.ts, PlaylistTrackRow.test.ts, and playlist.test.ts
SKIPPED — they use PlaylistTrack (with track_id/added_at), not TrackRef.
ArtistCard.svelte and +page.svelte route files (matched by initial grep)
SKIPPED — live code, not test files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-10 15:58:14 -04:00
parent 993bcc6a14
commit 9b4f907db6
24 changed files with 95 additions and 202 deletions
@@ -1,7 +1,7 @@
import { describe, expect, test, vi } from 'vitest'; import { describe, expect, test, vi } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte'; import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const playlistsData = vi.hoisted(() => ({ const playlistsData = vi.hoisted(() => ({
owned: [ owned: [
@@ -69,16 +69,7 @@ vi.mock('$lib/api/playlists', () => ({
import AddToPlaylistMenu from './AddToPlaylistMenu.svelte'; import AddToPlaylistMenu from './AddToPlaylistMenu.svelte';
const track: TrackRef = { const track = makeTrack();
id: 't1',
title: 'Roygbiv',
album_id: 'a1',
album_title: 'MHTRTC',
artist_id: 'ar1',
artist_name: 'BoC',
duration_sec: 137,
stream_url: '/api/tracks/t1/stream'
};
describe('AddToPlaylistMenu', () => { describe('AddToPlaylistMenu', () => {
test('lists own playlists alphabetically followed by "New playlist…"', () => { test('lists own playlists alphabetically followed by "New playlist…"', () => {
+9 -8
View File
@@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/svelte';
import type { AlbumRef, AlbumDetail, TrackRef } from '$lib/api/types'; import type { AlbumRef, AlbumDetail, TrackRef } from '$lib/api/types';
import { FALLBACK_COVER } from '$lib/media/covers'; import { FALLBACK_COVER } from '$lib/media/covers';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import { makeTrack } from '$test-utils/fixtures/track';
vi.mock('$lib/api/client', () => ({ vi.mock('$lib/api/client', () => ({
api: { get: vi.fn() } api: { get: vi.fn() }
@@ -80,13 +81,12 @@ describe('AlbumCard', () => {
test('+ queue button fetches album detail and calls enqueueTracks', async () => { test('+ queue button fetches album detail and calls enqueueTracks', async () => {
const tracks: TrackRef[] = [ const tracks: TrackRef[] = [
{ makeTrack({
id: 't1', title: 'So What', title: 'So What',
album_id: 'xyz', album_title: 'Kind of Blue', album_id: 'xyz', album_title: 'Kind of Blue',
artist_id: 'm-davis', artist_name: 'Miles Davis', artist_id: 'm-davis', artist_name: 'Miles Davis',
track_number: 1, disc_number: 1, duration_sec: 545, duration_sec: 545
stream_url: '/api/tracks/t1/stream' })
}
]; ];
const detail: AlbumDetail = { ...album, tracks }; const detail: AlbumDetail = { ...album, tracks };
(api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(detail); (api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(detail);
@@ -102,11 +102,12 @@ describe('AlbumCard', () => {
test('play overlay click fetches album detail and calls playQueue at index 0', async () => { test('play overlay click fetches album detail and calls playQueue at index 0', async () => {
const tracks: TrackRef[] = [ const tracks: TrackRef[] = [
{ id: 't1', title: 'So What', makeTrack({
title: 'So What',
album_id: 'xyz', album_title: 'Kind of Blue', album_id: 'xyz', album_title: 'Kind of Blue',
artist_id: 'm-davis', artist_name: 'Miles Davis', artist_id: 'm-davis', artist_name: 'Miles Davis',
track_number: 1, disc_number: 1, duration_sec: 545, duration_sec: 545
stream_url: '/api/tracks/t1/stream' } })
]; ];
const detail: AlbumDetail = { ...album, tracks }; const detail: AlbumDetail = { ...album, tracks };
(api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(detail); (api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(detail);
+4 -4
View File
@@ -3,6 +3,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { makeTracks } from '$test-utils/fixtures/track';
vi.mock('$app/navigation', () => ({ goto: vi.fn() })); vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
@@ -30,10 +31,9 @@ import { listAlbumTracks } from '$lib/api/albums';
import { likeEntity } from '$lib/api/likes'; import { likeEntity } from '$lib/api/likes';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
const TRACKS: TrackRef[] = [ const TRACKS: TrackRef[] = makeTracks(2, {
{ id: 't1', title: 'A', album_id: 'al1', album_title: 'Disc', artist_id: 'a1', artist_name: 'Test', duration_sec: 100, stream_url: '/s/t1' }, album_id: 'al1', album_title: 'Disc', artist_id: 'a1', artist_name: 'Test'
{ id: 't2', title: 'B', album_id: 'al1', album_title: 'Disc', artist_id: 'a1', artist_name: 'Test', duration_sec: 100, stream_url: '/s/t2' } });
];
const PROPS = { albumId: 'al1', albumTitle: 'Disc', artistId: 'a1', artistName: 'Test' }; const PROPS = { albumId: 'al1', albumTitle: 'Disc', artistId: 'a1', artistName: 'Test' };
+7 -9
View File
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, test, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte'; import { render, screen, fireEvent } from '@testing-library/svelte';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import type { ArtistRef, TrackRef } from '$lib/api/types'; import type { ArtistRef, TrackRef } from '$lib/api/types';
import { makeTrack, makeTracks } from '$test-utils/fixtures/track';
vi.mock('$lib/api/client', () => ({ vi.mock('$lib/api/client', () => ({
api: { get: vi.fn() } api: { get: vi.fn() }
@@ -46,14 +47,11 @@ describe('ArtistCard', () => {
}); });
test('play overlay fetches tracks, shuffles, calls playQueue', async () => { test('play overlay fetches tracks, shuffles, calls playQueue', async () => {
const tracks: TrackRef[] = [ const tracks: TrackRef[] = makeTracks(2, {
{ id: 't1', title: 'A', album_id: 'al-1', album_title: 'X', album_id: 'al-1', album_title: 'X',
artist_id: 'art-1', artist_name: 'BoC', artist_id: 'art-1', artist_name: 'BoC',
track_number: 1, disc_number: 1, duration_sec: 1, stream_url: '/x' }, duration_sec: 1
{ id: 't2', title: 'B', album_id: 'al-1', album_title: 'X', });
artist_id: 'art-1', artist_name: 'BoC',
track_number: 2, disc_number: 1, duration_sec: 1, stream_url: '/x' }
];
(api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(tracks); (api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce(tracks);
render(ArtistCard, { props: { artist } }); render(ArtistCard, { props: { artist } });
@@ -83,7 +81,7 @@ describe('ArtistCard', () => {
test('+queue button calls listArtistTracks then enqueueTracks', async () => { test('+queue button calls listArtistTracks then enqueueTracks', async () => {
const fakeTracks = [ const fakeTracks = [
{ id: 't1', title: 'A', album_id: 'al1', album_title: 'X', artist_id: 'art-1', artist_name: 'BoC', duration_sec: 60, stream_url: '/s/t1' } makeTrack({ artist_id: 'art-1', artist_name: 'BoC' })
]; ];
const { listArtistTracks } = await import('$lib/api/artists'); const { listArtistTracks } = await import('$lib/api/artists');
(listArtistTracks as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce(fakeTracks); (listArtistTracks as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce(fakeTracks);
+4 -4
View File
@@ -3,6 +3,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { makeTracks } from '$test-utils/fixtures/track';
vi.mock('$app/navigation', () => ({ goto: vi.fn() })); vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
@@ -28,10 +29,9 @@ import { enqueueTracks } from '$lib/player/store.svelte';
import { listArtistTracks } from '$lib/api/artists'; import { listArtistTracks } from '$lib/api/artists';
import { likeEntity, unlikeEntity } from '$lib/api/likes'; import { likeEntity, unlikeEntity } from '$lib/api/likes';
const TRACKS: TrackRef[] = [ const TRACKS: TrackRef[] = makeTracks(2, {
{ id: 't1', title: 'A', album_id: 'al1', album_title: 'X', artist_id: 'a1', artist_name: 'Test', duration_sec: 100, stream_url: '/s/t1' }, album_id: 'al1', artist_id: 'a1', artist_name: 'Test'
{ id: 't2', title: 'B', album_id: 'al1', album_title: 'X', artist_id: 'a1', artist_name: 'Test', duration_sec: 100, stream_url: '/s/t2' } });
];
afterEach(() => { afterEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
@@ -4,6 +4,7 @@ import type { TrackRef } from '$lib/api/types';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine'; import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine';
import { makeTracks } from '$test-utils/fixtures/track';
vi.mock('$lib/api/likes', () => emptyLikesMock()); vi.mock('$lib/api/likes', () => emptyLikesMock());
@@ -35,17 +36,11 @@ vi.mock('$lib/player/store.svelte', () => ({
import CompactTrackCard from './CompactTrackCard.svelte'; import CompactTrackCard from './CompactTrackCard.svelte';
import { playQueue, enqueueTrack } from '$lib/player/store.svelte'; import { playQueue, enqueueTrack } from '$lib/player/store.svelte';
const tracks: TrackRef[] = [ const titles = ['First', 'Second', 'Third'];
{ id: 't1', title: 'First', album_id: 'a1', album_title: 'A', const tracks: TrackRef[] = makeTracks(3, { artist_name: 'Artist' }).map((t, i) => ({
artist_id: 'art-1', artist_name: 'Artist', ...t,
track_number: 1, disc_number: 1, duration_sec: 1, stream_url: '/a' }, title: titles[i]
{ id: 't2', title: 'Second', album_id: 'a1', album_title: 'A', }));
artist_id: 'art-1', artist_name: 'Artist',
track_number: 2, disc_number: 1, duration_sec: 1, stream_url: '/b' },
{ id: 't3', title: 'Third', album_id: 'a1', album_title: 'A',
artist_id: 'art-1', artist_name: 'Artist',
track_number: 3, disc_number: 1, duration_sec: 1, stream_url: '/c' }
];
afterEach(() => vi.clearAllMocks()); afterEach(() => vi.clearAllMocks());
+2 -11
View File
@@ -1,7 +1,7 @@
import { afterEach, describe, expect, test, vi } from 'vitest'; import { afterEach, describe, expect, test, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte'; import { render, screen, fireEvent } from '@testing-library/svelte';
import FlagPopover from './FlagPopover.svelte'; import FlagPopover from './FlagPopover.svelte';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const invalidateMock = vi.fn(); const invalidateMock = vi.fn();
vi.mock('@tanstack/svelte-query', async (orig) => { vi.mock('@tanstack/svelte-query', async (orig) => {
@@ -18,16 +18,7 @@ vi.mock('$lib/api/quarantine', () => ({
import { flagTrack } from '$lib/api/quarantine'; import { flagTrack } from '$lib/api/quarantine';
const track: TrackRef = { const track = makeTrack();
id: 't1',
title: 'Roygbiv',
album_id: 'a1',
album_title: 'Geogaddi',
artist_id: 'ar1',
artist_name: 'Boards of Canada',
duration_sec: 240,
stream_url: '/api/tracks/t1/stream'
};
afterEach(() => vi.clearAllMocks()); afterEach(() => vi.clearAllMocks());
+4 -9
View File
@@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte'; import { render, screen, fireEvent } from '@testing-library/svelte';
import HistoryRow from './HistoryRow.svelte'; import HistoryRow from './HistoryRow.svelte';
import type { HistoryEvent } from '$lib/api/history'; import type { HistoryEvent } from '$lib/api/history';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const playQueue = vi.fn(); const playQueue = vi.fn();
@@ -10,16 +10,11 @@ vi.mock('$lib/player/store.svelte', () => ({
playQueue: (...args: unknown[]) => playQueue(...args) playQueue: (...args: unknown[]) => playQueue(...args)
})); }));
const sampleTrack: TrackRef = { const sampleTrack = makeTrack({
id: 'track-1',
title: 'Song Title', title: 'Song Title',
album_id: 'album-1',
album_title: 'Album', album_title: 'Album',
artist_id: 'artist-1', artist_name: 'Artist Name'
artist_name: 'Artist Name', });
duration_sec: 200,
stream_url: '/stream/track-1'
};
const sampleEvent: HistoryEvent = { const sampleEvent: HistoryEvent = {
id: 'event-1', id: 'event-1',
+5 -5
View File
@@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/svelte';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine'; import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine';
import { makeTrack } from '$test-utils/fixtures/track';
// Mutable state the mocked store reads from. // Mutable state the mocked store reads from.
const state = vi.hoisted(() => ({ const state = vi.hoisted(() => ({
@@ -57,13 +58,12 @@ import {
} from '$lib/player/store.svelte'; } from '$lib/player/store.svelte';
function track(): TrackRef { function track(): TrackRef {
return { return makeTrack({
id: 't1', title: 'So What', title: 'So What',
album_id: 'xyz', album_title: 'Kind of Blue', album_id: 'xyz', album_title: 'Kind of Blue',
artist_id: 'md', artist_name: 'Miles Davis', artist_id: 'md', artist_name: 'Miles Davis',
track_number: 1, disc_number: 1, duration_sec: 545
duration_sec: 545, stream_url: '/api/tracks/t1/stream' });
};
} }
beforeEach(() => { beforeEach(() => {
+2 -10
View File
@@ -2,6 +2,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte'; import { render, screen, fireEvent } from '@testing-library/svelte';
import QueueDrawer from './QueueDrawer.svelte'; import QueueDrawer from './QueueDrawer.svelte';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { makeTrack } from '$test-utils/fixtures/track';
const closeQueueDrawer = vi.fn(); const closeQueueDrawer = vi.fn();
let queueValue: TrackRef[] = []; let queueValue: TrackRef[] = [];
@@ -22,16 +23,7 @@ vi.mock('$lib/player/store.svelte', () => ({
moveQueueItem: vi.fn() moveQueueItem: vi.fn()
})); }));
const t = (id: string): TrackRef => ({ const t = (id: string): TrackRef => makeTrack({ id, title: `Song ${id}` });
id,
title: `Song ${id}`,
album_id: `al-${id}`,
album_title: 'A',
artist_id: `ar-${id}`,
artist_name: `Artist ${id}`,
duration_sec: 200,
stream_url: `/stream/${id}`
});
describe('QueueDrawer', () => { describe('QueueDrawer', () => {
beforeEach(() => { beforeEach(() => {
+4 -10
View File
@@ -1,7 +1,7 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'; import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte'; import { render, screen, fireEvent } from '@testing-library/svelte';
import QueueTrackRow from './QueueTrackRow.svelte'; import QueueTrackRow from './QueueTrackRow.svelte';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const playFromQueueIndex = vi.fn(); const playFromQueueIndex = vi.fn();
const removeFromQueue = vi.fn(); const removeFromQueue = vi.fn();
@@ -13,16 +13,10 @@ vi.mock('$lib/player/store.svelte', () => ({
moveQueueItem: (...args: unknown[]) => moveQueueItem(...args) moveQueueItem: (...args: unknown[]) => moveQueueItem(...args)
})); }));
const sampleTrack: TrackRef = { const sampleTrack = makeTrack({
id: 't1',
title: 'Song Title', title: 'Song Title',
album_id: 'al1', artist_name: 'Artist Name'
album_title: 'Album', });
artist_id: 'ar1',
artist_name: 'Artist Name',
duration_sec: 200,
stream_url: '/stream/t1'
};
describe('QueueTrackRow', () => { describe('QueueTrackRow', () => {
beforeEach(() => { beforeEach(() => {
@@ -1,6 +1,6 @@
import { afterEach, describe, expect, test, vi } from 'vitest'; import { afterEach, describe, expect, test, vi } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte'; import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const invalidateMock = vi.fn(); const invalidateMock = vi.fn();
vi.mock('@tanstack/svelte-query', async (orig) => { vi.mock('@tanstack/svelte-query', async (orig) => {
@@ -18,16 +18,7 @@ vi.mock('$lib/api/admin/tracks', () => ({
import RemoveTrackPopover from './RemoveTrackPopover.svelte'; import RemoveTrackPopover from './RemoveTrackPopover.svelte';
import { removeTrack } from '$lib/api/admin/tracks'; import { removeTrack } from '$lib/api/admin/tracks';
const track: TrackRef = { const track = makeTrack({ title: 'Roygbiv' });
id: 't1',
title: 'Roygbiv',
album_id: 'a1',
album_title: 'Geogaddi',
artist_id: 'ar1',
artist_name: 'Boards of Canada',
duration_sec: 240,
stream_url: '/api/tracks/t1/stream'
};
afterEach(() => vi.clearAllMocks()); afterEach(() => vi.clearAllMocks());
+2 -11
View File
@@ -3,7 +3,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine'; import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
// Mutable mock-user handle so individual tests can flip is_admin / null // Mutable mock-user handle so individual tests can flip is_admin / null
// without re-importing the module under test. // without re-importing the module under test.
@@ -44,16 +44,7 @@ vi.mock('$lib/player/store.svelte', () => ({
import TrackMenu from './TrackMenu.svelte'; import TrackMenu from './TrackMenu.svelte';
import { playNext, enqueueTrack } from '$lib/player/store.svelte'; import { playNext, enqueueTrack } from '$lib/player/store.svelte';
const track: TrackRef = { const track = makeTrack({ title: 'Roygbiv' });
id: 't1',
title: 'Roygbiv',
album_id: 'a1',
album_title: 'Geogaddi',
artist_id: 'ar1',
artist_name: 'Boards of Canada',
duration_sec: 240,
stream_url: '/api/tracks/t1/stream'
};
afterEach(() => { afterEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
+3 -14
View File
@@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/svelte';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine'; import { emptyQuarantineMock } from '../../test-utils/mocks/quarantine';
import { makeTrack } from '$test-utils/fixtures/track';
vi.mock('$lib/player/store.svelte', () => ({ vi.mock('$lib/player/store.svelte', () => ({
playQueue: vi.fn(), playQueue: vi.fn(),
@@ -18,20 +19,8 @@ import TrackRow from './TrackRow.svelte';
import { playQueue, enqueueTrack, playRadio } from '$lib/player/store.svelte'; import { playQueue, enqueueTrack, playRadio } from '$lib/player/store.svelte';
const tracks: TrackRef[] = [ const tracks: TrackRef[] = [
{ makeTrack({ title: 'So What', duration_sec: 545 }),
id: 't1', title: 'So What', makeTrack({ id: 't2', title: 'Freddie Freeloader', track_number: 2, duration_sec: 565, stream_url: '/api/tracks/t2/stream' })
album_id: 'xyz', album_title: 'Kind of Blue',
artist_id: 'm-davis', artist_name: 'Miles Davis',
track_number: 1, disc_number: 1,
duration_sec: 545, stream_url: '/api/tracks/t1/stream'
},
{
id: 't2', title: 'Freddie Freeloader',
album_id: 'xyz', album_title: 'Kind of Blue',
artist_id: 'm-davis', artist_name: 'Miles Davis',
track_number: 2, disc_number: 1,
duration_sec: 565, stream_url: '/api/tracks/t2/stream'
}
]; ];
afterEach(() => vi.clearAllMocks()); afterEach(() => vi.clearAllMocks());
+5 -6
View File
@@ -21,16 +21,15 @@ import {
} from './store.svelte'; } from './store.svelte';
import { api } from '$lib/api/client'; import { api } from '$lib/api/client';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { makeTrack } from '$test-utils/fixtures/track';
function track(id: string, dur = 200): TrackRef { function track(id: string, dur = 200): TrackRef {
return { return makeTrack({
id, title: `T ${id}`, id,
album_id: 'a', album_title: 'A', title: `T ${id}`,
artist_id: 'ar', artist_name: 'Ar',
track_number: Number(id), disc_number: 1,
duration_sec: dur, duration_sec: dur,
stream_url: `/api/tracks/${id}/stream` stream_url: `/api/tracks/${id}/stream`
}; });
} }
beforeEach(() => { beforeEach(() => {
@@ -1,15 +1,14 @@
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { makeTrack } from '$test-utils/fixtures/track';
function track(id: string): TrackRef { function track(id: string): TrackRef {
return { return makeTrack({
id, title: `T ${id}`, id,
album_id: 'a1', album_title: 'A', title: `T ${id}`,
artist_id: 'ar1', artist_name: 'Ar', stream_url: `/api/tracks/${id}/stream`
track_number: Number(id), disc_number: 1, });
duration_sec: 180, stream_url: `/api/tracks/${id}/stream`
};
} }
type Handler = (details: MediaSessionActionDetails) => void; type Handler = (details: MediaSessionActionDetails) => void;
+2 -11
View File
@@ -1,17 +1,8 @@
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { readPersistedQueue, writePersistedQueue, clearPersistedQueue } from './persisted'; import { readPersistedQueue, writePersistedQueue, clearPersistedQueue } from './persisted';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const sampleTrack: TrackRef = { const sampleTrack = makeTrack();
id: 't1',
title: 'Foo',
album_id: 'al1',
album_title: 'Baz',
artist_id: 'ar1',
artist_name: 'Bar',
duration_sec: 200,
stream_url: '/stream/t1'
};
describe('persisted queue', () => { describe('persisted queue', () => {
beforeEach(() => { beforeEach(() => {
+5 -6
View File
@@ -19,6 +19,7 @@ import {
} from './store.svelte'; } from './store.svelte';
import type { TrackRef } from '$lib/api/types'; import type { TrackRef } from '$lib/api/types';
import { writePersistedQueue, clearPersistedQueue } from './persisted'; import { writePersistedQueue, clearPersistedQueue } from './persisted';
import { makeTrack } from '$test-utils/fixtures/track';
vi.mock('$lib/auth/store.svelte', () => ({ vi.mock('$lib/auth/store.svelte', () => ({
user: { user: {
@@ -29,14 +30,12 @@ vi.mock('$lib/auth/store.svelte', () => ({
})); }));
function track(id: string, dur = 180): TrackRef { function track(id: string, dur = 180): TrackRef {
return { return makeTrack({
id, title: `T ${id}`, id,
album_id: 'a1', album_title: 'A', title: `T ${id}`,
artist_id: 'ar1', artist_name: 'Ar',
track_number: Number(id), disc_number: 1,
duration_sec: dur, duration_sec: dur,
stream_url: `/api/tracks/${id}/stream` stream_url: `/api/tracks/${id}/stream`
}; });
} }
beforeEach(() => { beforeEach(() => {
+2 -11
View File
@@ -1,20 +1,11 @@
import { describe, it, expect } from 'vitest'; import { describe, it, expect } from 'vitest';
import { dayBucket, groupByDay } from './dayGroup'; import { dayBucket, groupByDay } from './dayGroup';
import type { HistoryEvent } from '$lib/api/history'; import type { HistoryEvent } from '$lib/api/history';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const NOW = new Date('2026-05-04T14:00:00Z'); const NOW = new Date('2026-05-04T14:00:00Z');
const stubTrack: TrackRef = { const stubTrack = makeTrack();
id: 'track-x',
title: 'Song X',
album_id: 'al-x',
album_title: 'Album X',
artist_id: 'ar-x',
artist_name: 'Artist X',
duration_sec: 200,
stream_url: '/stream/x'
};
const mkEvent = (id: string, playedAt: string): HistoryEvent => ({ const mkEvent = (id: string, playedAt: string): HistoryEvent => ({
id, id,
+4 -3
View File
@@ -4,6 +4,7 @@ import { flushSync } from 'svelte';
import { mockQuery } from '../../../test-utils/query'; import { mockQuery } from '../../../test-utils/query';
import { emptyLikesMock } from '../../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../../test-utils/mocks/likes';
import type { AlbumDetail, TrackRef } from '$lib/api/types'; import type { AlbumDetail, TrackRef } from '$lib/api/types';
import { makeTrack } from '$test-utils/fixtures/track';
const state = vi.hoisted(() => ({ pageParams: { id: 'xyz' } as Record<string, string> })); const state = vi.hoisted(() => ({ pageParams: { id: 'xyz' } as Record<string, string> }));
@@ -25,14 +26,14 @@ import AlbumPage from './+page.svelte';
import { createAlbumQuery } from '$lib/api/queries'; import { createAlbumQuery } from '$lib/api/queries';
function track(id: string, title: string, number: number, dur: number): TrackRef { function track(id: string, title: string, number: number, dur: number): TrackRef {
return { return makeTrack({
id, title, id, title,
album_id: 'xyz', album_title: 'Kind of Blue', album_id: 'xyz', album_title: 'Kind of Blue',
artist_id: 'md', artist_name: 'Miles Davis', artist_id: 'md', artist_name: 'Miles Davis',
track_number: number, disc_number: 1, track_number: number,
duration_sec: dur, duration_sec: dur,
stream_url: `/api/tracks/${id}/stream` stream_url: `/api/tracks/${id}/stream`
}; });
} }
afterEach(() => { afterEach(() => {
+2 -11
View File
@@ -2,18 +2,9 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/svelte'; import { render, screen } from '@testing-library/svelte';
import HistoryPage from './+page.svelte'; import HistoryPage from './+page.svelte';
import type { HistoryEvent, HistoryResponse } from '$lib/api/history'; import type { HistoryEvent, HistoryResponse } from '$lib/api/history';
import type { TrackRef } from '$lib/api/types'; import { makeTrack } from '$test-utils/fixtures/track';
const mkTrack = (id: string): TrackRef => ({ const mkTrack = (id: string) => makeTrack({ id: `track-${id}`, title: `Song ${id}` });
id: `track-${id}`,
title: `Song ${id}`,
album_id: `album-${id}`,
album_title: `Album ${id}`,
artist_id: `artist-${id}`,
artist_name: `Artist ${id}`,
duration_sec: 200,
stream_url: `/stream/${id}`
});
const mkEvent = (id: string, playedAt: Date): HistoryEvent => ({ const mkEvent = (id: string, playedAt: Date): HistoryEvent => ({
id: `event-${id}`, id: `event-${id}`,
+5 -6
View File
@@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/svelte';
import { mockInfiniteQuery } from '../../../test-utils/query'; import { mockInfiniteQuery } from '../../../test-utils/query';
import type { ArtistRef, AlbumRef, TrackRef, Page } from '$lib/api/types'; import type { ArtistRef, AlbumRef, TrackRef, Page } from '$lib/api/types';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
import { makeTrack } from '$test-utils/fixtures/track';
vi.mock('$lib/api/likes', () => ({ vi.mock('$lib/api/likes', () => ({
createLikedIdsQuery: () => readable({ createLikedIdsQuery: () => readable({
@@ -42,12 +43,10 @@ describe('liked library page', () => {
id: 'al1', title: 'Y', sort_title: 'Y', artist_id: 'a1', artist_name: 'X', id: 'al1', title: 'Y', sort_title: 'Y', artist_id: 'a1', artist_name: 'X',
year: 2020, track_count: 1, duration_sec: 100, cover_url: '/x', cover_art_source: null year: 2020, track_count: 1, duration_sec: 100, cover_url: '/x', cover_art_source: null
}; };
const tr: TrackRef = { const tr: TrackRef = makeTrack({
id: 't1', title: 'Z', album_id: 'al1', album_title: 'Y', title: 'Z', album_id: 'al1', album_title: 'Y',
artist_id: 'a1', artist_name: 'X', artist_id: 'a1', artist_name: 'X', duration_sec: 100
track_number: 1, disc_number: 1, duration_sec: 100, });
stream_url: '/api/tracks/t1/stream'
};
(createLikedArtistsInfiniteQuery as ReturnType<typeof vi.fn>).mockReturnValue( (createLikedArtistsInfiniteQuery as ReturnType<typeof vi.fn>).mockReturnValue(
mockInfiniteQuery({ pages: [page([ar], 1)] }) mockInfiniteQuery({ pages: [page([ar], 1)] })
); );
+6 -6
View File
@@ -3,7 +3,8 @@ import { render, screen } from '@testing-library/svelte';
import { mockQuery } from '../../test-utils/query'; import { mockQuery } from '../../test-utils/query';
import { emptyLikesMock } from '../../test-utils/mocks/likes'; import { emptyLikesMock } from '../../test-utils/mocks/likes';
import { pageUrlModule } from '$test-utils/mocks/appState'; import { pageUrlModule } from '$test-utils/mocks/appState';
import type { ArtistRef, AlbumRef, TrackRef, SearchResponse } from '$lib/api/types'; import type { ArtistRef, AlbumRef, SearchResponse } from '$lib/api/types';
import { makeTrack } from '$test-utils/fixtures/track';
const state = vi.hoisted(() => ({ const state = vi.hoisted(() => ({
pageUrl: new URL('http://localhost/search') pageUrl: new URL('http://localhost/search')
@@ -44,13 +45,12 @@ const album: AlbumRef = {
id: 'al1', title: 'Kind of Blue', sort_title: 'Kind of Blue', artist_id: 'a1', artist_name: 'Miles Davis', id: 'al1', title: 'Kind of Blue', sort_title: 'Kind of Blue', artist_id: 'a1', artist_name: 'Miles Davis',
year: 1959, track_count: 5, duration_sec: 2630, cover_url: '/api/albums/al1/cover', cover_art_source: null year: 1959, track_count: 5, duration_sec: 2630, cover_url: '/api/albums/al1/cover', cover_art_source: null
}; };
const track: TrackRef = { const track = makeTrack({
id: 't1', title: 'So What', title: 'So What',
album_id: 'al1', album_title: 'Kind of Blue', album_id: 'al1', album_title: 'Kind of Blue',
artist_id: 'a1', artist_name: 'Miles Davis', artist_id: 'a1', artist_name: 'Miles Davis',
track_number: 1, disc_number: 1, duration_sec: 545, duration_sec: 545
stream_url: '/api/tracks/t1/stream' });
};
afterEach(() => { afterEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
+2 -7
View File
@@ -5,6 +5,7 @@ import { emptyLikesMock } from '../../../test-utils/mocks/likes';
import { emptyQuarantineMock } from '../../../test-utils/mocks/quarantine'; import { emptyQuarantineMock } from '../../../test-utils/mocks/quarantine';
import { pageUrlModule } from '$test-utils/mocks/appState'; import { pageUrlModule } from '$test-utils/mocks/appState';
import type { TrackRef, Page } from '$lib/api/types'; import type { TrackRef, Page } from '$lib/api/types';
import { makeTrack } from '$test-utils/fixtures/track';
const state = vi.hoisted(() => ({ pageUrl: new URL('http://localhost/search/tracks?q=miles') })); const state = vi.hoisted(() => ({ pageUrl: new URL('http://localhost/search/tracks?q=miles') }));
@@ -32,13 +33,7 @@ function page<T>(items: T[], total: number, offset = 0, limit = 50): Page<T> {
return { items, total, offset, limit }; return { items, total, offset, limit };
} }
const track: TrackRef = { const track = makeTrack({ title: 'So What' });
id: 't1', title: 'So What',
album_id: 'al1', album_title: 'Kind of Blue',
artist_id: 'a1', artist_name: 'Miles Davis',
track_number: 1, disc_number: 1, duration_sec: 545,
stream_url: '/api/tracks/t1/stream'
};
afterEach(() => { afterEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();