@@ -53,6 +53,7 @@ describe('DynamicCredentialService', () => {
5353 const createMockResolver = (
5454 shouldSucceed = true ,
5555 shouldThrowDataNotFound = false ,
56+ customData ?: ICredentialDataDecryptedObject ,
5657 ) : jest . Mocked < ICredentialResolver > => ( {
5758 metadata : {
5859 name : 'stub-resolver-1.0' ,
@@ -65,7 +66,7 @@ describe('DynamicCredentialService', () => {
6566 if ( ! shouldSucceed ) {
6667 throw new Error ( 'Resolution failed' ) ;
6768 }
68- return { token : 'dynamic-token' , apiKey : 'dynamic-key' } ;
69+ return customData ?? { token : 'dynamic-token' , apiKey : 'dynamic-key' } ;
6970 } ) ,
7071 setSecret : jest . fn ( ) ,
7172 validateOptions : jest . fn ( ) ,
@@ -160,7 +161,7 @@ describe('DynamicCredentialService', () => {
160161 const result = await service . resolveIfNeeded ( credentialsEntity , staticData , undefined ) ;
161162
162163 expect ( result ) . toBe ( staticData ) ;
163- expect ( mockLogger . warn ) . toHaveBeenCalledWith (
164+ expect ( mockLogger . debug ) . toHaveBeenCalledWith (
164165 'Resolver not found, falling back to static credentials' ,
165166 expect . objectContaining ( {
166167 credentialId : 'cred-123' ,
@@ -181,7 +182,7 @@ describe('DynamicCredentialService', () => {
181182 const result = await service . resolveIfNeeded ( credentialsEntity , staticData , undefined ) ;
182183
183184 expect ( result ) . toBe ( staticData ) ;
184- expect ( mockLogger . warn ) . toHaveBeenCalled ( ) ;
185+ expect ( mockLogger . debug ) . toHaveBeenCalled ( ) ;
185186 } ) ;
186187
187188 it ( 'execution context is missing and fallback is allowed' , async ( ) => {
@@ -197,7 +198,7 @@ describe('DynamicCredentialService', () => {
197198 const result = await service . resolveIfNeeded ( credentialsEntity , staticData , undefined ) ;
198199
199200 expect ( result ) . toBe ( staticData ) ;
200- expect ( mockLogger . warn ) . toHaveBeenCalledWith (
201+ expect ( mockLogger . debug ) . toHaveBeenCalledWith (
201202 'No execution context available, falling back to static credentials' ,
202203 expect . objectContaining ( {
203204 credentialId : 'cred-123' ,
@@ -252,7 +253,7 @@ describe('DynamicCredentialService', () => {
252253 ) ;
253254
254255 expect ( result ) . toBe ( staticData ) ;
255- expect ( mockLogger . warn ) . toHaveBeenCalledWith (
256+ expect ( mockLogger . debug ) . toHaveBeenCalledWith (
256257 'Dynamic credential resolution failed, falling back to static' ,
257258 expect . objectContaining ( {
258259 credentialId : 'cred-123' ,
@@ -282,7 +283,7 @@ describe('DynamicCredentialService', () => {
282283 ) ;
283284
284285 expect ( result ) . toBe ( staticData ) ;
285- expect ( mockLogger . warn ) . toHaveBeenCalledWith (
286+ expect ( mockLogger . debug ) . toHaveBeenCalledWith (
286287 'Dynamic credential resolution failed, falling back to static' ,
287288 expect . objectContaining ( {
288289 isDataNotFound : true ,
@@ -382,34 +383,54 @@ describe('DynamicCredentialService', () => {
382383 service . resolveIfNeeded ( credentialsEntity , staticData , executionContext ) ,
383384 ) . rejects . toThrow ( 'Failed to resolve dynamic credentials for "Test Credential"' ) ;
384385
385- expect ( mockLogger . error ) . toHaveBeenCalledWith (
386+ expect ( mockLogger . debug ) . toHaveBeenCalledWith (
386387 'Dynamic credential resolution failed without fallback' ,
387388 expect . any ( Object ) ,
388389 ) ;
389390 } ) ;
390391 } ) ;
391392
392393 describe ( 'should successfully resolve dynamic credentials when' , ( ) => {
393- it ( 'all conditions are met and resolver returns data' , async ( ) => {
394+ it ( 'all conditions are met and merges static with dynamic data' , async ( ) => {
394395 const credentialsEntity = createMockCredentialsEntity ( ) ;
395396 const resolverEntity = createMockResolverEntity ( ) ;
396- const mockResolver = createMockResolver ( ) ;
397397 const executionContext = createMockExecutionContext ( 'encrypted-credentials' ) ;
398398 const credentialContext = createMockCredentialContext ( ) ;
399399
400+ // Static data includes OAuth client config and old token
401+ const staticOAuthData : ICredentialDataDecryptedObject = {
402+ clientId : 'static-client-id' ,
403+ clientSecret : 'static-client-secret' ,
404+ token : 'static-token' , // Will be overridden
405+ apiKey : 'static-key' , // Will be overridden
406+ } ;
407+
408+ // Dynamic data includes new tokens (overrides token) and new fields
409+ const dynamicData : ICredentialDataDecryptedObject = {
410+ token : 'dynamic-token' ,
411+ apiKey : 'dynamic-key' ,
412+ refreshToken : 'dynamic-refresh-token' ,
413+ } ;
414+
415+ const mockResolver = createMockResolver ( true , false , dynamicData ) ;
416+
400417 mockResolverRepository . findOneBy . mockResolvedValue ( resolverEntity ) ;
401418 mockResolverRegistry . getResolverByName . mockReturnValue ( mockResolver ) ;
402419 mockCipher . decrypt . mockReturnValue ( JSON . stringify ( credentialContext ) ) ;
403420
404421 const result = await service . resolveIfNeeded (
405422 credentialsEntity ,
406- staticData ,
423+ staticOAuthData ,
407424 executionContext ,
408425 ) ;
409426
427+ // Verify merge: static fields preserved, dynamic fields added/overridden
410428 expect ( result ) . toEqual ( {
411- token : 'dynamic-token' ,
412- apiKey : 'dynamic-key' ,
429+ clientId : 'static-client-id' , // From static (preserved)
430+ clientSecret : 'static-client-secret' , // From static (preserved)
431+ token : 'dynamic-token' , // From dynamic (overridden)
432+ apiKey : 'dynamic-key' , // From dynamic (overridden)
433+ refreshToken : 'dynamic-refresh-token' , // From dynamic (new field)
413434 } ) ;
414435 expect ( mockResolver . getSecret ) . toHaveBeenCalledWith ( 'cred-123' , credentialContext , {
415436 prefix : 'test' ,
@@ -525,7 +546,7 @@ describe('DynamicCredentialService', () => {
525546 ) ;
526547
527548 expect ( result ) . toBe ( staticData ) ;
528- expect ( mockLogger . warn ) . toHaveBeenCalled ( ) ;
549+ expect ( mockLogger . debug ) . toHaveBeenCalled ( ) ;
529550 } ) ;
530551
531552 it ( 'empty resolver config' , async ( ) => {
@@ -644,7 +665,7 @@ describe('DynamicCredentialService', () => {
644665 ) ;
645666
646667 expect ( result ) . toBe ( staticData ) ;
647- expect ( mockLogger . warn ) . toHaveBeenCalledWith (
668+ expect ( mockLogger . debug ) . toHaveBeenCalledWith (
648669 'Resolver not found, falling back to static credentials' ,
649670 expect . objectContaining ( {
650671 resolverId : 'workflow-resolver-789' ,
0 commit comments