@@ -136,40 +136,108 @@ describe('resolveSlackSelectorCredential', () => {
136136 expect ( mocks . refreshToken ) . not . toHaveBeenCalled ( )
137137 } )
138138
139- it ( 'requires workflow scope for a direct bot token' , async ( ) => {
140- const result = await resolveSlackSelectorCredential ( principal , {
141- credential : 'xoxb-literal-secret' ,
142- requestId : 'request-1' ,
143- } )
139+ it . each ( [ 'xoxb-literal-secret' , '{{SLACK_CREDENTIAL}}' ] ) (
140+ 'requires workflow scope before resolving %s' ,
141+ async ( credential ) => {
142+ const result = await resolveSlackSelectorCredential ( principal , {
143+ credential,
144+ requestId : 'request-1' ,
145+ } )
144146
145- expect ( result ) . toEqual ( {
146- ok : false ,
147- status : 400 ,
148- error : 'Unable to resolve selector configuration' ,
149- } )
150- expect ( mocks . resolveContext ) . not . toHaveBeenCalled ( )
151- } )
147+ expect ( result ) . toEqual ( {
148+ ok : false ,
149+ status : 400 ,
150+ error : 'Unable to resolve selector configuration' ,
151+ } )
152+ expect ( mocks . resolveContext ) . not . toHaveBeenCalled ( )
153+ }
154+ )
152155
153- it ( 'does not reinterpret a referenced non-bot value as an OAuth credential id' , async ( ) => {
154- mocks . resolveContext . mockResolvedValue ( {
155- ok : true ,
156- context : { credential : 'not-a-bot-token' } ,
157- requesterUserId : 'viewer-1' ,
158- workspaceId : 'workspace-1' ,
159- } )
156+ it . each ( [
157+ [ 'OAuth' , 'oauth' , 'xoxp-oauth-token' , false ] ,
158+ [ 'custom bot' , 'service_account' , 'xoxb-custom-bot-token' , true ] ,
159+ ] ) (
160+ 'authorizes a referenced %s credential after environment resolution' ,
161+ async ( _label , credentialType , accessToken , isBotToken ) => {
162+ mocks . resolveContext
163+ . mockResolvedValueOnce ( {
164+ ok : true ,
165+ context : { credential : 'resolved-credential-id' } ,
166+ requesterUserId : 'viewer-1' ,
167+ workspaceId : 'workspace-1' ,
168+ } )
169+ . mockResolvedValueOnce ( {
170+ ok : true ,
171+ context : { } ,
172+ requesterUserId : 'viewer-1' ,
173+ workspaceId : 'workspace-1' ,
174+ credentialAccess : {
175+ ok : true ,
176+ workspaceId : 'workspace-1' ,
177+ credentialOwnerUserId : 'owner-1' ,
178+ credentialType,
179+ } ,
180+ } )
181+ mocks . refreshToken . mockResolvedValue ( accessToken )
182+
183+ const result = await resolveSlackSelectorCredential ( principal , {
184+ credential : '{{SLACK_CREDENTIAL_ID}}' ,
185+ workflowId : 'workflow-1' ,
186+ requestId : 'request-1' ,
187+ } )
188+
189+ expect ( mocks . resolveContext ) . toHaveBeenNthCalledWith ( 1 , principal , {
190+ workflowId : 'workflow-1' ,
191+ context : { credential : '{{SLACK_CREDENTIAL_ID}}' } ,
192+ } )
193+ expect ( mocks . resolveContext ) . toHaveBeenNthCalledWith ( 2 , principal , {
194+ workflowId : 'workflow-1' ,
195+ credentialId : 'resolved-credential-id' ,
196+ context : { } ,
197+ } )
198+ expect ( mocks . providerMatches ) . toHaveBeenCalledWith ( {
199+ credentialId : 'resolved-credential-id' ,
200+ credentialOwnerUserId : 'owner-1' ,
201+ serviceId : 'slack' ,
202+ } )
203+ expect ( mocks . refreshToken ) . toHaveBeenCalledWith (
204+ 'resolved-credential-id' ,
205+ 'owner-1' ,
206+ 'request-1'
207+ )
208+ expect ( result ) . toMatchObject ( { ok : true , accessToken, isBotToken } )
209+ }
210+ )
211+
212+ it ( 'provider-binds a referenced credential before token refresh' , async ( ) => {
213+ mocks . resolveContext
214+ . mockResolvedValueOnce ( {
215+ ok : true ,
216+ context : { credential : 'resolved-credential-id' } ,
217+ requesterUserId : 'viewer-1' ,
218+ workspaceId : 'workspace-1' ,
219+ } )
220+ . mockResolvedValueOnce ( {
221+ ok : true ,
222+ context : { } ,
223+ requesterUserId : 'viewer-1' ,
224+ workspaceId : 'workspace-1' ,
225+ credentialAccess : {
226+ ok : true ,
227+ workspaceId : 'workspace-1' ,
228+ credentialOwnerUserId : 'owner-1' ,
229+ credentialType : 'oauth' ,
230+ } ,
231+ } )
232+ mocks . providerMatches . mockResolvedValue ( false )
160233
161234 const result = await resolveSlackSelectorCredential ( principal , {
162- credential : '{{SLACK_BOT_TOKEN }}' ,
235+ credential : '{{SLACK_CREDENTIAL_ID }}' ,
163236 workflowId : 'workflow-1' ,
164237 requestId : 'request-1' ,
165238 } )
166239
167- expect ( result ) . toEqual ( {
168- ok : false ,
169- status : 400 ,
170- error : 'Unable to resolve selector configuration' ,
171- } )
172- expect ( mocks . providerMatches ) . not . toHaveBeenCalled ( )
240+ expect ( result ) . toEqual ( { ok : false , status : 400 , error : 'Select a Slack credential.' } )
173241 expect ( mocks . refreshToken ) . not . toHaveBeenCalled ( )
174242 } )
175243
0 commit comments