UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

257 lines (212 loc) 8.17 kB
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); }); }); });