test: add comprehensive test suite for Ombi integration
- Add tests for Ombi configuration parsing (OMBI_INSTANCES JSON array, legacy fallback) - Add tests for OmbiClient API methods (movie/TV requests, search by TMDB/IMDB/TVDB) - Add tests for OmbiRetriever caching, queue, and search functionality - Add tests for arrRetrieverRegistry initialization and retrieval methods - Add tests for DownloadMatcher.addOmbiMatching integration - Add tests for DownloadAssembler Ombi link generation utilities - Export addOmbiMatching from DownloadMatcher module
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
// Copyright (c) 2026 Gordon Bolton. MIT License.
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import nock from 'nock';
|
||||
|
||||
// Mock the logger before importing the client
|
||||
vi.mock('../../../server/utils/logger', () => ({
|
||||
logToFile: vi.fn()
|
||||
}));
|
||||
|
||||
// Import OmbiClient after mocking
|
||||
const OmbiClient = require('../../../server/clients/OmbiClient');
|
||||
|
||||
describe('OmbiClient', () => {
|
||||
const baseUrl = 'http://localhost:5000';
|
||||
const apiKey = 'test-api-key-12345';
|
||||
|
||||
beforeEach(() => {
|
||||
// Clean up nock after each test
|
||||
nock.cleanAll();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
nock.cleanAll();
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should initialize with URL and API key', () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
|
||||
expect(client.url).toBe(baseUrl);
|
||||
expect(client.apiKey).toBe(apiKey);
|
||||
});
|
||||
|
||||
it('should remove trailing slash from URL', () => {
|
||||
const client = new OmbiClient('http://localhost:5000/', apiKey);
|
||||
|
||||
expect(client.url).toBe('http://localhost:5000');
|
||||
});
|
||||
|
||||
it('should set up axios with API key header', () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
|
||||
expect(client.axios.defaults.headers['ApiKey']).toBe(apiKey);
|
||||
});
|
||||
|
||||
it('should set up axios with 10 second timeout', () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
|
||||
expect(client.axios.defaults.timeout).toBe(10000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMovieRequests', () => {
|
||||
it('should return movie requests on successful API call', async () => {
|
||||
const mockMovies = [
|
||||
{ id: 1, title: 'Test Movie 1', theMovieDbId: '12345' },
|
||||
{ id: 2, title: 'Test Movie 2', theMovieDbId: '67890' }
|
||||
];
|
||||
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/movie')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, mockMovies);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.getMovieRequests();
|
||||
|
||||
expect(result).toEqual(mockMovies);
|
||||
});
|
||||
|
||||
it('should return empty array on API error', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/movie')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(500, { error: 'Internal Server Error' });
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.getMovieRequests();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return empty array when response data is null', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/movie')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, null);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.getMovieRequests();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTvRequests', () => {
|
||||
it('should return TV requests on successful API call', async () => {
|
||||
const mockTvShows = [
|
||||
{ id: 1, title: 'Test Show 1', theTvDbId: '12345' },
|
||||
{ id: 2, title: 'Test Show 2', theTvDbId: '67890' }
|
||||
];
|
||||
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/tv')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, mockTvShows);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.getTvRequests();
|
||||
|
||||
expect(result).toEqual(mockTvShows);
|
||||
});
|
||||
|
||||
it('should return empty array on API error', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/tv')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(500, { error: 'Internal Server Error' });
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.getTvRequests();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return empty array when response data is null', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/tv')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, null);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.getTvRequests();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchMovieByTmdbId', () => {
|
||||
it('should return movie data for valid TMDB ID', async () => {
|
||||
const mockMovie = {
|
||||
id: 12345,
|
||||
title: 'Test Movie',
|
||||
theMovieDbId: '12345'
|
||||
};
|
||||
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/movie/12345')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, mockMovie);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchMovieByTmdbId('12345');
|
||||
|
||||
expect(result).toEqual(mockMovie);
|
||||
});
|
||||
|
||||
it('should return null for null TMDB ID', async () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchMovieByTmdbId(null);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null for undefined TMDB ID', async () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchMovieByTmdbId(undefined);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null on API error', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/movie/12345')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(404, { error: 'Not Found' });
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchMovieByTmdbId('12345');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchMovieByImdbId', () => {
|
||||
it('should return movie data for valid IMDB ID', async () => {
|
||||
const mockMovie = {
|
||||
id: 12345,
|
||||
title: 'Test Movie',
|
||||
imdbId: 'tt1234567'
|
||||
};
|
||||
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/movie/imdb/tt1234567')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, mockMovie);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchMovieByImdbId('tt1234567');
|
||||
|
||||
expect(result).toEqual(mockMovie);
|
||||
});
|
||||
|
||||
it('should return null for null IMDB ID', async () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchMovieByImdbId(null);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null on API error', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/movie/imdb/tt1234567')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(404, { error: 'Not Found' });
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchMovieByImdbId('tt1234567');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchTvByTvdbId', () => {
|
||||
it('should return TV show data for valid TVDB ID', async () => {
|
||||
const mockShow = {
|
||||
id: 12345,
|
||||
title: 'Test Show',
|
||||
theTvDbId: '12345'
|
||||
};
|
||||
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/tv/12345')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, mockShow);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchTvByTvdbId('12345');
|
||||
|
||||
expect(result).toEqual(mockShow);
|
||||
});
|
||||
|
||||
it('should return null for null TVDB ID', async () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchTvByTvdbId(null);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null on API error', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/tv/12345')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(404, { error: 'Not Found' });
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchTvByTvdbId('12345');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchTvByTmdbId', () => {
|
||||
it('should return TV show data for valid TMDB ID', async () => {
|
||||
const mockShow = {
|
||||
id: 12345,
|
||||
title: 'Test Show',
|
||||
theMovieDbId: '67890'
|
||||
};
|
||||
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/tv/tmdb/67890')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, mockShow);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchTvByTmdbId('67890');
|
||||
|
||||
expect(result).toEqual(mockShow);
|
||||
});
|
||||
|
||||
it('should return null for null TMDB ID', async () => {
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchTvByTmdbId(null);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null on API error', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Search/tv/tmdb/67890')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(404, { error: 'Not Found' });
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.searchTvByTmdbId('67890');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('testConnection', () => {
|
||||
it('should return true for successful connection', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/movie')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(200, []);
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.testConnection();
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for failed connection', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/movie')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.reply(401, { error: 'Unauthorized' });
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.testConnection();
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false on network error', async () => {
|
||||
nock(baseUrl)
|
||||
.get('/api/v1/Request/movie')
|
||||
.matchHeader('ApiKey', apiKey)
|
||||
.replyWithError('Network error');
|
||||
|
||||
const client = new OmbiClient(baseUrl, apiKey);
|
||||
const result = await client.testConnection();
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user