Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc

Issue 16173008: Reland 203015 "Add ManagedUserTokenFetcher to fetch scoped-down ..." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop.h"
8 #include "base/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
11 #include "chrome/browser/signin/oauth2_token_service.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "content/public/test/test_browser_thread.h"
14 #include "google_apis/gaia/gaia_urls.h"
15 #include "google_apis/gaia/google_service_auth_error.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/url_util.h"
18 #include "net/http/http_request_headers.h"
19 #include "net/http/http_status_code.h"
20 #include "net/url_request/test_url_fetcher_factory.h"
21 #include "net/url_request/url_fetcher_delegate.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace {
25
26 const char kManagedUserId[] = "abcdef";
27 const char kName[] = "Homestar";
28 const char kDeviceName[] = "Compy";
29
30 const char kAccessToken[] = "accesstoken";
31 const char kAuthorizationCode[] = "authorizationcode";
32 const char kManagedUserToken[] = "managedusertoken";
33
34 const char kIssueTokenResponseFormat[] =
35 "{"
36 " \"code\": \"%s\""
37 "}";
38
39 const char kGetRefreshTokenResponseFormat[] =
40 "{"
41 " \"access_token\": \"<ignored>\","
42 " \"expires_in\": 12345,"
43 " \"refresh_token\": \"%s\""
44 "}";
45
46 // MockOAuth2TokenService ---------------------------------------------
47
48 class MockOAuth2TokenService : public OAuth2TokenService {
49 public:
50 class Request : public OAuth2TokenService::Request {
51 public:
52 Request(const OAuth2TokenService::ScopeSet& scopes,
53 OAuth2TokenService::Consumer* consumer,
54 MockOAuth2TokenService* owner);
55 virtual ~Request();
56
57 void Succeed();
58 void Fail(GoogleServiceAuthError::State error);
59
60 const OAuth2TokenService::ScopeSet& scopes() const { return scopes_; }
61
62 private:
63 OAuth2TokenService::ScopeSet scopes_;
64
65 OAuth2TokenService::Consumer* consumer_;
66
67 MockOAuth2TokenService* owner_;
68 };
69
70 MockOAuth2TokenService();
71 virtual ~MockOAuth2TokenService();
72
73 Request* request() const { return request_; }
74
75 void ClearRequest(Request* request);
76
77 private:
78 // OAuth2TokenService overrides:
79 virtual scoped_ptr<OAuth2TokenService::Request> StartRequest(
80 const OAuth2TokenService::ScopeSet& scopes,
81 OAuth2TokenService::Consumer* consumer) OVERRIDE;
82 virtual std::string GetRefreshToken() OVERRIDE;
83
84 Request* request_;
85
86 DISALLOW_COPY_AND_ASSIGN(MockOAuth2TokenService);
87 };
88
89 MockOAuth2TokenService::Request::Request(
90 const OAuth2TokenService::ScopeSet& scopes,
91 OAuth2TokenService::Consumer* consumer,
92 MockOAuth2TokenService* owner)
93 : scopes_(scopes),
94 consumer_(consumer),
95 owner_(owner) {}
96
97 MockOAuth2TokenService::Request::~Request() {
98 owner_->ClearRequest(this);
99 }
100
101 void MockOAuth2TokenService::Request::Succeed() {
102 base::Time expiration_date = base::Time::Now() +
103 base::TimeDelta::FromHours(1);
104 consumer_->OnGetTokenSuccess(this, kAccessToken, expiration_date);
105 }
106
107 void MockOAuth2TokenService::Request::Fail(
108 GoogleServiceAuthError::State error) {
109 consumer_->OnGetTokenFailure(this, GoogleServiceAuthError(error));
110 }
111
112 MockOAuth2TokenService::MockOAuth2TokenService()
113 : OAuth2TokenService(NULL),
114 request_(NULL) {}
115
116 MockOAuth2TokenService::~MockOAuth2TokenService() {
117 EXPECT_FALSE(request_);
118 }
119
120 void MockOAuth2TokenService::ClearRequest(
121 MockOAuth2TokenService::Request* request) {
122 if (request_ == request)
123 request_ = NULL;
124 }
125
126 scoped_ptr<OAuth2TokenService::Request> MockOAuth2TokenService::StartRequest(
127 const OAuth2TokenService::ScopeSet& scopes,
128 OAuth2TokenService::Consumer* consumer) {
129 scoped_ptr<Request> request(new Request(scopes, consumer, this));
130 request_ = request.get();
131 return request.PassAs<OAuth2TokenService::Request>();
132 }
133
134 std::string MockOAuth2TokenService::GetRefreshToken() {
135 NOTREACHED();
136 return std::string();
137 }
138
139 // Utility methods --------------------------------------------------
140
141 // Slightly hacky way to extract a value from a URL-encoded POST request body.
142 bool GetValueForKey(const std::string& encoded_string,
143 const std::string& key,
144 std::string* value) {
145 GURL url("http://example.com/?" + encoded_string);
146 return net::GetValueForKeyInQuery(url, key, value);
147 }
148
149 void SendResponse(net::TestURLFetcher* url_fetcher,
150 const std::string& response) {
151 url_fetcher->set_status(
152 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
153 url_fetcher->set_response_code(net::HTTP_OK);
154 url_fetcher->SetResponseString(response);
155 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
156 }
157
158 void SetNetworkError(net::TestURLFetcher* url_fetcher, int error) {
159 url_fetcher->set_status(
160 net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
161 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
162 }
163
164 void SetHttpError(net::TestURLFetcher* url_fetcher, int error) {
165 url_fetcher->set_status(net::URLRequestStatus());
166 url_fetcher->set_response_code(error);
167 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
168 }
169
170 } // namespace
171
172 class ManagedUserRefreshTokenFetcherTest : public testing::Test {
173 public:
174 ManagedUserRefreshTokenFetcherTest();
175 virtual ~ManagedUserRefreshTokenFetcherTest() {}
176
177 protected:
178 void StartFetching();
179
180 MockOAuth2TokenService::Request* GetOAuth2TokenServiceRequest();
181 net::TestURLFetcher* GetIssueTokenRequest();
182 net::TestURLFetcher* GetRefreshTokenRequest();
183
184 void MakeIssueTokenRequestSucceed();
185 void MakeRefreshTokenFetchSucceed();
186
187 void Reset();
188
189 const GoogleServiceAuthError& error() const { return error_; }
190 const std::string& token() const { return token_; }
191
192 private:
193 void OnTokenFetched(const GoogleServiceAuthError& error,
194 const std::string& token);
195
196 base::WeakPtrFactory<ManagedUserRefreshTokenFetcherTest> weak_ptr_factory_;
197 base::MessageLoop message_loop_;
198 content::TestBrowserThread ui_thread_;
199 TestingProfile profile_;
200 MockOAuth2TokenService oauth2_token_service_;
201 net::TestURLFetcherFactory url_fetcher_factory_;
202 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;
203
204 GoogleServiceAuthError error_;
205 std::string token_;
206 };
207
208 ManagedUserRefreshTokenFetcherTest::ManagedUserRefreshTokenFetcherTest()
209 : weak_ptr_factory_(this),
210 ui_thread_(content::BrowserThread::UI, &message_loop_),
211 token_fetcher_(
212 ManagedUserRefreshTokenFetcher::Create(&oauth2_token_service_,
213 profile_.GetRequestContext())),
214 error_(GoogleServiceAuthError::NONE) {}
215
216 void ManagedUserRefreshTokenFetcherTest::StartFetching() {
217 token_fetcher_->Start(kManagedUserId, UTF8ToUTF16(kName), kDeviceName,
218 base::Bind(
219 &ManagedUserRefreshTokenFetcherTest::OnTokenFetched,
220 weak_ptr_factory_.GetWeakPtr()));
221 }
222
223 MockOAuth2TokenService::Request*
224 ManagedUserRefreshTokenFetcherTest::GetOAuth2TokenServiceRequest() {
225 MockOAuth2TokenService::Request* request = oauth2_token_service_.request();
226
227 OAuth2TokenService::ScopeSet scopes = request->scopes();
228 EXPECT_EQ(1u, scopes.size());
229 EXPECT_EQ(1u, scopes.count(GaiaUrls::GetInstance()->oauth1_login_scope()));
230 return request;
231 }
232
233 net::TestURLFetcher*
234 ManagedUserRefreshTokenFetcherTest::GetIssueTokenRequest() {
235 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(1);
236 if (!url_fetcher)
237 return NULL;
238
239 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_issue_token_url(),
240 url_fetcher->GetOriginalURL().spec());
241 std::string access_token;
242 net::HttpRequestHeaders headers;
243 url_fetcher->GetExtraRequestHeaders(&headers);
244 EXPECT_TRUE(headers.GetHeader("Authorization", &access_token));
245 EXPECT_EQ(std::string("Bearer ") + kAccessToken, access_token);
246 const std::string upload_data = url_fetcher->upload_data();
247 std::string managed_user_id;
248 EXPECT_TRUE(GetValueForKey(upload_data, "profile_id", &managed_user_id));
249 EXPECT_EQ(kManagedUserId, managed_user_id);
250 std::string name;
251 EXPECT_TRUE(GetValueForKey(upload_data, "profile_name", &name));
252 EXPECT_EQ(kName, name);
253 std::string device_name;
254 EXPECT_TRUE(GetValueForKey(upload_data, "device_name", &device_name));
255 EXPECT_EQ(kDeviceName, device_name);
256 return url_fetcher;
257 }
258
259 net::TestURLFetcher*
260 ManagedUserRefreshTokenFetcherTest::GetRefreshTokenRequest() {
261 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(0);
262 if (!url_fetcher)
263 return NULL;
264
265 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_token_url(),
266 url_fetcher->GetOriginalURL().spec());
267 std::string auth_code;
268 EXPECT_TRUE(GetValueForKey(url_fetcher->upload_data(), "code", &auth_code));
269 EXPECT_EQ(kAuthorizationCode, auth_code);
270 return url_fetcher;
271 }
272
273 void ManagedUserRefreshTokenFetcherTest::MakeIssueTokenRequestSucceed() {
274 SendResponse(GetIssueTokenRequest(),
275 base::StringPrintf(kIssueTokenResponseFormat,
276 kAuthorizationCode));
277 }
278
279 void ManagedUserRefreshTokenFetcherTest::MakeRefreshTokenFetchSucceed() {
280 SendResponse(GetRefreshTokenRequest(),
281 base::StringPrintf(kGetRefreshTokenResponseFormat,
282 kManagedUserToken));
283 }
284
285 void ManagedUserRefreshTokenFetcherTest::Reset() {
286 token_fetcher_.reset();
287 }
288
289 void ManagedUserRefreshTokenFetcherTest::OnTokenFetched(
290 const GoogleServiceAuthError& error,
291 const std::string& token) {
292 error_ = error;
293 token_ = token;
294 }
295
296 // Tests --------------------------------------------------------
297
298 TEST_F(ManagedUserRefreshTokenFetcherTest, Success) {
299 StartFetching();
300 GetOAuth2TokenServiceRequest()->Succeed();
301 MakeIssueTokenRequestSucceed();
302 MakeRefreshTokenFetchSucceed();
303
304 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
305 EXPECT_EQ(kManagedUserToken, token());
306 }
307
308 TEST_F(ManagedUserRefreshTokenFetcherTest, ExpiredAccessToken) {
309 StartFetching();
310 GetOAuth2TokenServiceRequest()->Succeed();
311 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
312 GetOAuth2TokenServiceRequest()->Succeed();
313 MakeIssueTokenRequestSucceed();
314 MakeRefreshTokenFetchSucceed();
315
316 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
317 EXPECT_EQ(kManagedUserToken, token());
318 }
319
320 TEST_F(ManagedUserRefreshTokenFetcherTest, ExpiredAccessTokenRetry) {
321 // If we get a 401 error for the second time, we should give up instead of
322 // retrying again.
323 StartFetching();
324 GetOAuth2TokenServiceRequest()->Succeed();
325 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
326 GetOAuth2TokenServiceRequest()->Succeed();
327 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
328
329 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
330 EXPECT_EQ(net::ERR_FAILED, error().network_error());
331 EXPECT_EQ(std::string(), token());
332 }
333
334 TEST_F(ManagedUserRefreshTokenFetcherTest, MalformedIssueTokenResponse) {
335 StartFetching();
336 GetOAuth2TokenServiceRequest()->Succeed();
337 SendResponse(GetIssueTokenRequest(), "choke");
338
339 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
340 EXPECT_EQ(net::ERR_INVALID_RESPONSE, error().network_error());
341 EXPECT_EQ(std::string(), token());
342 }
343
344 TEST_F(ManagedUserRefreshTokenFetcherTest, FetchAccessTokenFailure) {
345 StartFetching();
346 GetOAuth2TokenServiceRequest()->Fail(
347 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
348
349 EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error().state());
350 EXPECT_EQ(std::string(), token());
351 }
352
353 TEST_F(ManagedUserRefreshTokenFetcherTest, IssueTokenNetworkError) {
354 StartFetching();
355 GetOAuth2TokenServiceRequest()->Succeed();
356 SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR);
357
358 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
359 EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, error().network_error());
360 EXPECT_EQ(std::string(), token());
361 }
362
363 TEST_F(ManagedUserRefreshTokenFetcherTest, FetchRefreshTokenNetworkError) {
364 StartFetching();
365 GetOAuth2TokenServiceRequest()->Succeed();
366 MakeIssueTokenRequestSucceed();
367 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
368 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
369 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
370
371 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
372 EXPECT_EQ(net::ERR_FAILED, error().network_error());
373 EXPECT_EQ(std::string(), token());
374 }
375
376 TEST_F(ManagedUserRefreshTokenFetcherTest,
377 FetchRefreshTokenTransientNetworkError) {
378 StartFetching();
379 GetOAuth2TokenServiceRequest()->Succeed();
380 MakeIssueTokenRequestSucceed();
381 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
382
383 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
384 MakeRefreshTokenFetchSucceed();
385
386 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
387 EXPECT_EQ(kManagedUserToken, token());
388 }
389
390 TEST_F(ManagedUserRefreshTokenFetcherTest, FetchRefreshTokenBadRequest) {
391 StartFetching();
392 GetOAuth2TokenServiceRequest()->Succeed();
393 MakeIssueTokenRequestSucceed();
394 SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST);
395
396 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
397 EXPECT_EQ(net::ERR_FAILED, error().network_error());
398 EXPECT_EQ(std::string(), token());
399 }
400
401 TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileFetchingAccessToken) {
402 StartFetching();
403 Reset();
404
405 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
406 EXPECT_EQ(std::string(), token());
407 }
408
409 TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileCallingIssueToken) {
410 StartFetching();
411 GetOAuth2TokenServiceRequest()->Succeed();
412 Reset();
413
414 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
415 EXPECT_EQ(std::string(), token());
416 }
417
418 TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileFetchingRefreshToken) {
419 StartFetching();
420 GetOAuth2TokenServiceRequest()->Succeed();
421 MakeIssueTokenRequestSucceed();
422 Reset();
423
424 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
425 EXPECT_EQ(std::string(), token());
426 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698