Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / supervised_user / legacy / supervised_user_refresh_token_fetcher_unittest.cc
blobfd1672fd470aaa1a5daf69777a0a079153ca015b
1 // Copyright 2014 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.
5 #include "base/bind.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/strings/stringprintf.h"
8 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
9 #include "chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "content/public/test/test_browser_thread_bundle.h"
12 #include "google_apis/gaia/gaia_constants.h"
13 #include "google_apis/gaia/gaia_oauth_client.h"
14 #include "google_apis/gaia/gaia_urls.h"
15 #include "google_apis/gaia/google_service_auth_error.h"
16 #include "google_apis/gaia/oauth2_token_service.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/url_util.h"
19 #include "net/http/http_request_headers.h"
20 #include "net/http/http_status_code.h"
21 #include "net/url_request/test_url_fetcher_factory.h"
22 #include "net/url_request/url_fetcher_delegate.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace {
27 const char kAccountId[] = "account_id";
28 const char kDeviceId[] = "device_id";
29 const char kDeviceName[] = "Compy";
30 const char kSupervisedUserId[] = "abcdef";
32 const char kAccessToken[] = "accesstoken";
33 const char kAuthorizationCode[] = "authorizationcode";
34 const char kSupervisedUserToken[] = "supervisedusertoken";
35 const char kOAuth2RefreshToken[] = "refreshtoken";
37 const char kIssueTokenResponseFormat[] =
38 "{"
39 " \"code\": \"%s\""
40 "}";
42 const char kGetRefreshTokenResponseFormat[] =
43 "{"
44 " \"access_token\": \"<ignored>\","
45 " \"expires_in\": 12345,"
46 " \"refresh_token\": \"%s\""
47 "}";
49 // Utility methods --------------------------------------------------
51 // Slightly hacky way to extract a value from a URL-encoded POST request body.
52 bool GetValueForKey(const std::string& encoded_string,
53 const std::string& key,
54 std::string* value) {
55 GURL url("http://example.com/?" + encoded_string);
56 return net::GetValueForKeyInQuery(url, key, value);
59 void SendResponse(net::TestURLFetcher* url_fetcher,
60 const std::string& response) {
61 url_fetcher->set_status(
62 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
63 url_fetcher->set_response_code(net::HTTP_OK);
64 url_fetcher->SetResponseString(response);
65 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
68 void SetNetworkError(net::TestURLFetcher* url_fetcher, int error) {
69 url_fetcher->set_status(
70 net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
71 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
74 void SetHttpError(net::TestURLFetcher* url_fetcher, int error) {
75 url_fetcher->set_status(net::URLRequestStatus());
76 url_fetcher->set_response_code(error);
77 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
80 void VerifyTokenRequest(
81 std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests) {
82 ASSERT_EQ(1u, requests.size());
83 EXPECT_EQ(1u, requests[0].scopes.size());
84 EXPECT_EQ(1u, requests[0].scopes.count(GaiaConstants::kOAuth1LoginScope));
87 } // namespace
89 class SupervisedUserRefreshTokenFetcherTest : public testing::Test {
90 public:
91 SupervisedUserRefreshTokenFetcherTest();
92 ~SupervisedUserRefreshTokenFetcherTest() override {}
94 protected:
95 void StartFetching();
96 void StartFetchingWithDeviceId(const std::string& device_id);
98 net::TestURLFetcher* GetIssueTokenRequest();
99 net::TestURLFetcher* GetRefreshTokenRequest();
101 void MakeOAuth2TokenServiceRequestSucceed();
102 void MakeOAuth2TokenServiceRequestFail(GoogleServiceAuthError::State error);
103 void MakeIssueTokenRequestSucceed();
104 void MakeRefreshTokenFetchSucceed();
106 void Reset();
108 const GoogleServiceAuthError& error() const { return error_; }
109 const std::string& token() const { return token_; }
111 private:
112 void OnTokenFetched(const GoogleServiceAuthError& error,
113 const std::string& token);
115 content::TestBrowserThreadBundle thread_bundle_;
116 TestingProfile profile_;
117 FakeProfileOAuth2TokenService oauth2_token_service_;
118 net::TestURLFetcherFactory url_fetcher_factory_;
119 scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher_;
120 std::string device_id_;
122 GoogleServiceAuthError error_;
123 std::string token_;
124 base::WeakPtrFactory<SupervisedUserRefreshTokenFetcherTest> weak_ptr_factory_;
127 SupervisedUserRefreshTokenFetcherTest::SupervisedUserRefreshTokenFetcherTest()
128 : error_(GoogleServiceAuthError::NONE),
129 weak_ptr_factory_(this) {}
131 void SupervisedUserRefreshTokenFetcherTest::StartFetching() {
132 StartFetchingWithDeviceId(std::string());
135 void SupervisedUserRefreshTokenFetcherTest::StartFetchingWithDeviceId(
136 const std::string& device_id) {
137 device_id_ = device_id;
138 oauth2_token_service_.IssueRefreshToken(kOAuth2RefreshToken);
139 token_fetcher_ = SupervisedUserRefreshTokenFetcher::Create(
140 &oauth2_token_service_,
141 kAccountId,
142 device_id_,
143 profile_.GetRequestContext()).Pass();
144 token_fetcher_->Start(
145 kSupervisedUserId,
146 kDeviceName,
147 base::Bind(
148 &SupervisedUserRefreshTokenFetcherTest::OnTokenFetched,
149 weak_ptr_factory_.GetWeakPtr()));
152 net::TestURLFetcher*
153 SupervisedUserRefreshTokenFetcherTest::GetIssueTokenRequest() {
154 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(1);
155 if (!url_fetcher)
156 return NULL;
158 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_issue_token_url(),
159 url_fetcher->GetOriginalURL());
160 std::string access_token;
161 net::HttpRequestHeaders headers;
162 url_fetcher->GetExtraRequestHeaders(&headers);
163 EXPECT_TRUE(headers.GetHeader("Authorization", &access_token));
164 EXPECT_EQ(std::string("Bearer ") + kAccessToken, access_token);
165 const std::string upload_data = url_fetcher->upload_data();
166 std::string supervised_user_id;
167 EXPECT_TRUE(GetValueForKey(upload_data, "profile_id", &supervised_user_id));
168 EXPECT_EQ(kSupervisedUserId, supervised_user_id);
169 std::string device_name;
170 EXPECT_TRUE(GetValueForKey(upload_data, "device_name", &device_name));
171 EXPECT_EQ(kDeviceName, device_name);
172 std::string device_id;
173 EXPECT_EQ(!device_id_.empty(),
174 GetValueForKey(upload_data, "device_id", &device_id));
175 EXPECT_EQ(device_id_, device_id);
176 return url_fetcher;
179 net::TestURLFetcher*
180 SupervisedUserRefreshTokenFetcherTest::GetRefreshTokenRequest() {
181 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(
182 gaia::GaiaOAuthClient::kUrlFetcherId);
183 if (!url_fetcher)
184 return NULL;
186 EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_token_url(),
187 url_fetcher->GetOriginalURL());
188 std::string auth_code;
189 EXPECT_TRUE(GetValueForKey(url_fetcher->upload_data(), "code", &auth_code));
190 EXPECT_EQ(kAuthorizationCode, auth_code);
191 return url_fetcher;
194 void
195 SupervisedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestSucceed() {
196 std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests =
197 oauth2_token_service_.GetPendingRequests();
198 VerifyTokenRequest(requests);
199 base::Time expiration_date = base::Time::Now() +
200 base::TimeDelta::FromHours(1);
201 oauth2_token_service_.IssueTokenForScope(requests[0].scopes,
202 kAccessToken,
203 expiration_date);
206 void
207 SupervisedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestFail(
208 GoogleServiceAuthError::State error) {
209 std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests =
210 oauth2_token_service_.GetPendingRequests();
211 VerifyTokenRequest(requests);
212 oauth2_token_service_.IssueErrorForScope(requests[0].scopes,
213 GoogleServiceAuthError(error));
216 void SupervisedUserRefreshTokenFetcherTest::MakeIssueTokenRequestSucceed() {
217 SendResponse(GetIssueTokenRequest(),
218 base::StringPrintf(kIssueTokenResponseFormat,
219 kAuthorizationCode));
222 void SupervisedUserRefreshTokenFetcherTest::MakeRefreshTokenFetchSucceed() {
223 SendResponse(GetRefreshTokenRequest(),
224 base::StringPrintf(kGetRefreshTokenResponseFormat,
225 kSupervisedUserToken));
228 void SupervisedUserRefreshTokenFetcherTest::Reset() {
229 token_fetcher_.reset();
232 void SupervisedUserRefreshTokenFetcherTest::OnTokenFetched(
233 const GoogleServiceAuthError& error,
234 const std::string& token) {
235 error_ = error;
236 token_ = token;
239 // Tests --------------------------------------------------------
241 TEST_F(SupervisedUserRefreshTokenFetcherTest, Success) {
242 StartFetching();
243 MakeOAuth2TokenServiceRequestSucceed();
244 MakeIssueTokenRequestSucceed();
245 MakeRefreshTokenFetchSucceed();
247 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
248 EXPECT_EQ(kSupervisedUserToken, token());
251 TEST_F(SupervisedUserRefreshTokenFetcherTest, Success_WithDeviceId) {
252 StartFetchingWithDeviceId(kDeviceId);
253 MakeOAuth2TokenServiceRequestSucceed();
254 MakeIssueTokenRequestSucceed();
255 MakeRefreshTokenFetchSucceed();
257 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
258 EXPECT_EQ(kSupervisedUserToken, token());
261 TEST_F(SupervisedUserRefreshTokenFetcherTest, ExpiredAccessToken) {
262 StartFetching();
263 MakeOAuth2TokenServiceRequestSucceed();
264 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
265 MakeOAuth2TokenServiceRequestSucceed();
266 MakeIssueTokenRequestSucceed();
267 MakeRefreshTokenFetchSucceed();
269 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
270 EXPECT_EQ(kSupervisedUserToken, token());
273 TEST_F(SupervisedUserRefreshTokenFetcherTest, ExpiredAccessTokenRetry) {
274 // If we get a 401 error for the second time, we should give up instead of
275 // retrying again.
276 StartFetching();
277 MakeOAuth2TokenServiceRequestSucceed();
278 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
279 MakeOAuth2TokenServiceRequestSucceed();
280 SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
282 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
283 EXPECT_EQ(net::ERR_FAILED, error().network_error());
284 EXPECT_EQ(std::string(), token());
287 TEST_F(SupervisedUserRefreshTokenFetcherTest, MalformedIssueTokenResponse) {
288 StartFetching();
289 MakeOAuth2TokenServiceRequestSucceed();
290 SendResponse(GetIssueTokenRequest(), "choke");
292 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
293 EXPECT_EQ(net::ERR_INVALID_RESPONSE, error().network_error());
294 EXPECT_EQ(std::string(), token());
297 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchAccessTokenFailure) {
298 StartFetching();
299 MakeOAuth2TokenServiceRequestFail(
300 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
302 EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error().state());
303 EXPECT_EQ(std::string(), token());
306 TEST_F(SupervisedUserRefreshTokenFetcherTest, IssueTokenNetworkError) {
307 StartFetching();
308 MakeOAuth2TokenServiceRequestSucceed();
309 SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR);
311 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
312 EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, error().network_error());
313 EXPECT_EQ(std::string(), token());
316 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchRefreshTokenNetworkError) {
317 StartFetching();
318 MakeOAuth2TokenServiceRequestSucceed();
319 MakeIssueTokenRequestSucceed();
320 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
321 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
322 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
324 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
325 EXPECT_EQ(net::ERR_FAILED, error().network_error());
326 EXPECT_EQ(std::string(), token());
329 TEST_F(SupervisedUserRefreshTokenFetcherTest,
330 FetchRefreshTokenTransientNetworkError) {
331 StartFetching();
332 MakeOAuth2TokenServiceRequestSucceed();
333 MakeIssueTokenRequestSucceed();
334 SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
336 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
337 MakeRefreshTokenFetchSucceed();
339 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
340 EXPECT_EQ(kSupervisedUserToken, token());
343 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchRefreshTokenBadRequest) {
344 StartFetching();
345 MakeOAuth2TokenServiceRequestSucceed();
346 MakeIssueTokenRequestSucceed();
347 SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST);
349 EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
350 EXPECT_EQ(net::ERR_FAILED, error().network_error());
351 EXPECT_EQ(std::string(), token());
354 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileFetchingAccessToken) {
355 StartFetching();
356 Reset();
358 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
359 EXPECT_EQ(std::string(), token());
362 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileCallingIssueToken) {
363 StartFetching();
364 MakeOAuth2TokenServiceRequestSucceed();
365 Reset();
367 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
368 EXPECT_EQ(std::string(), token());
371 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileFetchingRefreshToken) {
372 StartFetching();
373 MakeOAuth2TokenServiceRequestSucceed();
374 MakeIssueTokenRequestSucceed();
375 Reset();
377 EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
378 EXPECT_EQ(std::string(), token());