Skip to content

Commit

Permalink
add tests for convert service
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu committed Mar 24, 2022
1 parent 563a547 commit 59a2ace
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 41 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
public
docs
lib
dist
build
2 changes: 1 addition & 1 deletion openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ components:
ConvertResponse:
type: object
properties:
asyncapi:
converted:
$ref: '#/components/schemas/AsyncAPIDocument'
Problem:
type: object
Expand Down
20 changes: 9 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.9",
"@asyncapi/avro-schema-parser": "^1.0.1",
"@asyncapi/converter": "^0.9.0",
"@asyncapi/converter": "^0.10.0",
"@asyncapi/dotnet-nats-template": "^0.4.5",
"@asyncapi/generator": "^1.9.0",
"@asyncapi/go-watermill-template": "^0.1.38",
Expand Down
15 changes: 5 additions & 10 deletions src/controllers/convert.controller.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { NextFunction, Request, Response, Router } from 'express';

import { AsyncAPIDocument } from '@asyncapi/parser';

import { Controller, SpecsEnum } from '../interfaces';
import { Controller, AsyncAPIDocument, SpecsEnum } from '../interfaces';

import { documentValidationMiddleware } from '../middlewares/document-validation.middleware';

import { ConvertService } from '../services/convert.service';

import { ProblemException } from '../exceptions/problem.exception';
import { parse, prepareParserConfig } from '../utils/parser';

type ConvertRequestDto = {
asyncapi: AsyncAPIDocument;
/**
* Spec version to upgrade to.
* Default is 'latest'.
Expand All @@ -21,7 +19,6 @@ type ConvertRequestDto = {
* Language to convert the file to.
*/
language?: 'json' | 'yaml' | 'yml',
asyncapi: AsyncAPIDocument
}

/**
Expand All @@ -35,16 +32,14 @@ export class ConvertController implements Controller {
private async convert(req: Request, res: Response, next: NextFunction) {
try {
const { version, language, asyncapi } = req.body as ConvertRequestDto;

await parse(asyncapi, prepareParserConfig(req));
const convertedSpec = await this.convertService.convertSpec(
const convertedSpec = await this.convertService.convert(
asyncapi,
version,
language,
version.toString(),
);

res.json({
asyncapi: convertedSpec
converted: convertedSpec
});
} catch (err: unknown) {
if (err instanceof ProblemException) {
Expand Down
8 changes: 3 additions & 5 deletions src/controllers/tests/convert.controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ info:
title: Super test
version: 1.0.0
channels: {}
x-parser-spec-parsed: true
`;

describe('ConvertController', () => {
Expand Down Expand Up @@ -52,7 +51,7 @@ describe('ConvertController', () => {
schemaPath: '#/properties/version/enum',
keyword: 'enum',
params: {
allowedValues: ALL_SPECS
allowedValues: [...ALL_SPECS, 'latest'],
},
message: 'must be equal to one of the allowed values'
}
Expand Down Expand Up @@ -87,14 +86,13 @@ describe('ConvertController', () => {
version: '2.3.0'
})
.expect(200, {
asyncapi: {
converted: {
asyncapi: '2.3.0',
info: {
title: 'Super test',
version: '1.0.0'
},
channels: {},
'x-parser-spec-parsed': true,
},
});
});
Expand All @@ -110,7 +108,7 @@ describe('ConvertController', () => {
language: 'yaml'
})
.expect(200, {
asyncapi: validYamlAsyncAPI2_3_0.trimStart(),
converted: validYamlAsyncAPI2_3_0.trimStart(),
});
});
});
Expand Down
7 changes: 5 additions & 2 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import specs from '@asyncapi/specs';
import { Router } from 'express';

export interface Controller {
basepath: string;
boot(): Router;
Expand All @@ -14,7 +15,9 @@ export interface Problem {
[key: string]: any;
}

export const ALL_SPECS = [...Object.keys(specs), 'latest'];
export type AsyncAPIDocument = { asyncapi: string } & Record<string, unknown>;

export const ALL_SPECS = [...Object.keys(specs)];
export const LAST_SPEC_VERSION = ALL_SPECS[ALL_SPECS.length - 1];

export type SpecsEnum = keyof typeof specs;
export type SpecsEnum = keyof typeof specs | 'latest';
6 changes: 4 additions & 2 deletions src/middlewares/document-validation.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { parse, prepareParserConfig, tryConvertToProblemException } from '../uti
*/
export async function documentValidationMiddleware(req: Request, _: Response, next: NextFunction) {
try {
const asyncapi = req.body?.asyncapi;
let asyncapi = req.body?.asyncapi;
if (!asyncapi) {
return next();
}
if (typeof asyncapi === 'object') {
asyncapi = JSON.parse(JSON.stringify(asyncapi));
}

const parsedDocument = await parse(asyncapi, prepareParserConfig(req));

req.parsedDocument = parsedDocument;
next();
} catch (err: any) {
Expand Down
23 changes: 14 additions & 9 deletions src/services/convert.service.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import { convert } from '@asyncapi/converter';
import { AsyncAPIDocument } from '@asyncapi/parser';

import YAML from 'js-yaml';
import { ProblemException } from '../exceptions/problem.exception';
import { LAST_SPEC_VERSION } from '../interfaces';
import { AsyncAPIDocument, LAST_SPEC_VERSION, SpecsEnum } from '../interfaces';

import type { ConvertVersion } from '@asyncapi/converter';

/**
* Service providing `@asyncapi/converter` functionality.
*/
export class ConvertService {
/**
* Convert the given spec to the desired language.
* Convert the given spec to the desired version and format.
* @param spec AsyncAPI spec
* @param language Language to convert to, YAML or JSON
* @param version [version] AsyncAPI spec version
* @param version AsyncAPI spec version
* @returns converted spec
*/
public async convertSpec(
spec: AsyncAPIDocument | string,
language: 'json' | 'yaml' | 'yml',
version: string = LAST_SPEC_VERSION,
public async convert(
spec: string | AsyncAPIDocument,
version: SpecsEnum = LAST_SPEC_VERSION,
language?: 'json' | 'yaml' | 'yml',
): Promise<string> {
if (version === 'latest') {
version = LAST_SPEC_VERSION;
}

try {
const asyncapiSpec = typeof spec === 'object' ? JSON.stringify(spec) : spec;
const convertedSpec = convert(asyncapiSpec, version);
const convertedSpec = convert(asyncapiSpec, version as ConvertVersion);

if (!language) {
return convertedSpec;
Expand Down
60 changes: 60 additions & 0 deletions src/services/tests/convert.service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { ConvertService } from '../convert.service';
import { ProblemException } from '../../exceptions/problem.exception';

const validJsonAsyncAPI2_0_0 = {
asyncapi: '2.0.0',
info: {
title: 'Super test',
version: '1.0.0'
},
channels: {}
};

const validYamlAsyncAPI2_3_0 = `
asyncapi: 2.3.0
info:
title: Super test
version: 1.0.0
channels: {}
`;

describe('ConvertService', () => {
const convertService = new ConvertService();

describe('.convert()', () => {
it('should throw error that the converter cannot convert to a lower version', async () => {
let err: ProblemException;
try {
await convertService.convert(validJsonAsyncAPI2_0_0, '1.2.0');
} catch (e) {
err = e;
}

expect(err).toEqual(new ProblemException({
type: 'internal-converter-error',
title: 'Could not convert document',
status: 422,
detail: 'Cannot downgrade from 2.0.0 to 1.2.0.',
}));
});

it('should pass when converting to 2.3.0 version', async () => {
const converted = await convertService.convert(validJsonAsyncAPI2_0_0, '2.3.0');

expect(converted).toEqual({
asyncapi: '2.3.0',
info: {
title: 'Super test',
version: '1.0.0'
},
channels: {},
});
});

it('should correctly convert JSON to YAML', async () => {
const converted = await convertService.convert(validJsonAsyncAPI2_0_0, '2.3.0', 'yaml');

expect(converted).toEqual(validYamlAsyncAPI2_3_0.trimStart());
});
});
});

0 comments on commit 59a2ace

Please sign in to comment.