@@ -63,17 +63,40 @@ describe("fromAwsCliV2CompatibleProviderChain", () => {
6363 accessKeyId : "PROFILE_ACCESS_KEY" ,
6464 secretAccessKey : "PROFILE_SECRET_KEY" ,
6565 } ) ;
66+ expect ( mockFromIni ) . toHaveBeenCalled ( ) ;
6667 expect ( mockLogger . debug ) . toHaveBeenCalledWith ( expect . stringContaining ( "Using fromIni with profile:test-profile" ) ) ;
6768 } ) ;
6869
69- it ( "should try credential chain when no static credentials or profile" , async ( ) => {
70+ it ( "should merge caller client config with init options" , async ( ) => {
71+ // Initial credentials
72+ const credentials = {
73+ accessKeyId : "TEST_ACCESS_KEY" ,
74+ secretAccessKey : "TEST_SECRET_KEY" ,
75+ } ;
76+
77+ const provider = fromAwsCliV2CompatibleProviderChain ( credentials ) ;
78+ const callerConfig = {
79+ profile : "caller-profile" ,
80+ logger : mockLogger ,
81+ region : mockRegion ,
82+ } ;
83+
84+ const result = await provider ( { callerClientConfig : callerConfig } ) ;
85+
86+ expect ( result ) . toEqual ( credentials ) ;
87+ expect ( mockLogger . debug ) . toHaveBeenCalled ( ) ;
88+ } ) ;
89+
90+ it ( "should fall back to environment variables if no profile is provided" , async ( ) => {
7091 const mockEnvCredentials = {
7192 accessKeyId : "ENV_ACCESS_KEY" ,
7293 secretAccessKey : "ENV_SECRET_KEY" ,
7394 } ;
7495
96+ const mockFromEnv = vi . fn ( ( ) => vi . fn ( async ( ) => mockEnvCredentials ) ) ;
97+
7598 vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
76- fromEnv : ( ) => ( ) => Promise . resolve ( mockEnvCredentials ) ,
99+ fromEnv : mockFromEnv ,
77100 } ) ) ;
78101
79102 const provider = fromAwsCliV2CompatibleProviderChain ( {
@@ -83,11 +106,98 @@ describe("fromAwsCliV2CompatibleProviderChain", () => {
83106 const result = await provider ( ) ;
84107
85108 expect ( result ) . toEqual ( mockEnvCredentials ) ;
109+ expect ( mockFromEnv ) . toHaveBeenCalled ( ) ;
86110 expect ( mockLogger . debug ) . toHaveBeenCalledWith ( expect . stringContaining ( "Using from custom credential chain" ) ) ;
87111 } ) ;
88112
89- it ( "should throw error when no credentials are found" , async ( ) => {
90- // Mock all providers to fail
113+ it ( "should fall back to web identity credentials when environment variables are unavailable" , async ( ) => {
114+ vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
115+ fromEnv : ( ) => ( ) => Promise . reject ( new Error ( "No env credentials" ) ) ,
116+ } ) ) ;
117+
118+ const mockTokenFileCredentials = {
119+ accessKeyId : "TOKEN_ACCESS_KEY" ,
120+ secretAccessKey : "TOKEN_SECRET_KEY" ,
121+ } ;
122+
123+ const mockFromTokenFile = vi . fn ( ( ) => vi . fn ( async ( ) => mockTokenFileCredentials ) ) ;
124+
125+ vi . mock ( "@aws-sdk/credential-provider-web-identity" , ( ) => ( {
126+ fromTokenFile : mockFromTokenFile ,
127+ } ) ) ;
128+
129+ const provider = fromAwsCliV2CompatibleProviderChain ( {
130+ logger : mockLogger ,
131+ } ) ;
132+
133+ const result = await provider ( ) ;
134+
135+ expect ( result ) . toEqual ( mockTokenFileCredentials ) ;
136+ expect ( mockFromTokenFile ) . toHaveBeenCalled ( ) ;
137+ } ) ;
138+
139+ it ( "should fall back to SSO credentials when web identity is unavailable" , async ( ) => {
140+ vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
141+ fromEnv : ( ) => ( ) => Promise . reject ( new Error ( "No env credentials" ) ) ,
142+ } ) ) ;
143+ vi . mock ( "@aws-sdk/credential-provider-web-identity" , ( ) => ( {
144+ fromTokenFile : ( ) => ( ) => Promise . reject ( new Error ( "No token file" ) ) ,
145+ } ) ) ;
146+
147+ const mockSSOCredentials = {
148+ accessKeyId : "SSO_ACCESS_KEY" ,
149+ secretAccessKey : "SSO_SECRET_KEY" ,
150+ } ;
151+
152+ const mockFromSSO = vi . fn ( ( ) => vi . fn ( async ( ) => mockSSOCredentials ) ) ;
153+
154+ vi . mock ( "@aws-sdk/credential-provider-sso" , ( ) => ( {
155+ fromSSO : mockFromSSO ,
156+ } ) ) ;
157+
158+ const provider = fromAwsCliV2CompatibleProviderChain ( {
159+ logger : mockLogger ,
160+ } ) ;
161+
162+ const result = await provider ( ) ;
163+
164+ expect ( result ) . toEqual ( mockSSOCredentials ) ;
165+ expect ( mockFromSSO ) . toHaveBeenCalled ( ) ;
166+ } ) ;
167+
168+ it ( "should fall back to process credentials when SSO is unavailable" , async ( ) => {
169+ vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
170+ fromEnv : ( ) => ( ) => Promise . reject ( new Error ( "No env credentials" ) ) ,
171+ } ) ) ;
172+ vi . mock ( "@aws-sdk/credential-provider-web-identity" , ( ) => ( {
173+ fromTokenFile : ( ) => ( ) => Promise . reject ( new Error ( "No token file" ) ) ,
174+ } ) ) ;
175+ vi . mock ( "@aws-sdk/credential-provider-sso" , ( ) => ( {
176+ fromSSO : ( ) => ( ) => Promise . reject ( new Error ( "No SSO credentials" ) ) ,
177+ } ) ) ;
178+
179+ const mockProcessCredentials = {
180+ accessKeyId : "PROCESS_ACCESS_KEY" ,
181+ secretAccessKey : "PROCESS_SECRET_KEY" ,
182+ } ;
183+
184+ const mockFromProcess = vi . fn ( ( ) => vi . fn ( async ( ) => mockProcessCredentials ) ) ;
185+
186+ vi . mock ( "@aws-sdk/credential-provider-process" , ( ) => ( {
187+ fromProcess : mockFromProcess ,
188+ } ) ) ;
189+
190+ const provider = fromAwsCliV2CompatibleProviderChain ( {
191+ logger : mockLogger ,
192+ } ) ;
193+
194+ const result = await provider ( ) ;
195+
196+ expect ( result ) . toEqual ( mockProcessCredentials ) ;
197+ expect ( mockFromProcess ) . toHaveBeenCalled ( ) ;
198+ } ) ;
199+
200+ it ( "should fall back to remote credentials when process credentials are unavailable" , async ( ) => {
91201 vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
92202 fromEnv : ( ) => ( ) => Promise . reject ( new Error ( "No env credentials" ) ) ,
93203 } ) ) ;
@@ -100,35 +210,51 @@ describe("fromAwsCliV2CompatibleProviderChain", () => {
100210 vi . mock ( "@aws-sdk/credential-provider-process" , ( ) => ( {
101211 fromProcess : ( ) => ( ) => Promise . reject ( new Error ( "No process credentials" ) ) ,
102212 } ) ) ;
213+
214+ const mockRemoteCredentials = {
215+ accessKeyId : "REMOTE_ACCESS_KEY" ,
216+ secretAccessKey : "REMOTE_SECRET_KEY" ,
217+ } ;
218+
219+ const mockRemoteProvider = vi . fn ( ( ) => vi . fn ( async ( ) => mockRemoteCredentials ) ) ;
220+
103221 vi . mock ( "@aws-sdk/credential-provider-node/src/remoteProvider" , ( ) => ( {
104- remoteProvider : ( ) => ( ) => Promise . reject ( new Error ( "No remote credentials" ) ) ,
222+ remoteProvider : mockRemoteProvider ,
105223 } ) ) ;
106224
107225 const provider = fromAwsCliV2CompatibleProviderChain ( {
108226 logger : mockLogger ,
109227 } ) ;
110228
111- await expect ( provider ( ) ) . rejects . toThrow ( CredentialsProviderError ) ;
112- await expect ( provider ( ) ) . rejects . toThrow ( "Could not load credentials from any providers" ) ;
229+ const result = await provider ( ) ;
230+
231+ expect ( result ) . toEqual ( mockRemoteCredentials ) ;
232+ expect ( mockRemoteProvider ) . toHaveBeenCalled ( ) ;
113233 } ) ;
114234
115- it ( "should merge caller client config with init options" , async ( ) => {
116- // Initial credentials
117- const credentials = {
118- accessKeyId : "TEST_ACCESS_KEY" ,
119- secretAccessKey : "TEST_SECRET_KEY" ,
120- } ;
235+ it ( "should throw error when no credentials are found" , async ( ) => {
236+ // Mock all providers to fail
237+ vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
238+ fromEnv : ( ) => ( ) => Promise . reject ( new Error ( "No env credentials" ) ) ,
239+ } ) ) ;
240+ vi . mock ( "@aws-sdk/credential-provider-web-identity" , ( ) => ( {
241+ fromTokenFile : ( ) => ( ) => Promise . reject ( new Error ( "No token file" ) ) ,
242+ } ) ) ;
243+ vi . mock ( "@aws-sdk/credential-provider-sso" , ( ) => ( {
244+ fromSSO : ( ) => ( ) => Promise . reject ( new Error ( "No SSO credentials" ) ) ,
245+ } ) ) ;
246+ vi . mock ( "@aws-sdk/credential-provider-process" , ( ) => ( {
247+ fromProcess : ( ) => ( ) => Promise . reject ( new Error ( "No process credentials" ) ) ,
248+ } ) ) ;
249+ vi . mock ( "@aws-sdk/credential-provider-node/src/remoteProvider" , ( ) => ( {
250+ remoteProvider : ( ) => ( ) => Promise . reject ( new Error ( "No remote credentials" ) ) ,
251+ } ) ) ;
121252
122- const provider = fromAwsCliV2CompatibleProviderChain ( credentials ) ;
123- const callerConfig = {
124- profile : "caller-profile" ,
253+ const provider = fromAwsCliV2CompatibleProviderChain ( {
125254 logger : mockLogger ,
126- region : mockRegion ,
127- } ;
128-
129- const result = await provider ( { callerClientConfig : callerConfig } ) ;
255+ } ) ;
130256
131- expect ( result ) . toEqual ( credentials ) ;
132- expect ( mockLogger . debug ) . toHaveBeenCalled ( ) ;
257+ await expect ( provider ( ) ) . rejects . toThrow ( CredentialsProviderError ) ;
258+ await expect ( provider ( ) ) . rejects . toThrow ( "Could not load credentials from any providers" ) ;
133259 } ) ;
134260} ) ;
0 commit comments