UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

271 lines (235 loc) 8.33 kB
/** * Copyright IBM Corp. 2024, 2025 */ import { processDeployment, validateGateways } from '../../src/index.js'; import fs from 'fs'; import path from 'path'; import * as GatewayService from '../../src/service/gateway-service.js'; import { AppConstants } from '../../src/constants/app-constants.js'; import { IpcError, Logger } from '@apic/studio-shared'; // Mock the Logger from studio-shared jest.mock('@apic/studio-shared', () => ({ Logger: { info: jest.fn(), debug: jest.fn(), warn: jest.fn(), error: jest.fn(), log: jest.fn(), }, IpcError: class IpcError extends Error { constructor(message: string) { super(message); this.name = 'IpcError'; } }, })); jest.mock('@apic/wmgw-smith-sdk', () => ({ WMGWRuntimeSDK: jest.fn().mockImplementation(() => ({ transformer: { transform: jest.fn().mockResolvedValue(Buffer.from('transformed')), }, inventory: jest.fn(), })), })); jest.mock('@apic/wmgw-smith-transformer', () => ({ createWmgwOrchestrator: jest.fn().mockImplementation(() => ({ transform: jest.fn().mockResolvedValue(Buffer.from('transformed')), })), })); describe('processDeployment', () => { beforeEach(() => { jest.clearAllMocks(); }); it('should return success response on deployment', async () => { const gatewaysJson = { gateways: [ { gatewayURL: 'http://example.com', gatewayUser: 'user', gatewaySecret: '123456', is_mcsp_enabled: false, }, ], overwrite: 'apis,alias', skip: 'policies', }; const zipBuffer = fs.readFileSync(path.resolve(__dirname, '../assets/gateway-asset.zip')); jest.spyOn(GatewayService, 'sendToGateway').mockResolvedValue({ success: true, statusCode: 200, message: 'Api deployment Successful', data: 'success', errors: [], }); const result = await processDeployment(gatewaysJson, zipBuffer); expect(result).toStrictEqual([ { success: true, statusCode: 200, message: 'Api deployment Successful', data: 'success', errors: [], }, ]); expect(Logger.info).toHaveBeenCalledWith('Starting deployment process', { gatewayCount: 1 }); expect(Logger.debug).toHaveBeenCalledWith( 'Deploying to gateway', expect.objectContaining({ gatewayURL: 'http://example.com' }) ); expect(Logger.debug).toHaveBeenCalledWith('Gateway deployment successful', { response: 'success', }); expect(Logger.info).toHaveBeenCalledWith('Deployment process completed.'); expect(Logger.error).not.toHaveBeenCalled(); expect(Logger.warn).not.toHaveBeenCalled(); }); it('should return multiple success responses on multi deployment', async () => { const gatewaysJson = { gateways: [ { gatewayURL: 'http://example.com', gatewayUser: 'user', gatewaySecret: '123456', is_mcsp_enabled: false, }, { gatewayURL: 'http://example2.com', gatewayUser: 'user2', gatewaySecret: 'abcdef', is_mcsp_enabled: true, }, ], overwrite: 'apis,alias', skip: 'policies', }; const zipBuffer = fs.readFileSync(path.resolve(__dirname, '../assets/gateway-asset.zip')); jest.spyOn(GatewayService, 'sendToGateway').mockResolvedValue({ success: true, statusCode: 200, message: 'Api deployment Successful', data: 'success', errors: [], }); const result = await processDeployment(gatewaysJson, zipBuffer); expect(result.length).toBe(2); expect(result[0].success).toBeTruthy(); expect(result[1].success).toBeTruthy(); expect(Logger.info).toHaveBeenCalledWith('Starting deployment process', { gatewayCount: 2 }); expect(Logger.debug).toHaveBeenCalledWith( 'Deploying to gateway', expect.objectContaining({ gatewayURL: 'http://example.com' }) ); expect(Logger.debug).toHaveBeenCalledWith( 'Deploying to gateway', expect.objectContaining({ gatewayURL: 'http://example2.com' }) ); expect(Logger.info).toHaveBeenCalledWith('Deployment process completed.'); expect(Logger.error).not.toHaveBeenCalled(); expect(Logger.warn).not.toHaveBeenCalled(); }); it('should return warning on deployment with no gateways provided', async () => { const gatewaysJson = { gateways: [], overwrite: 'apis,alias', skip: 'policies', }; const zipBuffer = fs.readFileSync(path.resolve(__dirname, '../assets/gateway-asset.zip')); const result = await processDeployment(gatewaysJson, zipBuffer); expect(result).toStrictEqual([]); expect(Logger.warn).toHaveBeenCalledWith('No gateways to deploy.'); expect(Logger.info).toHaveBeenCalledWith('Deployment process completed.'); expect(Logger.error).not.toHaveBeenCalled(); expect(Logger.debug).not.toHaveBeenCalled(); }); it('should return error response on deployment error', async () => { const gatewaysJson = { gateways: [ { gatewayURL: 'http://example.com', gatewayUser: 'user', gatewaySecret: '123456', is_mcsp_enabled: false, }, ], overwrite: 'apis,alias', skip: 'policies', }; const zipBuffer = fs.readFileSync(path.resolve(__dirname, '../assets/gateway-asset.zip')); jest.spyOn(GatewayService, 'sendToGateway').mockImplementation(() => { throw new Error('Gateway not found'); }); const result = await processDeployment(gatewaysJson, zipBuffer); expect(result).toStrictEqual([ { success: false, statusCode: 400, message: 'Error sending to http://example.com: Gateway not found', data: null, errors: ['Error sending to http://example.com: Gateway not found'], }, ]); expect(Logger.error).toHaveBeenCalledWith( 'Deployment failed', expect.any(Error), expect.objectContaining({ context: 'deploying to', gatewayURL: 'http://example.com' }) ); expect(Logger.warn).not.toHaveBeenCalled(); }); it('should return error response on deployment error due to promise rejection', async () => { const gatewaysJson = { gateways: [ { gatewayURL: 'http://example.com', gatewayUser: 'user', gatewaySecret: '123456', is_mcsp_enabled: false, }, ], overwrite: 'apis,alias', skip: 'policies', }; const zipBuffer = fs.readFileSync(path.resolve(__dirname, '../assets/gateway-asset.zip')); jest.spyOn(GatewayService, 'sendToGateway').mockRejectedValue({ some: 'random object' }); const result = await processDeployment(gatewaysJson, zipBuffer); expect(result).toStrictEqual([ { success: false, statusCode: 400, message: 'Unknown error sending to http://example.com', data: null, errors: ['Unknown error sending to http://example.com'], }, ]); expect(Logger.error).toHaveBeenCalledWith( 'Unknown deployment error', expect.any(Error), expect.objectContaining({ gatewayURL: 'http://example.com' }) ); expect(Logger.info).toHaveBeenCalledWith('Deployment process completed.'); expect(Logger.warn).not.toHaveBeenCalled(); }); describe('validateGateways', () => { const url = 'https://example.com'; const authHeader = 'Bearer token'; beforeEach(() => { jest.clearAllMocks(); }); it('should call validationManager and return success', async () => { jest .spyOn(GatewayService, 'validationManager') .mockResolvedValue({ data: 'OK', status: 200 }); const result = await validateGateways(url, authHeader); expect(result).toEqual({ data: 'OK', status: 200 }); expect(GatewayService.validationManager).toHaveBeenCalledWith( `${url}${AppConstants.GATEWAY_VALIDATION_URL}`, authHeader ); }); it('should throw error if URL is missing', async () => { await expect(validateGateways('', authHeader)).rejects.toThrow(IpcError); }); it('should throw error if authHeader is missing', async () => { await expect(validateGateways(url, '')).rejects.toThrow(IpcError); }); }); });