Skip to content

Commit

Permalink
fix(rulesets): add validation ruleset for v3
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni committed Sep 24, 2024
1 parent ecaffde commit 6f55c0b
Show file tree
Hide file tree
Showing 6 changed files with 388 additions and 83 deletions.
24 changes: 18 additions & 6 deletions docs/reference/asyncapi-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,6 @@ Parameter objects should have a `description`.

**Recommended:** No

### asyncapi-schema

Validate structure of AsyncAPI specification.

**Recommended:** Yes

### asyncapi-servers

A non-empty `servers` object is expected to be located at the root of the document.
Expand Down Expand Up @@ -164,6 +158,12 @@ specifications that reference those objects).

The following rules ONLY apply to AsyncAPI v2 documents.

### asyncapi-schema

Validate structure of AsyncAPI specification.

**Recommended:** Yes

### asyncapi-server-security

Server `security` values must match a scheme defined in the `components.securitySchemes` object. It also checks if there are `oauth2` scopes that have been defined for the given security.
Expand Down Expand Up @@ -862,3 +862,15 @@ invoicedItems:
Defining tags allows you to add more information like a `description`. For more information see [asyncapi-3-tag-description](#asyncapi-3-tag-description).

**Recommended:** Yes

### asyncapi-3-document-resolved

Validate structure of AsyncAPI specification when references have been resolved.

**Recommended:** Yes

### asyncapi-3-document-unresolved

Validate structure of AsyncAPI specification before references have been resolved.

**Recommended:** Yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/tester';

testRule('asyncapi-3-document-resolved', [
{
name: 'valid case AsyncAPI 3',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
},
errors: [],
},
{
name: 'valid case resolved case message',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
SomeChannel: {
address: 'users/{userId}/signedUp',
messages: {
SomeMessage: { $ref: '#/components/messages/SomeMessage' },
},
},
},
components: {
messages: {
SomeMessage: { payload: { type: 'string' } },
},
},
},
errors: [],
},
{
name: 'invalid AsyncAPI 3 info property is missing',
document: {
asyncapi: '3.0.0',
},
errors: [{ message: 'Object must have required property "info"', severity: DiagnosticSeverity.Error }],
},
{
name: 'invalid AsyncAPI 3 resolved case message',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
SomeChannel: {
address: 'users/{userId}/signedUp',
messages: {
SomeMessage: { $ref: '#/x-SomeMessage' },
},
},
},
'x-SomeMessage': { test: 'test' },
},
errors: [
{
message: 'Property "test" is not expected to be here',
severity: DiagnosticSeverity.Error,
path: ['channels', 'SomeChannel', 'messages', 'SomeMessage', 'test'],
},
],
},
{
name: 'valid case (3.0.0 version)',
document: {
asyncapi: '3.0.0',
info: {
title: 'Signup service example (internal)',
version: '0.1.0',
},
channels: {
'user/signedup': {
address: 'user/signedup',
messages: {
'subscribe.message': {
payload: {},
},
},
},
},
operations: {
'user/signedup.subscribe': {
action: 'send',
channel: {
address: 'user/signedup',
messages: {
'subscribe.message': {
payload: {},
},
},
},
messages: [
{
payload: {},
},
],
},
},
},
errors: [],
},

{
name: 'invalid case for 3.0.0 (info.version property is missing)',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
},
},
errors: [
{
message: '"info" property must have required property "version"',
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'valid case for 3.X.X (case validating $ref resolution works as expected)',
document: {
asyncapi: '3.0.0',
info: {
title: 'Signup service example (internal)',
version: '0.1.0',
},
channels: {
userSignedup: {
address: 'user/signedup',
messages: {
'subscribe.message': {
$ref: '#/components/messages/testMessage',
},
},
},
},
components: {
messages: {
testMessage: {
payload: {},
},
},
},
},
errors: [],
},
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/tester';

testRule('asyncapi-3-document-unresolved', [
{
name: 'valid case AsyncAPI 3',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
},
errors: [],
},
{
name: 'valid case unresolved case message',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
SomeChannel: {
address: 'users/{userId}/signedUp',
messages: {
SomeMessage: { $ref: '#/components/messages/SomeMessage' },
},
},
},
components: {
messages: {
SomeMessage: { payload: { type: 'string' } },
},
},
},
errors: [],
},
{
name: 'valid AsyncAPI 3 unresolved case operations',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
SomeChannel: {
address: 'users/{userId}/signedUp',
messages: {
SomeMessage: { $ref: '#/x-SomeMessage' },
},
},
},
operations: {
SomeOperation: {
action: 'send',
channel: {
$ref: '#/channels/SomeChannel',
},
messages: [{ $ref: '#/channels/SomeChannel' }],
},
},
},
errors: [],
},
{
name: 'invalid case for 3.0.0 (reference for info object is not allowed)',
document: {
asyncapi: '3.0.0',
info: {
$ref: '#/components/x-titles/someTitle',
},
components: {
'x-titles': {
someTitle: 'some-title',
},
},
},
errors: [
{
message: 'Referencing in this place is not allowed',
path: ['info'],
severity: DiagnosticSeverity.Error,
},
],
},
]);
18 changes: 0 additions & 18 deletions packages/rulesets/src/asyncapi/__tests__/asyncapi-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,6 @@ testRule('asyncapi-schema', [
},
errors: [],
},
{
name: 'valid case AsyncAPI 3',
document: {
asyncapi: '3.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
},
errors: [],
},
{
name: 'invalid AsyncAPI 2 channels property is missing',
document: {
Expand All @@ -36,11 +25,4 @@ testRule('asyncapi-schema', [
},
errors: [{ message: 'Object must have required property "channels"', severity: DiagnosticSeverity.Error }],
},
{
name: 'invalid AsyncAPI 3 info property is missing',
document: {
asyncapi: '3.0.0',
},
errors: [{ message: 'Object must have required property "info"', severity: DiagnosticSeverity.Error }],
},
]);
Loading

0 comments on commit 6f55c0b

Please sign in to comment.