From 8a18c20963d2365c5ae67910c05937846e09039b Mon Sep 17 00:00:00 2001 From: kukukk Date: Wed, 23 Nov 2022 17:24:03 +0200 Subject: [PATCH] feat(file-cache): Add tests --- src/north/north-connector.spec.js | 37 ++++++ src/service/cache/file-cache.service.spec.js | 127 ++++++++++++++++++- src/service/utils.js | 2 +- src/service/utils.spec.js | 9 ++ 4 files changed, 173 insertions(+), 2 deletions(-) diff --git a/src/north/north-connector.spec.js b/src/north/north-connector.spec.js index a78de0d6d4..1787b17c42 100644 --- a/src/north/north-connector.spec.js +++ b/src/north/north-connector.spec.js @@ -176,4 +176,41 @@ describe('NorthConnector', () => { expect(north.logger.trace).toHaveBeenCalledWith('Default retry test always return false.') expect(retry).toEqual(false) }) + + it('should get error files', async () => { + const fromDate = '2022-11-11T11:11:11.111' + const toDate = '2022-11-12T11:11:11.111' + const nameFilter = 'ile' + const pageNumber = 1 + const files = ['file1.name', 'file2.name', 'file3.name'] + north.fileCache.getErrorFiles.mockReturnValue(Promise.resolve(files)) + + const result = await north.getErrorFiles(fromDate, toDate, nameFilter, pageNumber) + expect(north.fileCache.getErrorFiles).toBeCalledWith(fromDate, toDate, nameFilter, pageNumber) + expect(result).toEqual(files) + }) + + it('should remove error files', async () => { + const files = ['file1.name', 'file2.name', 'file3.name'] + + await north.removeErrorFiles(files) + expect(north.fileCache.removeErrorFiles).toBeCalledWith(files) + }) + + it('should retry error files', async () => { + const files = ['file1.name', 'file2.name', 'file3.name'] + + await north.retryErrorFiles(files) + expect(north.fileCache.retryErrorFiles).toBeCalledWith(files) + }) + + it('should remove all error files', async () => { + await north.removeAllErrorFiles() + expect(north.fileCache.removeAllErrorFiles).toBeCalled() + }) + + it('should retry all error files', async () => { + await north.retryAllErrorFiles() + expect(north.fileCache.retryAllErrorFiles).toBeCalled() + }) }) diff --git a/src/service/cache/file-cache.service.spec.js b/src/service/cache/file-cache.service.spec.js index 63eb4a862c..74b9ff278e 100644 --- a/src/service/cache/file-cache.service.spec.js +++ b/src/service/cache/file-cache.service.spec.js @@ -3,7 +3,7 @@ const fs = require('node:fs/promises') const FileCache = require('./file-cache.service') -const { createFolder } = require('../utils') +const { createFolder, asyncFilter } = require('../utils') jest.mock('node:fs/promises') @@ -312,4 +312,129 @@ describe('FileCache', () => { expect(clearTimeoutSpy).toHaveBeenCalledTimes(1) expect(logger.debug).toHaveBeenCalledWith('Waiting for connector to finish sending file...') }) + + it('should return empty file list when the error folder is empty', async () => { + const fromDate = '2022-11-11T11:11:11.111' + const toDate = '2022-11-12T11:11:11.111' + const nameFilter = 'ile' + const pageNumber = 1 + cache.getFiles = jest.fn().mockReturnValue([]) + + const result = await cache.getErrorFiles(fromDate, toDate, nameFilter, pageNumber) + expect(cache.getFiles).toBeCalledWith(cache.errorFolder) + expect(result).toEqual([]) + }) + + it('should return filtered file list when the error folder is not empty', async () => { + const nameFilter = 'ile' + const fromDate = '2022-11-11T11:11:11.111' + const toDate = '2022-11-12T11:11:11.111' + const pageNumber = 1 + const filenames = ['file1.name', 'file2.name', 'file3.name'] + cache.getFiles = jest.fn().mockReturnValue(Promise.resolve(filenames)) + asyncFilter.mockReturnValue(['file1.name', 'file2.name']) + + const result = await cache.getErrorFiles(fromDate, toDate, nameFilter, pageNumber) + expect(cache.getFiles).toBeCalledWith(cache.errorFolder) + expect(asyncFilter).toHaveBeenCalled() + expect(result).toEqual(['file1.name', 'file2.name']) + }) + + it('should remove error files', async () => { + const filenames = ['file1.name', 'file2.name', 'file3.name'] + + await cache.removeErrorFiles(filenames) + expect(fs.unlink).toHaveBeenNthCalledWith(1, path.join(cache.errorFolder, filenames[0])) + expect(fs.unlink).toHaveBeenNthCalledWith(2, path.join(cache.errorFolder, filenames[1])) + expect(fs.unlink).toHaveBeenNthCalledWith(3, path.join(cache.errorFolder, filenames[2])) + }) + + it('should retry error files', async () => { + const filenames = ['file1.name', 'file2.name', 'file3.name'] + + await cache.retryErrorFiles(filenames) + expect(fs.rename).toHaveBeenNthCalledWith(1, path.join(cache.errorFolder, filenames[0]), path.join(cache.fileFolder, filenames[0])) + expect(fs.rename).toHaveBeenNthCalledWith(2, path.join(cache.errorFolder, filenames[1]), path.join(cache.fileFolder, filenames[1])) + expect(fs.rename).toHaveBeenNthCalledWith(3, path.join(cache.errorFolder, filenames[2]), path.join(cache.fileFolder, filenames[2])) + }) + + it('should remove all error files when the error folder is not empty', async () => { + const filenames = ['file1.name', 'file2.name', 'file3.name'] + cache.getFiles = jest.fn().mockReturnValue(Promise.resolve(filenames)) + cache.removeErrorFiles = jest.fn() + + await cache.removeAllErrorFiles() + expect(cache.removeErrorFiles).toHaveBeenCalledWith(filenames) + }) + + it('should not remove any error file when the error folder is empty', async () => { + cache.getFiles = jest.fn().mockReturnValue(Promise.resolve([])) + cache.removeErrorFiles = jest.fn() + + await cache.removeAllErrorFiles() + expect(cache.removeErrorFiles).not.toHaveBeenCalled() + }) + + it('should retry all error files when the error folder is not empty', async () => { + const filenames = ['file1.name', 'file2.name', 'file3.name'] + cache.getFiles = jest.fn().mockReturnValue(Promise.resolve(filenames)) + cache.retryErrorFiles = jest.fn() + + await cache.retryAllErrorFiles() + expect(cache.retryErrorFiles).toHaveBeenCalledWith(filenames) + }) + + it('should not remove any error file when the error folder is empty', async () => { + cache.getFiles = jest.fn().mockReturnValue(Promise.resolve([])) + cache.retryErrorFiles = jest.fn() + + await cache.retryAllErrorFiles() + expect(cache.retryErrorFiles).not.toHaveBeenCalled() + }) + + it('should get files from a folder', async () => { + const folder = 'folder' + const filenames = ['file1.name', 'file2.name'] + fs.readdir = jest.fn().mockReturnValue(filenames) + + const result = await cache.getFiles(folder) + expect(fs.readdir).toHaveBeenCalledWith(folder) + expect(result).toEqual(filenames) + }) + + it('should match file with date and name', async () => { + const folder = 'folder' + const filename = 'file.name' + const fromDate = '2022-11-11T11:11:11.111' + const toDate = '2022-11-12T11:11:11.111' + fs.stat = jest.fn().mockReturnValue({ mtimeMs: new Date('2022-11-12T00:00:00.000').getTime() }) + + const match = await cache.matchFile(folder, filename, fromDate, toDate, 'ile') + expect(fs.stat).toBeCalledWith(path.join(folder, filename)) + expect(match).toBeTruthy() + }) + + it('should not match file without date match', async () => { + const folder = 'folder' + const filename = 'file.name' + const fromDate = '2022-11-11T11:11:11.111' + const toDate = '2022-11-12T11:11:11.111' + fs.stat = jest.fn().mockReturnValue({ mtimeMs: new Date('2022-11-13T00:00:00.000').getTime() }) + + const match = await cache.matchFile(folder, filename, fromDate, toDate, 'ile') + expect(fs.stat).toBeCalledWith(path.join(folder, filename)) + expect(match).toBeFalsy() + }) + + it('should not match file without name match', async () => { + const folder = 'folder' + const filename = 'file.name' + const fromDate = '2022-11-11T11:11:11.111' + const toDate = '2022-11-12T11:11:11.111' + fs.stat = jest.fn().mockReturnValue({ mtimeMs: new Date('2022-11-13T00:00:00.000').getTime() }) + + const match = await cache.matchFile(folder, filename, fromDate, toDate, 'noMatch') + expect(fs.stat).toBeCalledWith(path.join(folder, filename)) + expect(match).toBeFalsy() + }) }) diff --git a/src/service/utils.js b/src/service/utils.js index 76ed742ea1..86dfcca210 100644 --- a/src/service/utils.js +++ b/src/service/utils.js @@ -139,7 +139,7 @@ const filesExists = async (filePath) => { */ const asyncFilter = async (array, predicate) => { const results = await Promise.all(array.map(predicate)) - return array.filter((filename, index) => results[index]) + return array.filter((item, index) => results[index]) } module.exports = { diff --git a/src/service/utils.spec.js b/src/service/utils.spec.js index af9151d6ee..0cc6dafab3 100644 --- a/src/service/utils.spec.js +++ b/src/service/utils.spec.js @@ -173,4 +173,13 @@ describe('Service utils', () => { expect(fsSync.createWriteStream).toBeCalledTimes(1) expect(fsSync.createWriteStream).toHaveBeenCalledWith('myOutputFile') }) + + it('should properly filter asynchronously', async () => { + const array = ['ok', 'ok', 'notOk', 'ok'] + const predicate = async (item) => item === 'ok' + + const result = await utils.asyncFilter(array, predicate) + + expect(result).toEqual(['ok', 'ok', 'ok']) + }) })