tests to ensure entries are created

This commit is contained in:
iPromKnight
2024-02-09 14:59:27 +00:00
committed by iPromKnight
parent c2ada8344e
commit 36864e4db1
9 changed files with 260 additions and 16 deletions

View File

@@ -1,12 +1,12 @@
import {IParsedTorrent} from "@interfaces/parsed_torrent"; import {IParsedTorrent} from "@interfaces/parsed_torrent";
import {ITorrentAttributes} from "@repository/interfaces/torrent_attributes"; import {ITorrentAttributes, ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes";
import {SkipTorrent} from "@repository/models/skipTorrent"; import {SkipTorrent} from "@repository/models/skipTorrent";
import {Torrent} from "@repository/models/torrent"; import {Torrent} from "@repository/models/torrent";
export interface ITorrentEntriesService { export interface ITorrentEntriesService {
createTorrentEntry(torrent: IParsedTorrent, overwrite: boolean): Promise<void>; createTorrentEntry(torrent: IParsedTorrent, overwrite: boolean): Promise<void>;
createSkipTorrentEntry(torrent: Torrent): Promise<[SkipTorrent, boolean | null]>; createSkipTorrentEntry(torrent: ITorrentCreationAttributes): Promise<[SkipTorrent, boolean | null]>;
getStoredTorrentEntry(torrent: Torrent): Promise<Torrent | SkipTorrent | null | undefined>; getStoredTorrentEntry(torrent: Torrent): Promise<Torrent | SkipTorrent | null | undefined>;

View File

@@ -110,7 +110,7 @@ export class TorrentEntriesService implements ITorrentEntriesService {
.then(() => this.logger.info(`Created ${torrent.provider} entry for [${torrent.infoHash}] ${torrent.title}`)); .then(() => this.logger.info(`Created ${torrent.provider} entry for [${torrent.infoHash}] ${torrent.title}`));
}; };
public createSkipTorrentEntry: (torrent: Torrent) => Promise<[SkipTorrent, boolean | null]> = async (torrent: Torrent) => this.repository.createSkipTorrent(torrent.dataValues); public createSkipTorrentEntry: (torrent: ITorrentCreationAttributes) => Promise<[SkipTorrent, boolean | null]> = async (torrent: ITorrentCreationAttributes) => this.repository.createSkipTorrent(torrent);
public getStoredTorrentEntry = async (torrent: Torrent): Promise<Torrent | SkipTorrent | null | undefined> => this.repository.getSkipTorrent(torrent.infoHash) public getStoredTorrentEntry = async (torrent: Torrent): Promise<Torrent | SkipTorrent | null | undefined> => this.repository.getSkipTorrent(torrent.infoHash)
.catch(() => this.repository.getTorrent(torrent.dataValues)) .catch(() => this.repository.getTorrent(torrent.dataValues))
@@ -173,8 +173,6 @@ export class TorrentEntriesService implements ITorrentEntriesService {
return {}; return {};
}); });
this.assignMetaIds(fileCollection, imdbId, kitsuId);
if (!fileCollection.contents || !fileCollection.contents.length) { if (!fileCollection.contents || !fileCollection.contents.length) {
return; return;
} }
@@ -206,10 +204,13 @@ export class TorrentEntriesService implements ITorrentEntriesService {
} }
return Promise.resolve(); return Promise.resolve();
}) })
.then(() => PromiseHelpers.sequence(fileCollection.videos!.map(video => (): Promise<void> => { .then(() => {
const newVideo: IFileCreationAttributes = {...video, infoHash: video.infoHash, title: video.title}; const promises = fileCollection.videos!.map(video => {
return this.repository.createFile(newVideo) const newVideo: IFileCreationAttributes = {...video, infoHash: video.infoHash, title: video.title};
}))) return this.repository.createFile(newVideo);
});
return Promise.all(promises);
})
.then(() => this.logger.info(`Created contents for ${torrent.provider} [${torrent.infoHash}] ${torrent.title}`)) .then(() => this.logger.info(`Created contents for ${torrent.provider} [${torrent.infoHash}] ${torrent.title}`))
.catch(error => this.logger.error(`Failed saving contents for [${torrent.infoHash}] ${torrent.title}`, error)); .catch(error => this.logger.error(`Failed saving contents for [${torrent.infoHash}] ${torrent.title}`, error));
}; };
@@ -248,7 +249,7 @@ export class TorrentEntriesService implements ITorrentEntriesService {
}; };
private assignMetaIds = (fileCollection: ITorrentFileCollection, imdbId: string | undefined, kitsuId: number): ITorrentFileCollection => { private assignMetaIds = (fileCollection: ITorrentFileCollection, imdbId: string | undefined, kitsuId: number): ITorrentFileCollection => {
if (fileCollection.videos && fileCollection.videos.length) { if (fileCollection && fileCollection.videos && fileCollection.videos.length) {
fileCollection.videos.forEach(video => { fileCollection.videos.forEach(video => {
video.imdbId = imdbId || ''; video.imdbId = imdbId || '';
video.kitsuId = kitsuId || 0; video.kitsuId = kitsuId || 0;

View File

@@ -47,6 +47,7 @@ describe('CacheService Tests', () => {
cacheMethod: CacheMethod; cacheMethod: CacheMethod;
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks();
process.env.LOG_LEVEL = 'debug'; process.env.LOG_LEVEL = 'debug';
loggingService = jest.requireMock<ILoggingService>('@services/logging_service'); loggingService = jest.requireMock<ILoggingService>('@services/logging_service');
cacheMethod = jest.fn().mockResolvedValue({}); cacheMethod = jest.fn().mockResolvedValue({});

View File

@@ -19,6 +19,7 @@ describe('LoggingService Tests', () => {
mockLogger: any; mockLogger: any;
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks();
service = new LoggingService(); service = new LoggingService();
mockLogger = (service as any).logger; mockLogger = (service as any).logger;
}); });

View File

@@ -23,6 +23,7 @@ const server = setupServer(
beforeAll(() => server.listen()) beforeAll(() => server.listen())
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(Date, 'now').mockImplementation(() => 1234567890); jest.spyOn(Date, 'now').mockImplementation(() => 1234567890);
}) })
afterEach(() => () => { afterEach(() => () => {

View File

@@ -53,6 +53,7 @@ describe('ProcessTorrentsJob Tests', () => {
torrentProcessingService: ITorrentProcessingService; torrentProcessingService: ITorrentProcessingService;
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks();
loggingService = jest.requireMock<ILoggingService>('@services/logging_service'); loggingService = jest.requireMock<ILoggingService>('@services/logging_service');
torrentProcessingService = jest.requireMock('@services/torrent_processing_service'); torrentProcessingService = jest.requireMock('@services/torrent_processing_service');
processTorrentsJob = new ProcessTorrentsJob(torrentProcessingService, loggingService); processTorrentsJob = new ProcessTorrentsJob(torrentProcessingService, loggingService);

View File

@@ -25,6 +25,7 @@ describe('TorrentDownloadService', () => {
mockLoggingService: ILoggingService; mockLoggingService: ILoggingService;
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks();
mockLoggingService = jest.requireMock<ILoggingService>('@services/logging_service'); mockLoggingService = jest.requireMock<ILoggingService>('@services/logging_service');
torrentDownloadService = new TorrentDownloadService(mockLoggingService); torrentDownloadService = new TorrentDownloadService(mockLoggingService);
}); });

View File

@@ -7,10 +7,11 @@ import {ITorrentFileCollection} from "@interfaces/torrent_file_collection";
import {ITorrentFileService} from "@interfaces/torrent_file_service"; import {ITorrentFileService} from "@interfaces/torrent_file_service";
import {ITorrentSubtitleService} from "@interfaces/torrent_subtitle_service"; import {ITorrentSubtitleService} from "@interfaces/torrent_subtitle_service";
import {IDatabaseRepository} from "@repository/interfaces/database_repository"; import {IDatabaseRepository} from "@repository/interfaces/database_repository";
import {IFileAttributes} from "@repository/interfaces/file_attributes";
import {ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes";
import {Torrent} from "@repository/models/torrent";
import {TorrentEntriesService} from "@services/torrent_entries_service"; import {TorrentEntriesService} from "@services/torrent_entries_service";
jest.mock('@services/logging_service', () => { jest.mock('@services/logging_service', () => {
return { return {
error: jest.fn(), error: jest.fn(),
@@ -22,19 +23,21 @@ jest.mock('@services/logging_service', () => {
jest.mock('@services/torrent_file_service', () => { jest.mock('@services/torrent_file_service', () => {
return { return {
parseTorrentFiles: jest.fn(), parseTorrentFiles: jest.fn().mockResolvedValue(undefined),
isPackTorrent: jest.fn().mockResolvedValue(undefined),
} }
}) })
jest.mock('@services/metadata_service', () => { jest.mock('@services/metadata_service', () => {
return { return {
getImdbId: jest.fn(), getImdbId: jest.fn().mockResolvedValue(undefined),
getKitsuId: jest.fn().mockResolvedValue(undefined),
} }
}) })
jest.mock('@services/torrent_subtitle_service', () => { jest.mock('@services/torrent_subtitle_service', () => {
return { return {
assignSubtitles: jest.fn(), assignSubtitles: jest.fn().mockResolvedValue(undefined),
} }
}) })
@@ -42,6 +45,11 @@ jest.mock('@repository/database_repository', () => {
return { return {
createTorrent: jest.fn().mockResolvedValue(undefined), createTorrent: jest.fn().mockResolvedValue(undefined),
createFile: jest.fn().mockResolvedValue(undefined), createFile: jest.fn().mockResolvedValue(undefined),
createSkipTorrent: jest.fn().mockResolvedValue(undefined),
getSkipTorrent: jest.fn().mockResolvedValue(undefined),
getTorrent: jest.fn().mockResolvedValue(undefined),
setTorrentSeeders: jest.fn().mockResolvedValue(undefined),
getFiles: jest.fn().mockResolvedValue(undefined),
} }
}) })
@@ -54,6 +62,8 @@ describe('TorrentEntriesService Tests', () => {
mockDatabaseRepository: IDatabaseRepository; mockDatabaseRepository: IDatabaseRepository;
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks();
mockFileService = jest.requireMock<ITorrentFileService>('@services/torrent_file_service'); mockFileService = jest.requireMock<ITorrentFileService>('@services/torrent_file_service');
mockMetadataService = jest.requireMock<IMetadataService>('@services/metadata_service'); mockMetadataService = jest.requireMock<IMetadataService>('@services/metadata_service');
mockSubtitleService = jest.requireMock<ITorrentSubtitleService>('@services/torrent_subtitle_service'); mockSubtitleService = jest.requireMock<ITorrentSubtitleService>('@services/torrent_subtitle_service');
@@ -106,4 +116,231 @@ describe('TorrentEntriesService Tests', () => {
expect(mockSubtitleService.assignSubtitles).toHaveReturnedWith(Promise.resolve(fileCollectionWithSubtitles)); expect(mockSubtitleService.assignSubtitles).toHaveReturnedWith(Promise.resolve(fileCollectionWithSubtitles));
expect(mockDatabaseRepository.createTorrent).toHaveBeenCalledWith(expect.objectContaining(torrent)); expect(mockDatabaseRepository.createTorrent).toHaveBeenCalledWith(expect.objectContaining(torrent));
}); });
it('should assign imdbId correctly', async () => {
const torrent : IParsedTorrent = {
title: 'Test title',
provider: 'Test provider',
infoHash: 'Test infoHash',
type: TorrentType.Movie,
};
const fileCollection : ITorrentFileCollection = {
videos: [{
fileIndex: 0,
title: 'Test video',
size: 123456,
imdbId: 'tt1234567',
}],
contents: [],
subtitles: [],
};
const fileCollectionWithSubtitles : ITorrentFileCollection = {
...fileCollection,
subtitles: [ {
fileId: 0,
title: 'Test subtitle',
fileIndex: 0,
path: 'Test path',
infoHash: 'Test infoHash',
}],
};
(mockMetadataService.getImdbId as jest.Mock).mockResolvedValue('tt1234567');
(mockFileService.parseTorrentFiles as jest.Mock).mockResolvedValue(fileCollection);
(mockSubtitleService.assignSubtitles as jest.Mock).mockResolvedValue(fileCollectionWithSubtitles);
(mockDatabaseRepository.createTorrent as jest.Mock).mockResolvedValue(torrent);
await torrentEntriesService.createTorrentEntry(torrent);
expect(torrent.imdbId).toEqual('tt1234567');
expect(torrent.kitsuId).toEqual(undefined);
});
it('should assign kitsuId correctly', async () => {
const torrent : IParsedTorrent = {
title: 'Test title',
provider: 'Test provider',
infoHash: 'Test infoHash',
type: TorrentType.Anime,
};
const fileCollection : ITorrentFileCollection = {
videos: [{
fileIndex: 0,
title: 'Test video',
size: 123456,
kitsuId: 11
}],
contents: [],
subtitles: [],
};
const fileCollectionWithSubtitles : ITorrentFileCollection = {
...fileCollection,
subtitles: [ {
fileId: 0,
title: 'Test subtitle',
fileIndex: 0,
path: 'Test path',
infoHash: 'Test infoHash',
}],
};
(mockMetadataService.getKitsuId as jest.Mock).mockResolvedValue(11);
(mockFileService.parseTorrentFiles as jest.Mock).mockResolvedValue(fileCollection);
(mockSubtitleService.assignSubtitles as jest.Mock).mockResolvedValue(fileCollectionWithSubtitles);
(mockDatabaseRepository.createTorrent as jest.Mock).mockResolvedValue(torrent);
await torrentEntriesService.createTorrentEntry(torrent);
expect(torrent.imdbId).toEqual(undefined);
expect(torrent.kitsuId).toEqual(11);
});
it('should create a skip torrent entry', async () => {
const torrent: ITorrentCreationAttributes = {
infoHash: 'Test infoHash',
provider: 'Test provider',
title: 'Test title',
type: TorrentType.Movie,
};
(mockDatabaseRepository.createSkipTorrent as jest.Mock).mockResolvedValue([torrent, null]);
const result = await torrentEntriesService.createSkipTorrentEntry(torrent);
expect(mockDatabaseRepository.createSkipTorrent).toHaveBeenCalledWith(torrent);
expect(result).toEqual([torrent, null]);
});
it('should get stored torrent entry', async () => {
const torrent = {
infoHash: 'Test infoHash',
provider: 'Test provider',
title: 'Test title',
type: TorrentType.Movie,
dataValues: {
infoHash: 'Test infoHash',
provider: 'Test provider',
title: 'Test title',
type: TorrentType.Movie,
}
} as Torrent;
(mockDatabaseRepository.getSkipTorrent as jest.Mock).mockRejectedValue(undefined);
(mockDatabaseRepository.getTorrent as jest.Mock).mockResolvedValue(torrent);
const result = await torrentEntriesService.getStoredTorrentEntry(torrent);
expect(mockDatabaseRepository.getSkipTorrent).toHaveBeenCalledWith(torrent.infoHash);
expect(mockDatabaseRepository.getTorrent).toHaveBeenCalledWith(torrent.dataValues);
expect(result).toEqual(torrent);
});
it('should check and update torrent', async () => {
const torrent : IParsedTorrent = {
title: 'Test title',
provider: 'Test provider',
infoHash: 'Test infoHash',
type: TorrentType.Movie,
seeders: 1,
};
const files : IFileAttributes[] = [{
infoHash: 'Test infoHash',
fileIndex: 0,
title: 'Test title',
path: 'Test path',
size: 123456,
},{
infoHash: 'Test infoHash 2',
fileIndex: 1,
title: 'Test title 2',
path: 'Test path 2',
size: 234567,
}];
const torrentInstance = {
...torrent,
dataValues:{ ...torrent},
save: jest.fn().mockResolvedValue(torrent),
};
const filesInstance = {
...files,
dataValues:{ ...files},
save: jest.fn().mockResolvedValue(files),
};
const seedersResponse = [1];
(mockDatabaseRepository.getTorrent as jest.Mock).mockResolvedValue(torrentInstance);
(mockDatabaseRepository.setTorrentSeeders as jest.Mock).mockResolvedValue(seedersResponse);
(mockDatabaseRepository.getFiles as jest.Mock).mockResolvedValue(filesInstance)
const result = await torrentEntriesService.checkAndUpdateTorrent(torrent);
expect(mockDatabaseRepository.getTorrent).toHaveBeenCalledWith({
infoHash: torrent.infoHash,
provider: torrent.provider
});
expect(mockDatabaseRepository.getFiles).toHaveBeenCalledWith(torrent.infoHash);
expect(mockDatabaseRepository.setTorrentSeeders).toHaveBeenCalledWith(torrentInstance.dataValues, 1);
expect(result).toEqual(true);
});
it('should create torrent contents', async () => {
const torrent = {
infoHash: 'Test infoHash',
provider: 'Test provider',
title: 'Test title',
type: TorrentType.Movie,
dataValues: {
infoHash: 'Test infoHash',
provider: 'Test provider',
title: 'Test title',
type: TorrentType.Movie,
}
} as Torrent;
const fileCollection : ITorrentFileCollection = {
videos: [{
id: 1,
title: 'Test video',
size: 123456,
imdbId: 'tt1234567',
infoHash: 'Test infoHash',
}],
contents: [],
subtitles: [],
};
const fileCollectionWithContents : ITorrentFileCollection = {
...fileCollection,
contents: [{
size: 123456,
fileIndex: 0,
path: 'Test path',
infoHash: 'Test infoHash',
}],
};
(mockDatabaseRepository.getFiles as jest.Mock).mockResolvedValue(fileCollection.videos);
(mockFileService.parseTorrentFiles as jest.Mock).mockResolvedValue(fileCollectionWithContents);
(mockSubtitleService.assignSubtitles as jest.Mock).mockResolvedValue(fileCollectionWithContents);
(mockDatabaseRepository.createFile as jest.Mock).mockResolvedValue(Promise.resolve());
(mockDatabaseRepository.createTorrent as jest.Mock).mockResolvedValue(torrent);
await torrentEntriesService.createTorrentContents(torrent);
const newTorrentFiles = await (mockDatabaseRepository.createTorrent as jest.Mock).mock.calls[0][0].files;
newTorrentFiles.forEach(file => {
expect(mockDatabaseRepository.createFile).toHaveBeenCalledWith(file);
});
});
}); });

View File

@@ -24,6 +24,7 @@ jest.mock('@services/cache_service', () => {
beforeAll(() => server.listen()) beforeAll(() => server.listen())
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(Date, 'now').mockImplementation(() => 1234567890); jest.spyOn(Date, 'now').mockImplementation(() => 1234567890);
}) })
afterEach(() => () => { afterEach(() => () => {