diff --git a/src/controllers/help.controller.ts b/src/controllers/help.controller.ts index 433d1910..0f3465a7 100644 --- a/src/controllers/help.controller.ts +++ b/src/controllers/help.controller.ts @@ -4,89 +4,89 @@ import { ProblemException } from '../exceptions/problem.exception'; import { getAppOpenAPI } from '../utils/app-openapi'; const getCommandsFromRequest = (req: Request): string[] => { - return req.params[0] ? req.params[0].split('/').filter(cmd => cmd.trim()) : []; -} + return req.params[0] ? req.params[0].split('/').filter(cmd => cmd.trim()) : []; +}; const getPathKeysMatchingCommands = (commands: string[], pathKeys: string[]): string | undefined => { - return pathKeys.find(pathKey => { - const pathParts = pathKey.split('/').filter(part => part !== ''); - if (pathParts.length !== commands.length) return false; - for (let i = 0; i < pathParts.length; i++) { - const pathPart = pathParts[i]; - const command = commands[i]; - if (pathPart !== command && !pathPart.startsWith('{')) { - return false; - } - } - return true; - }); -} + return pathKeys.find(pathKey => { + const pathParts = pathKey.split('/').filter(part => part !== ''); + if (pathParts.length !== commands.length) return false; + for (let i = 0; i < pathParts.length; i++) { + const pathPart = pathParts[i]; + const command = commands[i]; + if (pathPart !== command && !pathPart.startsWith('{')) { + return false; + } + } + return true; + }); +}; const getFullRequestBodySpec = (operationDetails: any) => { - if (operationDetails?.requestBody?.content?.['application/json']) { - return operationDetails.requestBody.content['application/json'].schema; - } - return null; -} + if (operationDetails?.requestBody?.content?.['application/json']) { + return operationDetails.requestBody.content['application/json'].schema; + } + return null; +}; const buildResponseObject = (matchedPathKey: string, method: string, operationDetails: any, requestBodySchema: any) => { - return { - command: matchedPathKey, - method: method.toUpperCase(), - summary: operationDetails.summary || '', - requestBody: requestBodySchema - }; -} + return { + command: matchedPathKey, + method: method.toUpperCase(), + summary: operationDetails.summary || '', + requestBody: requestBodySchema + }; +}; export class HelpController implements Controller { - public basepath = '/help'; + public basepath = '/help'; - public async boot(): Promise { - const router: Router = Router(); + public async boot(): Promise { + const router: Router = Router(); - router.get(/^\/help(\/.*)?$/, async (req: Request, res: Response, next: NextFunction) => { - const commands = getCommandsFromRequest(req); - let openapiSpec: any; + router.get(/^\/help(\/.*)?$/, async (req: Request, res: Response, next: NextFunction) => { + const commands = getCommandsFromRequest(req); + let openapiSpec: any; - try { - openapiSpec = await getAppOpenAPI(); - } catch (err) { - return next(err); - } + try { + openapiSpec = await getAppOpenAPI(); + } catch (err) { + return next(err); + } - if (commands.length === 0) { - const routes = Object.keys(openapiSpec.paths).map(path => ({ command: path.replace(/^\//, ''), url: `${this.basepath}${path}` })); - return res.json(routes); - } + if (commands.length === 0) { + const routes = Object.keys(openapiSpec.paths).map(path => ({ command: path.replace(/^\//, ''), url: `${this.basepath}${path}` })); + return res.json(routes); + } - const pathKeys = Object.keys(openapiSpec.paths); - const matchedPathKey = getPathKeysMatchingCommands(commands, pathKeys); - if (!matchedPathKey) { - return next(new ProblemException({ - type: 'invalid-asyncapi-command', - title: 'Invalid AsyncAPI Command', - status: 404, - detail: 'The given AsyncAPI command is not valid.' - })); - } + const pathKeys = Object.keys(openapiSpec.paths); + const matchedPathKey = getPathKeysMatchingCommands(commands, pathKeys); + if (!matchedPathKey) { + return next(new ProblemException({ + type: 'invalid-asyncapi-command', + title: 'Invalid AsyncAPI Command', + status: 404, + detail: 'The given AsyncAPI command is not valid.' + })); + } - const pathInfo = openapiSpec.paths[matchedPathKey]; - const method = commands.length > 1 ? 'get' : 'post'; - const operationDetails = pathInfo[method]; - if (!operationDetails) { - return next(new ProblemException({ - type: 'invalid-asyncapi-command', - title: 'Invalid AsyncAPI Command', - status: 404, - detail: 'The given AsyncAPI command is not valid.' - })); - } + const pathInfo = openapiSpec.paths[matchedPathKey]; + const method = commands.length > 1 ? 'get' : 'post'; + const operationDetails = pathInfo[method]; + if (!operationDetails) { + return next(new ProblemException({ + type: 'invalid-asyncapi-command', + title: 'Invalid AsyncAPI Command', + status: 404, + detail: 'The given AsyncAPI command is not valid.' + })); + } - const requestBodySchema = getFullRequestBodySpec(operationDetails); + const requestBodySchema = getFullRequestBodySpec(operationDetails); - return res.json(buildResponseObject(matchedPathKey, method, operationDetails, requestBodySchema)); - }); + return res.json(buildResponseObject(matchedPathKey, method, operationDetails, requestBodySchema)); + }); - return router; - } + return router; + } } \ No newline at end of file diff --git a/src/controllers/tests/help.controller.test.ts b/src/controllers/tests/help.controller.test.ts index 75133d5c..45b395ef 100644 --- a/src/controllers/tests/help.controller.test.ts +++ b/src/controllers/tests/help.controller.test.ts @@ -4,96 +4,96 @@ import { HelpController } from '../help.controller'; import { getAppOpenAPI } from '../../utils/app-openapi'; jest.mock('../../utils/app-openapi', () => ({ - getAppOpenAPI: jest.fn(), + getAppOpenAPI: jest.fn(), })); describe('HelpController', () => { - let app; - beforeAll(async () => { - app = new App([new HelpController()]); - await app.init(); - }); + let app; + beforeAll(async () => { + app = new App([new HelpController()]); + await app.init(); + }); - describe('[GET] /help', () => { - it('should return all commands', async () => { - (getAppOpenAPI as jest.Mock).mockResolvedValue({ - paths: { - "/validate": {}, - "/parse": {}, - "/generate": {}, - "/convert": {}, - "/bundle": {}, - "/help": {}, - "/diff": {} - } - }); + describe('[GET] /help', () => { + it('should return all commands', async () => { + (getAppOpenAPI as jest.Mock).mockResolvedValue({ + paths: { + '/validate': {}, + '/parse': {}, + '/generate': {}, + '/convert': {}, + '/bundle': {}, + '/help': {}, + '/diff': {} + } + }); - const response = await request(app.getServer()) - .get('/v1/help') - .expect(200); + const response = await request(app.getServer()) + .get('/v1/help') + .expect(200); - expect(response.body).toEqual([ - { - "command": "validate", - "url": "/help/validate" - }, - { - "command": "parse", - "url": "/help/parse" - }, - { - "command": "generate", - "url": "/help/generate" - }, - { - "command": "convert", - "url": "/help/convert" - }, - { - "command": "bundle", - "url": "/help/bundle" - }, - { - "command": "help", - "url": "/help/help" - }, - { - "command": "diff", - "url": "/help/diff" - } - ]); - }); + expect(response.body).toEqual([ + { + command: 'validate', + url: '/help/validate' + }, + { + command: 'parse', + url: '/help/parse' + }, + { + command: 'generate', + url: '/help/generate' + }, + { + command: 'convert', + url: '/help/convert' + }, + { + command: 'bundle', + url: '/help/bundle' + }, + { + command: 'help', + url: '/help/help' + }, + { + command: 'diff', + url: '/help/diff' + } + ]); + }); - it('should return 404 error for an invalid command', async () => { - const response = await request(app.getServer()) - .get('/v1/help/invalidCommand') - .expect(404); + it('should return 404 error for an invalid command', async () => { + const response = await request(app.getServer()) + .get('/v1/help/invalidCommand') + .expect(404); - expect(response.body).toEqual({ - type: 'https://api.asyncapi.com/problem/invalid-asyncapi-command', - title: 'Invalid AsyncAPI Command', - status: 404, - detail: 'The given AsyncAPI command is not valid.' - }); - }); + expect(response.body).toEqual({ + type: 'https://api.asyncapi.com/problem/invalid-asyncapi-command', + title: 'Invalid AsyncAPI Command', + status: 404, + detail: 'The given AsyncAPI command is not valid.' + }); + }); - it('should return 404 error for a command without a method', async () => { - (getAppOpenAPI as jest.Mock).mockResolvedValue({ - paths: { - "/someCommand": {} - } - }); + it('should return 404 error for a command without a method', async () => { + (getAppOpenAPI as jest.Mock).mockResolvedValue({ + paths: { + '/someCommand': {} + } + }); - const response = await request(app.getServer()) - .get('/v1/help/someCommand') - .expect(404); + const response = await request(app.getServer()) + .get('/v1/help/someCommand') + .expect(404); - expect(response.body).toEqual({ - type: 'https://api.asyncapi.com/problem/invalid-asyncapi-command', - title: 'Invalid AsyncAPI Command', - status: 404, - detail: 'The given AsyncAPI command is not valid.' - }); - }); - }); + expect(response.body).toEqual({ + type: 'https://api.asyncapi.com/problem/invalid-asyncapi-command', + title: 'Invalid AsyncAPI Command', + status: 404, + detail: 'The given AsyncAPI command is not valid.' + }); + }); + }); }); \ No newline at end of file