From 02e8c8af09048d1f7c13f5d74cbb62c624df20d0 Mon Sep 17 00:00:00 2001 From: Khuda Dad Nomani Date: Sat, 23 Mar 2024 00:45:58 +0000 Subject: [PATCH] feat: add all{components} functions --- src/models/asyncapi.ts | 18 ++++ src/models/v2/asyncapi.ts | 99 ++++++++++++++++++- src/models/v3/asyncapi.ts | 164 +++++++++++++++++++++++++++++++ test/models/v2/asyncapi.spec.ts | 165 ++++++++++++++++++++++++++++++++ test/models/v3/asyncapi.spec.ts | 165 ++++++++++++++++++++++++++++++++ 5 files changed, 610 insertions(+), 1 deletion(-) diff --git a/src/models/asyncapi.ts b/src/models/asyncapi.ts index cd08f7d48..3a2927e7c 100644 --- a/src/models/asyncapi.ts +++ b/src/models/asyncapi.ts @@ -8,6 +8,13 @@ import type { OperationsInterface } from './operations'; import type { SchemasInterface } from './schemas'; import type { SecuritySchemesInterface } from './security-schemes'; import type { ServersInterface } from './servers'; +import type { ServerVariablesInterface } from './server-variables'; +import type { ChannelParametersInterface } from './channel-parameters'; +import type { CorrelationIdsInterface } from './correlation-ids'; +import type { TagsInterface } from './tags'; +import type { OperationTraitsInterface } from './operation-traits'; +import type { MessageTraitsInterface } from './message-traits'; +import type { BindingsInterface } from './bindings'; import type { v2, v3 } from '../spec-types'; @@ -31,4 +38,15 @@ export interface AsyncAPIDocumentInterface extends BaseModel implements AsyncAPIDocumentInterface { + allSecuritySchemes(): SecuritySchemesInterface { + return this.securitySchemes(); + } + allServerVariables(): ServerVariablesInterface { + const serverVariables: ServerVariablesInterface = this.components().serverVariables(); + this.allServers().forEach(server => serverVariables.push(...server.variables())); + return serverVariables; + } + allParameters(): ChannelParametersInterface { + const channelParameters: ChannelParametersInterface = this.components().channelParameters(); + this.allChannels().forEach(channel => channelParameters.push(...channel.parameters())); + return channelParameters; + } + allCorrelationIds(): CorrelationIdsInterface { + const correlationIds: CorrelationIdsInterface = this.components().correlationIds(); + this.allMessages().forEach(message => { + message.traits().forEach(trait => { + const correlationId = trait.correlationId(); + if (!correlationId) { + return; + } + if (!correlationIds.includes(correlationId)) { + correlationIds.push(correlationId); + } + }); + + const correlationId = message.correlationId(); + if (!correlationId) { + return; + } + if (!correlationIds.includes(correlationId)) { + correlationIds.push(correlationId); + } + }); + return correlationIds; + } + allTags(): TagsInterface { + const rootTags: TagsInterface = tags(this); + this.allServers().forEach(server => rootTags.push(...server.tags())); + this.allOperations().forEach(channel => rootTags.push(...channel.tags())); + this.allOperationTraits().forEach(trait => rootTags.push(...trait.tags())); + this.allMessages().forEach(message => rootTags.push(...message.tags())); + this.allMessageTraits().forEach(trait => rootTags.push(...trait.tags())); + return rootTags; + } + allOperationTraits(): OperationTraitsInterface { + const operationTraits: OperationTraitsInterface = this.components().operationTraits(); + this.allOperations().forEach(operation => operation.traits().forEach(trait => ( + !operationTraits.some(t => t.json() === trait.json()) && operationTraits.push(trait) + ))); + + return operationTraits; + } + allMessageTraits(): MessageTraitsInterface { + const messageTraits: MessageTraitsInterface = this.components().messageTraits(); + this.allMessages().forEach(message => message.traits().forEach(trait => ( + !messageTraits.some(t => t.json() === trait.json()) && messageTraits.push(trait) + ))); + + return messageTraits; + } + allServerBindings(): BindingsInterface { + const serverBindings = Object.values(this.components().serverBindings()).flat(); + this.allServers().forEach(server => server.bindings().forEach(binding => ( + !serverBindings.some(b => b.json() === binding.json()) && serverBindings.push(binding) + ))); + return new Bindings(serverBindings); + } + allChannelBindings(): BindingsInterface { + const channelBindings = Object.values(this.components().channelBindings()).flat(); + this.allChannels().forEach(channel => channel.bindings().forEach(binding => ( + !channelBindings.some(b => b.json() === binding.json()) && channelBindings.push(binding) + ))); + return new Bindings(channelBindings); + } + allOperationBindings(): BindingsInterface { + const operationBindings = Object.values(this.components().operationBindings()).flat(); + this.allOperations().forEach(operation => operation.bindings().forEach(binding => ( + !operationBindings.some(b => b.json() === binding.json()) && operationBindings.push(binding) + ))); + return new Bindings(operationBindings); + } + allMessageBindings(): BindingsInterface { + const messageBindings = Object.values(this.components().messageBindings()).flat(); + this.allMessages().forEach(message => message.bindings().forEach(binding => ( + !messageBindings.some(b => b.json() === binding.json()) && messageBindings.push(binding) + ))); + return new Bindings(messageBindings); + } version(): string { return this._json.asyncapi; } diff --git a/src/models/v3/asyncapi.ts b/src/models/v3/asyncapi.ts index 756140b0b..d64658e76 100644 --- a/src/models/v3/asyncapi.ts +++ b/src/models/v3/asyncapi.ts @@ -11,6 +11,8 @@ import { SecuritySchemes } from './security-schemes'; import { SecurityScheme } from './security-scheme'; import { Components } from './components'; import { Schemas } from './schemas'; +import { Bindings } from './bindings'; +import { Tags } from './tags'; import { extensions } from './mixins'; import { tilde } from '../../utils'; @@ -30,10 +32,172 @@ import type { SchemasInterface } from '../schemas'; import type { OperationInterface } from '../operation'; import type { ChannelInterface } from '../channel'; import type { ServerInterface } from '../server'; +import type { BindingsInterface } from 'models/bindings'; +import type { ChannelParametersInterface } from 'models/channel-parameters'; +import type { CorrelationIdsInterface } from 'models/correlation-ids'; +import type { MessageTraitsInterface } from 'models/message-traits'; +import type { OperationTraitsInterface } from 'models/operation-traits'; +import type { ServerVariablesInterface } from 'models/server-variables'; +import type { TagsInterface } from 'models/tags'; +import type { Tag } from './tag'; +import type { TagInterface } from 'models/tag'; import type { v3 } from '../../spec-types'; export class AsyncAPIDocument extends BaseModel implements AsyncAPIDocumentInterface { + allSecuritySchemes(): SecuritySchemesInterface { + return this.securitySchemes(); + } + allServerVariables(): ServerVariablesInterface { + const serverVariables: ServerVariablesInterface = this.components().serverVariables(); + this.servers().forEach(server => { + server.variables().forEach(variable => { + if (!serverVariables.has(variable.id())) { + serverVariables.push(variable); + } + }); + }); + + return serverVariables; + } + allParameters(): ChannelParametersInterface { + const parameters: ChannelParametersInterface = this.components().channelParameters(); + this.channels().forEach(channel => { + channel.parameters().forEach(parameter => { + if (!parameters.includes(parameter)) { + parameters.push(parameter); + } + }); + }); + return parameters; + } + + allCorrelationIds(): CorrelationIdsInterface { + const correlationIds: CorrelationIdsInterface = this.components().correlationIds(); + this.allMessages().forEach(message => { + const correlationId = message.correlationId(); + if (correlationId) { + correlationIds.push(correlationId); + } + }); + + this.allMessageTraits().forEach(trait => { + const correlationId = trait.correlationId(); + if (correlationId) { + correlationIds.push(correlationId); + } + }); + + return correlationIds; + } + allTags(): TagsInterface { + const tags: TagInterface[] = Object.values(this.components().json().tags || {}) || []; + this.info().tags().forEach(tag => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + + this.servers().forEach(server => { + server.tags().forEach(tag => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + }); + + this.channels().forEach(channel => { + (channel.json().tags || []).forEach((tag: Tag) => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + }); + + this.operations().forEach(operation => { + operation.tags().forEach(tag => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + }); + + this.allOperationTraits().forEach(trait => { + trait.tags().forEach(tag => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + }); + + this.allMessages().forEach(message => { + message.tags().forEach(tag => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + }); + + this.allMessageTraits().forEach(trait => { + trait.tags().forEach(tag => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + }); + + return new Tags(tags); + } + allOperationTraits(): OperationTraitsInterface { + const traits: OperationTraitsInterface = this.components().operationTraits(); + this.operations().forEach(operation => { + operation.traits().forEach(trait => { + if (!traits.includes(trait)) { + traits.push(trait); + } + }); + }); + return traits; + } + allMessageTraits(): MessageTraitsInterface { + const messageTraits: MessageTraitsInterface = this.components().messageTraits(); + this.allMessages().forEach(message => { + message.traits().forEach(trait => { + if (!messageTraits.includes(trait)) { + messageTraits.push(trait); + } + }); + }); + return messageTraits; + } + allServerBindings(): BindingsInterface { + const serverBindings = Object.values(this.components().serverBindings()).flat(); + this.allServers().forEach(server => server.bindings().forEach(binding => ( + !serverBindings.some(b => b.json() === binding.json()) && serverBindings.push(binding) + ))); + return new Bindings(serverBindings); + } + allChannelBindings(): BindingsInterface { + const channelBindings = Object.values(this.components().channelBindings()).flat(); + this.allChannels().forEach(channel => channel.bindings().forEach(binding => ( + !channelBindings.some(b => b.json() === binding.json()) && channelBindings.push(binding) + ))); + return new Bindings(channelBindings); + } + allOperationBindings(): BindingsInterface { + const operationBindings = Object.values(this.components().operationBindings()).flat(); + this.allOperations().forEach(operation => operation.bindings().forEach(binding => ( + !operationBindings.some(b => b.json() === binding.json()) && operationBindings.push(binding) + ))); + return new Bindings(operationBindings); + } + allMessageBindings(): BindingsInterface { + const messageBindings = Object.values(this.components().messageBindings()).flat(); + this.allMessages().forEach(message => message.bindings().forEach(binding => ( + !messageBindings.some(b => b.json() === binding.json()) && messageBindings.push(binding) + ))); + return new Bindings(messageBindings); + } version(): string { return this._json.asyncapi; } diff --git a/test/models/v2/asyncapi.spec.ts b/test/models/v2/asyncapi.spec.ts index 3b5146ca9..aa8f64fa4 100644 --- a/test/models/v2/asyncapi.spec.ts +++ b/test/models/v2/asyncapi.spec.ts @@ -270,6 +270,171 @@ describe('AsyncAPIDocument model', function() { expect(d.allMessages()).toHaveLength(4); }); + describe('.allSecuritySchemes()', function() { + it('should return a collection of securitySchemes', function() { + const doc = serializeInput({components: { securitySchemes: { security1: { type: 'X509' }, security2: { type: 'apiKey' } } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allSecuritySchemes()).toBeInstanceOf(SecuritySchemes); + expect(d.allSecuritySchemes()).toHaveLength(2); + }); + + it('should return a collection of securitySchemes even if securitySchemes are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allSecuritySchemes()).toBeInstanceOf(SecuritySchemes); + }); + }); + + describe('.allServerVariables()', function() { + it('should return a collection of serverVariables', function() { + const doc = serializeInput({ servers: {serv1: {variables: {var3: {enum: []}}}},components: { serverVariables: { var1: { enum: [] }, var2: { enum: [] } } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allServerVariables()).toBeInstanceOf(Collection); + expect(d.allServerVariables()).toHaveLength(3); + }); + + it('should return a collection of serverVariables even if serverVariables are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allServerVariables()).toBeInstanceOf(Collection); + }); + }); + + describe('.allParameters()', function() { + it('should return a collection of channelParameters', function() { + const doc = serializeInput({ channels: {chan1: {parameters: {par3: {schema: {}}}},components: { parameters: { par1: { schema: {} }, par2: { schema: {} } } } }}); + const d = new AsyncAPIDocument(doc); + expect(d.allParameters()).toBeInstanceOf(Collection); + expect(d.allParameters()).toHaveLength(3); + }); + + it('should return a collection of channelParameters even if channelParameters are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allParameters()).toBeInstanceOf(Collection); + }); + }); + + describe('.allCorrelationIds()', function() { + it('should return a collection of correlationIds', function() { + const doc = serializeInput({ channels: {chan1: {publish: {message: {traits: [{correlationId: {location: ''}}],correlationId: {location: ''}}}}},components: { correlationIds: { correlationId1: {}, correlationId2: {} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allCorrelationIds()).toBeInstanceOf(Collection); + expect(d.allCorrelationIds()).toHaveLength(4); + }); + + it('should return a collection of correlationIds even if correlationIds are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allCorrelationIds()).toBeInstanceOf(Collection); + }); + }); + + describe('.allTags()', function() { + it('should return a collection of tags', function() { + const doc = serializeInput({tags: [{ name: 'tag1' }, { name: 'tag2' }] }); + const d = new AsyncAPIDocument(doc); + expect(d.allTags()).toBeInstanceOf(Collection); + expect(d.allTags()).toHaveLength(2); + }); + + it('should return a collection of tags even if tags are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allTags()).toBeInstanceOf(Collection); + }); + }); + + describe('.allOperationTraits()', function() { + it('should return a collection of operationTraits', function() { + const doc = serializeInput({ components: { operationTraits: { trait1: {}, trait2: {} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationTraits()).toBeInstanceOf(Collection); + expect(d.allOperationTraits()).toHaveLength(2); + }); + + it('should return a collection of operationTraits even if operationTraits are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationTraits()).toBeInstanceOf(Collection); + }); + }); + + describe('.allMessageTraits()', function() { + it('should return a collection of messageTraits', function() { + const doc = serializeInput({ components: { messageTraits: { trait1: {name: ''}, trait2: {name: ''} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageTraits()).toBeInstanceOf(Collection); + expect(d.allMessageTraits()).toHaveLength(2); + }); + + it('should return a collection of messageTraits even if messageTraits are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageTraits()).toBeInstanceOf(Collection); + }); + }); + + describe('.allServerBindings()', function() { + it('should return a collection of serverBindings', function() { + const doc = serializeInput({ components: { serverBindings: { binding1: {ws: {}}, binding2: {kafka: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allServerBindings()).toBeInstanceOf(Collection); + expect(d.allServerBindings()).toHaveLength(2); + }); + + it('should return a collection of serverBindings even if serverBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allServerBindings()).toBeInstanceOf(Collection); + }); + }); + + describe('.allChannelBindings()', function() { + it('should return a collection of channelBindings', function() { + const doc = serializeInput({ components: { channelBindings: { binding1: {ws: {}}, binding2: {http: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allChannelBindings()).toBeInstanceOf(Collection); + expect(d.allChannelBindings()).toHaveLength(2); + }); + + it('should return a collection of channelBindings even if channelBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allChannelBindings()).toBeInstanceOf(Collection); + }); + }); + + describe('.allOperationBindings()', function() { + it('should return a collection of operationBindings', function() { + const doc = serializeInput({ components: { operationBindings: { binding1: {ws: {}}, binding2: {mqtt: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationBindings()).toBeInstanceOf(Collection); + expect(d.allOperationBindings()).toHaveLength(2); + }); + + it('should return a collection of operationBindings even if operationBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationBindings()).toBeInstanceOf(Collection); + }); + }); + + describe('.allMessageBindings()', function() { + it('should return a collection of messageBindings', function() { + const doc = serializeInput({ components: { messageBindings: { websocket: { ws: {} }, http: {http: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageBindings()).toBeInstanceOf(Collection); + expect(d.allMessageBindings()).toHaveLength(2); + }); + + it('should return a collection of messageBindings even if messageBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageBindings()).toBeInstanceOf(Collection); + }); + }); + it('should return all messages (with messages from components)', function() { const message = {}; const channel = { publish: { message }, subscribe: { message: { oneOf: [{ payload: {} }, message] } } }; diff --git a/test/models/v3/asyncapi.spec.ts b/test/models/v3/asyncapi.spec.ts index 85e28e371..fad3fe6cb 100644 --- a/test/models/v3/asyncapi.spec.ts +++ b/test/models/v3/asyncapi.spec.ts @@ -165,6 +165,171 @@ describe('AsyncAPIDocument model', function() { }); }); + describe('.allSecuritySchemes()', function() { + it('should return a collection of securitySchemes', function() { + const doc = serializeInput({components: { securitySchemes: { security1: { type: 'X509' }, security2: { type: 'apiKey' } } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allSecuritySchemes()).toBeInstanceOf(SecuritySchemes); + expect(d.allSecuritySchemes()).toHaveLength(2); + }); + + it('should return a collection of securitySchemes even if securitySchemes are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allSecuritySchemes()).toBeInstanceOf(SecuritySchemes); + }); + }); + + describe('.allServerVariables()', function() { + it('should return a collection of serverVariables', function() { + const doc = serializeInput({ servers: {serv1: {variables: {var3: {enum: []}}}},components: { serverVariables: { var1: { enum: [] }, var2: { enum: [] } } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allServerVariables()).toBeInstanceOf(Collection); + expect(d.allServerVariables()).toHaveLength(3); + }); + + it('should return a collection of serverVariables even if serverVariables are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allServerVariables()).toBeInstanceOf(Collection); + }); + }); + + describe('.allParameters()', function() { + it('should return a collection of channelParameters', function() { + const doc = serializeInput({ channels: {chan1: {parameters: {par3: {enum: []}}},components: { parameters: { par1: { enum: [] }, par2: { enum: [] } } } }}); + const d = new AsyncAPIDocument(doc); + expect(d.allParameters()).toBeInstanceOf(Collection); + expect(d.allParameters()).toHaveLength(3); + }); + + it('should return a collection of channelParameters even if channelParameters are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allParameters()).toBeInstanceOf(Collection); + }); + }); + + describe('.allCorrelationIds()', function() { + it('should return a collection of correlationIds', function() { + const doc = serializeInput({ channels: {chan1: {messages: {mess1: {traits: [{correlationId: {location: ''}}],correlationId: {location: ''}}}}},components: { correlationIds: { correlationId1: {}, correlationId2: {} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allCorrelationIds()).toBeInstanceOf(Collection); + expect(d.allCorrelationIds()).toHaveLength(4); + }); + + it('should return a collection of correlationIds even if correlationIds are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allCorrelationIds()).toBeInstanceOf(Collection); + }); + }); + + describe('.allTags()', function() { + it('should return a collection of tags', function() { + const doc = serializeInput({info: { tags: [{ name: 'tag1' }, { name: 'tag2' }] }}); + const d = new AsyncAPIDocument(doc); + expect(d.allTags()).toBeInstanceOf(Collection); + expect(d.allTags()).toHaveLength(2); + }); + + it('should return a collection of tags even if tags are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allTags()).toBeInstanceOf(Collection); + }); + }); + + describe('.allOperationTraits()', function() { + it('should return a collection of operationTraits', function() { + const doc = serializeInput({ components: { operationTraits: { trait1: {}, trait2: {} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationTraits()).toBeInstanceOf(Collection); + expect(d.allOperationTraits()).toHaveLength(2); + }); + + it('should return a collection of operationTraits even if operationTraits are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationTraits()).toBeInstanceOf(Collection); + }); + }); + + describe('.allMessageTraits()', function() { + it('should return a collection of messageTraits', function() { + const doc = serializeInput({ components: { messageTraits: { trait1: {name: ''}, trait2: {name: ''} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageTraits()).toBeInstanceOf(Collection); + expect(d.allMessageTraits()).toHaveLength(2); + }); + + it('should return a collection of messageTraits even if messageTraits are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageTraits()).toBeInstanceOf(Collection); + }); + }); + + describe('.allServerBindings()', function() { + it('should return a collection of serverBindings', function() { + const doc = serializeInput({ components: { serverBindings: { binding1: {ws: {}}, binding2: {kafka: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allServerBindings()).toBeInstanceOf(Collection); + expect(d.allServerBindings()).toHaveLength(2); + }); + + it('should return a collection of serverBindings even if serverBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allServerBindings()).toBeInstanceOf(Collection); + }); + }); + + describe('.allChannelBindings()', function() { + it('should return a collection of channelBindings', function() { + const doc = serializeInput({ components: { channelBindings: { binding1: {ws: {}}, binding2: {http: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allChannelBindings()).toBeInstanceOf(Collection); + expect(d.allChannelBindings()).toHaveLength(2); + }); + + it('should return a collection of channelBindings even if channelBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allChannelBindings()).toBeInstanceOf(Collection); + }); + }); + + describe('.allOperationBindings()', function() { + it('should return a collection of operationBindings', function() { + const doc = serializeInput({ components: { operationBindings: { binding1: {ws: {}}, binding2: {mqtt: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationBindings()).toBeInstanceOf(Collection); + expect(d.allOperationBindings()).toHaveLength(2); + }); + + it('should return a collection of operationBindings even if operationBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allOperationBindings()).toBeInstanceOf(Collection); + }); + }); + + describe('.allMessageBindings()', function() { + it('should return a collection of messageBindings', function() { + const doc = serializeInput({ components: { messageBindings: { websocket: { ws: {} }, http: {http: {}} } } }); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageBindings()).toBeInstanceOf(Collection); + expect(d.allMessageBindings()).toHaveLength(2); + }); + + it('should return a collection of messageBindings even if messageBindings are not defined', function() { + const doc = serializeInput({}); + const d = new AsyncAPIDocument(doc); + expect(d.allMessageBindings()).toBeInstanceOf(Collection); + }); + }); + describe('.allMessages()', function() { it('should return a collection of messages', function() { const duplicatedMessage = {};