diff --git a/test/GoogleCloudPubSub.test.ts b/test/GoogleCloudPubSub.test.ts index b2d23c9..ccb318e 100644 --- a/test/GoogleCloudPubSub.test.ts +++ b/test/GoogleCloudPubSub.test.ts @@ -111,25 +111,9 @@ test('GPS001d - should properly emit, but not listen to the subscription', async }, }); - await new Promise(async (resolve, reject) => { - await pubSub.listen(topicName, { - options: { - autoAck: true, - }, - onMessage(): void { - reject(`Should not listen to anything, because unsubscribed from subscription ${topicName}`); - }, - onError(error) { - reject(error); - }, - }); - - await pubSub.unsubscribe(topicName); + const testUtils = new TestUtils(pubSub, topicName, t); - setTimeout(resolve, 2000); - - emitAfterDelay(pubSub, topicName); - }); + await testUtils.validateNotListeningAndEmit(topicName); t.pass('Test succeeded, because no message was received'); }); @@ -143,39 +127,12 @@ test('GPS001e - should properly emit and listen because wrong topic name to unsu }, }); - await new Promise(async (resolve, reject) => { - await pubSub.listen(topicName, { - options: { - autoAck: true, - }, - onMessage(message: EmittedMessage): void { - const spy: sinon.SinonSpy = sinon.spy(message.getOriginalMessage(), 'ack'); - if (isPayloadError(message.payload)) { - return reject('Error in payload'); - } - - const payload: OnMessage = message.payload; - t.deepEqual(payload, { - hello: 'world', - }); - t.falsy(spy.called); - t.truthy(message.id); - t.truthy(message.ackId); - t.truthy(message.emittedAt); - t.truthy(message.receivedAt); - t.is(message.count, 0); - t.truthy(message.duration); - t.pass(`Listen successfully to the topic ${topicName}`); - resolve(true); - }, - onError(error) { - reject(error); - }, - }); - - await pubSub.unsubscribe('wrong_subscription_or_topic_name'); + const testUtils = new TestUtils(pubSub, topicName, t); - emitAfterDelay(pubSub, topicName); + await testUtils.validateNotListeningAndEmit('wrong_subscription_or_topic_name', true, (message) => { + t.true(ackSpy.calledOnce); + t.true(ackSpy.called); + t.is(message.count, 0); }); }); @@ -189,25 +146,9 @@ test('GPS001f - should properly emit, but not listen to the subscription with a }, }); - await new Promise(async (resolve, reject) => { - await pubSub.listen(topicName, { - options: { - autoAck: true, - }, - onMessage(): void { - reject(`Should not listen to anything, because unsubscribed from subscription ${topicName}`); - }, - onError(error) { - reject(error); - }, - }); - - await pubSub.unsubscribe(topicName); - - setTimeout(resolve, 2000); + const testUtils = new TestUtils(pubSub, topicName, t); - emitAfterDelay(pubSub, topicName); - }); + await testUtils.validateNotListeningAndEmit(topicName); t.pass('Test succeeded, because no message was received'); }); @@ -223,27 +164,13 @@ test('GPS001g - should properly emit, but not listen to the subscription with a }, }); - await new Promise(async (resolve, reject) => { - await pubSub.listen(topicName, { - options: { - autoAck: true, - subscriptionOptions: { - name: customSubscriptionName, - }, - }, - onMessage(): void { - reject(`Should not listen to anything, because unsubscribed from subscription ${topicName}`); - }, - onError(error) { - reject(error); - }, - }); - - await pubSub.unsubscribe(customSubscriptionName); - - setTimeout(resolve, 2000); + const testUtils = new TestUtils(pubSub, topicName, t); - emitAfterDelay(pubSub, topicName); + await testUtils.validateNotListeningAndEmit(customSubscriptionName, false, undefined, { + autoAck: true, + subscriptionOptions: { + name: customSubscriptionName, + }, }); t.pass('Test succeeded, because no message was received'); diff --git a/test/utils/test-utils.ts b/test/utils/test-utils.ts index 02bed2a..842510f 100644 --- a/test/utils/test-utils.ts +++ b/test/utils/test-utils.ts @@ -33,44 +33,102 @@ export class TestUtils { ) { await new Promise((resolve, reject) => { void this.pubSub.listen(this.topicName, { - onMessage: (message: EmittedMessage): void => { - try { - if (isPayloadError(message.payload)) { - return reject('Error in payload'); - } + onMessage: this.handleMessage.bind(this, validateListenFn, resolve), + onError: this.handleError.bind(this, reject), + options: listenOptions, + }); + + void this.emitAfterDelay(); + }); + } - const payload: OnMessage = message.payload; - this.validateEmittedMessageProperties(message, payload); - validateListenFn(message); - resolve(true); - } catch (err) { - reject(err); - } - }, - onError: (error) => { - reject(error); - }, + /** + * Validate the unsubscription by rejecting the promise if a message is listened + * @param subscriptionName Name of the subscription to unsubscribe to + * @param shouldListen set to true if you do not want to reject the onMessage method + * @param validateListenFn Custom validation function with the emitted message as argument + * @param listenOptions Listen options + */ + public async validateNotListeningAndEmit( + subscriptionName: string, + shouldListen: boolean = false, + validateListenFn?: (msg: EmittedMessage) => void, + listenOptions?: GCListenOptions, + ) { + await new Promise(async (resolve, reject) => { + await this.pubSub.listen(this.topicName, { + onMessage: + shouldListen && validateListenFn + ? this.handleMessage.bind(this, validateListenFn, resolve) + : this.handleUnsubscribeMessage.bind(this, subscriptionName, reject), + onError: this.handleError.bind(this, reject), options: listenOptions, }); + await this.pubSub.unsubscribe(subscriptionName); + void this.emitAfterDelay(); + + await setTimeout(2000); + + resolve(true); }); } + /** + * Handle emitted messages + * @param validateListenFn Custom validation function with the emitted message as argument + * @param resolve Promise resolve function + * @param message Emitted message + */ + private handleMessage( + validateListenFn: (msg: EmittedMessage) => void, + resolve: (val: unknown) => void, + message: EmittedMessage, + ): void { + try { + if (isPayloadError(message.payload)) { + throw new Error('Error in payload'); + } + + const payload: OnMessage = message.payload; + this.validateEmittedMessageProperties(message, payload); + validateListenFn(message); + resolve(true); + } catch (err) { + throw err; + } + } + + /** + * Handle errors + * @param reject Promise reject function + * @param error Error object + */ + private handleError(reject: (reason?: any) => void, error: any): void { + reject(error); + } + + /** + * Handle messages after unsubscribe + * @param subscriptionName Subscription name + * @param reject Promise reject function + */ + private handleUnsubscribeMessage(subscriptionName: string, reject: (reason?: any) => void): void { + reject(`Should not listen to anything, because unsubscribed from subscription ${subscriptionName}`); + } + /** * Validate some properties of the Emitted Message * @param message Emitted message * @param payload Non error payload of the message */ private validateEmittedMessageProperties(message: EmittedMessage, payload: OnMessage) { - this.avaExecCtx.deepEqual(payload, { - hello: 'world', + const { avaExecCtx } = this; + avaExecCtx.deepEqual(payload, { hello: 'world' }); + ['id', 'ackId', 'emittedAt', 'receivedAt', 'duration'].forEach((property) => { + avaExecCtx.truthy(message[property as keyof EmittedMessage]); }); - this.avaExecCtx.truthy(message.id); - this.avaExecCtx.truthy(message.ackId); - this.avaExecCtx.truthy(message.emittedAt); - this.avaExecCtx.truthy(message.receivedAt); - this.avaExecCtx.truthy(message.duration); } /**