mirror of
https://github.com/xtrll/MusicMetaFinder.git
synced 2026-04-20 07:54:28 +02:00
test(utils): add tests for utility functions in utils folder
This commit is contained in:
32
package-lock.json
generated
32
package-lock.json
generated
@@ -14,7 +14,8 @@
|
|||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"ffmetadata": "^1.7.0",
|
"ffmetadata": "^1.7.0",
|
||||||
"fpcalc": "^1.3.0",
|
"fpcalc": "^1.3.0",
|
||||||
"mime-types": "^2.1.35"
|
"mime-types": "^2.1.35",
|
||||||
|
"nock": "^13.5.4"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"music-meta-finder": "cli.js"
|
"music-meta-finder": "cli.js"
|
||||||
@@ -3776,6 +3777,12 @@
|
|||||||
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
|
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/json-stringify-safe": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/json5": {
|
"node_modules/json5": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||||
@@ -4091,6 +4098,20 @@
|
|||||||
"@sinonjs/commons": "^3.0.0"
|
"@sinonjs/commons": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nock": {
|
||||||
|
"version": "13.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz",
|
||||||
|
"integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.1.0",
|
||||||
|
"json-stringify-safe": "^5.0.1",
|
||||||
|
"propagate": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-int64": {
|
"node_modules/node-int64": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||||
@@ -4419,6 +4440,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||||
},
|
},
|
||||||
|
"node_modules/propagate": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/proxy-from-env": {
|
"node_modules/proxy-from-env": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"ffmetadata": "^1.7.0",
|
"ffmetadata": "^1.7.0",
|
||||||
"fpcalc": "^1.3.0",
|
"fpcalc": "^1.3.0",
|
||||||
"mime-types": "^2.1.35"
|
"mime-types": "^2.1.35",
|
||||||
|
"nock": "^13.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.0.2",
|
"@eslint/eslintrc": "^3.0.2",
|
||||||
|
|||||||
78
test/utils/deleteDirectoryRecursively.test.js
Normal file
78
test/utils/deleteDirectoryRecursively.test.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { expect } from 'chai'
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import path from "path";
|
||||||
|
import deleteDirectoryRecursively from "../../src/utils/deleteDirectoryRecursively.js";
|
||||||
|
|
||||||
|
describe('DeleteDirectoryRecursively', () => {
|
||||||
|
let readdirStub, unlinkStub, rmdirStub;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
readdirStub = sinon.stub(fs, 'readdir');
|
||||||
|
unlinkStub = sinon.stub(fs, 'unlink');
|
||||||
|
rmdirStub = sinon.stub(fs, 'rmdir');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
readdirStub.restore();
|
||||||
|
unlinkStub.restore();
|
||||||
|
rmdirStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete an empty directory', async () => {
|
||||||
|
const dirPath = 'testDir';
|
||||||
|
|
||||||
|
readdirStub.withArgs(dirPath).resolves([]);
|
||||||
|
rmdirStub.withArgs(dirPath).resolves();
|
||||||
|
|
||||||
|
await deleteDirectoryRecursively(dirPath);
|
||||||
|
|
||||||
|
expect(readdirStub.calledOnce).to.be.true;
|
||||||
|
expect(rmdirStub.calledOnceWith(dirPath)).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete a directory with files', async () => {
|
||||||
|
const dirPath = 'dir';
|
||||||
|
const filePath = path.join(dirPath, 'file.txt');
|
||||||
|
|
||||||
|
readdirStub.withArgs(dirPath).resolves([{ name: 'file.txt', isDirectory: () => false }]);
|
||||||
|
unlinkStub.withArgs(filePath).resolves();
|
||||||
|
rmdirStub.withArgs(dirPath).resolves();
|
||||||
|
|
||||||
|
await deleteDirectoryRecursively(dirPath);
|
||||||
|
|
||||||
|
expect(readdirStub.calledOnce).to.be.true;
|
||||||
|
expect(unlinkStub.calledOnceWith(filePath)).to.be.true;
|
||||||
|
expect(rmdirStub.calledOnceWith(dirPath)).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete a nested directory with files', async () => {
|
||||||
|
const dirPath = 'dir';
|
||||||
|
const nestedDirPath = path.join(dirPath, 'nestedDir');
|
||||||
|
const filePath = path.join(dirPath, 'file.txt');
|
||||||
|
const nestedFilePath = path.join(nestedDirPath, 'nestedFile.txt');
|
||||||
|
|
||||||
|
readdirStub.withArgs(dirPath).resolves([
|
||||||
|
{ name: 'file.txt', isDirectory: () => false },
|
||||||
|
{ name: 'nestedDir', isDirectory: () => true },
|
||||||
|
]);
|
||||||
|
|
||||||
|
readdirStub.withArgs(nestedDirPath).resolves([
|
||||||
|
{ name: 'nestedFile.txt', isDirectory: () => false },
|
||||||
|
]);
|
||||||
|
|
||||||
|
unlinkStub.withArgs(filePath).resolves();
|
||||||
|
unlinkStub.withArgs(nestedFilePath).resolves();
|
||||||
|
rmdirStub.withArgs(dirPath).resolves();
|
||||||
|
rmdirStub.withArgs(nestedDirPath).resolves();
|
||||||
|
|
||||||
|
await deleteDirectoryRecursively(dirPath);
|
||||||
|
|
||||||
|
expect(readdirStub.calledTwice).to.be.true;
|
||||||
|
expect(unlinkStub.calledTwice).to.be.true;
|
||||||
|
expect(unlinkStub.calledWith(filePath)).to.be.true;
|
||||||
|
expect(unlinkStub.calledWith(nestedFilePath)).to.be.true;
|
||||||
|
expect(rmdirStub.calledWith(nestedDirPath)).to.be.true;
|
||||||
|
expect(rmdirStub.calledWith(dirPath)).to.be.true;
|
||||||
|
});
|
||||||
|
})
|
||||||
0
test/utils/downloadImage.test.js
Normal file
0
test/utils/downloadImage.test.js
Normal file
54
test/utils/ensureDirectoryExists.test.js
Normal file
54
test/utils/ensureDirectoryExists.test.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { expect } from 'chai';
|
||||||
|
import esmock from 'esmock';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
describe('ensureDirectoryExists', () => {
|
||||||
|
let ensureDirectoryExists;
|
||||||
|
let fsMock;
|
||||||
|
let sandbox;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
sandbox = sinon.createSandbox();
|
||||||
|
fsMock = {
|
||||||
|
existsSync: sandbox.stub(),
|
||||||
|
mkdirSync: sandbox.stub(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Dynamically import ensureDirectoryExists and replace fs with a mock
|
||||||
|
ensureDirectoryExists = await esmock(
|
||||||
|
'../../src/utils/ensureDirectoryExists.js',
|
||||||
|
{
|
||||||
|
'fs': fsMock,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
sandbox.restore();
|
||||||
|
esmock.purge(ensureDirectoryExists);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not create a directory if it already exists', () => {
|
||||||
|
const dirPath = 'path/to/existing/dir';
|
||||||
|
|
||||||
|
fsMock.existsSync.returns(true);
|
||||||
|
|
||||||
|
ensureDirectoryExists(dirPath);
|
||||||
|
|
||||||
|
expect(fsMock.existsSync.calledOnceWith(dirPath)).to.be.true;
|
||||||
|
expect(fsMock.mkdirSync.notCalled).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a directory if it does not exist', () => {
|
||||||
|
const dirPath = 'path/to/new/dir';
|
||||||
|
|
||||||
|
fsMock.existsSync.returns(false);
|
||||||
|
|
||||||
|
ensureDirectoryExists(dirPath);
|
||||||
|
|
||||||
|
expect(fsMock.existsSync.calledOnceWith(dirPath)).to.be.true;
|
||||||
|
expect(fsMock.mkdirSync.calledOnceWith(dirPath, { recursive: true })).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
89
test/utils/fetchFiles.test.js
Normal file
89
test/utils/fetchFiles.test.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import esmock from 'esmock';
|
||||||
|
|
||||||
|
function normalizeToForwardSlash(p) {
|
||||||
|
return p.split(path.sep).join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('fetchFiles', () => {
|
||||||
|
let fetchFiles, fsStub;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
fsStub = {
|
||||||
|
promises: {
|
||||||
|
stat: sinon.stub(),
|
||||||
|
readdir: sinon.stub()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchFiles = await esmock('../../src/utils/fetchFiles.js', {
|
||||||
|
fs: fsStub
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
esmock.purge(fetchFiles);
|
||||||
|
sinon.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array with a single file when given a file path', async () => {
|
||||||
|
const filePath = '/path/to/file.txt';
|
||||||
|
|
||||||
|
fsStub.promises.stat.resolves({ isFile: () => true, isDirectory: () => false });
|
||||||
|
|
||||||
|
const result = await fetchFiles(filePath);
|
||||||
|
expect(result).to.deep.equal([normalizeToForwardSlash(filePath)]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array of files when given a directory path', async () => {
|
||||||
|
const dirPath = '/path/to/directory';
|
||||||
|
const subdirPath = path.join(dirPath, 'subdir'); // Use path.join for consistency
|
||||||
|
|
||||||
|
fsStub.promises.stat.withArgs(dirPath).resolves({ isFile: () => false, isDirectory: () => true });
|
||||||
|
fsStub.promises.stat.withArgs(subdirPath).resolves({ isFile: () => false, isDirectory: () => true });
|
||||||
|
fsStub.promises.stat.resolves({ isFile: () => true, isDirectory: () => false }); // Default for files
|
||||||
|
|
||||||
|
fsStub.promises.readdir.withArgs(dirPath, { withFileTypes: true }).resolves([
|
||||||
|
{ name: 'file1.txt', isFile: () => true, isDirectory: () => false },
|
||||||
|
{ name: 'file2.txt', isFile: () => true, isDirectory: () => false },
|
||||||
|
{ name: 'subdir', isFile: () => false, isDirectory: () => true }
|
||||||
|
]);
|
||||||
|
fsStub.promises.readdir.withArgs(subdirPath, { withFileTypes: true }).resolves([
|
||||||
|
{ name: 'file3.txt', isFile: () => true, isDirectory: () => false }
|
||||||
|
]);
|
||||||
|
|
||||||
|
const result = await fetchFiles(dirPath);
|
||||||
|
console.log('Test Result:', result); // Add logging to debug the result
|
||||||
|
expect(result).to.deep.equal([
|
||||||
|
normalizeToForwardSlash(`${dirPath}/file1.txt`),
|
||||||
|
normalizeToForwardSlash(`${dirPath}/file2.txt`),
|
||||||
|
normalizeToForwardSlash(`${dirPath}/subdir/file3.txt`)
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the path does not exist', async () => {
|
||||||
|
const invalidPath = '/invalid/path';
|
||||||
|
|
||||||
|
fsStub.promises.stat.rejects(new Error('ENOENT: no such file or directory'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fetchFiles(invalidPath);
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.message).to.equal('Failed to fetch files: ENOENT: no such file or directory');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the path is neither a file nor a directory', async () => {
|
||||||
|
const weirdPath = '/weird/path';
|
||||||
|
|
||||||
|
fsStub.promises.stat.resolves({ isFile: () => false, isDirectory: () => false });
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fetchFiles(weirdPath);
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.message).to.equal('Failed to fetch files: Input path is neither a file nor a directory: /weird/path');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
92
test/utils/renameAudioFileTitle.test.js
Normal file
92
test/utils/renameAudioFileTitle.test.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import esmock from 'esmock';
|
||||||
|
|
||||||
|
// Utility function to normalize paths to use forward slashes
|
||||||
|
function normalizeToForwardSlash(p) {
|
||||||
|
return p.split(path.sep).join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('renameFile', () => {
|
||||||
|
let renameFile, fsStub, generateUniqueFilenameStub;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
fsStub = {
|
||||||
|
rename: sinon.stub()
|
||||||
|
};
|
||||||
|
|
||||||
|
generateUniqueFilenameStub = sinon.stub();
|
||||||
|
|
||||||
|
renameFile = await esmock('../../src/utils/renameAudioFileTitle.js', {
|
||||||
|
'fs/promises': fsStub,
|
||||||
|
'../../src/utils/generateUniqueFilename.js': generateUniqueFilenameStub
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
esmock.purge(renameFile);
|
||||||
|
sinon.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should rename a file successfully with valid artist, title, and filePath', async () => {
|
||||||
|
const artist = 'Artist';
|
||||||
|
const title = 'Title';
|
||||||
|
const filePath = normalizeToForwardSlash('/path/to/file.mp3');
|
||||||
|
const newFilePath = normalizeToForwardSlash('/path/to/Artist - Title.mp3');
|
||||||
|
|
||||||
|
generateUniqueFilenameStub.resolves(newFilePath);
|
||||||
|
fsStub.rename.resolves();
|
||||||
|
|
||||||
|
const result = await renameFile(artist, title, filePath);
|
||||||
|
|
||||||
|
console.log('Arguments passed to generateUniqueFilename:', generateUniqueFilenameStub.args);
|
||||||
|
console.log('Arguments expected for generateUniqueFilename:', [normalizeToForwardSlash('/path/to'), normalizeToForwardSlash('Artist - Title.mp3')]);
|
||||||
|
|
||||||
|
expect(result).to.equal(normalizeToForwardSlash(newFilePath));
|
||||||
|
expect(generateUniqueFilenameStub.calledWith(normalizeToForwardSlash('/path/to'), 'Artist - Title.mp3')).to.be.true;
|
||||||
|
expect(fsStub.rename.calledWith(normalizeToForwardSlash(filePath), normalizeToForwardSlash(newFilePath))).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if filePath, artist, or title are not provided', async () => {
|
||||||
|
try {
|
||||||
|
await renameFile('', 'Title', normalizeToForwardSlash('/path/to/file.mp3'));
|
||||||
|
throw new Error('Test failed - expected error not thrown');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.message).to.equal('File path, artist, and title must be provided when renaming file.');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await renameFile('Artist', '', normalizeToForwardSlash('/path/to/file.mp3'));
|
||||||
|
throw new Error('Test failed - expected error not thrown');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.message).to.equal('File path, artist, and title must be provided when renaming file.');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await renameFile('Artist', 'Title', '');
|
||||||
|
throw new Error('Test failed - expected error not thrown');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.message).to.equal('File path, artist, and title must be provided when renaming file.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the file rename operation fails', async () => {
|
||||||
|
const artist = 'Artist';
|
||||||
|
const title = 'Title';
|
||||||
|
const filePath = normalizeToForwardSlash('/path/to/file.mp3');
|
||||||
|
const newFilePath = normalizeToForwardSlash('/path/to/Artist - Title.mp3');
|
||||||
|
const renameError = new Error('Rename failed');
|
||||||
|
|
||||||
|
generateUniqueFilenameStub.resolves(newFilePath);
|
||||||
|
fsStub.rename.rejects(renameError);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await renameFile(artist, title, filePath);
|
||||||
|
throw new Error('Test failed - expected error not thrown');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).to.equal(renameError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
75
test/utils/retryAxios.test.js
Normal file
75
test/utils/retryAxios.test.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import { expect } from 'chai';
|
||||||
|
import nock from 'nock';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import esmock from 'esmock';
|
||||||
|
|
||||||
|
describe('retryAxios', () => {
|
||||||
|
let axiosInstance, axios, axiosRetry;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
axios = {
|
||||||
|
create: sinon.stub().returnsThis(),
|
||||||
|
interceptors: {
|
||||||
|
response: {
|
||||||
|
use: sinon.stub()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
axiosRetry = sinon.stub();
|
||||||
|
|
||||||
|
axiosInstance = await esmock('../../src/utils/retryAxios.js', {
|
||||||
|
'axios': axios,
|
||||||
|
'axios-retry': axiosRetry
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an axios instance and configure retry policy', async () => {
|
||||||
|
expect(axios.create.calledOnce).to.be.true;
|
||||||
|
expect(axiosRetry.calledOnce).to.be.true;
|
||||||
|
|
||||||
|
const [instance, config] = axiosRetry.firstCall.args;
|
||||||
|
expect(instance).to.equal(axiosInstance);
|
||||||
|
expect(config.retries).to.equal(3);
|
||||||
|
expect(config.retryDelay(1)).to.equal(2000);
|
||||||
|
expect(config.retryDelay(2)).to.equal(4000);
|
||||||
|
expect(config.retryCondition({ response: { status: 429 }})).to.be.true;
|
||||||
|
expect(config.retryCondition({ response: { status: 500 }})).to.be.true;
|
||||||
|
expect(config.retryCondition({ response: { status: 400 }})).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should retry 3 times before failing for 500 status code', async () => {
|
||||||
|
nock('https://api.example.com')
|
||||||
|
.get('/resource')
|
||||||
|
.reply(500)
|
||||||
|
.persist();
|
||||||
|
|
||||||
|
let error;
|
||||||
|
try {
|
||||||
|
await axiosInstance.get('https://api.example.com/resource');
|
||||||
|
} catch (err) {
|
||||||
|
error = err;
|
||||||
|
}
|
||||||
|
expect(error).to.exist;
|
||||||
|
|
||||||
|
nock.cleanAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not retry for 400 status code', async () => {
|
||||||
|
nock('https://api.example.com')
|
||||||
|
.get('/resource')
|
||||||
|
.reply(400);
|
||||||
|
|
||||||
|
let error;
|
||||||
|
try {
|
||||||
|
await axiosInstance.get('https://api.example.com/resource');
|
||||||
|
} catch (err) {
|
||||||
|
error = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).to.exist;
|
||||||
|
|
||||||
|
nock.cleanAll();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
78
test/utils/validateAudioFiles.test.js
Normal file
78
test/utils/validateAudioFiles.test.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { expect } from 'chai';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import esmock from 'esmock';
|
||||||
|
|
||||||
|
describe('validateAudioFile', () => {
|
||||||
|
let validateAudioFile, fsStub, mimeStub;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
fsStub = {
|
||||||
|
lstat: sinon.stub()
|
||||||
|
};
|
||||||
|
|
||||||
|
mimeStub = {
|
||||||
|
lookup: sinon.stub()
|
||||||
|
};
|
||||||
|
|
||||||
|
validateAudioFile = await esmock('../../src/utils/validateAudioFiles.js', {
|
||||||
|
'fs/promises': fsStub,
|
||||||
|
'mime-types': mimeStub
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
esmock.purge(validateAudioFile);
|
||||||
|
sinon.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null and log an error if the path is not a file', async () => {
|
||||||
|
const filePath = '/path/to/directory';
|
||||||
|
const consoleErrorStub = sinon.stub(console, 'error');
|
||||||
|
|
||||||
|
fsStub.lstat.resolves({ isFile: () => false });
|
||||||
|
|
||||||
|
const result = await validateAudioFile(filePath);
|
||||||
|
expect(result).to.be.null;
|
||||||
|
expect(consoleErrorStub.calledWith(`The path ${filePath} is not a file and is ignored.`)).to.be.true;
|
||||||
|
|
||||||
|
consoleErrorStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null and log an error if the file is not a recognized audio file type', async () => {
|
||||||
|
const filePath = '/path/to/file.txt';
|
||||||
|
const consoleErrorStub = sinon.stub(console, 'error');
|
||||||
|
|
||||||
|
fsStub.lstat.resolves({ isFile: () => true });
|
||||||
|
mimeStub.lookup.returns('text/plain');
|
||||||
|
|
||||||
|
const result = await validateAudioFile(filePath);
|
||||||
|
expect(result).to.be.null;
|
||||||
|
expect(consoleErrorStub.calledWith(`File ${filePath} is not an audio file and is ignored.`)).to.be.true;
|
||||||
|
|
||||||
|
consoleErrorStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the file path if the file is a recognized audio file type', async () => {
|
||||||
|
const filePath = '/path/to/file.mp3';
|
||||||
|
|
||||||
|
fsStub.lstat.resolves({ isFile: () => true });
|
||||||
|
mimeStub.lookup.returns('audio/mpeg');
|
||||||
|
|
||||||
|
const result = await validateAudioFile(filePath);
|
||||||
|
expect(result).to.equal(filePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null and log an error if an exception occurs during validation', async () => {
|
||||||
|
const filePath = '/path/to/file.mp3';
|
||||||
|
const error = new Error('Test Error');
|
||||||
|
const consoleErrorStub = sinon.stub(console, 'error');
|
||||||
|
|
||||||
|
fsStub.lstat.rejects(error);
|
||||||
|
|
||||||
|
const result = await validateAudioFile(filePath);
|
||||||
|
expect(result).to.be.null;
|
||||||
|
expect(consoleErrorStub.calledWith(`Error validating file ${filePath}: ${error}`)).to.be.true;
|
||||||
|
|
||||||
|
consoleErrorStub.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user