From a0ca2cb9cabc5e85666f67895aa952f1eda6ca71 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Tue, 1 Oct 2019 15:17:21 +0900 Subject: [PATCH 1/3] Add a test to verify handling incoming event types work --- src/App.spec.ts | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/App.spec.ts b/src/App.spec.ts index 8c60c9085..34374ce55 100644 --- a/src/App.spec.ts +++ b/src/App.spec.ts @@ -308,6 +308,88 @@ describe('App', () => { return overrides; } + describe('ack()', () => { + + function createReceiverEvents(): ReceiverEvent[] { + return [ + { // IncomingEventType.Event (app.event) + body: { + event: {}, + }, + respond: noop, + ack: noop, + }, + { // IncomingEventType.Command (app.command) + body: { + command: '/COMMAND_NAME', + }, + respond: noop, + ack: noop, + }, + { // IncomingEventType.Action (app.action) + body: { + actions: [{}], + channel: {}, + user: {}, + team: {}, + }, + respond: noop, + ack: noop, + }, + { // IncomingEventType.Action with dialog submission (app.action) + body: { + type: 'dialog_submission', + channel: {}, + user: {}, + team: {}, + }, + respond: noop, + ack: noop, + }, + { // IncomingEventType.ViewSubmitAction (app.view) + body: { + type: 'view_submission', + channel: {}, + user: {}, + team: {}, + }, + respond: noop, + ack: noop, + }, + // TODO: https://github.com/slackapi/bolt/issues/263 + // { + // body: { + // type: 'view_closed', + // channel: {}, + // user: {}, + // team: {}, + // }, + // respond: noop, + // ack: noop, + // }, + ]; + } + + it('should acknowledge any of possible events', async () => { + // Arrange + const fakeAckFn = sinon.fake.resolves({}); + const overrides = buildOverrides(withNoopWebClient()); + const App = await importApp(overrides); // tslint:disable-line:variable-name + const dummyReceiverEvents = createReceiverEvents(); + + // Act + const app = new App({ receiver: fakeReceiver, authorize: sinon.fake.resolves(dummyAuthorizationResult) }); + app.use((_args) => { fakeAckFn(); }); + app.error(fakeErrorHandler); + dummyReceiverEvents.forEach(dummyEvent => fakeReceiver.emit('message', dummyEvent)); + await delay(); + + // Assert + assert.equal(fakeAckFn.callCount, dummyReceiverEvents.length); + assert(fakeErrorHandler.notCalled); + }); + }); + describe('say()', () => { function createChannelContextualReceiverEvents(channelId: string): ReceiverEvent[] { From 03bd38d507ac768e47f64b6772104adc5b4198f5 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Wed, 2 Oct 2019 19:55:55 +0900 Subject: [PATCH 2/3] Add more tests --- src/App.spec.ts | 67 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/src/App.spec.ts b/src/App.spec.ts index 34374ce55..e43ba61c5 100644 --- a/src/App.spec.ts +++ b/src/App.spec.ts @@ -308,7 +308,7 @@ describe('App', () => { return overrides; } - describe('ack()', () => { + describe('routing', () => { function createReceiverEvents(): ReceiverEvent[] { return [ @@ -328,6 +328,21 @@ describe('App', () => { }, { // IncomingEventType.Action (app.action) body: { + type: 'block_actions', + actions: [{ + action_id: 'block_action_id' + }], + channel: {}, + user: {}, + team: {}, + }, + respond: noop, + ack: noop, + }, + { // IncomingEventType.Action (app.action) + body: { + type: 'interactive_message', + callback_id: 'interactive_message_callback_id', actions: [{}], channel: {}, user: {}, @@ -339,6 +354,31 @@ describe('App', () => { { // IncomingEventType.Action with dialog submission (app.action) body: { type: 'dialog_submission', + callback_id: 'dialog_submission_callback_id', + channel: {}, + user: {}, + team: {}, + }, + respond: noop, + ack: noop, + }, + { // IncomingEventType.Action for an external_select block (app.options) + body: { + type: 'block_suggestion', + action_id: 'external_select_action_id', + channel: {}, + user: {}, + team: {}, + actions: [], + }, + respond: noop, + ack: noop, + }, + { // IncomingEventType.Action for "data_source": "external" in dialogs (app.options) + body: { + type: 'dialog_suggestion', + callback_id: 'dialog_suggestion_callback_id', + name: 'the name', channel: {}, user: {}, team: {}, @@ -352,6 +392,9 @@ describe('App', () => { channel: {}, user: {}, team: {}, + view: { + callback_id: 'view_callback_id', + } }, respond: noop, ack: noop, @@ -363,6 +406,9 @@ describe('App', () => { // channel: {}, // user: {}, // team: {}, + // view: { + // callback_id: 'view_callback_id', + // } // }, // respond: noop, // ack: noop, @@ -372,20 +418,33 @@ describe('App', () => { it('should acknowledge any of possible events', async () => { // Arrange - const fakeAckFn = sinon.fake.resolves({}); + const ackFn = sinon.fake.resolves({}); + const actionFn = sinon.fake.resolves({}); + const viewFn = sinon.fake.resolves({}); + const optionsFn = sinon.fake.resolves({}); const overrides = buildOverrides(withNoopWebClient()); const App = await importApp(overrides); // tslint:disable-line:variable-name const dummyReceiverEvents = createReceiverEvents(); // Act const app = new App({ receiver: fakeReceiver, authorize: sinon.fake.resolves(dummyAuthorizationResult) }); - app.use((_args) => { fakeAckFn(); }); + app.use((_args) => { ackFn(); }); + app.action('block_action_id', ({ }) => { actionFn(); }) + app.action({ callback_id: 'interactive_message_callback_id' }, ({ }) => { actionFn(); }) + app.action({ callback_id: 'dialog_submission_callback_id' }, ({ }) => { actionFn(); }) + app.view('view_callback_id', ({ }) => { viewFn(); }) + app.options('external_select_action_id', ({ }) => { optionsFn(); }); + app.options({ callback_id: 'dialog_suggestion_callback_id' }, ({ }) => { optionsFn(); }); + app.error(fakeErrorHandler); dummyReceiverEvents.forEach(dummyEvent => fakeReceiver.emit('message', dummyEvent)); await delay(); // Assert - assert.equal(fakeAckFn.callCount, dummyReceiverEvents.length); + assert.equal(actionFn.callCount, 3); + assert.equal(viewFn.callCount, 1); + assert.equal(optionsFn.callCount, 2); + assert.equal(ackFn.callCount, dummyReceiverEvents.length); assert(fakeErrorHandler.notCalled); }); }); From de43612deb8b4a099086a35c9fb76ec4a8de8ab1 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Wed, 2 Oct 2019 20:08:56 +0900 Subject: [PATCH 3/3] Add message_action pattern to the tests --- src/App.spec.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/App.spec.ts b/src/App.spec.ts index e43ba61c5..ae38f5eb4 100644 --- a/src/App.spec.ts +++ b/src/App.spec.ts @@ -339,6 +339,17 @@ describe('App', () => { respond: noop, ack: noop, }, + { // IncomingEventType.Action (app.action) + body: { + type: 'message_action', + callback_id: 'message_action_callback_id', + channel: {}, + user: {}, + team: {}, + }, + respond: noop, + ack: noop, + }, { // IncomingEventType.Action (app.action) body: { type: 'interactive_message', @@ -430,6 +441,7 @@ describe('App', () => { const app = new App({ receiver: fakeReceiver, authorize: sinon.fake.resolves(dummyAuthorizationResult) }); app.use((_args) => { ackFn(); }); app.action('block_action_id', ({ }) => { actionFn(); }) + app.action({ callback_id: 'message_action_callback_id' }, ({ }) => { actionFn(); }) app.action({ callback_id: 'interactive_message_callback_id' }, ({ }) => { actionFn(); }) app.action({ callback_id: 'dialog_submission_callback_id' }, ({ }) => { actionFn(); }) app.view('view_callback_id', ({ }) => { viewFn(); }) @@ -441,7 +453,7 @@ describe('App', () => { await delay(); // Assert - assert.equal(actionFn.callCount, 3); + assert.equal(actionFn.callCount, 4); assert.equal(viewFn.callCount, 1); assert.equal(optionsFn.callCount, 2); assert.equal(ackFn.callCount, dummyReceiverEvents.length);