From 68546aeaa39cfeadd6ebe3d44263b0a9ce3015cd Mon Sep 17 00:00:00 2001 From: ue85540 Date: Mon, 3 Apr 2023 15:57:55 +0200 Subject: [PATCH 1/3] v3 request reply support --- src/models/operation-reply.ts | 3 +++ src/models/operation.ts | 3 +++ src/models/v3/operation-reply.ts | 10 ++++++++++ src/models/v3/operation.ts | 9 +++++++++ src/spec-types/v3.ts | 1 + test/models/v3/operation-reply.spec.ts | 26 ++++++++++++++++++++++++++ test/models/v3/operation.spec.ts | 14 ++++++++++++++ 7 files changed, 66 insertions(+) diff --git a/src/models/operation-reply.ts b/src/models/operation-reply.ts index ba8b89496..18f0da84d 100644 --- a/src/models/operation-reply.ts +++ b/src/models/operation-reply.ts @@ -1,6 +1,8 @@ import type { BaseModel } from './base'; import type { ExtensionsMixinInterface } from './mixins'; import type { ChannelInterface } from './channel'; +import type { MessagesInterface } from './messages'; + import type { OperationReplyAddressInterface } from './operation-reply-address'; export interface OperationReplyInterface extends BaseModel, ExtensionsMixinInterface { @@ -9,4 +11,5 @@ export interface OperationReplyInterface extends BaseModel, ExtensionsMixinInter address(): OperationReplyAddressInterface | undefined; hasChannel(): boolean; channel(): ChannelInterface | undefined; + messages(): MessagesInterface; } diff --git a/src/models/operation.ts b/src/models/operation.ts index 99d9b20e0..3dfe7b822 100644 --- a/src/models/operation.ts +++ b/src/models/operation.ts @@ -5,6 +5,7 @@ import type { OperationReplyInterface } from './operation-reply'; import type { ChannelsInterface } from './channels'; import type { ServersInterface } from './servers'; import type { MessagesInterface } from './messages'; +import { OperationReplyInterface } from './operation-reply'; export type OperationAction = 'send' | 'receive' | 'publish' | 'subscribe'; @@ -17,4 +18,6 @@ export interface OperationInterface extends BaseModel, OperationTraitInterface { messages(): MessagesInterface; reply(): OperationReplyInterface | undefined; traits(): OperationTraitsInterface; + hasReply(): boolean; + reply(): OperationReplyInterface | undefined; } diff --git a/src/models/v3/operation-reply.ts b/src/models/v3/operation-reply.ts index f26b32ef1..80cebad8b 100644 --- a/src/models/v3/operation-reply.ts +++ b/src/models/v3/operation-reply.ts @@ -1,5 +1,8 @@ import { BaseModel } from '../base'; import { Channel } from './channel'; +import { Message } from './message'; +import { Messages } from '../messages'; +import { MessagesInterface } from 'models/messages'; import { OperationReplyAddress } from './operation-reply-address'; import { extensions } from './mixins'; @@ -36,6 +39,13 @@ export class OperationReply extends BaseModel { + return this.createModel(Message, message, { id: messageName, pointer: this.jsonPath(`messages/${messageName}`) }); + }) + ); + } extensions(): ExtensionsInterface { return extensions(this); diff --git a/src/models/v3/operation.ts b/src/models/v3/operation.ts index 655b1da3d..38e02e7dd 100644 --- a/src/models/v3/operation.ts +++ b/src/models/v3/operation.ts @@ -89,4 +89,13 @@ export class Operation extends OperationTrait implements Ope }) ); } + + hasReply(): boolean { + return !!this._json.reply; + } + + reply(): OperationReplyInterface | undefined { + if (!this._json.reply) return undefined; + return new OperationReply(this._json.reply); + } } diff --git a/src/spec-types/v3.ts b/src/spec-types/v3.ts index b225c821d..45c98339b 100644 --- a/src/spec-types/v3.ts +++ b/src/spec-types/v3.ts @@ -143,6 +143,7 @@ export interface OperationTraitObject extends SpecificationExtensions { export interface OperationReplyObject extends SpecificationExtensions { channel?: ChannelObject | ReferenceObject; + messages?: MessagesObject; address?: OperationReplyAddressObject | ReferenceObject; } diff --git a/test/models/v3/operation-reply.spec.ts b/test/models/v3/operation-reply.spec.ts index 74cfaffe1..6370ca080 100644 --- a/test/models/v3/operation-reply.spec.ts +++ b/test/models/v3/operation-reply.spec.ts @@ -1,6 +1,8 @@ import { Channel } from '../../../src/models/v3/channel'; import { OperationReply } from '../../../src/models/v3/operation-reply'; import { OperationReplyAddress } from '../../../src/models/v3/operation-reply-address'; +import { Messages } from '../../../src/models/messages'; +import { Message } from '../../../src/models/v3/message'; import { assertExtensions } from './utils'; @@ -59,6 +61,30 @@ describe('OperationReply model', function() { expect(d.channel()).toBeUndefined(); }); }); + + describe('.messages()', function() { + it('should return collection of messages - single message', function() { + const d = new OperationReply({ messages: { someMessage: { messageId: 'messageId' } } }); + expect(d.messages()).toBeInstanceOf(Messages); + expect(d.messages().all()).toHaveLength(1); + expect(d.messages().all()[0]).toBeInstanceOf(Message); + }); + + it('should return collection of messages - more than one messages', function() { + const d = new OperationReply({ messages: { someMessage1: { messageId: 'messageId1' }, someMessage2: { messageId: 'messageId2' } } }); + expect(d.messages()).toBeInstanceOf(Messages); + expect(d.messages().all()).toHaveLength(2); + expect(d.messages().all()[0]).toBeInstanceOf(Message); + expect(d.messages().all()[0].messageId()).toEqual('messageId1'); + expect(d.messages().all()[1]).toBeInstanceOf(Message); + expect(d.messages().all()[1].messageId()).toEqual('messageId2'); + }); + + it('should return undefined if address is not present', function() { + const d = new OperationReply({}, { asyncapi: {} as any, pointer: '' }); + expect(d.channel()).toBeUndefined(); + }); + }); describe('mixins', function() { assertExtensions(OperationReply); diff --git a/test/models/v3/operation.spec.ts b/test/models/v3/operation.spec.ts index 1d8004482..41a4f9d87 100644 --- a/test/models/v3/operation.spec.ts +++ b/test/models/v3/operation.spec.ts @@ -150,6 +150,20 @@ describe('Operation model', function() { }); }); + describe('.reply()', function() { + it('should return undefined if reply is not defined', function () { + const d = new Operation({ action: 'send', channel: {}, traits: [] }); + expect(d.hasReply()).toBeFalsy(); + expect(d.reply()).toBeUndefined(); + }); + + it('should return a Reply object ', function () { + const d = new Operation({ action: 'send', channel: {}, reply: { address: { location: '$message.header#/replyTo' }} }); + expect(d.hasReply()).toBeTruthy(); + expect(d.reply()).toBeInstanceOf(OperationReply); + }); + }); + describe('mixins', function() { assertCoreModel(Operation); }); From 01dcd960462728af0da3c014952a3760c7738d36 Mon Sep 17 00:00:00 2001 From: ue85540 Date: Thu, 20 Apr 2023 08:06:26 +0200 Subject: [PATCH 2/3] remove duplicated code --- src/models/operation.ts | 2 -- src/models/v3/operation.ts | 12 ++++-------- test/models/v3/operation.spec.ts | 14 -------------- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/models/operation.ts b/src/models/operation.ts index 3dfe7b822..a4ac844af 100644 --- a/src/models/operation.ts +++ b/src/models/operation.ts @@ -5,7 +5,6 @@ import type { OperationReplyInterface } from './operation-reply'; import type { ChannelsInterface } from './channels'; import type { ServersInterface } from './servers'; import type { MessagesInterface } from './messages'; -import { OperationReplyInterface } from './operation-reply'; export type OperationAction = 'send' | 'receive' | 'publish' | 'subscribe'; @@ -19,5 +18,4 @@ export interface OperationInterface extends BaseModel, OperationTraitInterface { reply(): OperationReplyInterface | undefined; traits(): OperationTraitsInterface; hasReply(): boolean; - reply(): OperationReplyInterface | undefined; } diff --git a/src/models/v3/operation.ts b/src/models/v3/operation.ts index 38e02e7dd..e82997921 100644 --- a/src/models/v3/operation.ts +++ b/src/models/v3/operation.ts @@ -76,6 +76,10 @@ export class Operation extends OperationTrait implements Ope return new Messages(messages); } + hasReply(): boolean { + return !!this._json.reply; + } + reply(): OperationReplyInterface | undefined { if (this._json.reply) { return this.createModel(OperationReply, this._json.reply as v3.OperationReplyObject, { pointer: this.jsonPath('reply') }); @@ -90,12 +94,4 @@ export class Operation extends OperationTrait implements Ope ); } - hasReply(): boolean { - return !!this._json.reply; - } - - reply(): OperationReplyInterface | undefined { - if (!this._json.reply) return undefined; - return new OperationReply(this._json.reply); - } } diff --git a/test/models/v3/operation.spec.ts b/test/models/v3/operation.spec.ts index 41a4f9d87..1d8004482 100644 --- a/test/models/v3/operation.spec.ts +++ b/test/models/v3/operation.spec.ts @@ -150,20 +150,6 @@ describe('Operation model', function() { }); }); - describe('.reply()', function() { - it('should return undefined if reply is not defined', function () { - const d = new Operation({ action: 'send', channel: {}, traits: [] }); - expect(d.hasReply()).toBeFalsy(); - expect(d.reply()).toBeUndefined(); - }); - - it('should return a Reply object ', function () { - const d = new Operation({ action: 'send', channel: {}, reply: { address: { location: '$message.header#/replyTo' }} }); - expect(d.hasReply()).toBeTruthy(); - expect(d.reply()).toBeInstanceOf(OperationReply); - }); - }); - describe('mixins', function() { assertCoreModel(Operation); }); From bda35008638c9ac2b257ffdb4363e6fe573991ef Mon Sep 17 00:00:00 2001 From: ue85540 Date: Thu, 20 Apr 2023 08:07:25 +0200 Subject: [PATCH 3/3] remove unwanted empty line --- src/models/v3/operation.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/models/v3/operation.ts b/src/models/v3/operation.ts index e82997921..bc73fd869 100644 --- a/src/models/v3/operation.ts +++ b/src/models/v3/operation.ts @@ -93,5 +93,4 @@ export class Operation extends OperationTrait implements Ope }) ); } - }