@@ -3,10 +3,10 @@ import { fromIni } from "@aws-sdk/credential-provider-ini";
3
3
import { fromProcess } from "@aws-sdk/credential-provider-process" ;
4
4
import { fromSSO } from "@aws-sdk/credential-provider-sso" ;
5
5
import { fromTokenFile } from "@aws-sdk/credential-provider-web-identity" ;
6
- import { chain , CredentialsProviderError , memoize } from "@smithy/property-provider" ;
6
+ import { CredentialsProviderError } from "@smithy/property-provider" ;
7
7
import { ENV_PROFILE , loadSharedConfigFiles } from "@smithy/shared-ini-file-loader" ;
8
8
9
- import { defaultProvider } from "./defaultProvider" ;
9
+ import { credentialsTreatedAsExpired , credentialsWillNeedRefresh , defaultProvider } from "./defaultProvider" ;
10
10
import { remoteProvider } from "./remoteProvider" ;
11
11
12
12
jest . mock ( "@aws-sdk/credential-provider-env" ) ;
@@ -15,7 +15,6 @@ jest.mock("@aws-sdk/credential-provider-ini");
15
15
jest . mock ( "@aws-sdk/credential-provider-process" ) ;
16
16
jest . mock ( "@aws-sdk/credential-provider-sso" ) ;
17
17
jest . mock ( "@aws-sdk/credential-provider-web-identity" ) ;
18
- jest . mock ( "@smithy/property-provider" ) ;
19
18
jest . mock ( "@smithy/shared-ini-file-loader" ) ;
20
19
jest . mock ( "./remoteProvider" ) ;
21
20
@@ -25,19 +24,24 @@ describe(defaultProvider.name, () => {
25
24
secretAccessKey : "mockSecretAccessKey" ,
26
25
} ;
27
26
27
+ const credentials = ( ) => {
28
+ throw new CredentialsProviderError ( "test" , true ) ;
29
+ } ;
30
+
31
+ const finalCredentials = ( ) => {
32
+ return mockCreds ;
33
+ } ;
34
+
28
35
const mockInit = {
29
36
profile : "mockProfile" ,
30
37
} ;
31
38
32
- const mockEnvFn = jest . fn ( ) ;
33
- const mockSsoFn = jest . fn ( ) ;
34
- const mockIniFn = jest . fn ( ) ;
35
- const mockProcessFn = jest . fn ( ) ;
36
- const mockTokenFileFn = jest . fn ( ) ;
37
- const mockRemoteProviderFn = jest . fn ( ) ;
38
-
39
- const mockChainFn = jest . fn ( ) ;
40
- const mockMemoizeFn = jest . fn ( ) . mockResolvedValue ( mockCreds ) ;
39
+ const mockEnvFn = jest . fn ( ) . mockImplementation ( ( ) => credentials ( ) ) ;
40
+ const mockSsoFn = jest . fn ( ) . mockImplementation ( ( ) => credentials ( ) ) ;
41
+ const mockIniFn = jest . fn ( ) . mockImplementation ( ( ) => credentials ( ) ) ;
42
+ const mockProcessFn = jest . fn ( ) . mockImplementation ( ( ) => credentials ( ) ) ;
43
+ const mockTokenFileFn = jest . fn ( ) . mockImplementation ( ( ) => credentials ( ) ) ;
44
+ const mockRemoteProviderFn = jest . fn ( ) . mockImplementation ( ( ) => finalCredentials ( ) ) ;
41
45
42
46
beforeEach ( ( ) => {
43
47
[
@@ -47,51 +51,48 @@ describe(defaultProvider.name, () => {
47
51
[ fromProcess , mockProcessFn ] ,
48
52
[ fromTokenFile , mockTokenFileFn ] ,
49
53
[ remoteProvider , mockRemoteProviderFn ] ,
50
- [ chain , mockChainFn ] ,
51
- [ memoize , mockMemoizeFn ] ,
52
54
] . forEach ( ( [ fromFn , mockFn ] ) => {
53
55
( fromFn as jest . Mock ) . mockReturnValue ( mockFn ) ;
54
56
} ) ;
55
57
} ) ;
56
58
57
59
afterEach ( async ( ) => {
58
- const errorFnIndex = ( chain as jest . Mock ) . mock . calls [ 0 ] . length ;
59
- const errorFn = ( chain as jest . Mock ) . mock . calls [ 0 ] [ errorFnIndex - 1 ] ;
60
- const expectedError = new CredentialsProviderError ( "Could not load credentials from any providers" , false ) ;
61
- try {
62
- await errorFn ( ) ;
63
- fail ( `expected ${ expectedError } ` ) ;
64
- } catch ( error ) {
65
- expect ( error . toString ( ) ) . toStrictEqual ( expectedError . toString ( ) ) ;
66
- }
67
-
68
- expect ( memoize ) . toHaveBeenCalledWith ( mockChainFn , expect . any ( Function ) , expect . any ( Function ) ) ;
69
-
70
60
jest . clearAllMocks ( ) ;
71
61
} ) ;
72
62
73
63
describe ( "without fromEnv" , ( ) => {
74
- afterEach ( ( ) => {
75
- expect ( chain ) . toHaveBeenCalledWith (
76
- mockSsoFn ,
77
- mockIniFn ,
78
- mockProcessFn ,
79
- mockTokenFileFn ,
80
- mockRemoteProviderFn ,
81
- expect . any ( Function )
82
- ) ;
83
- } ) ;
84
-
85
64
it ( "creates provider chain and memoizes it" , async ( ) => {
86
- const receivedCreds = await defaultProvider ( mockInit ) ( ) ;
87
- expect ( receivedCreds ) . toStrictEqual ( mockCreds ) ;
65
+ const provider = defaultProvider ( mockInit ) ;
88
66
89
- expect ( fromEnv ) . not . toHaveBeenCalled ( ) ;
90
- for ( const fromFn of [ fromSSO , fromIni , fromProcess , fromTokenFile , remoteProvider ] ) {
91
- expect ( fromFn ) . toHaveBeenCalledWith ( mockInit ) ;
67
+ // initial call proceeds through the chain.
68
+ {
69
+ const receivedCreds = await provider ( ) ;
70
+ expect ( receivedCreds ) . toEqual ( mockCreds ) ;
71
+
72
+ expect ( fromEnv ) . not . toHaveBeenCalled ( ) ;
73
+ expect ( fromSSO ) . toHaveBeenCalledWith ( mockInit ) ;
74
+ expect ( fromIni ) . toHaveBeenCalledWith ( mockInit ) ;
75
+ expect ( fromProcess ) . toHaveBeenCalledWith ( mockInit ) ;
76
+ expect ( fromTokenFile ) . toHaveBeenCalledWith ( mockInit ) ;
77
+ expect ( remoteProvider ) . toHaveBeenCalledWith ( mockInit ) ;
78
+
79
+ expect ( loadSharedConfigFiles ) . not . toHaveBeenCalled ( ) ;
92
80
}
93
81
94
- expect ( loadSharedConfigFiles ) . not . toHaveBeenCalled ( ) ;
82
+ jest . clearAllMocks ( ) ;
83
+
84
+ // subsequent call does not enter the chain.
85
+ {
86
+ const receivedCreds = await provider ( ) ;
87
+ expect ( receivedCreds ) . toEqual ( mockCreds ) ;
88
+
89
+ expect ( fromEnv ) . not . toHaveBeenCalled ( ) ;
90
+ expect ( fromSSO ) . not . toHaveBeenCalledWith ( mockInit ) ;
91
+ expect ( fromIni ) . not . toHaveBeenCalledWith ( mockInit ) ;
92
+ expect ( fromProcess ) . not . toHaveBeenCalledWith ( mockInit ) ;
93
+ expect ( fromTokenFile ) . not . toHaveBeenCalledWith ( mockInit ) ;
94
+ expect ( remoteProvider ) . not . toHaveBeenCalledWith ( mockInit ) ;
95
+ }
95
96
} ) ;
96
97
97
98
it ( `if env['${ ENV_PROFILE } '] is set` , async ( ) => {
@@ -123,63 +124,42 @@ describe(defaultProvider.name, () => {
123
124
for ( const fromFn of [ fromSSO , fromIni , fromProcess , fromTokenFile , remoteProvider ] ) {
124
125
expect ( fromFn ) . toHaveBeenCalledWith ( mockInitWithoutProfile ) ;
125
126
}
126
-
127
- expect ( chain ) . toHaveBeenCalledWith (
128
- mockEnvFn ,
129
- mockSsoFn ,
130
- mockIniFn ,
131
- mockProcessFn ,
132
- mockTokenFileFn ,
133
- mockRemoteProviderFn ,
134
- expect . any ( Function )
135
- ) ;
136
127
} ) ;
137
128
138
- describe ( "memoize isExpired" , ( ) => {
129
+ describe ( credentialsTreatedAsExpired . name , ( ) => {
139
130
const mockDateNow = Date . now ( ) ;
140
131
beforeEach ( async ( ) => {
141
132
jest . spyOn ( Date , "now" ) . mockReturnValueOnce ( mockDateNow ) ;
142
- await defaultProvider ( mockInit ) ( ) ;
143
133
} ) ;
144
134
145
135
it ( "returns true if expiration is defined, and creds have expired" , ( ) => {
146
- const memoizeExpiredFn = ( memoize as jest . Mock ) . mock . calls [ 0 ] [ 1 ] ;
147
136
const expiration = new Date ( mockDateNow - 24 * 60 * 60 * 1000 ) ;
148
- expect ( memoizeExpiredFn ( { expiration } ) ) . toEqual ( true ) ;
137
+ expect ( credentialsTreatedAsExpired ( { ... mockCreds , expiration } ) ) . toEqual ( true ) ;
149
138
} ) ;
150
139
151
140
it ( "returns true if expiration is defined, and creds expire in <5 mins" , ( ) => {
152
- const memoizeExpiredFn = ( memoize as jest . Mock ) . mock . calls [ 0 ] [ 1 ] ;
153
141
const expiration = new Date ( mockDateNow + 299 * 1000 ) ;
154
- expect ( memoizeExpiredFn ( { expiration } ) ) . toEqual ( true ) ;
142
+ expect ( credentialsTreatedAsExpired ( { ... mockCreds , expiration } ) ) . toEqual ( true ) ;
155
143
} ) ;
156
144
157
145
it ( "returns false if expiration is defined, but creds expire in >5 mins" , ( ) => {
158
- const memoizeExpiredFn = ( memoize as jest . Mock ) . mock . calls [ 0 ] [ 1 ] ;
159
146
const expiration = new Date ( mockDateNow + 301 * 1000 ) ;
160
- expect ( memoizeExpiredFn ( { expiration } ) ) . toEqual ( false ) ;
147
+ expect ( credentialsTreatedAsExpired ( { ... mockCreds , expiration } ) ) . toEqual ( false ) ;
161
148
} ) ;
162
149
163
150
it ( "returns false if expiration is not defined" , ( ) => {
164
- const memoizeExpiredFn = ( memoize as jest . Mock ) . mock . calls [ 0 ] [ 1 ] ;
165
- expect ( memoizeExpiredFn ( { } ) ) . toEqual ( false ) ;
151
+ expect ( credentialsTreatedAsExpired ( { ...mockCreds } ) ) . toEqual ( false ) ;
166
152
} ) ;
167
153
} ) ;
168
154
169
- describe ( "memoize requiresRefresh" , ( ) => {
170
- beforeEach ( async ( ) => {
171
- await defaultProvider ( mockInit ) ( ) ;
172
- } ) ;
173
-
155
+ describe ( credentialsWillNeedRefresh . name , ( ) => {
174
156
it ( "returns true if expiration is not defined" , ( ) => {
175
- const memoizeRefreshFn = ( memoize as jest . Mock ) . mock . calls [ 0 ] [ 2 ] ;
176
- const expiration = Date . now ( ) ;
177
- expect ( memoizeRefreshFn ( { expiration } ) ) . toEqual ( true ) ;
157
+ const expiration = new Date ( ) ;
158
+ expect ( credentialsWillNeedRefresh ( { ...mockCreds , expiration } ) ) . toEqual ( true ) ;
178
159
} ) ;
179
160
180
161
it ( "returns false if expiration is not defined" , ( ) => {
181
- const memoizeRefreshFn = ( memoize as jest . Mock ) . mock . calls [ 0 ] [ 2 ] ;
182
- expect ( memoizeRefreshFn ( { } ) ) . toEqual ( false ) ;
162
+ expect ( credentialsWillNeedRefresh ( { ...mockCreds } ) ) . toEqual ( false ) ;
183
163
} ) ;
184
164
} ) ;
185
165
} ) ;
0 commit comments