UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

395 lines (324 loc) 13.1 kB
/** * Copyright Super iPaaS Integration LLC, an IBM Company 2024 */ import fs, {existsSync, statSync, readFileSync, accessSync} from 'fs-extra'; import path, {join} from 'path'; import crypto from 'crypto'; import {hasReadAccess, isDirectory, isDirOrFileExists, isFile, isSubDirectoryExists, readFile, readFileAsBuffer, isYamlFile, isJsonFile, isOtherFile, getRandomFileName, getSubDirectory, writeJsonToFile, readJsonFromFile, checkFileExists, ensureDirectoryExists, readFileAsString, readDirectoryContents, getFileNameFromPath, createBuildZip, normalizePath, getParentDir } from './fs-helper'; jest.mock('fs'); jest.mock('fs-extra'); jest.mock('path'); jest.mock('crypto', () => ({ randomUUID: jest.fn(), })); jest.mock('./message-helper', () => ({ __esModule: true, showError: jest.fn() })); describe('FS Helper test suite', () => { afterEach(() => { jest.clearAllMocks(); }); it('should return true if file exists', () => { (existsSync as jest.Mock).mockReturnValue(true); expect(isDirOrFileExists('sample path')).toBe(true); }); it('should return false if file does not exists', () => { (existsSync as jest.Mock).mockReturnValue(false); expect(isDirOrFileExists('sample path')).toBe(false); }); it('should return false if the given path is not directory', () => { (existsSync as jest.Mock).mockReturnValue(true); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => false }); expect(isDirectory('sample path')).toBe(false); }); it('should return true if the given path is directory', () => { (existsSync as jest.Mock).mockReturnValue(true); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => true }); expect(isDirectory('sample path')).toBe(true); }); it('should return false if the given path does not exists', () => { (existsSync as jest.Mock).mockReturnValue(false); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => true }); expect(isDirectory('sample path')).toBe(false); }); it('should return false if sub-directory does not exists', () => { (existsSync as jest.Mock).mockReturnValue(true); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => false }); (join as jest.Mock).mockReturnValue(''); expect(isSubDirectoryExists('sample path', 'test')).toBe(false); }); it('should return true if sub-directory does exists', () => { (existsSync as jest.Mock).mockReturnValue(true); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => true }); (join as jest.Mock).mockReturnValue(''); expect(isSubDirectoryExists('sample path', 'test')).toBe(true); }); it('should return true if the given path is a file', () => { (existsSync as jest.Mock).mockReturnValue(true); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => false, isFile: () => true }); expect(isFile('sample path')).toBe(true); }); it('should return false if the given path is not a file', () => { (existsSync as jest.Mock).mockReturnValue(true); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => false, isFile: () => false }); expect(isFile('sample path')).toBe(false); }); it('should return false if the given path does not exists', () => { (existsSync as jest.Mock).mockReturnValue(false); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => false, isFile: () => true }); expect(isFile('sample path')).toBe(false); }); it('should return content of the file', () => { const fileContent = 'File content'; (existsSync as jest.Mock).mockReturnValue(true); (statSync as jest.Mock).mockReturnValue({ isDirectory: () => false, isFile: () => true }); (join as jest.Mock).mockReturnValue(''); (readFileSync as jest.Mock).mockReturnValue(Buffer.alloc(fileContent.length, fileContent)); expect(readFile('dir path', 'filename')).toBe(fileContent); }); it('should return true if access permission is available', () => { (accessSync as jest.Mock).mockReturnValue(true); expect(hasReadAccess('sample path')).toBe(true); }); it('should return false if access permission is not available', () => { jest.spyOn(fs, 'accessSync').mockImplementation(() => { throw new Error('test'); }); expect(hasReadAccess('sample path')).toBe(false); }); it('should return file content as buffer', () => { expect(readFileAsBuffer('sample path')).toBeInstanceOf(Buffer); }); it('should generate a random file name with default extension', () => { (crypto.randomUUID as jest.Mock).mockReturnValue('random-uuid'); const fileName = getRandomFileName(); expect(fileName).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.yml$/i); }); it('should return a random file name with provided extension', () => { (crypto.randomUUID as jest.Mock).mockReturnValue('random-uuid'); const fileName = getRandomFileName('.txt'); expect(fileName).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.txt$/i); }); it('should add a dot to the extension if not provided', () => { (crypto.randomUUID as jest.Mock).mockReturnValue('random-uuid'); const fileName = getRandomFileName('txt'); expect(fileName).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.txt$/i); }); it('should return true for .yml files', () => { expect(isYamlFile('file.yml')).toBe(true); }); it('should return true for .yaml files', () => { expect(isYamlFile('file.yaml')).toBe(true); }); it('should return false for non-yaml files', () => { expect(isYamlFile('file.txt')).toBe(false); }); it('should return yaml file as false for null', () => { expect(isYamlFile(null as unknown as string)).toBe(false); }); it('should return yaml file as false for undefined', () => { expect(isYamlFile(undefined as unknown as string)).toBe(false); }); it('should return true for .json files', () => { expect(isJsonFile('file.json')).toBe(true); }); it('should return false for non-json files', () => { expect(isJsonFile('file.txt')).toBe(false); }); it('should return json file as false for null', () => { expect(isJsonFile(null as unknown as string)).toBe(false); }); it('should return json file as false for undefined', () => { expect(isJsonFile(undefined as unknown as string)).toBe(false); }); it('should return true for .txt files', () => { expect(isOtherFile('file.txt')).toBe(true); }); it('should return other file as false for json files', () => { expect(isOtherFile('file.json')).toBe(false); }); it('should return other file as false for null', () => { expect(isOtherFile(null as unknown as string)).toBe(false); }); it('should return other file as false for undefined', () => { expect(isOtherFile(undefined as unknown as string)).toBe(false); }); it('should throw an error if the subdirectory does not exist', () => { jest.spyOn({ isSubDirectoryExists }, 'isSubDirectoryExists').mockReturnValue(false); const parentDirPath = '/parent/dir'; const folderName = 'subfolder'; const errorMessage = `The folder '${folderName}' is invalid or does not exist inside parent directory '${parentDirPath}'`; expect(() => getSubDirectory(parentDirPath, folderName)).toThrowError(errorMessage); }); it('should return the file name from the given path', () => { const filePath = 'path/to/file.txt'; const expectedFileName = 'file.txt'; (path.basename as jest.Mock).mockReturnValue(expectedFileName); const result = getFileNameFromPath(filePath); expect(result).toBe(expectedFileName); }); it('should create build zip and return true', async () => { const fileContent = 'File content'; const buffer = Buffer.alloc(fileContent.length, fileContent); const folderPath = 'path/to/directory/build.zip'; const result = await createBuildZip(buffer, folderPath); expect(result).toBe(true); }); it('should return false if the file path do not .zip', async () => { const fileContent = 'File content'; const buffer = Buffer.alloc(fileContent.length, fileContent); const folderPath = 'path/to/directory/build'; const result = await createBuildZip(buffer, folderPath); expect(result).toBe(false); }); describe('writeJsonToFile', () => { it('should write JSON to file with the correct options', async () => { const filePath = 'path/to/file.json'; const data = { key: 'value' }; const options = { spaces: 2 }; await writeJsonToFile(filePath, data, options); expect(fs.writeJson).toHaveBeenCalledWith(filePath, data, options); }); it('should throw an error if writing fails', async () => { const filePath = 'path/to/file.json'; const data = { key: 'value' }; (fs.writeJson as jest.Mock).mockRejectedValue(new Error('Write failed')); await expect(writeJsonToFile(filePath, data)).rejects.toThrow('Failed to write JSON to file: Write failed'); }); }); describe('readJsonFromFile', () => { const mockFilePath = 'mock/file/path.json'; const mockJsonData = { key: 'value' }; it('should read JSON data from a file successfully', async () => { (fs.readJson as jest.Mock).mockResolvedValue(mockJsonData); const result = await readJsonFromFile(mockFilePath); expect(fs.readJson).toHaveBeenCalledWith(mockFilePath); expect(result).toEqual(mockJsonData); }); it('should throw an error if reading JSON from the file fails', async () => { const errorMessage = 'mock error message'; (fs.readJson as jest.Mock).mockRejectedValue(new Error(errorMessage)); await expect(readJsonFromFile(mockFilePath)).rejects.toThrow(`${errorMessage}`); }); }); describe('checkFileExists', () => { it('should return true if the file exists', async () => { const filePath = 'path/to/file.json'; (fs.pathExists as jest.Mock).mockResolvedValue(true); const result = await checkFileExists(filePath); expect(result).toBe(true); expect(fs.pathExists).toHaveBeenCalledWith(filePath); }); it('should return false if the file does not exist', async () => { const filePath = 'path/to/file.json'; (fs.pathExists as jest.Mock).mockResolvedValue(false); const result = await checkFileExists(filePath); expect(result).toBe(false); }); it('should throw an error if checking fails', async () => { const filePath = 'path/to/file.json'; (fs.pathExists as jest.Mock).mockRejectedValue(new Error('Check failed')); await expect(checkFileExists(filePath)).rejects.toThrow('Failed to check if file exists: Check failed'); }); }); describe('ensureDirectoryExists', () => { it('should ensure the directory exists', async () => { const dirPath = 'path/to/dir'; await ensureDirectoryExists(dirPath); expect(fs.ensureDir).toHaveBeenCalledWith(dirPath); }); it('should throw an error if directory creation fails', async () => { const dirPath = 'path/to/dir'; (fs.ensureDir as jest.Mock).mockRejectedValue(new Error('Ensure dir failed')); await expect(ensureDirectoryExists(dirPath)).rejects.toThrow('Failed to ensure directory exists: Ensure dir failed'); }); }); describe('readFileAsString', () => { it('should return the file content as a string', () => { const filePath = 'path/to/file.txt'; const fileContent = 'File content here'; (fs.existsSync as jest.Mock).mockReturnValue(true); (fs.readFileSync as jest.Mock).mockReturnValue(fileContent); const result = readFileAsString(filePath); expect(result).toBe(fileContent); expect(fs.existsSync).toHaveBeenCalledWith(filePath); expect(fs.readFileSync).toHaveBeenCalledWith(filePath, 'utf8'); }); it('should throw an error if the file does not exist', () => { const filePath = 'path/to/nonexistent-file.txt'; (fs.existsSync as jest.Mock).mockReturnValue(false); expect(() => readFileAsString(filePath)).toThrow(`The file '${filePath}' does not exist`); expect(fs.existsSync).toHaveBeenCalledWith(filePath); }); it('should throw an error if reading file fails', () => { const filePath = 'path/to/file.txt'; (fs.existsSync as jest.Mock).mockReturnValue(true); (fs.readFileSync as jest.Mock).mockImplementation(() => { throw new Error('Failed to read file'); }); expect(() => readFileAsString(filePath)).toThrow('Failed to read file'); }); }); describe('readDirectoryContents', () => { it('should return the list of files in the directory', () => { const folderPath = 'path/to/directory'; const directoryContents = ['file1.txt', 'file2.txt']; (fs.readdirSync as jest.Mock).mockReturnValue(directoryContents); const result = readDirectoryContents(folderPath); expect(result).toEqual(directoryContents); expect(fs.readdirSync).toHaveBeenCalledWith(folderPath); }); it('should throw an error if directory reading fails', () => { const folderPath = 'path/to/directory'; (fs.readdirSync as jest.Mock).mockImplementation(() => { throw new Error('Failed to read directory'); }); expect(() => readDirectoryContents(folderPath)).toThrow('Failed to read directory'); }); }); });