Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1728)

Delta Between Two Patch Sets: Src/GoogleApis.Auth.Tests/OAuth2/AuthorizationCodeFlowTests.cs

Issue 13972043: Issue 351: Reimplement OAuth2 (Step 3 - Tests, Flows and Credential) (Closed) Base URL: https://google-api-dotnet-client.googlecode.com/hg/
Left Patch Set: Created 10 years, 10 months ago
Right Patch Set: minor Created 10 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 /* 1 /*
2 Copyright 2013 Google Inc 2 Copyright 2013 Google Inc
3 3
4 Licensed under the Apache License, Version 2.0 (the "License"); 4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License. 5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at 6 You may obtain a copy of the License at
7 7
8 http://www.apache.org/licenses/LICENSE-2.0 8 http://www.apache.org/licenses/LICENSE-2.0
9 9
10 Unless required by applicable law or agreed to in writing, software 10 Unless required by applicable law or agreed to in writing, software
(...skipping 30 matching lines...) Expand all
41 public class AuthorizationCodeFlowTests 41 public class AuthorizationCodeFlowTests
42 { 42 {
43 private const string TokenUrl = "https://token.com"; 43 private const string TokenUrl = "https://token.com";
44 private const string AuthorizationCodeUrl = "https://authorization.com"; 44 private const string AuthorizationCodeUrl = "https://authorization.com";
45 45
46 #region Constructor 46 #region Constructor
47 47
48 [Test] 48 [Test]
49 public void TestConstructor_ArgumentException() 49 public void TestConstructor_ArgumentException()
50 { 50 {
51 // ClientSecrets are missing 51 // ClientSecrets are missing.
52 try 52 try
53 { 53 {
54 new AuthorizationCodeFlow(new AuthorizationCodeFlow.Initializer( 54 new AuthorizationCodeFlow(new AuthorizationCodeFlow.Initializer(
55 "https://authorization_code.com", "https://token.com")); 55 "https://authorization_code.com", "https://token.com"));
56 Assert.Fail(); 56 Assert.Fail();
57 } 57 }
58 catch (ArgumentException ex) 58 catch (ArgumentException ex)
59 { 59 {
60 Assert.True(ex.Message.Contains("client secret or client secret stream MUST be set"), 60 Assert.True(ex.Message.Contains("You MUST set ClientSecret or Cl ientSecretStream"));
61 "User MUST specify client secrets!");
62 } 61 }
63 } 62 }
64 63
65 [Test] 64 [Test]
66 public void TestConstructor_DefaultValues() 65 public void TestConstructor_DefaultValues()
67 { 66 {
68 var flow = CreateFlow(); 67 var flow = CreateFlow();
69 Assert.NotNull(flow.AccessMethod); 68 Assert.NotNull(flow.AccessMethod);
70 Assert.That(flow.AccessMethod, Is.InstanceOf<BearerToken.Authorizati onHeaderAccessMethod>()); 69 Assert.That(flow.AccessMethod, Is.InstanceOf<BearerToken.Authorizati onHeaderAccessMethod>());
71 Assert.That(flow.AuthorizationServerUrl, Is.EqualTo("https://authori zation.com")); 70 Assert.That(flow.AuthorizationServerUrl, Is.EqualTo("https://authori zation.com"));
72 Assert.NotNull(flow.ClientSecrets); 71 Assert.NotNull(flow.ClientSecrets);
73 Assert.That(flow.ClientSecrets.ClientId, Is.EqualTo("id")); 72 Assert.That(flow.ClientSecrets.ClientId, Is.EqualTo("id"));
74 Assert.That(flow.ClientSecrets.ClientSecret, Is.EqualTo("secret")); 73 Assert.That(flow.ClientSecrets.ClientSecret, Is.EqualTo("secret"));
75 Assert.That(flow.Clock, Is.InstanceOf<SystemClock>()); 74 Assert.That(flow.Clock, Is.InstanceOf<SystemClock>());
76 Assert.Null(flow.DataStore); 75 Assert.Null(flow.DataStore);
77 Assert.NotNull(flow.HttpClient); 76 Assert.NotNull(flow.HttpClient);
78 Assert.NotNull(flow.Scopes); 77 Assert.NotNull(flow.Scopes);
79 Assert.That(flow.TokenServerEncodedUrl, Is.EqualTo("https://token.co m")); 78 Assert.That(flow.TokenServerUrl, Is.EqualTo("https://token.com"));
80 79
81 Assert.That(flow.HttpClient.MessageHandler.UnsuccessfulResponseHandl ers.Count(), Is.EqualTo(1)); 80 Assert.That(flow.HttpClient.MessageHandler.UnsuccessfulResponseHandl ers.Count(), Is.EqualTo(1));
82 Assert.That(flow.HttpClient.MessageHandler.UnsuccessfulResponseHandl ers.First(), 81 Assert.That(flow.HttpClient.MessageHandler.UnsuccessfulResponseHandl ers.First(),
83 Is.InstanceOf<BackOffHandler>()); 82 Is.InstanceOf<BackOffHandler>());
84 } 83 }
85 84
86 #endregion 85 #endregion
87 86
88 #region LoadToken 87 #region LoadToken
89 88
90 [Test] 89 [Test]
91 public void LoadToken_NoDataStore() 90 public void LoadTokenAsync_NoDataStore()
92 { 91 {
93 var flow = CreateFlow(); 92 var flow = CreateFlow();
94 Assert.Null(flow.LoadToken("user", CancellationToken.None).Result); 93 Assert.Null(flow.LoadTokenAsync("user", CancellationToken.None).Resu lt);
95 } 94 }
96 95
97 [Test] 96 [Test]
98 public void LoadToken_NullResponse() 97 public void LoadTokenAsync_NullResponse()
99 { 98 {
100 TaskCompletionSource<TokenResponse> tcs = new TaskCompletionSource<T okenResponse>(); 99 TaskCompletionSource<TokenResponse> tcs = new TaskCompletionSource<T okenResponse>();
101 tcs.SetResult(null); 100 tcs.SetResult(null);
102 Assert.Null(SubtestLoadToken(tcs)); 101 Assert.Null(SubtestLoadTokenAsync(tcs));
103 } 102 }
104 103
105 [Test] 104 [Test]
106 public void LoadToken_TokenResponse() 105 public void LoadTokenAsync_TokenResponse()
107 { 106 {
108 TokenResponse response = new TokenResponse 107 TokenResponse response = new TokenResponse
109 { 108 {
110 AccessToken = "access" 109 AccessToken = "access"
111 }; 110 };
112 111
113 TaskCompletionSource<TokenResponse> tcs = new TaskCompletionSource<T okenResponse>(); 112 TaskCompletionSource<TokenResponse> tcs = new TaskCompletionSource<T okenResponse>();
114 tcs.SetResult(response); 113 tcs.SetResult(response);
115 var result = SubtestLoadToken(tcs); 114 var result = SubtestLoadTokenAsync(tcs);
116 Assert.That(result, Is.EqualTo(response)); 115 Assert.That(result, Is.EqualTo(response));
117 } 116 }
118 117
119 private TokenResponse SubtestLoadToken(TaskCompletionSource<TokenRespons e> tcs) 118 private TokenResponse SubtestLoadTokenAsync(TaskCompletionSource<TokenRe sponse> tcs)
120 { 119 {
121 var mock = new Mock<IDataStore>(); 120 var mock = new Mock<IDataStore>();
122 mock.Setup(ds => ds.Get<TokenResponse>("user")).Returns(tcs.Task); 121 mock.Setup(ds => ds.GetAsync<TokenResponse>("user")).Returns(tcs.Tas k);
123 var flow = CreateFlow(dataStore: mock.Object); 122 var flow = CreateFlow(dataStore: mock.Object);
124 var result = flow.LoadToken("user", CancellationToken.None).Result; 123 var result = flow.LoadTokenAsync("user", CancellationToken.None).Res ult;
125 // Verify that Get("user") was called. 124 mock.Verify(ds => ds.GetAsync<TokenResponse>("user"));
126 mock.Verify(ds => ds.Get<TokenResponse>("user"));
127 return result; 125 return result;
128 } 126 }
129 127
130 #endregion 128 #endregion
131 129
132 #region CreateAuthorizationCodeRequest 130 #region CreateAuthorizationCodeRequest
133 131
134 [Test] 132 [Test]
135 public void TestCreateAuthorizationCodeRequest() 133 public void TestCreateAuthorizationCodeRequest()
136 { 134 {
137 var request = CreateFlow(scopes: new[] { "a", "b" }).CreateAuthoriza tionCodeRequest("redirect"); 135 var request = CreateFlow(scopes: new[] { "a", "b" }).CreateAuthoriza tionCodeRequest("redirect");
138 Assert.That(request.AuthorizationServerUrl, Is.EqualTo(new Uri(Autho rizationCodeUrl))); 136 Assert.That(request.AuthorizationServerUrl, Is.EqualTo(new Uri(Autho rizationCodeUrl)));
139 Assert.That(request.ClientId, Is.EqualTo("id")); 137 Assert.That(request.ClientId, Is.EqualTo("id"));
140 Assert.That(request.RedirectUri, Is.EqualTo("redirect")); 138 Assert.That(request.RedirectUri, Is.EqualTo("redirect"));
141 Assert.That(request.ResponseType, Is.EqualTo("code")); 139 Assert.That(request.ResponseType, Is.EqualTo("code"));
142 Assert.That(request.Scope, Is.EqualTo("a b")); 140 Assert.That(request.Scope, Is.EqualTo("a b"));
143 Assert.Null(request.State); 141 Assert.Null(request.State);
144 } 142 }
145 143
146 #endregion 144 #endregion
147 145
148 [Test] 146 [Test]
149 public void TestExchangeCodeForToken() 147 public void TestExchangeCodeForTokenAsync()
150 { 148 {
151 var mock = new Mock<IDataStore>(); 149 var mock = new Mock<IDataStore>();
152 var handler = new FetchTokenMessageHandler(); 150 var handler = new FetchTokenMessageHandler();
153 handler.AuthorizationCodeTokenRequest = new AuthorizationCodeTokenRe quest() 151 handler.AuthorizationCodeTokenRequest = new AuthorizationCodeTokenRe quest()
154 { 152 {
155 Code = "c0de", 153 Code = "c0de",
156 RedirectUri = "redIrect", 154 RedirectUri = "redIrect",
157 Scope = "a" 155 Scope = "a"
158 }; 156 };
159 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r); 157 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r);
160 158
161 TaskCompletionSource<object> tcs = new TaskCompletionSource<object>( ); 159 TaskCompletionSource<object> tcs = new TaskCompletionSource<object>( );
162 tcs.SetResult(null); 160 tcs.SetResult(null);
163 mock.Setup(ds => ds.Store("uSer", It.IsAny<TokenResponse>())).Return s(tcs.Task); 161 mock.Setup(ds => ds.StoreAsync("uSer", It.IsAny<TokenResponse>())).R eturns(tcs.Task);
164 162
165 var flow = CreateFlow(httpClientFactory: mockFactory, scopes: new[] { "a" }, dataStore: mock.Object); 163 var flow = CreateFlow(httpClientFactory: mockFactory, scopes: new[] { "a" }, dataStore: mock.Object);
166 var response = flow.ExchangeCodeForToken("uSer", "c0de", "redIrect", CancellationToken.None).Result; 164 var response = flow.ExchangeCodeForTokenAsync("uSer", "c0de", "redIr ect", CancellationToken.None).Result;
167 SubtestTokenResponse(response); 165 SubtestTokenResponse(response);
168 166
169 mock.Verify(ds => ds.Store("uSer", It.IsAny<TokenResponse>())); 167 mock.Verify(ds => ds.StoreAsync("uSer", It.IsAny<TokenResponse>()));
170 } 168 }
171 169
172 [Test] 170 [Test]
173 public void TestRefreshToken() 171 public void TestRefreshTokenAsync()
174 { 172 {
175 var mock = new Mock<IDataStore>(); 173 var mock = new Mock<IDataStore>();
176 var handler = new FetchTokenMessageHandler(); 174 var handler = new FetchTokenMessageHandler();
177 handler.RefreshTokenRequest = new RefreshTokenRequest() 175 handler.RefreshTokenRequest = new RefreshTokenRequest()
178 { 176 {
179 RefreshToken = "REFRESH", 177 RefreshToken = "REFRESH",
180 Scope = "a" 178 Scope = "a"
181 }; 179 };
182 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r); 180 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r);
183 181
184 TaskCompletionSource<object> tcs = new TaskCompletionSource<object>( ); 182 TaskCompletionSource<object> tcs = new TaskCompletionSource<object>( );
185 tcs.SetResult(null); 183 tcs.SetResult(null);
186 mock.Setup(ds => ds.Store("uSer", It.IsAny<TokenResponse>())).Return s(tcs.Task); 184 mock.Setup(ds => ds.StoreAsync("uSer", It.IsAny<TokenResponse>())).R eturns(tcs.Task);
187 185
188 var flow = CreateFlow(httpClientFactory: mockFactory, scopes: new[] { "a" }, dataStore: mock.Object); 186 var flow = CreateFlow(httpClientFactory: mockFactory, scopes: new[] { "a" }, dataStore: mock.Object);
189 var response = flow.RefreshToken("uSer", "REFRESH", CancellationToke n.None).Result; 187 var response = flow.RefreshTokenAsync("uSer", "REFRESH", Cancellatio nToken.None).Result;
190 SubtestTokenResponse(response); 188 SubtestTokenResponse(response);
191 189
192 190
193 mock.Verify(ds => ds.Store("uSer", It.IsAny<TokenResponse>())); 191 mock.Verify(ds => ds.StoreAsync("uSer", It.IsAny<TokenResponse>()));
194 } 192 }
195 193
196 #region FetchToken 194 #region FetchToken
197 195
196 /// <summary>
197 /// Fetch token message handler, which expects an authorization code tok en request or a refresh token request.
198 /// It verifies all the query parameters are valid and return an error r esponse in case <see cref="Error"/>·
199 /// is <c>true</c>.
200 /// </summary>
198 public class FetchTokenMessageHandler : CountableMessageHandler 201 public class FetchTokenMessageHandler : CountableMessageHandler
199 { 202 {
200 internal AuthorizationCodeTokenRequest AuthorizationCodeTokenRequest { get; set; } 203 internal AuthorizationCodeTokenRequest AuthorizationCodeTokenRequest { get; set; }
201 internal RefreshTokenRequest RefreshTokenRequest { get; set; } 204 internal RefreshTokenRequest RefreshTokenRequest { get; set; }
202 internal bool Error { get; set; } 205 internal bool Error { get; set; }
203 206
204 protected override async Task<HttpResponseMessage> SendAsyncCore(Htt pRequestMessage request, 207 protected override async Task<HttpResponseMessage> SendAsyncCore(Htt pRequestMessage request,
205 CancellationToken taskCancellationToken) 208 CancellationToken taskCancellationToken)
206 { 209 {
207 Assert.That(request.RequestUri, Is.EqualTo(new Uri(TokenUrl))); 210 Assert.That(request.RequestUri, Is.EqualTo(new Uri(TokenUrl)));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 Scope = "b", 293 Scope = "b",
291 }); 294 });
292 response.Content = new StringContent(serializedObject, Encod ing.UTF8); 295 response.Content = new StringContent(serializedObject, Encod ing.UTF8);
293 } 296 }
294 297
295 return response; 298 return response;
296 } 299 }
297 } 300 }
298 301
299 [Test] 302 [Test]
300 public void TestFetchToken_AuthorizationCodeRequest() 303 public void TestFetchTokenAsync_AuthorizationCodeRequest()
301 { 304 {
302 var handler = new FetchTokenMessageHandler(); 305 var handler = new FetchTokenMessageHandler();
303 handler.AuthorizationCodeTokenRequest = new AuthorizationCodeTokenRe quest() 306 handler.AuthorizationCodeTokenRequest = new AuthorizationCodeTokenRe quest()
304 { 307 {
305 Code = "c0de", 308 Code = "c0de",
306 RedirectUri = "redIrect", 309 RedirectUri = "redIrect",
307 Scope = "a" 310 Scope = "a"
308 }; 311 };
309 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r); 312 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r);
310 313
311 var flow = CreateFlow(httpClientFactory: mockFactory); 314 var flow = CreateFlow(httpClientFactory: mockFactory);
312 var response = flow.FetchToken("user", handler.AuthorizationCodeToke nRequest, 315 var response = flow.FetchTokenAsync("user", handler.AuthorizationCod eTokenRequest,
313 CancellationToken.None).Result; 316 CancellationToken.None).Result;
314 SubtestTokenResponse(response); 317 SubtestTokenResponse(response);
315 } 318 }
316 319
317 [Test] 320 [Test]
318 public void TestFetchToken_RefreshTokenRequest() 321 public void TestFetchTokenAsync_RefreshTokenRequest()
319 { 322 {
320 var handler = new FetchTokenMessageHandler(); 323 var handler = new FetchTokenMessageHandler();
321 handler.RefreshTokenRequest = new RefreshTokenRequest() 324 handler.RefreshTokenRequest = new RefreshTokenRequest()
322 { 325 {
323 RefreshToken = "REFRESH", 326 RefreshToken = "REFRESH",
324 Scope = "a" 327 Scope = "a"
325 }; 328 };
326 329
327 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r); 330 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r);
328 331
329 var flow = CreateFlow(httpClientFactory: mockFactory); 332 var flow = CreateFlow(httpClientFactory: mockFactory);
330 var response = flow.FetchToken("user", handler.RefreshTokenRequest, CancellationToken.None).Result; 333 var response = flow.FetchTokenAsync("user", handler.RefreshTokenRequ est, CancellationToken.None).Result;
331 SubtestTokenResponse(response); 334 SubtestTokenResponse(response);
332 } 335 }
333 336
334 [Test] 337 [Test]
335 public void TestFetchToken_AuthorizationCodeRequest_Error() 338 public void TestFetchTokenAsync_AuthorizationCodeRequest_Error()
336 { 339 {
337 var handler = new FetchTokenMessageHandler(); 340 var handler = new FetchTokenMessageHandler();
338 handler.AuthorizationCodeTokenRequest = new AuthorizationCodeTokenRe quest() 341 handler.AuthorizationCodeTokenRequest = new AuthorizationCodeTokenRe quest()
339 { 342 {
340 Code = "c0de", 343 Code = "c0de",
341 RedirectUri = "redIrect", 344 RedirectUri = "redIrect",
342 Scope = "a" 345 Scope = "a"
343 }; 346 };
344 handler.Error = true; 347 handler.Error = true;
345 SubtestFetchToken_Error(handler); 348 SubtestFetchTokenAsync_Error(handler);
346 } 349 }
347 350
348 [Test] 351 [Test]
349 public void TestFetchToken_RefreshTokenRequest_Error() 352 public void TestFetchTokenAsync_RefreshTokenRequest_Error()
350 { 353 {
351 var handler = new FetchTokenMessageHandler(); 354 var handler = new FetchTokenMessageHandler();
352 handler.RefreshTokenRequest = new RefreshTokenRequest() 355 handler.RefreshTokenRequest = new RefreshTokenRequest()
353 { 356 {
354 RefreshToken = "REFRESH", 357 RefreshToken = "REFRESH",
355 Scope = "a" 358 Scope = "a"
356 }; 359 };
357 handler.Error = true; 360 handler.Error = true;
358 SubtestFetchToken_Error(handler); 361 SubtestFetchTokenAsync_Error(handler);
359 } 362 }
360 363
361 private void SubtestFetchToken_Error(FetchTokenMessageHandler handler) 364 /// <summary>Subtest for receiving an error token response.</summary>
365 /// <param name="handler">The message handler.</param>
366 private void SubtestFetchTokenAsync_Error(FetchTokenMessageHandler handl er)
362 { 367 {
363 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r); 368 MockHttpClientFactory mockFactory = new MockHttpClientFactory(handle r);
364 var flow = CreateFlow(httpClientFactory: mockFactory); 369 var flow = CreateFlow(httpClientFactory: mockFactory);
365 try 370 try
366 { 371 {
367 var request = 372 var request =
368 (TokenRequest)handler.AuthorizationCodeTokenRequest ?? (Toke nRequest)handler.RefreshTokenRequest; 373 (TokenRequest)handler.AuthorizationCodeTokenRequest ?? (Toke nRequest)handler.RefreshTokenRequest;
369 var result = flow.FetchToken("user", request, CancellationToken. None).Result; 374 var result = flow.FetchTokenAsync("user", request, CancellationT oken.None).Result;
370 Assert.Fail(); 375 Assert.Fail();
371 } 376 }
372 catch (AggregateException aex) 377 catch (AggregateException aex)
373 { 378 {
374 var ex = aex.InnerException as TokenResponseException; 379 var ex = aex.InnerException as TokenResponseException;
375 Assert.IsNotNull(ex); 380 Assert.IsNotNull(ex);
376 var result = ex.Error; 381 var result = ex.Error;
377 Assert.That(result.Error, Is.EqualTo("error")); 382 Assert.That(result.Error, Is.EqualTo("error"));
378 Assert.That(result.ErrorDescription, Is.EqualTo("desc")); 383 Assert.That(result.ErrorDescription, Is.EqualTo("desc"));
379 Assert.That(result.ErrorUri, Is.EqualTo("uri")); 384 Assert.That(result.ErrorUri, Is.EqualTo("uri"));
380 } 385 }
381 } 386 }
382 387
383 #endregion 388 #endregion
384 389
385 /// <summary>Creates an authorization code flow with the given parameter s.</summary> 390 /// <summary>Creates an authorization code flow with the given parameter s.</summary>
386 /// <param name="dataStore">The data store.</param> 391 /// <param name="dataStore">The data store.</param>
387 /// <param name="scopes">The Scopes</param> 392 /// <param name="scopes">The Scopes.</param>
388 /// <param name="httpClientFactory">The HTTP client factory. If not set the default will be used</param> 393 /// <param name="httpClientFactory">The HTTP client factory. If not set the default will be used.</param>
389 /// <returns>Authorization code flow</returns> 394 /// <returns>Authorization code flow</returns>
390 private AuthorizationCodeFlow CreateFlow(IDataStore dataStore = null, IE numerable<string> scopes = null, 395 private AuthorizationCodeFlow CreateFlow(IDataStore dataStore = null, IE numerable<string> scopes = null,
391 IHttpClientFactory httpClientFactory = null) 396 IHttpClientFactory httpClientFactory = null)
392 { 397 {
393 var secrets = new ClientSecrets() { ClientId = "id", ClientSecret = "secret" }; 398 var secrets = new ClientSecrets() { ClientId = "id", ClientSecret = "secret" };
394 var initializer = new AuthorizationCodeFlow.Initializer(Authorizatio nCodeUrl, TokenUrl) 399 var initializer = new AuthorizationCodeFlow.Initializer(Authorizatio nCodeUrl, TokenUrl)
395 { 400 {
396 ClientSecrets = secrets, 401 ClientSecrets = secrets,
397 HttpClientFactory = httpClientFactory 402 HttpClientFactory = httpClientFactory
398 }; 403 };
(...skipping 12 matching lines...) Expand all
411 /// <summary>Verifies that the token response contains the expected data .</summary> 416 /// <summary>Verifies that the token response contains the expected data .</summary>
412 /// <param name="response">The token response</param> 417 /// <param name="response">The token response</param>
413 private void SubtestTokenResponse(TokenResponse response) 418 private void SubtestTokenResponse(TokenResponse response)
414 { 419 {
415 Assert.That(response.RefreshToken, Is.EqualTo("r")); 420 Assert.That(response.RefreshToken, Is.EqualTo("r"));
416 Assert.That(response.ExpiresInSeconds, Is.EqualTo(100)); 421 Assert.That(response.ExpiresInSeconds, Is.EqualTo(100));
417 Assert.That(response.Scope, Is.EqualTo("b")); 422 Assert.That(response.Scope, Is.EqualTo("b"));
418 } 423 }
419 } 424 }
420 } 425 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b