@@ -63,17 +63,40 @@ describe("fromAwsCliV2CompatibleProviderChain", () => {
63
63
accessKeyId : "PROFILE_ACCESS_KEY" ,
64
64
secretAccessKey : "PROFILE_SECRET_KEY" ,
65
65
} ) ;
66
+ expect ( mockFromIni ) . toHaveBeenCalled ( ) ;
66
67
expect ( mockLogger . debug ) . toHaveBeenCalledWith ( expect . stringContaining ( "Using fromIni with profile:test-profile" ) ) ;
67
68
} ) ;
68
69
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 ( ) => {
70
91
const mockEnvCredentials = {
71
92
accessKeyId : "ENV_ACCESS_KEY" ,
72
93
secretAccessKey : "ENV_SECRET_KEY" ,
73
94
} ;
74
95
96
+ const mockFromEnv = vi . fn ( ( ) => vi . fn ( async ( ) => mockEnvCredentials ) ) ;
97
+
75
98
vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
76
- fromEnv : ( ) => ( ) => Promise . resolve ( mockEnvCredentials ) ,
99
+ fromEnv : mockFromEnv ,
77
100
} ) ) ;
78
101
79
102
const provider = fromAwsCliV2CompatibleProviderChain ( {
@@ -83,11 +106,98 @@ describe("fromAwsCliV2CompatibleProviderChain", () => {
83
106
const result = await provider ( ) ;
84
107
85
108
expect ( result ) . toEqual ( mockEnvCredentials ) ;
109
+ expect ( mockFromEnv ) . toHaveBeenCalled ( ) ;
86
110
expect ( mockLogger . debug ) . toHaveBeenCalledWith ( expect . stringContaining ( "Using from custom credential chain" ) ) ;
87
111
} ) ;
88
112
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 ( ) => {
91
201
vi . mock ( "@aws-sdk/credential-provider-env" , ( ) => ( {
92
202
fromEnv : ( ) => ( ) => Promise . reject ( new Error ( "No env credentials" ) ) ,
93
203
} ) ) ;
@@ -100,35 +210,51 @@ describe("fromAwsCliV2CompatibleProviderChain", () => {
100
210
vi . mock ( "@aws-sdk/credential-provider-process" , ( ) => ( {
101
211
fromProcess : ( ) => ( ) => Promise . reject ( new Error ( "No process credentials" ) ) ,
102
212
} ) ) ;
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
+
103
221
vi . mock ( "@aws-sdk/credential-provider-node/src/remoteProvider" , ( ) => ( {
104
- remoteProvider : ( ) => ( ) => Promise . reject ( new Error ( "No remote credentials" ) ) ,
222
+ remoteProvider : mockRemoteProvider ,
105
223
} ) ) ;
106
224
107
225
const provider = fromAwsCliV2CompatibleProviderChain ( {
108
226
logger : mockLogger ,
109
227
} ) ;
110
228
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 ( ) ;
113
233
} ) ;
114
234
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
+ } ) ) ;
121
252
122
- const provider = fromAwsCliV2CompatibleProviderChain ( credentials ) ;
123
- const callerConfig = {
124
- profile : "caller-profile" ,
253
+ const provider = fromAwsCliV2CompatibleProviderChain ( {
125
254
logger : mockLogger ,
126
- region : mockRegion ,
127
- } ;
128
-
129
- const result = await provider ( { callerClientConfig : callerConfig } ) ;
255
+ } ) ;
130
256
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" ) ;
133
259
} ) ;
134
260
} ) ;
0 commit comments