// Copyright (c) 2026 Gordon Bolton. MIT License. // Tests for the shared `buildArrQueueCache` helper (Issue #61). import { describe, it, expect } from 'vitest'; import { createRequire } from 'module'; const require = createRequire(import.meta.url); const { buildArrQueueCache } = require('../../../server/utils/arrQueueHelpers'); const sonarrInstances = [ { id: 's1', url: 'http://sonarr-1', apiKey: 'KEY_S1', name: 'Sonarr 1' } ]; const radarrInstances = [ { id: 'r1', url: 'http://radarr-1', apiKey: 'KEY_R1', name: 'Radarr 1' } ]; describe('buildArrQueueCache', () => { it('returns empty array for empty / missing input', () => { expect(buildArrQueueCache([], sonarrInstances, 'series')).toEqual([]); expect(buildArrQueueCache(null, sonarrInstances, 'series')).toEqual([]); expect(buildArrQueueCache(undefined, sonarrInstances, 'series')).toEqual([]); }); it('returns empty array for invalid mediaKey', () => { const queues = [{ instance: 's1', data: { records: [{ id: 1 }] } }]; expect(buildArrQueueCache(queues, sonarrInstances, 'bogus')).toEqual([]); }); it('tags Sonarr records with _instanceUrl/_instanceKey and decorates embedded series', () => { const queues = [ { instance: 's1', data: { records: [ { id: 1, downloadId: 'dl-1', series: { id: 100, title: 'X' } } ] } } ]; const out = buildArrQueueCache(queues, sonarrInstances, 'series'); expect(out).toHaveLength(1); expect(out[0]._instanceUrl).toBe('http://sonarr-1'); expect(out[0]._instanceKey).toBe('KEY_S1'); expect(out[0].series._instanceUrl).toBe('http://sonarr-1'); }); it('tags Radarr records and decorates embedded movie', () => { const queues = [ { instance: 'r1', data: { records: [ { id: 11, downloadId: 'dl-r1', movie: { id: 555, title: 'M' } } ] } } ]; const out = buildArrQueueCache(queues, radarrInstances, 'movie'); expect(out).toHaveLength(1); expect(out[0]._instanceUrl).toBe('http://radarr-1'); expect(out[0]._instanceKey).toBe('KEY_R1'); expect(out[0].movie._instanceUrl).toBe('http://radarr-1'); }); it('annotates Sonarr season pack records (multiple entries sharing downloadId)', () => { const queues = [ { instance: 's1', data: { records: [ { id: 1, downloadId: 'pack-A', episodeId: 101 }, { id: 2, downloadId: 'pack-A', episodeId: 102 }, { id: 3, downloadId: 'pack-A', episodeId: 103 }, { id: 4, downloadId: 'single-B', episodeId: 200 } ] } } ]; const out = buildArrQueueCache(queues, sonarrInstances, 'series'); expect(out).toHaveLength(4); const packMembers = out.filter(r => r.downloadId === 'pack-A'); expect(packMembers).toHaveLength(3); for (const r of packMembers) { expect(r.isSeasonPack).toBe(true); expect(r.episodeCount).toBe(3); } const single = out.find(r => r.downloadId === 'single-B'); expect(single.isSeasonPack).toBeUndefined(); expect(single.episodeCount).toBeUndefined(); }); it('does not annotate Radarr records as season packs even if downloadId repeats', () => { const queues = [ { instance: 'r1', data: { records: [ { id: 1, downloadId: 'dup', movie: { id: 1 } }, { id: 2, downloadId: 'dup', movie: { id: 2 } } ] } } ]; const out = buildArrQueueCache(queues, radarrInstances, 'movie'); expect(out).toHaveLength(2); for (const r of out) { expect(r.isSeasonPack).toBeUndefined(); expect(r.episodeCount).toBeUndefined(); } }); it('skips malformed records and continues', () => { const queues = [ { instance: 's1', data: { records: [ null, { id: 1, downloadId: 'ok', series: { id: 1 } } ] } }, null, { instance: 's1' } // no data property ]; const out = buildArrQueueCache(queues, sonarrInstances, 'series'); expect(out).toHaveLength(1); expect(out[0].id).toBe(1); }); it('handles unknown instance id gracefully (null url/key)', () => { const queues = [ { instance: 'unknown-instance', data: { records: [{ id: 1, downloadId: 'x' }] } } ]; const out = buildArrQueueCache(queues, sonarrInstances, 'series'); expect(out).toHaveLength(1); expect(out[0]._instanceUrl).toBeNull(); expect(out[0]._instanceKey).toBeNull(); }); });