@apistudio/apim-cli
Version:
CLI for API Management Products
193 lines (155 loc) • 7.53 kB
text/typescript
/**
* Copyright Super iPaaS Integration LLC, an IBM Company 2024
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
import AdmZip from 'adm-zip';
import { loadCacheWithProject } from './asset-cache-helper.js';
import { isYamlFile } from '../common/fs-helper.js';
import { readMultiYaml } from '../common/yaml-helper.js';
import { isValidAsset } from './asset-helper.js';
import { AssetCache } from '../../cache/asset-cache.js';
import { getRefsFromAsset } from '../../handlers/asset-handler.js';
import { BaseAsset } from '../../model/assets-model.js';
jest.mock('../common/fs-helper.js', () => ({
isYamlFile: jest.fn(),
}));
jest.mock('../common/yaml-helper.js', () => ({
readMultiYaml: jest.fn(),
}));
jest.mock('./asset-helper.js', () => ({
isValidAsset: jest.fn(),
}));
jest.mock('../common/message-helper.js', () => ({
showWarning: jest.fn(),
showInfo: jest.fn()
}));
jest.mock('../../cache/asset-cache.js', () => {
return {
AssetCache: {
getInstance: jest.fn().mockReturnValue({
markAsProcessed: jest.fn(),
checkAndMarkAsUnProcessed: jest.fn(),
}),
},
};
});
jest.mock('../../handlers/asset-handler.js', () => ({
getRefsFromAsset: jest.fn(),
}));
describe('Asset cache helper function test suite', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('should handle empty zip', () => {
const zip = new AdmZip();
jest.spyOn(zip, 'getEntries').mockReturnValue([]);
loadCacheWithProject(zip);
expect(readMultiYaml).not.toHaveBeenCalled();
expect(isValidAsset).not.toHaveBeenCalled();
expect(AssetCache.getInstance().markAsProcessed).not.toHaveBeenCalled();
expect(getRefsFromAsset).not.toHaveBeenCalled();
});
it('should handle zip with invalid asset', () => {
const zip = new AdmZip();
const mockAsset = { kind: 'invalidKind', metadata: { name: 'invalidName' } } as BaseAsset;
jest.spyOn(zip, 'getEntries').mockReturnValue([
{ entryName: 'asset.yml', isDirectory: false, getData: jest.fn().mockReturnValue(Buffer.from('invalid yaml')) } as any,
]);
(isYamlFile as jest.Mock).mockReturnValue(true);
(readMultiYaml as jest.Mock).mockReturnValue([mockAsset]);
(isValidAsset as jest.Mock).mockReturnValue(false);
loadCacheWithProject(zip);
expect(readMultiYaml).toHaveBeenCalledWith('asset.yml', 'invalid yaml');
expect(isValidAsset).toHaveBeenCalledWith(mockAsset);
expect(AssetCache.getInstance().markAsProcessed).not.toHaveBeenCalled();
expect(getRefsFromAsset).not.toHaveBeenCalled();
});
it('should handle zip with non-yaml files', () => {
const zip = new AdmZip();
jest.spyOn(zip, 'getEntries').mockReturnValue([
{ entryName: 'file.txt', isDirectory: false, getData: jest.fn() } as any,
{ entryName: 'image.png', isDirectory: false, getData: jest.fn() } as any,
]);
(isYamlFile as jest.Mock).mockReturnValue(false);
loadCacheWithProject(zip);
expect(readMultiYaml).not.toHaveBeenCalled();
expect(isValidAsset).not.toHaveBeenCalled();
expect(AssetCache.getInstance().markAsProcessed).not.toHaveBeenCalled();
expect(getRefsFromAsset).not.toHaveBeenCalled();
});
it('should handle zip with one valid asset', () => {
const zip = new AdmZip();
const mockAsset = { kind: 'validKind', metadata: { name: 'validName' } } as BaseAsset;
const mockRefs = [{ kind: 'refKind', metadata: { name: 'refName' } }] as BaseAsset[];
jest.spyOn(zip, 'getEntries').mockReturnValue([
{ entryName: 'asset.yml', isDirectory: false, getData: jest.fn().mockReturnValue(Buffer.from('valid yaml')) } as any,
]);
(isYamlFile as jest.Mock).mockReturnValue(true);
(readMultiYaml as jest.Mock).mockReturnValue([mockAsset]);
(isValidAsset as jest.Mock).mockReturnValue(true);
(getRefsFromAsset as jest.Mock).mockReturnValue(mockRefs);
loadCacheWithProject(zip);
expect(readMultiYaml).toHaveBeenCalledWith('asset.yml', 'valid yaml');
expect(isValidAsset).toHaveBeenCalledWith(mockAsset);
expect(AssetCache.getInstance().markAsProcessed).toHaveBeenCalledWith(mockAsset);
expect(getRefsFromAsset).toHaveBeenCalledWith(mockAsset);
expect(AssetCache.getInstance().checkAndMarkAsUnProcessed).toHaveBeenCalledWith(mockRefs[0]);
});
it('should handle dependency assets correctly', () => {
const zip = new AdmZip();
const mockAsset = { kind: 'validKind', metadata: { name: 'validName' } } as BaseAsset;
const mockRefAsset = { kind: 'refKind', metadata: { name: 'refName' } } as BaseAsset;
const mockRefs = [mockRefAsset];
jest.spyOn(zip, 'getEntries').mockReturnValue([
{ entryName: 'asset.yml', isDirectory: false, getData: jest.fn().mockReturnValue(Buffer.from('valid yaml')) } as any,
]);
(isYamlFile as jest.Mock).mockReturnValue(true);
(readMultiYaml as jest.Mock).mockReturnValue([mockAsset]);
(isValidAsset as jest.Mock).mockReturnValue(true);
(getRefsFromAsset as jest.Mock).mockReturnValue(mockRefs);
loadCacheWithProject(zip);
expect(readMultiYaml).toHaveBeenCalledWith('asset.yml', 'valid yaml');
expect(isValidAsset).toHaveBeenCalledWith(mockAsset);
expect(AssetCache.getInstance().markAsProcessed).toHaveBeenCalledWith(mockAsset);
expect(getRefsFromAsset).toHaveBeenCalledWith(mockAsset);
expect(AssetCache.getInstance().checkAndMarkAsUnProcessed).toHaveBeenCalledWith(mockRefAsset);
});
it('should process multiple valid assets in one YAML file', () => {
const zip = new AdmZip();
const mockAssets = [
{ kind: 'validKind1', metadata: { name: 'validName1' } } as BaseAsset,
{ kind: 'validKind2', metadata: { name: 'validName2' } } as BaseAsset,
];
jest.spyOn(zip, 'getEntries').mockReturnValue([
{ entryName: 'assets.yml', isDirectory: false, getData: jest.fn().mockReturnValue(Buffer.from('multiple valid yaml')) } as any,
]);
(isYamlFile as jest.Mock).mockReturnValue(true);
(readMultiYaml as jest.Mock).mockReturnValue(mockAssets);
(isValidAsset as jest.Mock).mockReturnValue(true);
loadCacheWithProject(zip);
mockAssets.forEach(asset => {
expect(isValidAsset).toHaveBeenCalledWith(asset);
expect(AssetCache.getInstance().markAsProcessed).toHaveBeenCalledWith(asset);
});
expect(readMultiYaml).toHaveBeenCalledWith('assets.yml','multiple valid yaml');
});
it('should process valid assets and skip invalid ones in one YAML file', () => {
const zip = new AdmZip();
const validAsset = { kind: 'validKind', metadata: { name: 'validName' } } as BaseAsset;
const invalidAsset = { kind: 'invalidKind', metadata: { name: 'invalidName' } } as BaseAsset;
jest.spyOn(zip, 'getEntries').mockReturnValue([
{ entryName: 'assets.yml', isDirectory: false, getData: jest.fn().mockReturnValue(Buffer.from('valid and invalid yaml')) } as any,
]);
(isYamlFile as jest.Mock).mockReturnValue(true);
(readMultiYaml as jest.Mock).mockReturnValue([validAsset, invalidAsset]);
(isValidAsset as jest.Mock)
.mockReturnValueOnce(true) // validAsset
.mockReturnValueOnce(false); // invalidAsset
loadCacheWithProject(zip);
expect(readMultiYaml).toHaveBeenCalledWith('assets.yml', 'valid and invalid yaml');
expect(isValidAsset).toHaveBeenCalledWith(validAsset);
expect(isValidAsset).toHaveBeenCalledWith(invalidAsset);
expect(AssetCache.getInstance().markAsProcessed).toHaveBeenCalledWith(validAsset);
expect(AssetCache.getInstance().markAsProcessed).not.toHaveBeenCalledWith(invalidAsset);
});
});