diff --git a/src/App.ts b/src/App.ts index 7ff89fe06..7aa16830a 100644 --- a/src/App.ts +++ b/src/App.ts @@ -969,10 +969,6 @@ export default class App if (functionInputs) { context.functionInputs = functionInputs; } - } - - // Attach and make available the JIT/function-related token on context - if (this.attachFunctionToken) { if (functionBotAccessToken) { context.functionBotAccessToken = functionBotAccessToken; } diff --git a/test/unit/App/middlewares/arguments.spec.ts b/test/unit/App/middlewares/arguments.spec.ts index 75d0ef2b1..1187b25ef 100644 --- a/test/unit/App/middlewares/arguments.spec.ts +++ b/test/unit/App/middlewares/arguments.spec.ts @@ -8,6 +8,7 @@ import { type Override, createDummyAppMentionEventMiddlewareArgs, createDummyBlockActionEventMiddlewareArgs, + createDummyCustomFunctionMiddlewareArgs, createDummyMessageEventMiddlewareArgs, createDummyReceiverEvent, createDummyViewSubmissionMiddlewareArgs, @@ -761,5 +762,92 @@ describe('App middleware and listener arguments', () => { sinon.assert.calledOnce(fakeAck); }); + + it('should have function executed event details from a custom step payload', async () => { + const fakeAxiosPost = sinon.fake.resolves({}); + overrides = buildOverrides([withNoopWebClient(), withAxiosPost(fakeAxiosPost)]); + const MockApp = await importApp(overrides); + const callbackId = 'reverse_string'; + const functionBotAccessToken = 'xwfp-example'; + const functionExecutionId = 'Fx1234567890'; + const inputs = { + numerics: 12, + stringToReverse: 'palindrome', + trimmedSpaces: false, + }; + + const app = new MockApp({ + attachFunctionToken: false, // https://github.com/slackapi/bolt-js/pull/2513 + receiver: fakeReceiver, + authorize: sinon.fake.resolves(dummyAuthorizationResult), + }); + + let called = false; + app.function(callbackId, async ({ context }) => { + assert.strictEqual(context.functionExecutionId, functionExecutionId); + assert.strictEqual(context.functionBotAccessToken, functionBotAccessToken); + called = true; + }); + app.error(fakeErrorHandler); + + await fakeReceiver.sendEvent({ + ...createDummyCustomFunctionMiddlewareArgs({ + callbackId, + functionBotAccessToken, + functionExecutionId, + inputs, + }), + ack: fakeAck, + }); + + assert.isTrue(called); + sinon.assert.calledOnce(fakeAck); + }); + + it('should have function executed event details from a block actions payload', async () => { + const fakeAxiosPost = sinon.fake.resolves({}); + overrides = buildOverrides([withNoopWebClient(), withAxiosPost(fakeAxiosPost)]); + const MockApp = await importApp(overrides); + const callbackId = 'reverse_string_button'; + const functionBotAccessToken = 'xwfp-example'; + const functionExecutionId = 'Fx1234567890'; + const inputs = { + numerics: 12, + stringToReverse: 'palindrome', + trimmedSpaces: false, + }; + + const app = new MockApp({ + attachFunctionToken: false, // https://github.com/slackapi/bolt-js/pull/2513 + receiver: fakeReceiver, + authorize: sinon.fake.resolves(dummyAuthorizationResult), + }); + + app.action(callbackId, async ({ ack, context }) => { + assert.strictEqual(context.functionExecutionId, functionExecutionId); + assert.strictEqual(context.functionBotAccessToken, functionBotAccessToken); + assert.deepStrictEqual(context.functionInputs, inputs); + await ack(); + }); + app.error(fakeErrorHandler); + + await fakeReceiver.sendEvent({ + ...createDummyBlockActionEventMiddlewareArgs( + { + action_id: callbackId, + }, + { + bot_access_token: functionBotAccessToken, + function_data: { + execution_id: functionExecutionId, + inputs, + }, + }, + ), + ack: fakeAck, + }); + + sinon.assert.calledOnce(fakeAck); + }); }); }); diff --git a/test/unit/helpers/events.ts b/test/unit/helpers/events.ts index 00887f307..e7e9e9e65 100644 --- a/test/unit/helpers/events.ts +++ b/test/unit/helpers/events.ts @@ -303,13 +303,23 @@ export function createDummyCommandMiddlewareArgs(commandOverrides?: DummyCommand }; } +interface DummyCustomFunctionOverride { + callbackId?: string; + functionBotAccessToken?: string; + functionExecutionId?: string; + inputs?: Record; +} export function createDummyCustomFunctionMiddlewareArgs( - functionOverrides: { - callbackId?: string; - inputs?: Record; - } = { callbackId: 'reverse', inputs: { stringToReverse: 'hello' } }, + functionOverrides: DummyCustomFunctionOverride = { + callbackId: 'reverse', + functionBotAccessToken: 'xwfp-valid', + functionExecutionId: 'Fx111', + inputs: { stringToReverse: 'hello' }, + }, ): SlackCustomFunctionMiddlewareArgs { functionOverrides.callbackId = functionOverrides.callbackId || 'reverse'; + functionOverrides.functionBotAccessToken = functionOverrides.functionBotAccessToken || 'xwfp-valid'; + functionOverrides.functionExecutionId = functionOverrides.functionExecutionId || 'Fx111'; functionOverrides.inputs = functionOverrides.inputs ? functionOverrides.inputs : { stringToReverse: 'hello' }; const testFunction = { id: 'Fn111', @@ -345,10 +355,10 @@ export function createDummyCustomFunctionMiddlewareArgs( type: 'function_executed', function: testFunction, inputs: functionOverrides.inputs, - function_execution_id: 'Fx111', + function_execution_id: functionOverrides.functionExecutionId, workflow_execution_id: 'Wf111', event_ts: '1659055013.509853', - bot_access_token: 'xwfp-valid', + bot_access_token: functionOverrides.functionBotAccessToken, } as const; const body = {