@@ -18,6 +18,8 @@ limitations under the License.
18
18
using Google . Apis . Http ;
19
19
using Google . Apis . Tests . Mocks ;
20
20
using System ;
21
+ using System . Collections . Generic ;
22
+ using System . Linq ;
21
23
using System . Threading . Tasks ;
22
24
using Xunit ;
23
25
using static Google . Apis . Auth . JsonWebSignature ;
@@ -153,5 +155,99 @@ public async Task FetchesOidcToken_WithOptions(OidcTokenFormat format, string ta
153
155
154
156
Assert . Equal ( expectedQueryString , messageHandler . LatestRequest . RequestUri . Query ) ;
155
157
}
158
+
159
+ public static IEnumerable < object [ ] > Scoped_WithDefaultTokenUrl_Data
160
+ {
161
+ get
162
+ {
163
+ // explicit scopes, expected token URL
164
+ yield return new object [ ] { null , GoogleAuthConsts . EffectiveComputeTokenUrl } ;
165
+ yield return new object [ ] { new string [ ] { "scope1" , "scope2" } , $ "{ GoogleAuthConsts . EffectiveComputeTokenUrl } ?scopes=scope1,scope2" } ;
166
+ }
167
+ }
168
+
169
+ public static IEnumerable < object [ ] > Scoped_WithCustomTokenUrl_Data
170
+ {
171
+ get
172
+ {
173
+ // explicit scopes, custom token URL, expected token URL
174
+ yield return new object [ ] { null , "https://custom.metadata.server/compute/token" , "https://custom.metadata.server/compute/token" } ;
175
+ yield return new object [ ] { null , "https://custom.metadata.server/compute/token?parameter=value" , "https://custom.metadata.server/compute/token?parameter=value" } ;
176
+ yield return new object [ ] { new string [ ] { "scope1" , "scope2" } , "https://custom.metadata.server/compute/token" , "https://custom.metadata.server/compute/token?scopes=scope1,scope2" } ;
177
+ yield return new object [ ] { new string [ ] { "scope1" , "scope2" } , "https://custom.metadata.server/compute/token?parameter=value" , "https://custom.metadata.server/compute/token?parameter=value&scopes=scope1,scope2" } ;
178
+ }
179
+ }
180
+
181
+ private void AssertScoped ( ComputeCredential credential , string [ ] scopes , string expectedTokenUrl )
182
+ {
183
+ Assert . Collection ( credential . Scopes ?? Enumerable . Empty < string > ( ) ,
184
+ ( scopes ? . Select < string , Action < string > > ( expectedScope => actualScope => Assert . Equal ( expectedScope , actualScope ) ) ?? Enumerable . Empty < Action < string > > ( ) ) . ToArray ( ) ) ;
185
+ Assert . Equal ( expectedTokenUrl , credential . EffectiveTokenServerUrl ) ;
186
+ }
187
+
188
+ private async Task AssertUsesScopedUrl ( ComputeCredential credential , FetchesTokenMessageHandler fakeMessageHandler , string expectedTokenUrl )
189
+ {
190
+ Assert . NotNull ( await credential . GetAccessTokenForRequestAsync ( ) ) ;
191
+ Assert . Equal ( 1 , fakeMessageHandler . Calls ) ;
192
+ Assert . Equal ( expectedTokenUrl , fakeMessageHandler . Requests . First ( ) . RequestUri . AbsoluteUri ) ;
193
+ }
194
+
195
+ [ Theory ]
196
+ [ MemberData ( nameof ( Scoped_WithDefaultTokenUrl_Data ) ) ]
197
+ public async Task Scoped_Initializer_WithDefaultTokenUrl ( string [ ] scopes , string expectedTokenUrl )
198
+ {
199
+ var fakeMessageHandler = new FetchesTokenMessageHandler ( ) ;
200
+ var credential = new ComputeCredential ( new ComputeCredential . Initializer ( )
201
+ {
202
+ Scopes = scopes ,
203
+ HttpClientFactory = new MockHttpClientFactory ( fakeMessageHandler )
204
+ } ) ;
205
+
206
+ AssertScoped ( credential , scopes , expectedTokenUrl ) ;
207
+ await AssertUsesScopedUrl ( credential , fakeMessageHandler , expectedTokenUrl ) ;
208
+ }
209
+
210
+ [ Theory ]
211
+ [ MemberData ( nameof ( Scoped_WithDefaultTokenUrl_Data ) ) ]
212
+ public async Task Scoped_MaybeWithScopes_WithDefaultTokenUrl ( string [ ] scopes , string expectedTokenUrl )
213
+ {
214
+ var fakeMessageHandler = new FetchesTokenMessageHandler ( ) ;
215
+ var credential = ( new ComputeCredential ( new ComputeCredential . Initializer ( )
216
+ {
217
+ HttpClientFactory = new MockHttpClientFactory ( fakeMessageHandler )
218
+ } ) as IGoogleCredential ) . MaybeWithScopes ( scopes ) as ComputeCredential ;
219
+
220
+ AssertScoped ( credential , scopes , expectedTokenUrl ) ;
221
+ await AssertUsesScopedUrl ( credential , fakeMessageHandler , expectedTokenUrl ) ;
222
+ }
223
+
224
+ [ Theory ]
225
+ [ MemberData ( nameof ( Scoped_WithCustomTokenUrl_Data ) ) ]
226
+ public async Task Scoped_Initializer_WithCustomTokenUrl ( string [ ] scopes , string customTokenUrl , string expectedTokenUrl )
227
+ {
228
+ var fakeMessageHandler = new FetchesTokenMessageHandler ( ) ;
229
+ var credential = new ComputeCredential ( new ComputeCredential . Initializer ( customTokenUrl )
230
+ {
231
+ Scopes = scopes ,
232
+ HttpClientFactory = new MockHttpClientFactory ( fakeMessageHandler )
233
+ } ) ;
234
+
235
+ AssertScoped ( credential , scopes , expectedTokenUrl ) ;
236
+ await AssertUsesScopedUrl ( credential , fakeMessageHandler , expectedTokenUrl ) ;
237
+ }
238
+
239
+ [ Theory ]
240
+ [ MemberData ( nameof ( Scoped_WithCustomTokenUrl_Data ) ) ]
241
+ public async Task Scoped_MaybeWithScopes_WithCustomTokenUrl ( string [ ] scopes , string customTokenUrl , string expectedTokenUrl )
242
+ {
243
+ var fakeMessageHandler = new FetchesTokenMessageHandler ( ) ;
244
+ var credential = ( new ComputeCredential ( new ComputeCredential . Initializer ( customTokenUrl )
245
+ {
246
+ HttpClientFactory = new MockHttpClientFactory ( fakeMessageHandler )
247
+ } ) as IGoogleCredential ) . MaybeWithScopes ( scopes ) as ComputeCredential ;
248
+
249
+ AssertScoped ( credential , scopes , expectedTokenUrl ) ;
250
+ await AssertUsesScopedUrl ( credential , fakeMessageHandler , expectedTokenUrl ) ;
251
+ }
156
252
}
157
253
}
0 commit comments