From aee3364677630a7267bedddd0db0f388368243c3 Mon Sep 17 00:00:00 2001 From: Shane DeWael Date: Wed, 22 May 2019 11:03:25 -0700 Subject: [PATCH 1/3] fix message actions and start helpers.ts tests --- src/helpers.spec.ts | 62 +++++++++++++++++++++++++++++++++++++++++++++ src/helpers.ts | 2 +- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/helpers.spec.ts diff --git a/src/helpers.spec.ts b/src/helpers.spec.ts new file mode 100644 index 000000000..e8bc29168 --- /dev/null +++ b/src/helpers.spec.ts @@ -0,0 +1,62 @@ +// tslint:disable:no-implicit-dependencies +import { assert } from 'chai'; +import { getTypeAndConversation, IncomingEventType } from './helpers'; +import { SlackAction } from './types'; +import { Func } from 'mocha'; + +describe('getTypeAndConversation()', () => { + function matchesActionType(actionType: string): Func { + return () => { + // Arrange + const messageActionBody: SlackAction = createFakeMessageAction(actionType); + + // Act + const typeAndConversation = getTypeAndConversation(messageActionBody); + + // Assert + assert(typeAndConversation.type === IncomingEventType.Action); + }; + } + + describe('action types', () => { + it('should find Action type for message actions', matchesActionType('message_action')); + it('should find Action type for dialog submissions', matchesActionType('dialog_submission')); + it('should find Action type for block actions', matchesActionType('block_actions')); + it('should find Action type for interactive actions', matchesActionType('interactive_message')); + }); +}); + +function createFakeMessageAction(actionType: string): SlackAction { + const action: Partial = { + type: actionType, + channel: { id: 'CHANNEL_ID', name: 'CHANNEL_NAME' }, + user: { id: 'USER_ID', name: 'USER_NAME' }, + team: { id: 'TEAM_ID', domain: 'TEAM_DOMAIN' }, + response_url: 'https://hooks.slack.com/actions/RESPONSE_URL', + token: 'TOKEN', + }; + + if (actionType === 'interactive_message') { + action.actions = [{ + type: 'button', + name: 'NAME', + value: 'VALUE', + }]; + } + + if (actionType === 'block_actions') { + action.actions = [{ + type: 'button', + value: 'VALUE', + text: { + type: 'plain_text', + text: 'TEXT', + }, + block_id: 'BLOCK_ID', + action_id: 'ACTION_ID', + action_ts: 'ACTION_TS', + }]; + } + + return action as SlackAction; +} diff --git a/src/helpers.ts b/src/helpers.ts index e1515b565..cf25a3386 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -46,7 +46,7 @@ export function getTypeAndConversation(body: any): { type?: IncomingEventType, c (body as SlackOptionsMiddlewareArgs['body']).channel.id, }; } - if (body.actions !== undefined || body.type === 'dialog_submission') { + if (body.actions !== undefined || body.type === 'dialog_submission' || body.type === 'message_action') { return { type: IncomingEventType.Action, conversationId: (body as SlackActionMiddlewareArgs['body']).channel.id, From fa1ab33e18e3cb6965f0e52478aeda0fa95683e9 Mon Sep 17 00:00:00 2001 From: Shane DeWael Date: Wed, 22 May 2019 18:04:34 -0700 Subject: [PATCH 2/3] Add helpers tests --- src/helpers.spec.ts | 195 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 150 insertions(+), 45 deletions(-) diff --git a/src/helpers.spec.ts b/src/helpers.spec.ts index e8bc29168..6ec738a41 100644 --- a/src/helpers.spec.ts +++ b/src/helpers.spec.ts @@ -1,62 +1,167 @@ // tslint:disable:no-implicit-dependencies +import 'mocha'; import { assert } from 'chai'; import { getTypeAndConversation, IncomingEventType } from './helpers'; -import { SlackAction } from './types'; -import { Func } from 'mocha'; describe('getTypeAndConversation()', () => { - function matchesActionType(actionType: string): Func { - return () => { - // Arrange - const messageActionBody: SlackAction = createFakeMessageAction(actionType); + describe('event types', () => { + // Arrange + const conversationId = 'CONVERSATION_ID'; + const dummyEventBody = { + event: { + type: 'app_home_opened', + channel: conversationId, + event_ts: 'EVENT_TS', + }, + }; + it('should find Event type for generic event', () => { // Act - const typeAndConversation = getTypeAndConversation(messageActionBody); + const typeAndConversation = getTypeAndConversation(dummyEventBody); // Assert - assert(typeAndConversation.type === IncomingEventType.Action); + assert(typeAndConversation.type === IncomingEventType.Event); + assert(typeAndConversation.conversationId === conversationId); + }); + }); + + describe('command types', () => { + // Arrange + const conversationId = 'CONVERSATION_ID'; + const dummyCommandBody = { + command: 'COMMAND_NAME', + channel_id: conversationId, + response_url: 'https://hooks.slack.com/commands/RESPONSE_URL', }; - } + + it('should find Command type for generic command', () => { + // Act + const typeAndConversation = getTypeAndConversation(dummyCommandBody); + + // Assert + assert(typeAndConversation.type === IncomingEventType.Command); + assert(typeAndConversation.conversationId === conversationId); + }); + }); + + describe('options types', () => { + // Arrange + const conversationId = 'CONVERSATION_ID'; + const dummyActionBodies = createFakeOptions(conversationId); + + dummyActionBodies.forEach((option) => { + it(`should find Option type for ${option.type}`, () => { + // Act + const typeAndConversation = getTypeAndConversation(option); + + // Assert + assert(typeAndConversation.type === IncomingEventType.Options); + assert(typeAndConversation.conversationId === conversationId); + }); + }); + }); describe('action types', () => { - it('should find Action type for message actions', matchesActionType('message_action')); - it('should find Action type for dialog submissions', matchesActionType('dialog_submission')); - it('should find Action type for block actions', matchesActionType('block_actions')); - it('should find Action type for interactive actions', matchesActionType('interactive_message')); + // Arrange + const conversationId = 'CONVERSATION_ID'; + const dummyActionBodies = createFakeActions(conversationId); + + dummyActionBodies.forEach((action) => { + it(`should find Action type for ${action.type}`, () => { + // Act + const typeAndConversation = getTypeAndConversation(action); + + // Assert + assert(typeAndConversation.type === IncomingEventType.Action); + assert(typeAndConversation.conversationId === conversationId); + }); + }); + }); + + describe('invalid events', () => { + // Arrange + const fakeEventBody = { + fake: 'THIS_IS_FAKE', + channel: { id: 'FAKE_CONVERSATION_ID' }, + }; + + it('should not find type for invalid event', () => { + // Act + const typeAndConversation = getTypeAndConversation(fakeEventBody); + + // Assert + assert.isEmpty(typeAndConversation); + }); }); }); -function createFakeMessageAction(actionType: string): SlackAction { - const action: Partial = { - type: actionType, - channel: { id: 'CHANNEL_ID', name: 'CHANNEL_NAME' }, - user: { id: 'USER_ID', name: 'USER_NAME' }, - team: { id: 'TEAM_ID', domain: 'TEAM_DOMAIN' }, - response_url: 'https://hooks.slack.com/actions/RESPONSE_URL', - token: 'TOKEN', - }; - - if (actionType === 'interactive_message') { - action.actions = [{ - type: 'button', - name: 'NAME', - value: 'VALUE', - }]; - } - - if (actionType === 'block_actions') { - action.actions = [{ - type: 'button', - value: 'VALUE', - text: { - type: 'plain_text', - text: 'TEXT', - }, - block_id: 'BLOCK_ID', - action_id: 'ACTION_ID', - action_ts: 'ACTION_TS', - }]; - } +function createFakeActions(conversationId: string): any[] { + return [ + // Body for a message action + { + type: 'message_action', + channel: { id: conversationId }, + callback_id: 'CALLBACK_ID', + }, + // Body for a dialog submission + { + type: 'dialog_submission', + channel: { id: conversationId }, + callback_id: 'CALLBACK_ID', + submission: { KEY: 'VALUE' }, + }, + // Body for an action within an interactive message + { + type: 'interactive_message', + channel: { id: conversationId }, + callback_id: 'CALLBACK_ID', + actions: [ + { + type: 'button', + name: 'NAME', + value: 'VALUE', + }, + ], + }, + // Body for an action within a block + { + type: 'block_actions', + channel: { id: conversationId }, + actions: [ + { + type: 'static_select', + selected_option: { + text: { + type: 'plain_text', + text: 'ELEMENT_TEXT', + }, + value: 'VALUE', + }, + }, + ], + }, + ]; +} - return action as SlackAction; +function createFakeOptions(conversationId: string): any[] { + return [ + // Body for an options request in an interactive message + { + type: 'interactive_message', + channel: { id: conversationId }, + name: 'OPTIONS_NAME', + }, + // Body for an options request in a dialog + { + type: 'dialog_suggestion', + channel: { id: conversationId }, + name: 'OPTIONS_NAME', + }, + // Body for an action within a block + { + type: 'block_suggestion', + channel: { id: conversationId }, + action_id: 'ACTION_ID', + }, + ]; } From 34e13b6c4ac9cb8ab7c2095365b02c703aee3d2a Mon Sep 17 00:00:00 2001 From: Shane DeWael Date: Fri, 24 May 2019 14:54:00 -0700 Subject: [PATCH 3/3] Remove some unnecessary body parameters --- src/helpers.spec.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/helpers.spec.ts b/src/helpers.spec.ts index 6ec738a41..eb0038f18 100644 --- a/src/helpers.spec.ts +++ b/src/helpers.spec.ts @@ -11,7 +11,6 @@ describe('getTypeAndConversation()', () => { event: { type: 'app_home_opened', channel: conversationId, - event_ts: 'EVENT_TS', }, }; @@ -101,25 +100,19 @@ function createFakeActions(conversationId: string): any[] { { type: 'message_action', channel: { id: conversationId }, - callback_id: 'CALLBACK_ID', }, // Body for a dialog submission { type: 'dialog_submission', channel: { id: conversationId }, - callback_id: 'CALLBACK_ID', - submission: { KEY: 'VALUE' }, }, // Body for an action within an interactive message { type: 'interactive_message', channel: { id: conversationId }, - callback_id: 'CALLBACK_ID', actions: [ { type: 'button', - name: 'NAME', - value: 'VALUE', }, ], }, @@ -130,13 +123,6 @@ function createFakeActions(conversationId: string): any[] { actions: [ { type: 'static_select', - selected_option: { - text: { - type: 'plain_text', - text: 'ELEMENT_TEXT', - }, - value: 'VALUE', - }, }, ], }, @@ -161,7 +147,6 @@ function createFakeOptions(conversationId: string): any[] { { type: 'block_suggestion', channel: { id: conversationId }, - action_id: 'ACTION_ID', }, ]; }