33 */
44import { afterAll , beforeEach , describe , expect , it , vi } from 'vitest'
55
6- const { mockFetch, mockResolveSelectorCredentialBundle } = vi . hoisted ( ( ) => ( {
6+ const { mockFetch, mockGetCredential , mockResolveSelectorCredentialBundle } = vi . hoisted ( ( ) => ( {
77 mockFetch : vi . fn ( ) ,
8+ mockGetCredential : vi . fn ( ) ,
89 mockResolveSelectorCredentialBundle : vi . fn ( ) ,
910} ) )
1011
12+ vi . mock ( '@/lib/oauth/credential-service' , ( ) => ( {
13+ getCredential : mockGetCredential ,
14+ } ) )
15+
1116vi . mock ( '@/lib/selectors/server/providers/credential-bundle' , ( ) => ( {
1217 resolveSelectorCredentialBundle : mockResolveSelectorCredentialBundle ,
1318} ) )
@@ -30,7 +35,18 @@ function args(
3035 workspaceId : 'workspace-1' ,
3136 principal : { kind : 'session' , userId : 'user-1' , sessionId : 'session-1' } ,
3237 requesterUserId : 'user-1' ,
33- credential : { suppliedId : 'credential-1' } ,
38+ credential : {
39+ suppliedId : 'credential-1' ,
40+ providerId : 'eloqua' ,
41+ access : {
42+ ok : true ,
43+ credentialOwnerUserId : 'owner-1' ,
44+ workspaceId : 'workspace-1' ,
45+ resolvedCredentialId : 'account-1' ,
46+ credentialType : 'oauth' ,
47+ } ,
48+ signal,
49+ } ,
3450 references : new Map ( ) ,
3551 protectedValues : createSelectorProtectedValues ( ) ,
3652 signal,
@@ -41,9 +57,12 @@ describe('Oracle Eloqua server selector adapter', () => {
4157 beforeEach ( ( ) => {
4258 vi . clearAllMocks ( )
4359 vi . stubGlobal ( 'fetch' , mockFetch )
60+ mockGetCredential . mockResolvedValue ( {
61+ providerId : 'eloqua' ,
62+ scope : '__eloqua_instance__:https://secure.p03.eloqua.com,full' ,
63+ } )
4464 mockResolveSelectorCredentialBundle . mockResolvedValue ( {
4565 accessToken : 'server-only-token' ,
46- instanceUrl : 'https://secure.p03.eloqua.com' ,
4766 } )
4867 } )
4968
@@ -99,7 +118,14 @@ describe('Oracle Eloqua server selector adapter', () => {
99118 expect ( firstUrl . searchParams . get ( 'count' ) ) . toBe ( '100' )
100119 expect ( firstUrl . searchParams . get ( 'page' ) ) . toBe ( '1' )
101120 expect ( secondUrl . searchParams . get ( 'page' ) ) . toBe ( '2' )
121+ expect ( mockGetCredential ) . toHaveBeenCalledTimes ( 2 )
122+ expect ( mockGetCredential ) . toHaveBeenCalledWith ( 'selector-execution' , 'account-1' , 'owner-1' )
102123 expect ( mockResolveSelectorCredentialBundle ) . toHaveBeenCalledTimes ( 2 )
124+ expect ( mockResolveSelectorCredentialBundle ) . toHaveBeenCalledWith (
125+ expect . objectContaining ( {
126+ credential : expect . objectContaining ( { providerId : 'eloqua' , suppliedId : 'account-1' } ) ,
127+ } )
128+ )
103129 } )
104130
105131 it . each ( [
@@ -125,14 +151,55 @@ describe('Oracle Eloqua server selector adapter', () => {
125151 } )
126152
127153 it ( 'rejects a credential with an unsafe destination before fetching' , async ( ) => {
128- mockResolveSelectorCredentialBundle . mockResolvedValue ( {
129- accessToken : 'server-only-token ' ,
130- instanceUrl : 'https://evil.example' ,
154+ mockGetCredential . mockResolvedValue ( {
155+ providerId : 'eloqua ' ,
156+ scope : '__eloqua_instance__: https://evil.example,full ' ,
131157 } )
132158
133159 await expect (
134160 eloquaSelectorAttachments [ 'eloqua.forms' ] . execute ( args ( { kind : 'list' } , 'eloqua.forms' ) )
135161 ) . rejects . toBeInstanceOf ( SelectorConnectionUnavailableError )
162+ expect ( mockResolveSelectorCredentialBundle ) . not . toHaveBeenCalled ( )
163+ expect ( mockFetch ) . not . toHaveBeenCalled ( )
164+ } )
165+
166+ it ( 'fails closed when the stored credential scope does not contain a pod' , async ( ) => {
167+ mockGetCredential . mockResolvedValue ( {
168+ providerId : 'eloqua' ,
169+ scope : 'full' ,
170+ } )
171+
172+ await expect (
173+ eloquaSelectorAttachments [ 'eloqua.forms' ] . execute ( args ( { kind : 'list' } , 'eloqua.forms' ) )
174+ ) . rejects . toBeInstanceOf ( SelectorConnectionUnavailableError )
175+ expect ( mockResolveSelectorCredentialBundle ) . not . toHaveBeenCalled ( )
176+ expect ( mockFetch ) . not . toHaveBeenCalled ( )
177+ } )
178+
179+ it ( 'fails closed when the stored credential provider does not match Eloqua' , async ( ) => {
180+ mockGetCredential . mockResolvedValue ( {
181+ providerId : 'salesforce' ,
182+ scope : '__eloqua_instance__:https://secure.p03.eloqua.com,full' ,
183+ } )
184+
185+ await expect (
186+ eloquaSelectorAttachments [ 'eloqua.forms' ] . execute ( args ( { kind : 'list' } , 'eloqua.forms' ) )
187+ ) . rejects . toBeInstanceOf ( SelectorConnectionUnavailableError )
188+ expect ( mockResolveSelectorCredentialBundle ) . not . toHaveBeenCalled ( )
189+ expect ( mockFetch ) . not . toHaveBeenCalled ( )
190+ } )
191+
192+ it ( 'does not begin token resolution when credential loading is cancelled' , async ( ) => {
193+ const controller = new AbortController ( )
194+ mockGetCredential . mockReturnValue ( new Promise ( ( ) => undefined ) )
195+
196+ const pending = eloquaSelectorAttachments [ 'eloqua.forms' ] . execute (
197+ args ( { kind : 'list' } , 'eloqua.forms' , controller . signal )
198+ )
199+ controller . abort ( )
200+
201+ await expect ( pending ) . rejects . toMatchObject ( { name : 'AbortError' } )
202+ expect ( mockResolveSelectorCredentialBundle ) . not . toHaveBeenCalled ( )
136203 expect ( mockFetch ) . not . toHaveBeenCalled ( )
137204 } )
138205
0 commit comments