Skip to content

Commit

Permalink
add tests for schema parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu committed Aug 26, 2022
1 parent 7924134 commit 833dbce
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 20 deletions.
5 changes: 2 additions & 3 deletions src/custom-operations/parse-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { JSONPath } from 'jsonpath-plus';
import { toPath } from 'lodash';

import { parseSchema, getSchemaFormat, getDefaultSchemaFormat } from '../schema-parser';
import { xParserOriginalSchemaFormat, xParserOriginalPayload } from '../constants';
import { xParserOriginalPayload } from '../constants';

import type { Parser } from '../parser';
import type { ParseSchemaInput } from "../schema-parser";
Expand Down Expand Up @@ -67,7 +67,6 @@ export async function parseSchemasV2(parser: Parser, detailed: DetailedAsyncAPI)
}

async function parseSchemaV2(parser: Parser, item: ToParseItem) {
item.value[xParserOriginalSchemaFormat] = item.input.schemaFormat;
item.value[xParserOriginalPayload] = item.input;
item.value[xParserOriginalPayload] = item.input.data;
item.value.payload = await parseSchema(parser, item.input);
}
5 changes: 3 additions & 2 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AsyncAPIDocumentInterface, newAsyncAPIDocument } from "./models";

import { customOperations } from './custom-operations';
import { validate } from "./lint";
import { createDetailedAsyncAPI, normalizeInput, toAsyncAPIDocument } from "./utils";
import { createDetailedAsyncAPI, normalizeInput, toAsyncAPIDocument, unfreezeObject } from "./utils";

import { xParserSpecParsed } from './constants';

Expand Down Expand Up @@ -47,7 +47,7 @@ export async function parse(parser: Parser, asyncapi: ParseInput, options?: Pars
}

// unfreeze the object - Spectral makes resolved document "freezed"
const validatedDoc = JSON.parse(JSON.stringify(validated));
const validatedDoc = unfreezeObject(validated);
validatedDoc[String(xParserSpecParsed)] = true;

const detailed = createDetailedAsyncAPI(asyncapi as string | Record<string, unknown>, validatedDoc);
Expand All @@ -67,6 +67,7 @@ export async function parse(parser: Parser, asyncapi: ParseInput, options?: Pars

const defaultOptions: ParseOptions = {
applyTraits: true,
parseSchemas: true,
};
function normalizeOptions(options?: ParseOptions): ParseOptions {
if (!options || typeof options !== 'object') {
Expand Down
2 changes: 2 additions & 0 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Spectral } from "@stoplight/spectral-core";
import { parse } from "./parse";
import { lint, validate } from "./lint";
import { registerSchemaParser } from './schema-parser';
import { AsyncAPISchemaParser } from "./schema-parser/asyncapi-schema-parser";
import { configureSpectral } from "./spectral";

import type { IConstructorOpts } from "@stoplight/spectral-core";
Expand All @@ -28,6 +29,7 @@ export class Parser {
this.spectral = new Spectral(spectral);
}

this.registerSchemaParser(AsyncAPISchemaParser());
configureSpectral(this);
}

Expand Down
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ export function normalizeInput(asyncapi: string | MaybeAsyncAPI): string {
return JSON.stringify(asyncapi, undefined, 2);
};

export function unfreezeObject(data: unknown) {
return JSON.parse(JSON.stringify(data))
}

export function hasErrorDiagnostic(diagnostics: ISpectralDiagnostic[]): boolean {
return diagnostics.some(diagnostic => diagnostic.severity === DiagnosticSeverity.Error);
}
Expand Down
96 changes: 96 additions & 0 deletions test/custom-operations/parse-schema.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { AsyncAPIDocumentV2 } from '../../src/models';
import { Parser } from '../../src/parser';
import { parse } from '../../src/parse';
import { xParserOriginalPayload } from '../../src/constants';

describe('custom operations - parse schemas', function() {
const parser = new Parser();

it('should parse valid schema format', async function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
channel: {
publish: {
operationId: 'operationId',
message: {
schemaFormat: 'application/vnd.aai.asyncapi;version=2.0.0',
payload: {
type: 'object',
}
}
}
}
}
}
const { parsed, diagnostics } = await parse(parser, document);

expect(parsed).toBeInstanceOf(AsyncAPIDocumentV2);
expect(diagnostics.length > 0).toEqual(true);

expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual({ type: 'object' });
expect(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]).toEqual({ type: 'object' });
expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]);
});

it('should parse valid default schema format', async function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
channel: {
publish: {
operationId: 'operationId',
message: {
payload: {
type: 'object',
}
}
}
}
}
}
const { parsed, diagnostics } = await parse(parser, document);

expect(parsed).toBeInstanceOf(AsyncAPIDocumentV2);
expect(diagnostics.length > 0).toEqual(true);

expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual({ type: 'object' });
expect(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]).toEqual({ type: 'object' });
expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]);
});

it('should parse invalid schema format', async function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
channel: {
publish: {
operationId: 'operationId',
message: {
schemaFormat: 'not existing',
payload: {
type: 'object',
}
}
}
}
}
}
const { parsed, diagnostics } = await parse(parser, document);

expect(parsed).toBeUndefined();
expect(diagnostics.length > 0).toEqual(true);
});
});
1 change: 0 additions & 1 deletion test/schema-parser/asyncapi-schema-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { AsyncAPISchemaParser } from '../../src/schema-parser/asyncapi-schema-pa
import type { SchemaValidateResult } from '../../src/types';

describe('AsyncAPISchemaParser', function () {

const validSchema = {
asyncapi: {
semver: {
Expand Down
46 changes: 32 additions & 14 deletions test/schema-parser/spectral-rule-v2.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Parser } from '../../src/parser';
import { validate } from '../../src/lint';
import { AsyncAPISchemaParser } from '../../src/schema-parser/asyncapi-schema-parser';

import type { ISpectralDiagnostic } from '@stoplight/spectral-core';
import type { SchemaValidateResult } from '../../src/types';

describe('aas2schemaParserRule', function() {
const parser = new Parser();
parser.registerSchemaParser(AsyncAPISchemaParser()); // use that parser for testing

it('should validate AsyncAPI Schema with valid schema', async function() {
const document = {
Expand Down Expand Up @@ -37,7 +35,7 @@ describe('aas2schemaParserRule', function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
title: 'Invalid AsyncApi document',
version: '1.0',
},
channels: {
Expand Down Expand Up @@ -78,7 +76,7 @@ describe('aas2schemaParserRule', function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
title: 'Invalid AsyncApi document',
version: '1.0',
},
channels: {},
Expand Down Expand Up @@ -118,7 +116,7 @@ describe('aas2schemaParserRule', function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
title: 'Invalid AsyncApi document',
version: '1.0',
},
channels: {},
Expand Down Expand Up @@ -162,7 +160,7 @@ describe('aas2schemaParserRule', function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
title: 'Invalid AsyncApi document',
version: '1.0',
},
channels: {
Expand Down Expand Up @@ -212,25 +210,45 @@ describe('aas2schemaParserRule', function() {
expect(filteredDiagnostics).toEqual(expectedResult.map(e => expect.objectContaining(e)));
});

it('should validate AsyncAPI Schema with non supported schema format', async function() {
it('should validate AsyncAPI Schema with supported schema format', async function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
channel: {
publish: {
message: {
schemaFormat: 'application/vnd.aai.asyncapi;version=2.0.0',
payload: {
type: 'object',
}
}
}
}
}
}
const { diagnostics } = await validate(parser, document);
const filteredDiagnostics = filterDiagnostics(diagnostics, 'asyncapi-schemas-v2');
expect(filteredDiagnostics).toHaveLength(0);
});

it('should validate AsyncAPI Schema with non supported schema format', async function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Invalid AsyncApi document',
version: '1.0',
},
channels: {
channel: {
publish: {
message: {
schemaFormat: 'not existing',
payload: {
oneOf: "this should be an array",
properties: {
name: {
if: "this should be an if"
}
}
type: 'object',
}
}
}
Expand All @@ -254,7 +272,7 @@ describe('aas2schemaParserRule', function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
title: 'Invalid AsyncApi document',
version: '1.0',
},
channels: {
Expand Down

0 comments on commit 833dbce

Please sign in to comment.