@apistudio/apim-cli
Version:
CLI for API Management Products
257 lines (212 loc) • 8.17 kB
text/typescript
import fs from 'fs-extra';
import { showError, showInfo } from '../../helpers/common/message-helper.js';
import { setGatewayEndpoint, getGatewayEndpoints, GatewayEndpointJson } from './config.js'; // Adjust the import path
import { GatewayResponseAPI } from '../../model/studio/deploy-response-model.js';
import { constructKey } from '../../helpers/apim/test-helper.js';
import { ALL_ENDPOINTS_FETCHED_FROM_STORE,
CONFIG,
DEPLOYMENT_DATA_UPDATED,
NO_DATA_TO_PROCESS,
NO_ENDPOINTS_IN_STORE,
NO_ENDPOINTS_STORE_CONFIGURED,
NO_UPDATES_NEEDED,
SOME_ENDPOINTS_MISSING_FROM_STORE } from '../../constants/message-constants.js';
jest.mock('path', () => ({
join: jest.fn().mockImplementation((...args) => args.join('/')),
resolve: jest.fn().mockImplementation((...args) => args.join('/')),
}));
jest.mock('fs-extra', () => ({
ensureDir: jest.fn(),
pathExists: jest.fn(),
writeJson: jest.fn(),
readJson: jest.fn(),
}));
jest.mock('../../helpers/common/message-helper.js', () => ({
showInfo: jest.fn(),
showError: jest.fn(),
showWarning: jest.fn(),
}));
jest.mock('../../helpers/apim/test-helper.js', () => ({
constructKey: jest.fn(),
}));
jest.mock('env-paths', () => {
return jest.fn((name: string) => ({
data: `/mock/path/${name}-data`,
config: `/mock/path/${name}-config`,
cache: `/mock/path/${name}-cache`,
log: `/mock/path/${name}-log`,
temp: `/mock/path/${name}-temp`,
}));
});
jest.mock('../../debug/debug-manager.js', () => ({
DebugManager: {
getInstance: jest.fn().mockReturnValue({
setDebugEnabled: jest.fn(),
isDebugEnabled: jest.fn().mockReturnValue(true),
}),
},
}));
describe('Configuration Test Suite', () => {
beforeEach(() => {
(constructKey as jest.Mock).mockImplementation((apiResponse) => apiResponse.name);
jest.clearAllMocks();
});
describe('setGatewayEndpoint', () => {
const mockResponse: GatewayResponseAPI[] = [
{
name: 'api1',
gatewayEndpoints: ['https://api1.com'],
kind: 'API',
namespace: 'default',
version: '1.0.0',
assetName: 'asset1',
},
{
name: 'api2',
gatewayEndpoints: ['https://api2.com'],
kind: 'API',
namespace: 'default',
version: '1.1.0',
assetName: 'asset2',
}
];
beforeEach(() => {
jest.clearAllMocks();
});
it('should show NO_DATA_TO_PROCESS when response is empty', async () => {
const emptyResponse: GatewayResponseAPI[] = [];
await setGatewayEndpoint(emptyResponse);
expect(showError).toHaveBeenCalledWith(CONFIG + NO_DATA_TO_PROCESS);
});
it('should create config if file does not exist and set new endpoints', async () => {
(fs.pathExists as jest.Mock).mockResolvedValueOnce(false);
(fs.pathExists as jest.Mock).mockResolvedValueOnce(true);
(fs.readJson as jest.Mock).mockResolvedValue({ deployments: [] });
(fs.writeJson as jest.Mock).mockResolvedValueOnce(undefined);
await setGatewayEndpoint(mockResponse);
expect(fs.writeJson).toHaveBeenCalled();
expect(showInfo).toHaveBeenCalledWith(expect.any(String));
});
it('should update the config file if the endpoints need to be updated', async () => {
const currentData = {
deployments: [
{
api: 'api1',
endpoints: ['https://old-api1.com'],
}
]
};
(fs.pathExists as jest.Mock).mockResolvedValue(true);
(fs.readJson as jest.Mock).mockResolvedValue(currentData);
(fs.writeJson as jest.Mock).mockResolvedValue(undefined);
await setGatewayEndpoint(mockResponse);
expect(fs.writeJson).toHaveBeenCalled();
expect(showInfo).toHaveBeenCalledWith(CONFIG + DEPLOYMENT_DATA_UPDATED);
});
it('should show NO_UPDATES_NEEDED if no changes are required', async () => {
const currentData = {
deployments: [
{
api: 'api1',
endpoints: ['https://api1.com'],
},
{
api: 'api2',
endpoints: ['https://api2.com'],
}
]
};
(fs.pathExists as jest.Mock).mockResolvedValue(true);
(fs.readJson as jest.Mock).mockResolvedValue(currentData);
await setGatewayEndpoint(mockResponse);
expect(showInfo).toHaveBeenCalledWith(CONFIG + NO_UPDATES_NEEDED);
expect(fs.writeJson).not.toHaveBeenCalled();
});
it('should append new deployments to the config file if they are missing', async () => {
const currentData = {
deployments: [
{
api: 'api1',
endpoints: ['https://api1.com'],
},
],
};
(fs.pathExists as jest.Mock).mockResolvedValue(true);
(fs.readJson as jest.Mock).mockResolvedValue(currentData);
(fs.writeJson as jest.Mock).mockResolvedValue(undefined);
await setGatewayEndpoint(mockResponse);
expect(fs.writeJson).toHaveBeenCalledWith(expect.any(String), {
deployments: expect.arrayContaining([
expect.objectContaining({ api: 'api1', endpoints: ['https://api1.com'] }),
expect.objectContaining({ api: 'api2', endpoints: ['https://api2.com'] }),
]),
}, { spaces: 2 });
expect(showInfo).toHaveBeenCalledWith(CONFIG + DEPLOYMENT_DATA_UPDATED);
});
it('should handle errors when setting the endpoints fails', async () => {
(fs.pathExists as jest.Mock).mockRejectedValue(new Error('File system error'));
await setGatewayEndpoint(mockResponse);
expect(showError).toHaveBeenCalledWith(expect.any(String));
});
});
describe('getGatewayEndpoints', () => {
it('should return found and not found endpoints', async () => {
(fs.pathExists as jest.Mock).mockResolvedValue(true);
(fs.readJson as jest.Mock).mockResolvedValue({
deployments: [
{ api: 'api1', endpoints: ['http://example.com'] },
{ api: 'api2', endpoints: ['http://example2.com'] },
],
});
const result = await getGatewayEndpoints('api1,api3');
expect(result).toEqual({
foundEndpoints: {
api1: ['http://example.com'],
},
notFoundApis: 'api3',
});
expect(showInfo).toHaveBeenCalledWith(CONFIG + SOME_ENDPOINTS_MISSING_FROM_STORE);
});
it('should return found endpoints and empty notFoundApis if all requested APIs are found', async () => {
const mockData = {
deployments: [
{ api: 'api1', endpoints: ['http://example.com'] },
{ api: 'api2', endpoints: ['http://example2.com'] },
],
} as GatewayEndpointJson;
(fs.pathExists as jest.Mock).mockResolvedValue(true);
(fs.readJson as jest.Mock).mockResolvedValue(mockData);
const result = await getGatewayEndpoints('api1,api2');
expect(result).toEqual({ foundEndpoints: { api1: ['http://example.com'], api2: ['http://example2.com'] }, notFoundApis: '' });
expect(showInfo).toHaveBeenCalledWith(CONFIG + ALL_ENDPOINTS_FETCHED_FROM_STORE);
});
it('should return some found endpoints and missing APIs', async () => {
const mockData: GatewayEndpointJson = {
deployments: [
{ api: 'api1', endpoints: ['http://example.com'] },
],
};
(fs.pathExists as jest.Mock).mockResolvedValue(true);
(fs.readJson as jest.Mock).mockResolvedValue(mockData);
const result = await getGatewayEndpoints('api1,api2');
expect(result).toEqual({ foundEndpoints: { api1: ['http://example.com'] }, notFoundApis: 'api2' });
expect(showInfo).toHaveBeenCalledWith(CONFIG + SOME_ENDPOINTS_MISSING_FROM_STORE);
});
it('should return empty found endpoints and all APIs as missing', async () => {
const mockData: GatewayEndpointJson = {
deployments: [],
};
(fs.pathExists as jest.Mock).mockResolvedValue(true);
(fs.readJson as jest.Mock).mockResolvedValue(mockData);
const result = await getGatewayEndpoints('api1,api2');
expect(result).toEqual({ foundEndpoints: {}, notFoundApis: 'api1,api2' });
expect(showInfo).toHaveBeenCalledWith(CONFIG + NO_ENDPOINTS_IN_STORE);
});
it('should handle case where file does not exist', async () => {
(fs.pathExists as jest.Mock).mockResolvedValue(false);
const result = await getGatewayEndpoints('api1');
expect(result).not.toBeNull();
expect(showInfo).toHaveBeenCalledWith(CONFIG + NO_ENDPOINTS_STORE_CONFIGURED);
});
});
});