Files
seerr/server/api/servarr/sonarr.test.ts

120 lines
3.8 KiB
TypeScript

import assert from 'node:assert/strict';
import { afterEach, describe, it, mock } from 'node:test';
import type { AxiosInstance } from 'axios';
import SonarrAPI from '@server/api/servarr/sonarr';
function buildSonarr(): SonarrAPI {
return new SonarrAPI({ url: 'http://localhost:8989/api/v3', apiKey: 'test' });
}
function getAxios(sonarr: SonarrAPI): AxiosInstance {
return (sonarr as unknown as { axios: AxiosInstance }).axios;
}
describe('SonarrAPI removeSeries', () => {
afterEach(() => mock.restoreAll());
it('removes the series when it exists in the library', async () => {
const sonarr = buildSonarr();
mock.method(SonarrAPI.prototype, 'getSeriesByTvdbId', async () => ({
id: 9,
title: 'Test Series',
}));
const del = mock.method(getAxios(sonarr), 'delete', async () => ({}));
await sonarr.removeSeries(1234);
assert.strictEqual(del.mock.callCount(), 1);
assert.strictEqual(del.mock.calls[0].arguments[0], '/series/9');
});
it('does nothing when the series is not in the library', async () => {
const sonarr = buildSonarr();
mock.method(getAxios(sonarr), 'get', async () => ({
data: [{ id: 0, title: 'Breaking Bad' }],
}));
const del = mock.method(getAxios(sonarr), 'delete', async () => ({}));
await assert.doesNotReject(() => sonarr.removeSeries(1234));
assert.strictEqual(del.mock.callCount(), 0);
});
it('rejects when the tvdbId is unknown to the lookup', async () => {
const sonarr = buildSonarr();
mock.method(getAxios(sonarr), 'get', async () => ({ data: [] }));
const del = mock.method(getAxios(sonarr), 'delete', async () => ({}));
await assert.rejects(() => sonarr.removeSeries(1234), /Series not found/);
assert.strictEqual(del.mock.callCount(), 0);
});
it('ignores a 404 when the series was already removed in Sonarr', async () => {
const sonarr = buildSonarr();
mock.method(SonarrAPI.prototype, 'getSeriesByTvdbId', async () => ({
id: 9,
title: 'Test Series',
}));
mock.method(getAxios(sonarr), 'delete', async () => {
throw { response: { status: 404 } };
});
await assert.doesNotReject(() => sonarr.removeSeries(1234));
});
it('rethrows errors other than 404', async () => {
const sonarr = buildSonarr();
mock.method(SonarrAPI.prototype, 'getSeriesByTvdbId', async () => ({
id: 9,
title: 'Test Series',
}));
mock.method(getAxios(sonarr), 'delete', async () => {
throw { response: { status: 500 } };
});
await assert.rejects(() => sonarr.removeSeries(1234));
});
it('rethrows a 404 from the lookup instead of treating it as removed', async () => {
const sonarr = buildSonarr();
mock.method(getAxios(sonarr), 'get', async () => {
throw { response: { status: 404 } };
});
const del = mock.method(getAxios(sonarr), 'delete', async () => ({}));
await assert.rejects(
() => sonarr.removeSeries(1234),
(e: unknown) =>
(e as { response?: { status?: number } }).response?.status === 404
);
assert.strictEqual(del.mock.callCount(), 0);
});
});
describe('SonarrAPI getSeriesByTvdbId', () => {
afterEach(() => mock.restoreAll());
it('rethrows a 401 from the lookup with the status intact', async () => {
const sonarr = buildSonarr();
mock.method(getAxios(sonarr), 'get', async () => {
throw { response: { status: 401 } };
});
await assert.rejects(
() => sonarr.getSeriesByTvdbId(1234),
(e: unknown) =>
(e as { response?: { status?: number } }).response?.status === 401
);
});
it('throws "Series not found" when the lookup returns no results', async () => {
const sonarr = buildSonarr();
mock.method(getAxios(sonarr), 'get', async () => ({ data: [] }));
await assert.rejects(() => sonarr.getSeriesByTvdbId(1234), {
message: 'Series not found',
});
});
});