mirror of
https://github.com/xtrll/MusicMetaFinder.git
synced 2026-04-17 15:53:29 +02:00
test(services): add tests for service layer functions
This commit is contained in:
80
test/services/fileService.test.js
Normal file
80
test/services/fileService.test.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import esmock from 'esmock';
|
||||
import path from 'path';
|
||||
|
||||
describe('validateAudioFiles', function() {
|
||||
let validateAudioFileStub;
|
||||
let validateAudioFiles;
|
||||
|
||||
const validMp3File = 'path/to/valid/file.mp3';
|
||||
const unsupportedFile = 'path/to/unsupported/file.wav';
|
||||
const invalidFile = 'path/to/invalid/file.txt';
|
||||
|
||||
beforeEach(async function() {
|
||||
validateAudioFileStub = sinon.stub();
|
||||
validateAudioFileStub.withArgs(validMp3File).resolves(validMp3File);
|
||||
validateAudioFileStub.withArgs(unsupportedFile).resolves(unsupportedFile);
|
||||
validateAudioFileStub.withArgs(invalidFile).resolves(null);
|
||||
|
||||
// Mocking validateAudioFile and its dependencies
|
||||
validateAudioFiles = await esmock('../../src/services/fileService.js', {
|
||||
'../../src/utils/validateAudioFiles.js': { default: validateAudioFileStub }
|
||||
});
|
||||
|
||||
validateAudioFiles = validateAudioFiles.default;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
esmock.purge();
|
||||
});
|
||||
|
||||
it('should return only valid and supported audio file paths', async function() {
|
||||
const filePaths = [validMp3File, unsupportedFile, invalidFile];
|
||||
|
||||
const result = await validateAudioFiles(filePaths);
|
||||
|
||||
// Ensure that only the valid mp3 file is returned
|
||||
expect(result).to.deep.equal([validMp3File]);
|
||||
});
|
||||
|
||||
it('should throw a TypeError if input is not an array', async function() {
|
||||
try {
|
||||
await validateAudioFiles('not an array');
|
||||
expect.fail('Expected TypeError to be thrown');
|
||||
} catch (error) {
|
||||
expect(error).to.be.instanceOf(TypeError);
|
||||
expect(error.message).to.equal('Input must be an array of file paths (strings).');
|
||||
}
|
||||
});
|
||||
|
||||
it('should ignore unsupported file extensions', async function() {
|
||||
const filePaths = [validMp3File, unsupportedFile];
|
||||
|
||||
const result = await validateAudioFiles(filePaths);
|
||||
|
||||
// Ensure that only the valid mp3 file is returned
|
||||
expect(result).to.deep.equal([validMp3File]);
|
||||
});
|
||||
|
||||
it('should handle empty array input gracefully', async function() {
|
||||
const result = await validateAudioFiles([]);
|
||||
|
||||
// Ensure that an empty array is returned
|
||||
expect(result).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it('should log an error for unsupported extensions', async function() {
|
||||
const consoleErrorStub = sinon.stub(console, 'error');
|
||||
|
||||
const filePaths = [unsupportedFile];
|
||||
|
||||
await validateAudioFiles(filePaths);
|
||||
|
||||
// Ensure that an error is logged for the unsupported file
|
||||
expect(consoleErrorStub.calledOnceWithExactly(`File ${path.basename(unsupportedFile)} is an audio file but .wav format is not yet supported and so is ignored.`)).to.be.true;
|
||||
|
||||
consoleErrorStub.restore();
|
||||
});
|
||||
});
|
||||
107
test/services/metadata/metadataWriters/writeMetadata.test.js
Normal file
107
test/services/metadata/metadataWriters/writeMetadata.test.js
Normal file
@@ -0,0 +1,107 @@
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import esmock from 'esmock';
|
||||
|
||||
describe('writeMetadata', function() {
|
||||
let fsExistsSyncStub;
|
||||
let writeMetadataPromiseStub;
|
||||
let writeAlbumArtStub;
|
||||
let renameFileStub;
|
||||
let writeMetadata;
|
||||
|
||||
const filePath = 'path/to/track.mp3';
|
||||
const albumArtPath = 'path/to/albumArt.jpg';
|
||||
const newFilePath = 'path/to/new_track.mp3';
|
||||
|
||||
const validMetadata = {
|
||||
title: 'Test Title',
|
||||
artist: 'Test Artist',
|
||||
lyrics: 'Test Lyrics',
|
||||
albumArt: albumArtPath,
|
||||
};
|
||||
|
||||
beforeEach(async function() {
|
||||
fsExistsSyncStub = sinon.stub();
|
||||
writeMetadataPromiseStub = sinon.stub().resolves();
|
||||
writeAlbumArtStub = sinon.stub().resolves();
|
||||
renameFileStub = sinon.stub().resolves(newFilePath);
|
||||
|
||||
writeMetadata = await esmock('../../../../src/services/metadata/metadataWriters/writeMetadata.js', {
|
||||
'fs': { existsSync: fsExistsSyncStub },
|
||||
'util': { promisify: sinon.stub().returns(writeMetadataPromiseStub) },
|
||||
'../../../../src/services/metadata/metadataWriters/writeAlbumArt.js': { default: writeAlbumArtStub },
|
||||
'../../../../src/utils/renameAudioFileTitle.js': { default: renameFileStub }
|
||||
});
|
||||
|
||||
writeMetadata = writeMetadata.default;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
esmock.purge();
|
||||
});
|
||||
|
||||
it('should write metadata and album art to an MP3 file', async function() {
|
||||
fsExistsSyncStub.withArgs(filePath).returns(true);
|
||||
|
||||
await writeMetadata(validMetadata, filePath);
|
||||
|
||||
expect(writeMetadataPromiseStub.calledOnceWithExactly(filePath, {
|
||||
title: validMetadata.title,
|
||||
artist: validMetadata.artist,
|
||||
lyrics: validMetadata.lyrics,
|
||||
})).to.be.true;
|
||||
|
||||
expect(writeAlbumArtStub.calledOnceWithExactly(filePath, albumArtPath)).to.be.true;
|
||||
expect(renameFileStub.calledOnceWithExactly(validMetadata.title, validMetadata.artist, filePath)).to.be.true;
|
||||
});
|
||||
|
||||
it('should throw an error if metadata is not an object', async function() {
|
||||
fsExistsSyncStub.withArgs(filePath).returns(true);
|
||||
|
||||
try {
|
||||
await writeMetadata('invalid metadata', filePath);
|
||||
expect.fail('Expected TypeError to be thrown');
|
||||
} catch (error) {
|
||||
expect(error).to.be.instanceOf(TypeError);
|
||||
expect(error.message).to.equal('Metadata provided must be an object.');
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error if filePath is not a string', async function() {
|
||||
fsExistsSyncStub.withArgs(filePath).returns(true);
|
||||
|
||||
try {
|
||||
await writeMetadata(validMetadata, {});
|
||||
expect.fail('Expected TypeError to be thrown');
|
||||
} catch (error) {
|
||||
expect(error).to.be.instanceOf(TypeError);
|
||||
expect(error.message).to.equal('File path must be a string.');
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error if the file path does not exist', async function() {
|
||||
fsExistsSyncStub.withArgs(filePath).returns(false);
|
||||
|
||||
try {
|
||||
await writeMetadata(validMetadata, filePath);
|
||||
expect.fail('Expected Error to be thrown');
|
||||
} catch (error) {
|
||||
expect(error.message).to.equal(`No file found at the given path: ${filePath}`);
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle errors during metadata writing process and provide context', async function() {
|
||||
const writeError = new Error('Failed to write metadata');
|
||||
fsExistsSyncStub.withArgs(filePath).returns(true);
|
||||
writeMetadataPromiseStub.rejects(writeError);
|
||||
|
||||
try {
|
||||
await writeMetadata(validMetadata, filePath);
|
||||
expect.fail('Expected Error to be thrown');
|
||||
} catch (error) {
|
||||
expect(error.message).to.equal(`Failed to write metadata to ${filePath}: ${writeError.message}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
75
test/services/metadata/metadataWritingService.test.js
Normal file
75
test/services/metadata/metadataWritingService.test.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import esmock from 'esmock';
|
||||
|
||||
describe('writeMetadataService', function() {
|
||||
let writeMetadataStub;
|
||||
let writeMetadataService;
|
||||
|
||||
const validMetadata = {
|
||||
title: 'Test Title',
|
||||
artist: 'Test Artist',
|
||||
lyrics: 'Test Lyrics',
|
||||
filePath: 'path/to/test/file.mp3',
|
||||
};
|
||||
|
||||
const invalidMetadata = {
|
||||
title: 'Test Title',
|
||||
artist: 'Test Artist',
|
||||
lyrics: 'Test Lyrics',
|
||||
filePath: '', // Invalid file path
|
||||
};
|
||||
|
||||
beforeEach(async function() {
|
||||
writeMetadataStub = sinon.stub().resolves();
|
||||
|
||||
// Mocking writeMetadata and its dependencies
|
||||
writeMetadataService = await esmock('../../../src/services/metadata/metadataWritingService.js', {
|
||||
'../../../src/services/metadata/metadataWriters/writeMetadata.js': { default: writeMetadataStub }
|
||||
});
|
||||
|
||||
writeMetadataService = writeMetadataService.default;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
esmock.purge();
|
||||
});
|
||||
|
||||
it('should write metadata to all files in the array', async function() {
|
||||
const metadataArray = [validMetadata, validMetadata];
|
||||
|
||||
await writeMetadataService(metadataArray);
|
||||
|
||||
// Ensure writeMetadata is called twice
|
||||
expect(writeMetadataStub.calledTwice).to.be.true;
|
||||
expect(writeMetadataStub.alwaysCalledWith(validMetadata, validMetadata.filePath)).to.be.true;
|
||||
});
|
||||
|
||||
it('should skip metadata objects without a file path', async function() {
|
||||
const metadataArray = [validMetadata, invalidMetadata, { title: 'No FilePath' }];
|
||||
|
||||
await writeMetadataService(metadataArray);
|
||||
|
||||
// Ensure writeMetadata is called only once for the valid metadata
|
||||
expect(writeMetadataStub.calledOnceWithExactly(validMetadata, validMetadata.filePath)).to.be.true;
|
||||
});
|
||||
|
||||
it('should handle errors during the writing of metadata', async function() {
|
||||
const error = new Error('Failed to write metadata');
|
||||
writeMetadataStub.rejects(error);
|
||||
|
||||
const metadataArray = [validMetadata];
|
||||
|
||||
try {
|
||||
await writeMetadataService(metadataArray);
|
||||
} catch (e) {
|
||||
expect.fail('No error should be thrown from service');
|
||||
}
|
||||
|
||||
// Ensure error is logged (this would normally go to your logging mechanism)
|
||||
expect(writeMetadataStub.calledOnceWithExactly(validMetadata, validMetadata.filePath)).to.be.true;
|
||||
// Check if console.error was called (mock console.error if needed)
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import esmock from 'esmock';
|
||||
|
||||
describe('normalizeMetadata', function() {
|
||||
let normalizeMusicBrainzStub;
|
||||
let normalizeMetadata;
|
||||
|
||||
const fileObjectsWithMetadata = [{ id: 1 }, { id: 2 }];
|
||||
|
||||
beforeEach(async function() {
|
||||
normalizeMusicBrainzStub = sinon.stub().resolves([{ normalized: true }]);
|
||||
|
||||
// Mocking normalizeMusicBrainz module and its dependencies
|
||||
normalizeMetadata = await esmock('../../../../src/services/metadata/normalizers/metadataNormalizerService.js', {
|
||||
'../../../../src/services/metadata/normalizers/normalizeMusicBrainz.js': { default: normalizeMusicBrainzStub }
|
||||
});
|
||||
|
||||
normalizeMetadata = normalizeMetadata.default;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
esmock.purge();
|
||||
});
|
||||
|
||||
it('should use normalizeMusicBrainz for "acoustid" source', async function() {
|
||||
const result = await normalizeMetadata(fileObjectsWithMetadata, 'acoustid');
|
||||
|
||||
// Ensure normalizeMusicBrainzStub is called once with correct parameters
|
||||
expect(normalizeMusicBrainzStub.calledOnceWithExactly(fileObjectsWithMetadata)).to.be.true;
|
||||
// Validate the return value
|
||||
expect(result).to.deep.equal([{ normalized: true }]);
|
||||
});
|
||||
|
||||
it('should use default normalizer (normalizeMusicBrainz) for unsupported source', async function() {
|
||||
const result = await normalizeMetadata(fileObjectsWithMetadata, 'unsupportedSource');
|
||||
|
||||
// Ensure default normalizer is used for unsupported source
|
||||
expect(normalizeMusicBrainzStub.calledOnceWithExactly(fileObjectsWithMetadata)).to.be.true;
|
||||
// Validate the return value
|
||||
expect(result).to.deep.equal([{ normalized: true }]);
|
||||
});
|
||||
|
||||
it('should use default normalizer (normalizeMusicBrainz) when source is not provided', async function() {
|
||||
const result = await normalizeMetadata(fileObjectsWithMetadata);
|
||||
|
||||
// Ensure default normalizer is used when source is not provided
|
||||
expect(normalizeMusicBrainzStub.calledOnceWithExactly(fileObjectsWithMetadata)).to.be.true;
|
||||
// Validate the return value
|
||||
expect(result).to.deep.equal([{ normalized: true }]);
|
||||
});
|
||||
|
||||
// it('should return <audd normalizer> when "audd" source is provided', async function() {
|
||||
//
|
||||
// const result = await normalizeMetadata(fileObjectsWithMetadata, 'audd');
|
||||
//
|
||||
// expect(normalizeMusicBrainzStub.called).to.be.false;
|
||||
// });
|
||||
});
|
||||
113
test/services/metadata/normalizers/normalizeMusicBrainz.test.js
Normal file
113
test/services/metadata/normalizers/normalizeMusicBrainz.test.js
Normal file
@@ -0,0 +1,113 @@
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import esmock from 'esmock';
|
||||
|
||||
describe('normalizeMusicBrainz', function() {
|
||||
let saveImageToFileStub;
|
||||
let normalizeMusicBrainz;
|
||||
|
||||
beforeEach(async function() {
|
||||
saveImageToFileStub = sinon.stub().resolves('/path/to/saved/image.jpg');
|
||||
|
||||
// Mocking saveImageToFile and its dependencies
|
||||
normalizeMusicBrainz = await esmock('../../../../src/services/metadata/normalizers/normalizeMusicBrainz.js', {
|
||||
'../../../../src/services/saveImageToFile.js': { default: saveImageToFileStub }
|
||||
});
|
||||
|
||||
normalizeMusicBrainz = normalizeMusicBrainz.default;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
esmock.purge();
|
||||
});
|
||||
|
||||
it('should normalize metadata and save album art', async function() {
|
||||
const fileObjectsWithMetadata = [{
|
||||
trackMetadata: {
|
||||
title: 'Test Title',
|
||||
'artist-credit': [{ artist: { name: 'Test Artist' } }],
|
||||
'first-release-date': '2023-01-01',
|
||||
},
|
||||
albumArtUrl: 'http://example.com/albumArt.jpg',
|
||||
lyrics: 'Test lyrics',
|
||||
filePath: 'path/to/test/file.mp3',
|
||||
}];
|
||||
|
||||
const result = await normalizeMusicBrainz(fileObjectsWithMetadata);
|
||||
|
||||
expect(result).to.deep.equal([{
|
||||
title: 'Test Title',
|
||||
artist: 'Test Artist',
|
||||
releaseDate: '2023-01-01',
|
||||
albumArt: '/path/to/saved/image.jpg',
|
||||
lyrics: 'Test lyrics',
|
||||
filePath: 'path/to/test/file.mp3',
|
||||
}]);
|
||||
expect(saveImageToFileStub.calledOnceWithExactly('http://example.com/albumArt.jpg', './images')).to.be.true;
|
||||
});
|
||||
|
||||
it('should handle missing metadata and return null', async function() {
|
||||
const fileObjectsWithMetadata = [{
|
||||
trackMetadata: null,
|
||||
albumArtUrl: 'http://example.com/albumArt.jpg',
|
||||
lyrics: 'Test lyrics',
|
||||
filePath: 'path/to/test/file.mp3',
|
||||
}];
|
||||
|
||||
const result = await normalizeMusicBrainz(fileObjectsWithMetadata);
|
||||
|
||||
expect(result).to.deep.equal([null]);
|
||||
expect(saveImageToFileStub.called).to.be.false;
|
||||
});
|
||||
|
||||
it('should handle missing album art URL gracefully', async function() {
|
||||
const fileObjectsWithMetadata = [{
|
||||
trackMetadata: {
|
||||
title: 'Test Title',
|
||||
'artist-credit': [{ artist: { name: 'Test Artist' } }],
|
||||
'first-release-date': '2023-01-01',
|
||||
},
|
||||
albumArtUrl: null,
|
||||
lyrics: 'Test lyrics',
|
||||
filePath: 'path/to/test/file.mp3',
|
||||
}];
|
||||
|
||||
const result = await normalizeMusicBrainz(fileObjectsWithMetadata);
|
||||
|
||||
expect(result).to.deep.equal([{
|
||||
title: 'Test Title',
|
||||
artist: 'Test Artist',
|
||||
releaseDate: '2023-01-01',
|
||||
albumArt: null,
|
||||
lyrics: 'Test lyrics',
|
||||
filePath: 'path/to/test/file.mp3',
|
||||
}]);
|
||||
expect(saveImageToFileStub.called).to.be.false;
|
||||
});
|
||||
|
||||
it('should propagate errors from saveImageToFile', async function() {
|
||||
const fileObjectsWithMetadata = [{
|
||||
trackMetadata: {
|
||||
title: 'Test Title',
|
||||
'artist-credit': [{ artist: { name: 'Test Artist' } }],
|
||||
'first-release-date': '2023-01-01',
|
||||
},
|
||||
albumArtUrl: 'http://example.com/albumArt.jpg',
|
||||
lyrics: 'Test lyrics',
|
||||
filePath: 'path/to/test/file.mp3',
|
||||
}];
|
||||
|
||||
const saveImageError = new Error('Failed to save image');
|
||||
saveImageToFileStub.rejects(saveImageError);
|
||||
|
||||
try {
|
||||
await normalizeMusicBrainz(fileObjectsWithMetadata);
|
||||
expect.fail('Expected an error to be thrown');
|
||||
} catch (error) {
|
||||
expect(error.message).to.equal(`Error normalizing MusicBrainz metadata for file path/to/test/file.mp3: ${saveImageError.message}`);
|
||||
}
|
||||
expect(saveImageToFileStub.calledOnceWithExactly('http://example.com/albumArt.jpg', './images')).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
66
test/services/musicRecognitionService.test.js
Normal file
66
test/services/musicRecognitionService.test.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import esmock from 'esmock';
|
||||
|
||||
describe('recognizeAudio', function() {
|
||||
let recognizeUsingAuddStub;
|
||||
let recognizeUsingAcoustidStub;
|
||||
let recognizeAudio;
|
||||
|
||||
const filePaths = ['path/to/file1.mp3', 'path/to/file2.mp3'];
|
||||
|
||||
beforeEach(async function() {
|
||||
recognizeUsingAuddStub = sinon.stub().resolves([{ recognized: true, service: 'audd' }]);
|
||||
recognizeUsingAcoustidStub = sinon.stub().resolves([{ recognized: true, service: 'acoustid' }]);
|
||||
|
||||
// Mocking recognition services and their dependencies
|
||||
recognizeAudio = await esmock('../../src/services/musicRecognitionService.js', {
|
||||
'../../src/adapters/recognition/auddAdapter.js': { default: recognizeUsingAuddStub },
|
||||
'../../src/adapters/recognition/acoustidAdapter.js': { default: recognizeUsingAcoustidStub }
|
||||
});
|
||||
|
||||
recognizeAudio = recognizeAudio.default;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
esmock.purge();
|
||||
});
|
||||
|
||||
it('should use recognizeUsingAudd for "audd" source', async function() {
|
||||
const result = await recognizeAudio(filePaths, 'audd');
|
||||
|
||||
// Ensure recognizeUsingAuddStub is called once with the correct parameters
|
||||
expect(recognizeUsingAuddStub.calledOnceWithExactly(filePaths)).to.be.true;
|
||||
// Validate the return value
|
||||
expect(result).to.deep.equal([{ recognized: true, service: 'audd' }]);
|
||||
});
|
||||
|
||||
it('should use recognizeUsingAcoustid for "acoustid" source', async function() {
|
||||
const result = await recognizeAudio(filePaths, 'acoustid');
|
||||
|
||||
// Ensure recognizeUsingAcoustidStub is called once with the correct parameters
|
||||
expect(recognizeUsingAcoustidStub.calledOnceWithExactly(filePaths)).to.be.true;
|
||||
// Validate the return value
|
||||
expect(result).to.deep.equal([{ recognized: true, service: 'acoustid' }]);
|
||||
});
|
||||
|
||||
it('should use default recognition service for unsupported source', async function() {
|
||||
const result = await recognizeAudio(filePaths, 'unsupportedSource');
|
||||
|
||||
// Ensure default recognition service (recognizeUsingAcoustid) is used for unsupported source
|
||||
expect(recognizeUsingAcoustidStub.calledOnceWithExactly(filePaths)).to.be.true;
|
||||
// Validate the return value
|
||||
expect(result).to.deep.equal([{ recognized: true, service: 'acoustid' }]);
|
||||
});
|
||||
|
||||
it('should use default recognition service when source is not provided', async function() {
|
||||
const result = await recognizeAudio(filePaths);
|
||||
|
||||
// Ensure default recognition service (recognizeUsingAcoustid) is used when source is not provided
|
||||
expect(recognizeUsingAcoustidStub.calledOnceWithExactly(filePaths)).to.be.true;
|
||||
// Validate the return value
|
||||
expect(result).to.deep.equal([{ recognized: true, service: 'acoustid' }]);
|
||||
});
|
||||
});
|
||||
|
||||
72
test/services/saveImageToFile.test.js
Normal file
72
test/services/saveImageToFile.test.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import { expect } from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import esmock from 'esmock';
|
||||
import path from 'path';
|
||||
|
||||
describe('saveImageToFile', function() {
|
||||
let downloadImageStub;
|
||||
let ensureDirectoryExistsStub;
|
||||
let saveImageToFile;
|
||||
|
||||
const imageUrl = 'http://example.com/image.jpg';
|
||||
const outputDirectory = 'path/to/output';
|
||||
const savedImagePath = path.join(path.resolve(outputDirectory), path.basename(imageUrl));
|
||||
|
||||
beforeEach(async function() {
|
||||
downloadImageStub = sinon.stub().resolves(savedImagePath);
|
||||
ensureDirectoryExistsStub = sinon.stub();
|
||||
|
||||
// Mocking downloadImage and ensureDirectoryExists functions
|
||||
saveImageToFile = await esmock('../../src/services/saveImageToFile.js', {
|
||||
'../../src/utils/downloadImage.js': { default: downloadImageStub },
|
||||
'../../src/utils/ensureDirectoryExists.js': { default: ensureDirectoryExistsStub }
|
||||
});
|
||||
|
||||
saveImageToFile = saveImageToFile.default;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
esmock.purge();
|
||||
});
|
||||
|
||||
it('should save image to specified directory', async function() {
|
||||
const result = await saveImageToFile(imageUrl, outputDirectory);
|
||||
|
||||
// Ensure ensureDirectoryExists is called with the resolved output directory
|
||||
expect(ensureDirectoryExistsStub.calledOnceWithExactly(path.resolve(outputDirectory))).to.be.true;
|
||||
|
||||
// Ensure downloadImage is called with correct URL and save path
|
||||
expect(downloadImageStub.calledOnceWithExactly(imageUrl, savedImagePath)).to.be.true;
|
||||
|
||||
// Validate the return value (saved image path)
|
||||
expect(result).to.equal(savedImagePath);
|
||||
});
|
||||
|
||||
it('should throw an error if downloadImage fails', async function() {
|
||||
const error = new Error('Failed to download image');
|
||||
downloadImageStub.rejects(error);
|
||||
|
||||
try {
|
||||
await saveImageToFile(imageUrl, outputDirectory);
|
||||
expect.fail('Expected an error to be thrown');
|
||||
} catch (err) {
|
||||
// Ensure error is logged and re-thrown
|
||||
expect(err).to.equal(error);
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error if ensureDirectoryExists fails', async function() {
|
||||
const error = new Error('Failed to ensure directory exists');
|
||||
ensureDirectoryExistsStub.throws(error);
|
||||
|
||||
try {
|
||||
await saveImageToFile(imageUrl, outputDirectory);
|
||||
expect.fail('Expected an error to be thrown');
|
||||
} catch (err) {
|
||||
// Ensure error is logged and re-thrown
|
||||
expect(err).to.equal(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user