Files
Homarr/src/pages/api/modules/media-requests/index.spec.ts
Manuel fb52c4b003 Add ad guard home (#937)
*  Add add guard home

*  Add request for blocked domains and fix request for blocked queries

* ♻️ PR feedback

*  Fix tests
2023-05-20 14:42:15 +02:00

539 lines
16 KiB
TypeScript

import Consola from 'consola';
import { createMocks } from 'node-mocks-http';
import { describe, expect, it, vi } from 'vitest';
import 'vitest-fetch-mock';
import { ConfigType } from '../../../../types/config';
import MediaRequestsRoute from './index';
const mockedGetConfig = vi.fn();
describe('media-requests api', () => {
it('reduce when empty list of requests', async () => {
// Arrange
const { req, res } = createMocks();
vi.mock('./../../../../tools/config/getConfig.ts', () => ({
get getConfig() {
return mockedGetConfig;
},
}));
mockedGetConfig.mockReturnValue({
apps: [],
});
// Act
await MediaRequestsRoute(req, res);
// Assert
expect(res._getStatusCode()).toBe(200);
expect(res.finished).toBe(true);
expect(JSON.parse(res._getData())).toEqual([]);
});
it('log error when fetch was not successful', async () => {
// Arrange
const { req, res } = createMocks();
vi.mock('./../../../../tools/config/getConfig.ts', () => ({
get getConfig() {
return mockedGetConfig;
},
}));
mockedGetConfig.mockReturnValue({
apps: [
{
integration: {
type: 'overseerr',
properties: [
{
field: 'apiKey',
type: 'private',
value: 'abc',
},
],
},
},
],
} as ConfigType);
const logSpy = vi.spyOn(Consola, 'error');
// Act
await MediaRequestsRoute(req, res);
// Assert
expect(res._getStatusCode()).toBe(200);
expect(res.finished).toBe(true);
expect(JSON.parse(res._getData())).toEqual([]);
expect(logSpy).toHaveBeenCalledOnce();
expect(logSpy.mock.lastCall).toEqual([
'Failed to request data from Overseerr: FetchError: invalid json response body at reason: Unexpected end of JSON input',
]);
logSpy.mockRestore();
});
it('fetch and return requests in response with external url', async () => {
// Arrange
const { req, res } = createMocks({
method: 'GET',
});
vi.mock('./../../../../tools/config/getConfig.ts', () => ({
get getConfig() {
return mockedGetConfig;
},
}));
mockedGetConfig.mockReturnValue({
apps: [
{
url: 'http://my-overseerr.local',
behaviour: {
externalUrl: 'http://my-overseerr.external',
},
integration: {
type: 'overseerr',
properties: [
{
field: 'apiKey',
type: 'private',
value: 'abc',
},
],
},
},
],
widgets: [
{
id: 'hjeruijgrig',
type: 'media-requests-list',
properties: {
replaceLinksWithExternalHost: true,
},
},
],
} as unknown as ConfigType);
const logSpy = vi.spyOn(Consola, 'error');
fetchMock.mockResponse((request) => {
if (request.url === 'http://my-overseerr.local/api/v1/request?take=25&skip=0&sort=added') {
return JSON.stringify({
pageInfo: { pages: 3, pageSize: 20, results: 42, page: 1 },
results: [
{
id: 44,
status: 2,
createdAt: '2023-04-06T19:38:45.000Z',
updatedAt: '2023-04-06T19:38:45.000Z',
type: 'movie',
is4k: false,
serverId: 0,
profileId: 4,
tags: [],
isAutoRequest: false,
media: {
downloadStatus: [],
downloadStatus4k: [],
id: 999,
mediaType: 'movie',
tmdbId: 99999999,
tvdbId: null,
imdbId: null,
status: 5,
status4k: 1,
createdAt: '2023-02-06T19:38:45.000Z',
updatedAt: '2023-02-06T20:00:04.000Z',
lastSeasonChange: '2023-08-06T19:38:45.000Z',
mediaAddedAt: '2023-05-14T06:30:34.000Z',
serviceId: 0,
serviceId4k: null,
externalServiceId: 32,
externalServiceId4k: null,
externalServiceSlug: '000000000000',
externalServiceSlug4k: null,
ratingKey: null,
ratingKey4k: null,
jellyfinMediaId: '0000',
jellyfinMediaId4k: null,
mediaUrl:
'http://your-jellyfin.local/web/index.html#!/details?id=mn8q2j4gq038g&context=home&serverId=jf83fj34gm340g',
serviceUrl: 'http://your-jellyfin.local/movie/0000',
},
seasons: [],
modifiedBy: {
permissions: 2,
warnings: [],
id: 1,
email: 'example-user@homarr.dev',
plexUsername: null,
jellyfinUsername: 'example-user',
username: null,
recoveryLinkExpirationDate: null,
userType: 3,
plexId: null,
jellyfinUserId: '00000000000000000',
jellyfinDeviceId: '111111111111111111',
jellyfinAuthToken: '2222222222222222222',
plexToken: null,
avatar: '/os_logo_square.png',
movieQuotaLimit: null,
movieQuotaDays: null,
tvQuotaLimit: null,
tvQuotaDays: null,
createdAt: '2022-07-03T19:53:08.000Z',
updatedAt: '2022-07-03T19:53:08.000Z',
requestCount: 34,
displayName: 'Example User',
},
requestedBy: {
permissions: 2,
warnings: [],
id: 1,
email: 'example-user@homarr.dev',
plexUsername: null,
jellyfinUsername: 'example-user',
username: null,
recoveryLinkExpirationDate: null,
userType: 3,
plexId: null,
jellyfinUserId: '00000000000000000',
jellyfinDeviceId: '111111111111111111',
jellyfinAuthToken: '2222222222222222222',
plexToken: null,
avatar: '/os_logo_square.png',
movieQuotaLimit: null,
movieQuotaDays: null,
tvQuotaLimit: null,
tvQuotaDays: null,
createdAt: '2022-07-03T19:53:08.000Z',
updatedAt: '2022-07-03T19:53:08.000Z',
requestCount: 34,
displayName: 'Example User',
},
seasonCount: 0,
},
],
});
}
if (request.url === 'http://my-overseerr.local/api/v1/movie/99999999') {
return JSON.stringify({
id: 0,
adult: false,
budget: 0,
genres: [
{
id: 18,
name: 'Dashboards',
},
],
relatedVideos: [],
originalLanguage: 'jp',
originalTitle: 'Homarrrr Movie',
popularity: 9.352,
productionCompanies: [],
productionCountries: [],
releaseDate: '2023-12-08',
releases: {
results: [],
},
revenue: 0,
spokenLanguages: [
{
english_name: 'Japanese',
iso_639_1: 'jp',
name: '日本語',
},
],
status: 'Released',
title: 'Homarr Movie',
video: false,
voteAverage: 9.999,
voteCount: 0,
backdropPath: '/mhjq8jr0qgrjnghnh.jpg',
homepage: '',
imdbId: 'tt0000000',
overview: 'A very cool movie',
posterPath: '/hf4j0928gq543njgh8935nqh8.jpg',
runtime: 97,
tagline: '',
credits: {},
collection: null,
externalIds: {
facebookId: null,
imdbId: null,
instagramId: null,
twitterId: null,
},
watchProviders: [],
keywords: [],
});
}
return Promise.reject(new Error(`Bad url: ${request.url}`));
});
// Act
await MediaRequestsRoute(req, res);
// Assert
expect(res._getStatusCode()).toBe(200);
expect(res.finished).toBe(true);
expect(JSON.parse(res._getData())).toEqual([
{
airDate: '2023-12-08',
backdropPath: 'https://image.tmdb.org/t/p/original//mhjq8jr0qgrjnghnh.jpg',
createdAt: '2023-04-06T19:38:45.000Z',
href: 'http://my-overseerr.external/movie/99999999',
id: 44,
name: 'Homarrrr Movie',
posterPath:
'https://image.tmdb.org/t/p/w600_and_h900_bestv2//hf4j0928gq543njgh8935nqh8.jpg',
status: 2,
type: 'movie',
userLink: 'http://my-overseerr.external/users/1',
userName: 'Example User',
userProfilePicture: 'http://my-overseerr.external//os_logo_square.png',
},
]);
expect(logSpy).not.toHaveBeenCalled();
logSpy.mockRestore();
});
it('fetch and return requests in response with internal url', async () => {
// Arrange
const { req, res } = createMocks({
method: 'GET',
});
vi.mock('./../../../../tools/config/getConfig.ts', () => ({
get getConfig() {
return mockedGetConfig;
},
}));
mockedGetConfig.mockReturnValue({
apps: [
{
url: 'http://my-overseerr.local',
behaviour: {
externalUrl: 'http://my-overseerr.external',
},
integration: {
type: 'overseerr',
properties: [
{
field: 'apiKey',
type: 'private',
value: 'abc',
},
],
},
},
],
widgets: [
{
id: 'hjeruijgrig',
type: 'media-requests-list',
properties: {
replaceLinksWithExternalHost: false,
},
},
],
} as unknown as ConfigType);
const logSpy = vi.spyOn(Consola, 'error');
fetchMock.mockResponse((request) => {
if (request.url === 'http://my-overseerr.local/api/v1/request?take=25&skip=0&sort=added') {
return JSON.stringify({
pageInfo: { pages: 3, pageSize: 20, results: 42, page: 1 },
results: [
{
id: 44,
status: 2,
createdAt: '2023-04-06T19:38:45.000Z',
updatedAt: '2023-04-06T19:38:45.000Z',
type: 'movie',
is4k: false,
serverId: 0,
profileId: 4,
tags: [],
isAutoRequest: false,
media: {
downloadStatus: [],
downloadStatus4k: [],
id: 999,
mediaType: 'movie',
tmdbId: 99999999,
tvdbId: null,
imdbId: null,
status: 5,
status4k: 1,
createdAt: '2023-02-06T19:38:45.000Z',
updatedAt: '2023-02-06T20:00:04.000Z',
lastSeasonChange: '2023-08-06T19:38:45.000Z',
mediaAddedAt: '2023-05-14T06:30:34.000Z',
serviceId: 0,
serviceId4k: null,
externalServiceId: 32,
externalServiceId4k: null,
externalServiceSlug: '000000000000',
externalServiceSlug4k: null,
ratingKey: null,
ratingKey4k: null,
jellyfinMediaId: '0000',
jellyfinMediaId4k: null,
mediaUrl:
'http://your-jellyfin.local/web/index.html#!/details?id=mn8q2j4gq038g&context=home&serverId=jf83fj34gm340g',
serviceUrl: 'http://your-jellyfin.local/movie/0000',
},
seasons: [],
modifiedBy: {
permissions: 2,
warnings: [],
id: 1,
email: 'example-user@homarr.dev',
plexUsername: null,
jellyfinUsername: 'example-user',
username: null,
recoveryLinkExpirationDate: null,
userType: 3,
plexId: null,
jellyfinUserId: '00000000000000000',
jellyfinDeviceId: '111111111111111111',
jellyfinAuthToken: '2222222222222222222',
plexToken: null,
avatar: '/os_logo_square.png',
movieQuotaLimit: null,
movieQuotaDays: null,
tvQuotaLimit: null,
tvQuotaDays: null,
createdAt: '2022-07-03T19:53:08.000Z',
updatedAt: '2022-07-03T19:53:08.000Z',
requestCount: 34,
displayName: 'Example User',
},
requestedBy: {
permissions: 2,
warnings: [],
id: 1,
email: 'example-user@homarr.dev',
plexUsername: null,
jellyfinUsername: 'example-user',
username: null,
recoveryLinkExpirationDate: null,
userType: 3,
plexId: null,
jellyfinUserId: '00000000000000000',
jellyfinDeviceId: '111111111111111111',
jellyfinAuthToken: '2222222222222222222',
plexToken: null,
avatar: '/os_logo_square.png',
movieQuotaLimit: null,
movieQuotaDays: null,
tvQuotaLimit: null,
tvQuotaDays: null,
createdAt: '2022-07-03T19:53:08.000Z',
updatedAt: '2022-07-03T19:53:08.000Z',
requestCount: 34,
displayName: 'Example User',
},
seasonCount: 0,
},
],
});
}
if (request.url === 'http://my-overseerr.local/api/v1/movie/99999999') {
return JSON.stringify({
id: 0,
adult: false,
budget: 0,
genres: [
{
id: 18,
name: 'Dashboards',
},
],
relatedVideos: [],
originalLanguage: 'jp',
originalTitle: 'Homarrrr Movie',
popularity: 9.352,
productionCompanies: [],
productionCountries: [],
releaseDate: '2023-12-08',
releases: {
results: [],
},
revenue: 0,
spokenLanguages: [
{
english_name: 'Japanese',
iso_639_1: 'jp',
name: '日本語',
},
],
status: 'Released',
title: 'Homarr Movie',
video: false,
voteAverage: 9.999,
voteCount: 0,
backdropPath: '/mhjq8jr0qgrjnghnh.jpg',
homepage: '',
imdbId: 'tt0000000',
overview: 'A very cool movie',
posterPath: '/hf4j0928gq543njgh8935nqh8.jpg',
runtime: 97,
tagline: '',
credits: {},
collection: null,
externalIds: {
facebookId: null,
imdbId: null,
instagramId: null,
twitterId: null,
},
watchProviders: [],
keywords: [],
});
}
return Promise.reject(new Error(`Bad url: ${request.url}`));
});
// Act
await MediaRequestsRoute(req, res);
// Assert
expect(res._getStatusCode()).toBe(200);
expect(res.finished).toBe(true);
expect(JSON.parse(res._getData())).toEqual([
{
airDate: '2023-12-08',
backdropPath: 'https://image.tmdb.org/t/p/original//mhjq8jr0qgrjnghnh.jpg',
createdAt: '2023-04-06T19:38:45.000Z',
href: 'http://my-overseerr.local/movie/99999999',
id: 44,
name: 'Homarrrr Movie',
posterPath:
'https://image.tmdb.org/t/p/w600_and_h900_bestv2//hf4j0928gq543njgh8935nqh8.jpg',
status: 2,
type: 'movie',
userLink: 'http://my-overseerr.local/users/1',
userName: 'Example User',
userProfilePicture: 'http://my-overseerr.local//os_logo_square.png',
},
]);
expect(logSpy).not.toHaveBeenCalled();
logSpy.mockRestore();
});
});