@apistudio/apim-cli
Version:
CLI for API Management Products
184 lines (151 loc) • 6.63 kB
text/typescript
import AdmZip from 'adm-zip';
import path from 'path';
import { isYamlFile } from '../common/fs-helper.js';
import { convertParsedYmlToString, parseYamlContent } from '../common/yaml-helper.js';
import {
FAILED_TO_PROCESS_ENTRY,
NO_ENV_FILE
} from '../../constants/message-constants.js';
import { showError } from '../common/message-helper.js';
import { parseEnvInput, updateEnvironmentAssetInZip } from './env-helper.js';
jest.mock('adm-zip');
jest.mock('path');
jest.mock('../common/yaml-helper.js', () => {
let initialVariables: { key: string; value: string }[] = [];
const toJSMock = jest.fn(() => ({
kind: 'Environment',
spec: { variables: [...initialVariables] },
}));
const setInMock = jest.fn((path: string[], value: { key: string; value: string }) => {
if (path.join('.') === 'spec.variables') {
initialVariables = [...initialVariables, value];
toJSMock.mockReturnValue({
kind: 'Environment',
spec: { variables: [...initialVariables] },
});
}
});
const hasInMock = jest.fn((path: string[]) => {
return path.join('.') === 'spec.variables';
});
return {
convertParsedYmlToString: jest.fn(),
parseYamlContent: jest.fn((content: string) => ({
toJS: toJSMock,
setIn: setInMock,
hasIn: hasInMock,
})),
};
});
jest.mock('../common/fs-helper.js', () => ({
isYamlFile: jest.fn(),
}));
jest.mock('../common/message-helper', () => ({
showError: jest.fn(),
}));
describe('Env helper test suite', () => {
describe('parseEnvInput', () => {
it('should correctly parse single key-value pairs', () => {
const input = "key1=value1,key2=value2";
const expected = {
key1: 'value1',
key2: 'value2',
};
expect(parseEnvInput(input)).toEqual(expected);
});
it('should correctly parse key with multiple comma-separated values', () => {
const input = `key1="value1,value2",key2="value with spaces"`;
const expected = {
key1: 'value1,value2',
key2: 'value with spaces',
};
expect(parseEnvInput(input)).toEqual(expected);
});
it('should handle spaces around keys and values', () => {
const input = " key1 = ' value1, value2 ' , key2 = ' value with spaces ' ";
const expected = {
key1: 'value1, value2',
key2: 'value with spaces',
};
expect(parseEnvInput(input)).toEqual(expected);
});
it('should throw an error for missing key', () => {
const input = "=value";
expect(() => parseEnvInput(input)).toThrow('Invalid environment variable format: Key must be provided for the value: =value');
});
it('should throw an error for missing value', () => {
const input = "key1=";
expect(() => parseEnvInput(input)).toThrow('Invalid environment variable format: Value must be provided for the key: key1');
});
it('should handle empty input gracefully', () => {
const input = "";
const expected = {};
expect(parseEnvInput(input)).toEqual(expected);
});
it('should handle malformed input', () => {
const input = "key1=value1,,key2=value2=";
const expected = {
key1: 'value1',
key2: 'value2=',
};
expect(parseEnvInput(input)).toEqual(expected);
});
it('should handle quotes around keys and values', () => {
const input = "'key1'='value1','key2'='value with spaces'";
const expected = {
key1: 'value1',
key2: 'value with spaces',
};
expect(parseEnvInput(input)).toEqual(expected);
});
});
describe('updateEnvironmentAssetInZip', () => {
let mockZipBuffer: Buffer;
let mockZip: AdmZip;
let mockEntries: any[];
beforeEach(() => {
mockZipBuffer = Buffer.from('mock-zip-buffer');
mockZip = {
getEntries: jest.fn(),
updateFile: jest.fn(),
toBuffer: jest.fn(() => Buffer.from('updated-zip-buffer')),
} as unknown as AdmZip;
mockEntries = [
{ entryName: 'env/file1.yaml', getData: jest.fn(() => Buffer.from('yaml-content')) },
{ entryName: 'env/file2.yaml', getData: jest.fn(() => Buffer.from('yaml-content')) },
];
(AdmZip as jest.Mock).mockImplementation(() => mockZip);
mockZip.getEntries = jest.fn().mockReturnValue(mockEntries);
(isYamlFile as jest.Mock).mockImplementation((path) => path.endsWith('.yaml'));
jest.clearAllMocks();
(convertParsedYmlToString as jest.Mock).mockReturnValue('updated-yaml-content');
(path.normalize as jest.Mock).mockImplementation((p) => p);
});
afterEach(() => {
jest.clearAllMocks();
});
it('should throw an error if no YAML files are found in the specified directory', async () => {
mockZip.getEntries = jest.fn().mockReturnValue([]);
await expect(updateEnvironmentAssetInZip(mockZipBuffer, { key: 'value' }, 'env'))
.rejects.toThrow(`${NO_ENV_FILE} env`);
});
it('should update YAML files in the zip buffer', async () => {
const envMap = { key: 'value' };
await updateEnvironmentAssetInZip(mockZipBuffer, envMap, 'env');
expect(convertParsedYmlToString).toHaveBeenCalled();
});
it('should update YAML files in the zip buffer with multiple key-value pairs', async () => {
const envMap = { key1: 'value1', key2: 'value2' };
await updateEnvironmentAssetInZip(mockZipBuffer, envMap, 'env');
expect(convertParsedYmlToString).toHaveBeenCalled();
});
it('should handle errors while processing entries', async () => {
mockEntries[0].getData.mockImplementation(() => {
throw new Error('Failed to read file');
});
const envMap = { key: 'value' };
await updateEnvironmentAssetInZip(mockZipBuffer, envMap, 'env');
expect(showError).toHaveBeenCalledWith(`${FAILED_TO_PROCESS_ENTRY} env/file1.yaml: Failed to read file`);
});
});
});