26d9e429a9
Build and Push Docker Image / build (push) Successful in 46s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m21s
CI / Security audit (push) Successful in 1m37s
CI / Tests & coverage (push) Successful in 2m13s
CI / Swagger Validation & Coverage (push) Successful in 1m59s
This commit addresses code review findings and completes the test coverage plan for the new Ombi webhook functionality introduced in recent commits. Changes: - Removed obsolete tests for getOmbiLink and getOmbiSearchLink functions (replaced by getOmbiDetailsLink in commit "Fix: Generate Ombi links directly from TMDB ID") - Simplified DownloadMatcher.addOmbiMatching tests to match new synchronous implementation (no longer makes API calls, generates links from TMDB IDs) - Added comprehensive integration tests for Ombi webhook endpoints: * GET /api/ombi/webhook/status (6 tests) * POST /api/ombi/webhook/enable (4 tests) * POST /api/ombi/webhook/test (3 tests) - Added frontend state object tests for Ombi fields (7 tests) - Added skipped SSE endpoint tests with documentation (2 tests) - Added skipped frontend API/UI tests with documentation (5 tests) Code review fixes: - Fixed variable shadowing in ombi.test.js (reused outer scope variable) - Removed redundant network error test (duplicate of previous test) - Updated outdated documentation comment for skipped tests Test results: 764 passing, 15 skipped, 34 test files Skipped tests are documented with clear justifications: - SSE endpoint: requires EventSource or manual SSE handling - Frontend API functions: require complex mocking, covered by integration tests - Frontend UI functions: tightly coupled to DOM, better suited for E2E testing - GET /api/ombi/requests: requires complex arrRetrieverRegistry mocking Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
149 lines
5.0 KiB
JavaScript
149 lines
5.0 KiB
JavaScript
// Copyright (c) 2026 Gordon Bolton. MIT License.
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
|
|
// Mock dependencies
|
|
vi.mock('../../../server/utils/logger', () => ({
|
|
logToFile: vi.fn()
|
|
}));
|
|
|
|
// Import after mocking
|
|
const DownloadMatcher = require('../../../server/services/DownloadMatcher');
|
|
|
|
describe('DownloadMatcher', () => {
|
|
const ombiBaseUrl = 'http://localhost:5000';
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('addOmbiMatching', () => {
|
|
it('should return early when ombiBaseUrl is missing', () => {
|
|
const downloadObj = { type: 'series', title: 'Test Show' };
|
|
const series = { tvdbId: '12345', tmdbId: '67890' };
|
|
const context = { ombiBaseUrl: null };
|
|
|
|
DownloadMatcher.addOmbiMatching(downloadObj, series, context);
|
|
|
|
expect(downloadObj.ombiLink).toBeUndefined();
|
|
expect(downloadObj.ombiTooltip).toBeUndefined();
|
|
});
|
|
|
|
it('should return early when seriesOrMovie is missing', () => {
|
|
const downloadObj = { type: 'series', title: 'Test Show' };
|
|
const context = { ombiBaseUrl };
|
|
|
|
DownloadMatcher.addOmbiMatching(downloadObj, null, context);
|
|
|
|
expect(downloadObj.ombiLink).toBeUndefined();
|
|
expect(downloadObj.ombiTooltip).toBeUndefined();
|
|
});
|
|
|
|
it('should add ombiLink for series with TMDB ID', () => {
|
|
const downloadObj = { type: 'series', title: 'Test Show' };
|
|
const series = { tmdbId: '67890' };
|
|
const context = { ombiBaseUrl };
|
|
|
|
DownloadMatcher.addOmbiMatching(downloadObj, series, context);
|
|
|
|
expect(downloadObj.ombiLink).toBe('http://localhost:5000/details/tv/67890');
|
|
expect(downloadObj.ombiTooltip).toBe('View in Ombi');
|
|
});
|
|
|
|
it('should add ombiLink for movie with TMDB ID', () => {
|
|
const downloadObj = { type: 'movie', title: 'Test Movie' };
|
|
const movie = { tmdbId: '54321' };
|
|
const context = { ombiBaseUrl };
|
|
|
|
DownloadMatcher.addOmbiMatching(downloadObj, movie, context);
|
|
|
|
expect(downloadObj.ombiLink).toBe('http://localhost:5000/details/movie/54321');
|
|
expect(downloadObj.ombiTooltip).toBe('View in Ombi');
|
|
});
|
|
|
|
it('should not add ombiLink when TMDB ID is missing', () => {
|
|
const downloadObj = { type: 'series', title: 'Test Show' };
|
|
const series = { tvdbId: '12345' };
|
|
const context = { ombiBaseUrl };
|
|
|
|
DownloadMatcher.addOmbiMatching(downloadObj, series, context);
|
|
|
|
expect(downloadObj.ombiLink).toBeUndefined();
|
|
expect(downloadObj.ombiTooltip).toBeUndefined();
|
|
});
|
|
|
|
it('should not add ombiLink for unknown download type', () => {
|
|
const downloadObj = { type: 'unknown', title: 'Test Unknown' };
|
|
const series = { tmdbId: '67890' };
|
|
const context = { ombiBaseUrl };
|
|
|
|
DownloadMatcher.addOmbiMatching(downloadObj, series, context);
|
|
|
|
expect(downloadObj.ombiLink).toBeUndefined();
|
|
expect(downloadObj.ombiTooltip).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('buildSeriesMapFromRecords', () => {
|
|
it('should build a map from queue and history records', () => {
|
|
const queueRecords = [
|
|
{ seriesId: 1, series: { id: 1, title: 'Series 1' } }
|
|
];
|
|
const historyRecords = [
|
|
{ seriesId: 2, series: { id: 2, title: 'Series 2' } }
|
|
];
|
|
|
|
const result = DownloadMatcher.buildSeriesMapFromRecords(queueRecords, historyRecords);
|
|
|
|
expect(result.get(1)).toEqual({ id: 1, title: 'Series 1' });
|
|
expect(result.get(2)).toEqual({ id: 2, title: 'Series 2' });
|
|
});
|
|
|
|
it('should not overwrite existing series in map', () => {
|
|
const queueRecords = [
|
|
{ seriesId: 1, series: { id: 1, title: 'Series 1' } }
|
|
];
|
|
const historyRecords = [
|
|
{ seriesId: 1, series: { id: 1, title: 'Series 1 from History' } }
|
|
];
|
|
|
|
const result = DownloadMatcher.buildSeriesMapFromRecords(queueRecords, historyRecords);
|
|
|
|
expect(result.get(1).title).toBe('Series 1');
|
|
});
|
|
});
|
|
|
|
describe('buildMoviesMapFromRecords', () => {
|
|
it('should build a map from queue and history records', () => {
|
|
const queueRecords = [
|
|
{ movieId: 1, movie: { id: 1, title: 'Movie 1' } }
|
|
];
|
|
const historyRecords = [
|
|
{ movieId: 2, movie: { id: 2, title: 'Movie 2' } }
|
|
];
|
|
|
|
const result = DownloadMatcher.buildMoviesMapFromRecords(queueRecords, historyRecords);
|
|
|
|
expect(result.get(1)).toEqual({ id: 1, title: 'Movie 1' });
|
|
expect(result.get(2)).toEqual({ id: 2, title: 'Movie 2' });
|
|
});
|
|
});
|
|
|
|
describe('getSlotStatusAndSpeed', () => {
|
|
it('should return Paused status when queue is paused', () => {
|
|
const slot = { status: 'Downloading' };
|
|
const result = DownloadMatcher.getSlotStatusAndSpeed(slot, 'Paused', '0', '0');
|
|
|
|
expect(result.status).toBe('Paused');
|
|
expect(result.speed).toBe('0');
|
|
});
|
|
|
|
it('should return slot status when queue is active', () => {
|
|
const slot = { status: 'Downloading' };
|
|
const result = DownloadMatcher.getSlotStatusAndSpeed(slot, 'Active', '1.5 MB/s', '1536');
|
|
|
|
expect(result.status).toBe('Downloading');
|
|
expect(result.speed).toBe('1.5 MB/s');
|
|
});
|
|
});
|
|
});
|