Files
minstrel/web/src/lib/api/quarantine.test.ts
T

117 lines
3.2 KiB
TypeScript

import { describe, expect, test, vi, beforeEach, afterEach } from 'vitest';
vi.mock('./client', () => ({
api: {
get: vi.fn(),
post: vi.fn(),
put: vi.fn(),
del: vi.fn()
},
apiFetch: vi.fn()
}));
import { flagTrack, unflagTrack, listMyQuarantine } from './quarantine';
import { api, apiFetch } from './client';
import { qk } from './queries';
import type {
LidarrQuarantineRow,
LidarrQuarantineMineRow
} from './types';
const mockRow: LidarrQuarantineRow = {
user_id: 'u1',
track_id: 't1',
reason: 'bad_rip',
notes: null,
created_at: '2026-01-01T00:00:00Z'
};
const mockMineRow: LidarrQuarantineMineRow = {
track_id: 't1',
reason: 'bad_rip',
notes: null,
created_at: '2026-01-01T00:00:00Z',
track_title: 'Avril 14th',
track_duration_ms: 120000,
album_id: 'alb1',
album_title: 'Drukqs',
album_cover_art_path: null,
artist_id: 'art1',
artist_name: 'Aphex Twin'
};
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
vi.clearAllMocks();
});
describe('flagTrack', () => {
test('POSTs /api/quarantine without notes when none provided', async () => {
(api.post as ReturnType<typeof vi.fn>).mockResolvedValueOnce(mockRow);
const out = await flagTrack({ track_id: 't1', reason: 'bad_rip' });
expect(api.post).toHaveBeenCalledWith('/api/quarantine', {
track_id: 't1',
reason: 'bad_rip'
});
const body = (api.post as ReturnType<typeof vi.fn>).mock.calls[0][1] as Record<
string,
unknown
>;
expect(body).not.toHaveProperty('notes');
expect(out).toBe(mockRow);
});
test('omits empty-string notes from the body', async () => {
(api.post as ReturnType<typeof vi.fn>).mockResolvedValueOnce(mockRow);
await flagTrack({ track_id: 't1', reason: 'wrong_tags', notes: '' });
const body = (api.post as ReturnType<typeof vi.fn>).mock.calls[0][1] as Record<
string,
unknown
>;
expect(body).toEqual({ track_id: 't1', reason: 'wrong_tags' });
expect(body).not.toHaveProperty('notes');
});
test('includes notes when a non-empty string is provided', async () => {
(api.post as ReturnType<typeof vi.fn>).mockResolvedValueOnce(mockRow);
await flagTrack({
track_id: 't1',
reason: 'duplicate',
notes: 'same as t0'
});
expect(api.post).toHaveBeenCalledWith('/api/quarantine', {
track_id: 't1',
reason: 'duplicate',
notes: 'same as t0'
});
});
});
describe('unflagTrack', () => {
test('DELETEs /api/quarantine/:trackID', async () => {
(apiFetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce(null);
await unflagTrack('t1');
expect(apiFetch).toHaveBeenCalledWith('/api/quarantine/t1', {
method: 'DELETE'
});
});
});
describe('listMyQuarantine', () => {
test('GETs /api/quarantine/mine', async () => {
(api.get as ReturnType<typeof vi.fn>).mockResolvedValueOnce([mockMineRow]);
const out = await listMyQuarantine();
expect(api.get).toHaveBeenCalledWith('/api/quarantine/mine');
expect(out).toEqual([mockMineRow]);
});
});
describe('qk.myQuarantine', () => {
test('returns the expected key tuple', () => {
expect(qk.myQuarantine()).toEqual(['myQuarantine']);
});
});