Add tests for API endpoints, liked store, listen tracker and paged list
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import type { LikedTrack, Track } from '$lib/types';
|
||||
|
||||
function track(id: string): Track {
|
||||
return {
|
||||
id,
|
||||
title: id,
|
||||
artist: 'Artist',
|
||||
duration: 100,
|
||||
explicit: false,
|
||||
listensCount: 0
|
||||
} as unknown as Track;
|
||||
}
|
||||
|
||||
function likedTrack(id: string): LikedTrack {
|
||||
return { ...track(id), likedAt: 1 } as LikedTrack;
|
||||
}
|
||||
|
||||
async function freshStore() {
|
||||
vi.resetModules();
|
||||
return (await import('./liked.svelte')).liked;
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
describe('liked store', () => {
|
||||
it('hydrates only once', async () => {
|
||||
const liked = await freshStore();
|
||||
liked.hydrate([likedTrack('a')]);
|
||||
liked.hydrate([likedTrack('b')]);
|
||||
expect(liked.isLiked('a')).toBe(true);
|
||||
expect(liked.isLiked('b')).toBe(false);
|
||||
expect(liked.count).toBe(1);
|
||||
});
|
||||
|
||||
it('likes and unlikes a track', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: true }));
|
||||
const liked = await freshStore();
|
||||
await liked.toggle(track('a'));
|
||||
expect(liked.isLiked('a')).toBe(true);
|
||||
await liked.toggle(track('a'));
|
||||
expect(liked.isLiked('a')).toBe(false);
|
||||
expect(fetch).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('reverts a failed like', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: false }));
|
||||
const liked = await freshStore();
|
||||
await liked.toggle(track('a'));
|
||||
expect(liked.isLiked('a')).toBe(false);
|
||||
});
|
||||
|
||||
it('reverts a failed unlike', async () => {
|
||||
const liked = await freshStore();
|
||||
liked.hydrate([likedTrack('a')]);
|
||||
vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('offline')));
|
||||
await liked.toggle(track('a'));
|
||||
expect(liked.isLiked('a')).toBe(true);
|
||||
});
|
||||
|
||||
it('keeps changes made to other tracks while a request fails', async () => {
|
||||
const liked = await freshStore();
|
||||
let rejectFirst: (reason: Error) => void = () => {};
|
||||
const fetchMock = vi
|
||||
.fn()
|
||||
.mockImplementationOnce(() => new Promise((_, reject) => (rejectFirst = reject)))
|
||||
.mockResolvedValueOnce({ ok: true });
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
|
||||
const first = liked.toggle(track('a'));
|
||||
await liked.toggle(track('b'));
|
||||
rejectFirst(new Error('offline'));
|
||||
await first;
|
||||
|
||||
expect(liked.isLiked('a')).toBe(false);
|
||||
expect(liked.isLiked('b')).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user