Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / supervised_user / supervised_user_refresh_token_fetcher_unittest.cc
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.
4
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/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"
24
25 namespace {
26
27 const char kAccountId[] = "account_id";
28 const char kDeviceName[] = "Compy";
29 const char kSupervisedUserId[] = "abcdef";
30
31 const char kAccessToken[] = "accesstoken";
32 const char kAuthorizationCode[] = "authorizationcode";
33 const char kSupervisedUserToken[] = "supervisedusertoken";
34 const char kOAuth2RefreshToken[] = "refreshtoken";
35
36 const char kIssueTokenResponseFormat[] =
37     "{"
38     "  \"code\": \"%s\""
39     "}";
40
41 const char kGetRefreshTokenResponseFormat[] =
42     "{"
43     "  \"access_token\": \"<ignored>\","
44     "  \"expires_in\": 12345,"
45     "  \"refresh_token\": \"%s\""
46     "}";
47
48 // Utility methods --------------------------------------------------
49
50 // Slightly hacky way to extract a value from a URL-encoded POST request body.
51 bool GetValueForKey(const std::string& encoded_string,
52                     const std::string& key,
53                     std::string* value) {
54   GURL url("http://example.com/?" + encoded_string);
55   return net::GetValueForKeyInQuery(url, key, value);
56 }
57
58 void SendResponse(net::TestURLFetcher* url_fetcher,
59                   const std::string& response) {
60   url_fetcher->set_status(
61       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
62   url_fetcher->set_response_code(net::HTTP_OK);
63   url_fetcher->SetResponseString(response);
64   url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
65 }
66
67 void SetNetworkError(net::TestURLFetcher* url_fetcher, int error) {
68   url_fetcher->set_status(
69       net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
70   url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
71 }
72
73 void SetHttpError(net::TestURLFetcher* url_fetcher, int error) {
74   url_fetcher->set_status(net::URLRequestStatus());
75   url_fetcher->set_response_code(error);
76   url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
77 }
78
79 void VerifyTokenRequest(
80     std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests) {
81   ASSERT_EQ(1u, requests.size());
82   EXPECT_EQ(1u, requests[0].scopes.size());
83   EXPECT_EQ(1u, requests[0].scopes.count(GaiaConstants::kOAuth1LoginScope));
84 }
85
86 }  // namespace
87
88 class SupervisedUserRefreshTokenFetcherTest : public testing::Test {
89  public:
90   SupervisedUserRefreshTokenFetcherTest();
91   virtual ~SupervisedUserRefreshTokenFetcherTest() {}
92
93  protected:
94   void StartFetching();
95
96   net::TestURLFetcher* GetIssueTokenRequest();
97   net::TestURLFetcher* GetRefreshTokenRequest();
98
99   void MakeOAuth2TokenServiceRequestSucceed();
100   void MakeOAuth2TokenServiceRequestFail(GoogleServiceAuthError::State error);
101   void MakeIssueTokenRequestSucceed();
102   void MakeRefreshTokenFetchSucceed();
103
104   void Reset();
105
106   const GoogleServiceAuthError& error() const { return error_; }
107   const std::string& token() const { return token_; }
108
109  private:
110   void OnTokenFetched(const GoogleServiceAuthError& error,
111                       const std::string& token);
112
113   content::TestBrowserThreadBundle thread_bundle_;
114   TestingProfile profile_;
115   FakeProfileOAuth2TokenService oauth2_token_service_;
116   net::TestURLFetcherFactory url_fetcher_factory_;
117   scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher_;
118
119   GoogleServiceAuthError error_;
120   std::string token_;
121   base::WeakPtrFactory<SupervisedUserRefreshTokenFetcherTest> weak_ptr_factory_;
122 };
123
124 SupervisedUserRefreshTokenFetcherTest::SupervisedUserRefreshTokenFetcherTest()
125     : token_fetcher_(SupervisedUserRefreshTokenFetcher::Create(
126                          &oauth2_token_service_,
127                          kAccountId,
128                          profile_.GetRequestContext())),
129       error_(GoogleServiceAuthError::NONE),
130       weak_ptr_factory_(this) {}
131
132 void SupervisedUserRefreshTokenFetcherTest::StartFetching() {
133   oauth2_token_service_.IssueRefreshToken(kOAuth2RefreshToken);
134   token_fetcher_->Start(
135       kSupervisedUserId,
136       kDeviceName,
137       base::Bind(
138           &SupervisedUserRefreshTokenFetcherTest::OnTokenFetched,
139           weak_ptr_factory_.GetWeakPtr()));
140 }
141
142 net::TestURLFetcher*
143 SupervisedUserRefreshTokenFetcherTest::GetIssueTokenRequest() {
144   net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(1);
145   if (!url_fetcher)
146     return NULL;
147
148   EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_issue_token_url(),
149             url_fetcher->GetOriginalURL());
150   std::string access_token;
151   net::HttpRequestHeaders headers;
152   url_fetcher->GetExtraRequestHeaders(&headers);
153   EXPECT_TRUE(headers.GetHeader("Authorization", &access_token));
154   EXPECT_EQ(std::string("Bearer ") + kAccessToken, access_token);
155   const std::string upload_data = url_fetcher->upload_data();
156   std::string supervised_user_id;
157   EXPECT_TRUE(GetValueForKey(upload_data, "profile_id", &supervised_user_id));
158   EXPECT_EQ(kSupervisedUserId, supervised_user_id);
159   std::string device_name;
160   EXPECT_TRUE(GetValueForKey(upload_data, "device_name", &device_name));
161   EXPECT_EQ(kDeviceName, device_name);
162   return url_fetcher;
163 }
164
165 net::TestURLFetcher*
166 SupervisedUserRefreshTokenFetcherTest::GetRefreshTokenRequest() {
167   net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(
168       gaia::GaiaOAuthClient::kUrlFetcherId);
169   if (!url_fetcher)
170     return NULL;
171
172   EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_token_url(),
173             url_fetcher->GetOriginalURL());
174   std::string auth_code;
175   EXPECT_TRUE(GetValueForKey(url_fetcher->upload_data(), "code", &auth_code));
176   EXPECT_EQ(kAuthorizationCode, auth_code);
177   return url_fetcher;
178 }
179
180 void
181 SupervisedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestSucceed() {
182   std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests =
183       oauth2_token_service_.GetPendingRequests();
184   VerifyTokenRequest(requests);
185   base::Time expiration_date = base::Time::Now() +
186                                base::TimeDelta::FromHours(1);
187   oauth2_token_service_.IssueTokenForScope(requests[0].scopes,
188                                            kAccessToken,
189                                            expiration_date);
190 }
191
192 void
193 SupervisedUserRefreshTokenFetcherTest::MakeOAuth2TokenServiceRequestFail(
194     GoogleServiceAuthError::State error) {
195   std::vector<FakeProfileOAuth2TokenService::PendingRequest> requests =
196       oauth2_token_service_.GetPendingRequests();
197   VerifyTokenRequest(requests);
198   oauth2_token_service_.IssueErrorForScope(requests[0].scopes,
199                                            GoogleServiceAuthError(error));
200 }
201
202 void SupervisedUserRefreshTokenFetcherTest::MakeIssueTokenRequestSucceed() {
203   SendResponse(GetIssueTokenRequest(),
204                base::StringPrintf(kIssueTokenResponseFormat,
205                                   kAuthorizationCode));
206 }
207
208 void SupervisedUserRefreshTokenFetcherTest::MakeRefreshTokenFetchSucceed() {
209   SendResponse(GetRefreshTokenRequest(),
210                base::StringPrintf(kGetRefreshTokenResponseFormat,
211                                   kSupervisedUserToken));
212 }
213
214 void SupervisedUserRefreshTokenFetcherTest::Reset() {
215   token_fetcher_.reset();
216 }
217
218 void SupervisedUserRefreshTokenFetcherTest::OnTokenFetched(
219     const GoogleServiceAuthError& error,
220     const std::string& token) {
221   error_ = error;
222   token_ = token;
223 }
224
225 // Tests --------------------------------------------------------
226
227 TEST_F(SupervisedUserRefreshTokenFetcherTest, Success) {
228   StartFetching();
229   MakeOAuth2TokenServiceRequestSucceed();
230   MakeIssueTokenRequestSucceed();
231   MakeRefreshTokenFetchSucceed();
232
233   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
234   EXPECT_EQ(kSupervisedUserToken, token());
235 }
236
237 TEST_F(SupervisedUserRefreshTokenFetcherTest, ExpiredAccessToken) {
238   StartFetching();
239   MakeOAuth2TokenServiceRequestSucceed();
240   SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
241   MakeOAuth2TokenServiceRequestSucceed();
242   MakeIssueTokenRequestSucceed();
243   MakeRefreshTokenFetchSucceed();
244
245   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
246   EXPECT_EQ(kSupervisedUserToken, token());
247 }
248
249 TEST_F(SupervisedUserRefreshTokenFetcherTest, ExpiredAccessTokenRetry) {
250   // If we get a 401 error for the second time, we should give up instead of
251   // retrying again.
252   StartFetching();
253   MakeOAuth2TokenServiceRequestSucceed();
254   SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
255   MakeOAuth2TokenServiceRequestSucceed();
256   SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
257
258   EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
259   EXPECT_EQ(net::ERR_FAILED, error().network_error());
260   EXPECT_EQ(std::string(), token());
261 }
262
263 TEST_F(SupervisedUserRefreshTokenFetcherTest, MalformedIssueTokenResponse) {
264   StartFetching();
265   MakeOAuth2TokenServiceRequestSucceed();
266   SendResponse(GetIssueTokenRequest(), "choke");
267
268   EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
269   EXPECT_EQ(net::ERR_INVALID_RESPONSE, error().network_error());
270   EXPECT_EQ(std::string(), token());
271 }
272
273 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchAccessTokenFailure) {
274   StartFetching();
275   MakeOAuth2TokenServiceRequestFail(
276       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
277
278   EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error().state());
279   EXPECT_EQ(std::string(), token());
280 }
281
282 TEST_F(SupervisedUserRefreshTokenFetcherTest, IssueTokenNetworkError) {
283   StartFetching();
284   MakeOAuth2TokenServiceRequestSucceed();
285   SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR);
286
287   EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
288   EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, error().network_error());
289   EXPECT_EQ(std::string(), token());
290 }
291
292 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchRefreshTokenNetworkError) {
293   StartFetching();
294   MakeOAuth2TokenServiceRequestSucceed();
295   MakeIssueTokenRequestSucceed();
296   SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
297   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
298   SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
299
300   EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
301   EXPECT_EQ(net::ERR_FAILED, error().network_error());
302   EXPECT_EQ(std::string(), token());
303 }
304
305 TEST_F(SupervisedUserRefreshTokenFetcherTest,
306        FetchRefreshTokenTransientNetworkError) {
307   StartFetching();
308   MakeOAuth2TokenServiceRequestSucceed();
309   MakeIssueTokenRequestSucceed();
310   SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
311
312   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
313   MakeRefreshTokenFetchSucceed();
314
315   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
316   EXPECT_EQ(kSupervisedUserToken, token());
317 }
318
319 TEST_F(SupervisedUserRefreshTokenFetcherTest, FetchRefreshTokenBadRequest) {
320   StartFetching();
321   MakeOAuth2TokenServiceRequestSucceed();
322   MakeIssueTokenRequestSucceed();
323   SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST);
324
325   EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
326   EXPECT_EQ(net::ERR_FAILED, error().network_error());
327   EXPECT_EQ(std::string(), token());
328 }
329
330 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileFetchingAccessToken) {
331   StartFetching();
332   Reset();
333
334   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
335   EXPECT_EQ(std::string(), token());
336 }
337
338 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileCallingIssueToken) {
339   StartFetching();
340   MakeOAuth2TokenServiceRequestSucceed();
341   Reset();
342
343   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
344   EXPECT_EQ(std::string(), token());
345 }
346
347 TEST_F(SupervisedUserRefreshTokenFetcherTest, CancelWhileFetchingRefreshToken) {
348   StartFetching();
349   MakeOAuth2TokenServiceRequestSucceed();
350   MakeIssueTokenRequestSucceed();
351   Reset();
352
353   EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
354   EXPECT_EQ(std::string(), token());
355 }