import { afterEach, describe, expect, test, vi } from 'vitest'; import { removeTrack } from './tracks'; afterEach(() => { vi.unstubAllGlobals(); }); function stubFetch(status: number, body: unknown, init: Partial = {}) { const res = new Response( body === null ? null : JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' }, ...init } ); const spy = vi.fn().mockResolvedValue(res); vi.stubGlobal('fetch', spy); return spy; } describe('removeTrack', () => { test('DELETEs /api/admin/tracks/:id with no query string when unmonitor unset', async () => { const spy = stubFetch(200, { deleted_track_id: 't-1', deleted_album_id: 'al-1' }); const r = await removeTrack('t-1'); expect(r.deleted_track_id).toBe('t-1'); expect(r.deleted_album_id).toBe('al-1'); expect(r.deleted_artist_id).toBeUndefined(); expect(r.lidarr_unmonitor_failed).toBeUndefined(); const call = spy.mock.calls[0]; expect(call[0]).toBe('/api/admin/tracks/t-1'); expect((call[1] as RequestInit).method).toBe('DELETE'); }); test('appends ?unmonitor=true when option set', async () => { const spy = stubFetch(200, { deleted_track_id: 't-1', lidarr_unmonitor_failed: true }); const r = await removeTrack('t-1', { unmonitor: true }); expect(r.lidarr_unmonitor_failed).toBe(true); const call = spy.mock.calls[0]; expect(call[0]).toBe('/api/admin/tracks/t-1?unmonitor=true'); }); test('omits the query string when unmonitor: false', async () => { const spy = stubFetch(200, { deleted_track_id: 't-1' }); await removeTrack('t-1', { unmonitor: false }); const call = spy.mock.calls[0]; expect(call[0]).toBe('/api/admin/tracks/t-1'); }); test('surfaces not_found as ApiError', async () => { stubFetch(404, { error: 'not_found' }); await expect(removeTrack('t-1')).rejects.toMatchObject({ code: 'not_found' }); }); });