gaia_auth_fetcher_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright (c) 2012 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// A complete set of unit tests for GaiaAuthFetcher.
6// Originally ported from GoogleAuthenticator tests.
7
8#include <string>
9
10#include "base/json/json_reader.h"
11#include "base/strings/stringprintf.h"
12#include "base/values.h"
13#include "google_apis/gaia/gaia_auth_consumer.h"
14#include "google_apis/gaia/gaia_auth_fetcher.h"
15#include "google_apis/gaia/gaia_urls.h"
16#include "google_apis/gaia/google_service_auth_error.h"
17#include "google_apis/gaia/mock_url_fetcher_factory.h"
18#include "google_apis/google_api_keys.h"
19#include "net/base/load_flags.h"
20#include "net/base/net_errors.h"
21#include "net/http/http_status_code.h"
22#include "net/url_request/test_url_fetcher_factory.h"
23#include "net/url_request/url_fetcher_delegate.h"
24#include "net/url_request/url_request_status.h"
25#include "net/url_request/url_request_test_util.h"
26#include "testing/gmock/include/gmock/gmock.h"
27#include "testing/gtest/include/gtest/gtest.h"
28#include "url/gurl.h"
29
30using ::testing::Invoke;
31using ::testing::_;
32
33const char kGetAuthCodeValidCookie[] =
34    "oauth_code=test-code; Path=/test; Secure; HttpOnly";
35const char kGetAuthCodeCookieNoSecure[] =
36    "oauth_code=test-code; Path=/test; HttpOnly";
37const char kGetAuthCodeCookieNoHttpOnly[] =
38    "oauth_code=test-code; Path=/test; Secure";
39const char kGetAuthCodeCookieNoOAuthCode[] =
40    "Path=/test; Secure; HttpOnly";
41const char kGetTokenPairValidResponse[] =
42    "{"
43    "  \"refresh_token\": \"rt1\","
44    "  \"access_token\": \"at1\","
45    "  \"expires_in\": 3600,"
46    "  \"token_type\": \"Bearer\""
47    "}";
48
49MockFetcher::MockFetcher(bool success,
50                         const GURL& url,
51                         const std::string& results,
52                         net::URLFetcher::RequestType request_type,
53                         net::URLFetcherDelegate* d)
54    : TestURLFetcher(0, url, d) {
55  set_url(url);
56  net::URLRequestStatus::Status code;
57
58  if (success) {
59    set_response_code(net::HTTP_OK);
60    code = net::URLRequestStatus::SUCCESS;
61  } else {
62    set_response_code(net::HTTP_FORBIDDEN);
63    code = net::URLRequestStatus::FAILED;
64  }
65
66  set_status(net::URLRequestStatus(code, 0));
67  SetResponseString(results);
68}
69
70MockFetcher::MockFetcher(const GURL& url,
71                         const net::URLRequestStatus& status,
72                         int response_code,
73                         const net::ResponseCookies& cookies,
74                         const std::string& results,
75                         net::URLFetcher::RequestType request_type,
76                         net::URLFetcherDelegate* d)
77    : TestURLFetcher(0, url, d) {
78  set_url(url);
79  set_status(status);
80  set_response_code(response_code);
81  set_cookies(cookies);
82  SetResponseString(results);
83}
84
85MockFetcher::~MockFetcher() {}
86
87void MockFetcher::Start() {
88  delegate()->OnURLFetchComplete(this);
89}
90
91class GaiaAuthFetcherTest : public testing::Test {
92 protected:
93  GaiaAuthFetcherTest()
94      : client_login_source_(GaiaUrls::GetInstance()->client_login_url()),
95        issue_auth_token_source_(
96            GaiaUrls::GetInstance()->issue_auth_token_url()),
97        client_login_to_oauth2_source_(
98            GaiaUrls::GetInstance()->client_login_to_oauth2_url()),
99        oauth2_token_source_(GaiaUrls::GetInstance()->oauth2_token_url()),
100        token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()),
101        merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()),
102        uberauth_token_source_(
103            GaiaUrls::GetInstance()->oauth1_login_url().Resolve(
104                "?source=&issueuberauth=1")),
105        oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()) {}
106
107  void RunParsingTest(const std::string& data,
108                      const std::string& sid,
109                      const std::string& lsid,
110                      const std::string& token) {
111    std::string out_sid;
112    std::string out_lsid;
113    std::string out_token;
114
115    GaiaAuthFetcher::ParseClientLoginResponse(data,
116                                              &out_sid,
117                                              &out_lsid,
118                                              &out_token);
119    EXPECT_EQ(lsid, out_lsid);
120    EXPECT_EQ(sid, out_sid);
121    EXPECT_EQ(token, out_token);
122  }
123
124  void RunErrorParsingTest(const std::string& data,
125                           const std::string& error,
126                           const std::string& error_url,
127                           const std::string& captcha_url,
128                           const std::string& captcha_token) {
129    std::string out_error;
130    std::string out_error_url;
131    std::string out_captcha_url;
132    std::string out_captcha_token;
133
134    GaiaAuthFetcher::ParseClientLoginFailure(data,
135                                             &out_error,
136                                             &out_error_url,
137                                             &out_captcha_url,
138                                             &out_captcha_token);
139    EXPECT_EQ(error, out_error);
140    EXPECT_EQ(error_url, out_error_url);
141    EXPECT_EQ(captcha_url, out_captcha_url);
142    EXPECT_EQ(captcha_token, out_captcha_token);
143  }
144
145  net::ResponseCookies cookies_;
146  GURL client_login_source_;
147  GURL issue_auth_token_source_;
148  GURL client_login_to_oauth2_source_;
149  GURL oauth2_token_source_;
150  GURL token_auth_source_;
151  GURL merge_session_source_;
152  GURL uberauth_token_source_;
153  GURL oauth_login_gurl_;
154
155 protected:
156  net::TestURLRequestContextGetter* GetRequestContext() {
157    if (!request_context_getter_.get()) {
158      request_context_getter_ = new net::TestURLRequestContextGetter(
159          message_loop_.message_loop_proxy());
160    }
161    return request_context_getter_.get();
162  }
163
164  base::MessageLoop message_loop_;
165  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
166};
167
168class MockGaiaConsumer : public GaiaAuthConsumer {
169 public:
170  MockGaiaConsumer() {}
171  ~MockGaiaConsumer() {}
172
173  MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result));
174  MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service,
175      const std::string& token));
176  MOCK_METHOD1(OnClientOAuthSuccess,
177               void(const GaiaAuthConsumer::ClientOAuthResult& result));
178  MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
179  MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data));
180  MOCK_METHOD1(OnClientLoginFailure,
181      void(const GoogleServiceAuthError& error));
182  MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
183      const GoogleServiceAuthError& error));
184  MOCK_METHOD1(OnClientOAuthFailure,
185      void(const GoogleServiceAuthError& error));
186  MOCK_METHOD1(OnMergeSessionFailure, void(
187      const GoogleServiceAuthError& error));
188  MOCK_METHOD1(OnUberAuthTokenFailure, void(
189      const GoogleServiceAuthError& error));
190  MOCK_METHOD1(OnListAccountsSuccess, void(const std::string& data));
191  MOCK_METHOD1(OnGetCheckConnectionInfoSuccess, void(const std::string& data));
192};
193
194#if defined(OS_WIN)
195#define MAYBE_ErrorComparator DISABLED_ErrorComparator
196#else
197#define MAYBE_ErrorComparator ErrorComparator
198#endif
199
200TEST_F(GaiaAuthFetcherTest, MAYBE_ErrorComparator) {
201  GoogleServiceAuthError expected_error =
202      GoogleServiceAuthError::FromConnectionError(-101);
203
204  GoogleServiceAuthError matching_error =
205      GoogleServiceAuthError::FromConnectionError(-101);
206
207  EXPECT_TRUE(expected_error == matching_error);
208
209  expected_error = GoogleServiceAuthError::FromConnectionError(6);
210
211  EXPECT_FALSE(expected_error == matching_error);
212
213  expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
214
215  EXPECT_FALSE(expected_error == matching_error);
216
217  matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
218
219  EXPECT_TRUE(expected_error == matching_error);
220}
221
222TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
223  int error_no = net::ERR_CONNECTION_RESET;
224  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
225
226  GoogleServiceAuthError expected_error =
227      GoogleServiceAuthError::FromConnectionError(error_no);
228
229  MockGaiaConsumer consumer;
230  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
231      .Times(1);
232
233  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
234
235  MockFetcher mock_fetcher(
236      client_login_source_, status, 0, net::ResponseCookies(), std::string(),
237      net::URLFetcher::GET, &auth);
238  auth.OnURLFetchComplete(&mock_fetcher);
239}
240
241TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
242  int error_no = net::ERR_CONNECTION_RESET;
243  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
244
245  GoogleServiceAuthError expected_error =
246      GoogleServiceAuthError::FromConnectionError(error_no);
247
248  MockGaiaConsumer consumer;
249  EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
250      .Times(1);
251
252  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
253
254  MockFetcher mock_fetcher(
255      issue_auth_token_source_, status, 0, cookies_, std::string(),
256      net::URLFetcher::GET, &auth);
257  auth.OnURLFetchComplete(&mock_fetcher);
258}
259
260
261TEST_F(GaiaAuthFetcherTest, LoginDenied) {
262  std::string data("Error=BadAuthentication");
263  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
264
265  GoogleServiceAuthError expected_error(
266      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
267
268  MockGaiaConsumer consumer;
269  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
270      .Times(1);
271
272  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
273
274  MockFetcher mock_fetcher(
275      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, data,
276      net::URLFetcher::GET, &auth);
277  auth.OnURLFetchComplete(&mock_fetcher);
278}
279
280TEST_F(GaiaAuthFetcherTest, ParseRequest) {
281  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
282  RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
283  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
284  RunParsingTest("SID=sid\nAuth=auth\n", "sid", std::string(), "auth");
285  RunParsingTest("LSID=lsid\nAuth=auth\n", std::string(), "lsid", "auth");
286  RunParsingTest("\nAuth=auth\n", std::string(), std::string(), "auth");
287  RunParsingTest("SID=sid", "sid", std::string(), std::string());
288}
289
290TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
291  RunErrorParsingTest("Url=U\n"
292                      "Error=E\n"
293                      "CaptchaToken=T\n"
294                      "CaptchaUrl=C\n", "E", "U", "C", "T");
295  RunErrorParsingTest("CaptchaToken=T\n"
296                      "Error=E\n"
297                      "Url=U\n"
298                      "CaptchaUrl=C\n", "E", "U", "C", "T");
299  RunErrorParsingTest("\n\n\nCaptchaToken=T\n"
300                      "\nError=E\n"
301                      "\nUrl=U\n"
302                      "CaptchaUrl=C\n", "E", "U", "C", "T");
303}
304
305
306TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
307  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
308
309  GaiaAuthConsumer::ClientLoginResult result;
310  result.lsid = "lsid";
311  result.sid = "sid";
312  result.token = "auth";
313  result.data = data;
314
315  MockGaiaConsumer consumer;
316  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
317      .Times(1);
318
319  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
320  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
321  MockFetcher mock_fetcher(
322      client_login_source_, status, net::HTTP_OK, cookies_, data,
323      net::URLFetcher::GET, &auth);
324  auth.OnURLFetchComplete(&mock_fetcher);
325}
326
327TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
328  MockGaiaConsumer consumer;
329  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
330      .Times(1);
331
332  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
333  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
334  MockFetcher mock_fetcher(
335      issue_auth_token_source_, status, net::HTTP_OK, cookies_, "token",
336      net::URLFetcher::GET, &auth);
337  auth.OnURLFetchComplete(&mock_fetcher);
338}
339
340TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
341  std::string response =
342      base::StringPrintf("Error=BadAuthentication\n%s\n",
343                         GaiaAuthFetcher::kSecondFactor);
344  EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
345}
346
347TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
348  std::string response = "Error=BadAuthentication\n";
349  EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
350}
351
352TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
353  std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
354      GaiaAuthFetcher::kSecondFactor);
355
356  GoogleServiceAuthError error =
357      GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);
358
359  MockGaiaConsumer consumer;
360  EXPECT_CALL(consumer, OnClientLoginFailure(error))
361      .Times(1);
362
363  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
364  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
365  MockFetcher mock_fetcher(
366      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, response,
367      net::URLFetcher::GET, &auth);
368  auth.OnURLFetchComplete(&mock_fetcher);
369}
370
371TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
372  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
373  std::string data = "Url=http://www.google.com/login/captcha\n"
374                     "Error=CaptchaRequired\n"
375                     "CaptchaToken=CCTOKEN\n"
376                     "CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
377  GoogleServiceAuthError error =
378      GaiaAuthFetcher::GenerateAuthError(data, status);
379
380  std::string token = "CCTOKEN";
381  GURL image_url("http://accounts.google.com/Captcha?ctoken=CCTOKEN");
382  GURL unlock_url("http://www.google.com/login/captcha");
383
384  EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED);
385  EXPECT_EQ(error.captcha().token, token);
386  EXPECT_EQ(error.captcha().image_url, image_url);
387  EXPECT_EQ(error.captcha().unlock_url, unlock_url);
388}
389
390TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
391  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
392  std::string data = "Error=AccountDeleted\n";
393  GoogleServiceAuthError error =
394      GaiaAuthFetcher::GenerateAuthError(data, status);
395  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
396}
397
398TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
399  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
400  std::string data = "Error=AccountDisabled\n";
401  GoogleServiceAuthError error =
402      GaiaAuthFetcher::GenerateAuthError(data, status);
403  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
404}
405
406TEST_F(GaiaAuthFetcherTest, BadAuthenticationError) {
407  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
408  std::string data = "Error=BadAuthentication\n";
409  GoogleServiceAuthError error =
410      GaiaAuthFetcher::GenerateAuthError(data, status);
411  EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
412}
413
414TEST_F(GaiaAuthFetcherTest, IncomprehensibleError) {
415  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
416  std::string data = "Error=Gobbledygook\n";
417  GoogleServiceAuthError error =
418      GaiaAuthFetcher::GenerateAuthError(data, status);
419  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
420}
421
422TEST_F(GaiaAuthFetcherTest, ServiceUnavailableError) {
423  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
424  std::string data = "Error=ServiceUnavailable\n";
425  GoogleServiceAuthError error =
426      GaiaAuthFetcher::GenerateAuthError(data, status);
427  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
428}
429
430TEST_F(GaiaAuthFetcherTest, FullLogin) {
431  MockGaiaConsumer consumer;
432  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
433      .Times(1);
434
435  MockURLFetcherFactory<MockFetcher> factory;
436
437  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
438  auth.StartClientLogin("username",
439                        "password",
440                        "service",
441                        std::string(),
442                        std::string(),
443                        GaiaAuthFetcher::HostedAccountsAllowed);
444}
445
446TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
447  MockGaiaConsumer consumer;
448  EXPECT_CALL(consumer, OnClientLoginFailure(_))
449      .Times(1);
450
451  MockURLFetcherFactory<MockFetcher> factory;
452  factory.set_success(false);
453
454  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
455  auth.StartClientLogin("username",
456                        "password",
457                        "service",
458                        std::string(),
459                        std::string(),
460                        GaiaAuthFetcher::HostedAccountsAllowed);
461}
462
463TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
464  MockGaiaConsumer consumer;
465  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
466      .Times(1);
467
468  net::TestURLFetcherFactory factory;
469
470  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
471  auth.StartClientLogin("username",
472                        "password",
473                        "service",
474                        std::string(),
475                        std::string(),
476                        GaiaAuthFetcher::HostedAccountsAllowed);
477
478  EXPECT_TRUE(auth.HasPendingFetch());
479  MockFetcher mock_fetcher(
480      client_login_source_,
481      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
482      net::HTTP_OK, cookies_, "SID=sid\nLSID=lsid\nAuth=auth\n",
483      net::URLFetcher::GET, &auth);
484  auth.OnURLFetchComplete(&mock_fetcher);
485  EXPECT_FALSE(auth.HasPendingFetch());
486}
487
488TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
489  MockGaiaConsumer consumer;
490  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
491      .Times(1);
492
493  net::TestURLFetcherFactory factory;
494  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
495  auth.StartIssueAuthToken("sid", "lsid", "service");
496
497  EXPECT_TRUE(auth.HasPendingFetch());
498  MockFetcher mock_fetcher(
499      issue_auth_token_source_,
500      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
501      net::HTTP_OK, cookies_, "token",
502      net::URLFetcher::GET, &auth);
503  auth.OnURLFetchComplete(&mock_fetcher);
504  EXPECT_FALSE(auth.HasPendingFetch());
505}
506
507TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
508  MockGaiaConsumer consumer;
509  EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
510      .Times(1);
511
512  net::TestURLFetcherFactory factory;
513
514  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
515  auth.StartIssueAuthToken("sid", "lsid", "service");
516
517  EXPECT_TRUE(auth.HasPendingFetch());
518  MockFetcher mock_fetcher(
519      issue_auth_token_source_,
520      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
521      net::HTTP_FORBIDDEN,
522      cookies_,
523      std::string(),
524      net::URLFetcher::GET,
525      &auth);
526  auth.OnURLFetchComplete(&mock_fetcher);
527  EXPECT_FALSE(auth.HasPendingFetch());
528}
529
530TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
531  MockGaiaConsumer consumer;
532  EXPECT_CALL(consumer, OnClientOAuthSuccess(
533      GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1);
534
535  net::TestURLFetcherFactory factory;
536  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
537  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
538  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
539  EXPECT_TRUE(NULL != fetcher);
540  EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
541            fetcher->GetLoadFlags());
542
543  net::ResponseCookies cookies;
544  cookies.push_back(kGetAuthCodeValidCookie);
545  EXPECT_TRUE(auth.HasPendingFetch());
546  MockFetcher mock_fetcher1(
547      client_login_to_oauth2_source_,
548      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
549      net::HTTP_OK,
550      cookies,
551      std::string(),
552      net::URLFetcher::POST,
553      &auth);
554  auth.OnURLFetchComplete(&mock_fetcher1);
555  EXPECT_TRUE(auth.HasPendingFetch());
556  MockFetcher mock_fetcher2(
557      oauth2_token_source_,
558      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
559      net::HTTP_OK, cookies_, kGetTokenPairValidResponse,
560      net::URLFetcher::POST, &auth);
561  auth.OnURLFetchComplete(&mock_fetcher2);
562  EXPECT_FALSE(auth.HasPendingFetch());
563}
564
565TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies) {
566  MockGaiaConsumer consumer;
567  net::TestURLFetcherFactory factory;
568  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
569  auth.StartCookieForOAuthLoginTokenExchange("0");
570  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
571  EXPECT_TRUE(NULL != fetcher);
572  EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
573  EXPECT_FALSE(EndsWith(fetcher->upload_data(), "device_type=chrome", true));
574}
575
576TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies_DeviceId) {
577  MockGaiaConsumer consumer;
578  net::TestURLFetcherFactory factory;
579  std::string expected_device_id("ABCDE-12345");
580  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
581  auth.StartCookieForOAuthLoginTokenExchangeWithDeviceId("0",
582                                                         expected_device_id);
583  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
584  EXPECT_TRUE(NULL != fetcher);
585  EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
586  EXPECT_TRUE(EndsWith(fetcher->upload_data(), "device_type=chrome", true));
587  net::HttpRequestHeaders extra_request_headers;
588  fetcher->GetExtraRequestHeaders(&extra_request_headers);
589  std::string device_id;
590  EXPECT_TRUE(extra_request_headers.GetHeader("X-Device-ID", &device_id));
591  EXPECT_EQ(device_id, expected_device_id);
592}
593
594TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
595  MockGaiaConsumer consumer;
596  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
597      .Times(1);
598
599  net::TestURLFetcherFactory factory;
600  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
601  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
602
603  net::ResponseCookies cookies;
604  EXPECT_TRUE(auth.HasPendingFetch());
605  MockFetcher mock_fetcher(
606      client_login_to_oauth2_source_,
607      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
608      net::HTTP_FORBIDDEN,
609      cookies,
610      std::string(),
611      net::URLFetcher::POST,
612      &auth);
613  auth.OnURLFetchComplete(&mock_fetcher);
614  EXPECT_FALSE(auth.HasPendingFetch());
615}
616
617TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
618  MockGaiaConsumer consumer;
619  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
620      .Times(1);
621
622  net::TestURLFetcherFactory factory;
623  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
624  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
625
626  net::ResponseCookies cookies;
627  cookies.push_back(kGetAuthCodeValidCookie);
628  EXPECT_TRUE(auth.HasPendingFetch());
629  MockFetcher mock_fetcher1(
630      client_login_to_oauth2_source_,
631      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
632      net::HTTP_OK,
633      cookies,
634      std::string(),
635      net::URLFetcher::POST,
636      &auth);
637  auth.OnURLFetchComplete(&mock_fetcher1);
638  EXPECT_TRUE(auth.HasPendingFetch());
639  MockFetcher mock_fetcher2(
640      oauth2_token_source_,
641      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
642      net::HTTP_FORBIDDEN,
643      cookies_,
644      std::string(),
645      net::URLFetcher::POST,
646      &auth);
647  auth.OnURLFetchComplete(&mock_fetcher2);
648  EXPECT_FALSE(auth.HasPendingFetch());
649}
650
651TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) {
652  MockGaiaConsumer consumer;
653  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
654      .Times(1);
655
656  net::TestURLFetcherFactory factory;
657
658  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
659  auth.StartMergeSession("myubertoken", std::string());
660
661  EXPECT_TRUE(auth.HasPendingFetch());
662  MockFetcher mock_fetcher(
663      merge_session_source_,
664      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
665      net::HTTP_OK, cookies_, "<html></html>", net::URLFetcher::GET,
666      &auth);
667  auth.OnURLFetchComplete(&mock_fetcher);
668  EXPECT_FALSE(auth.HasPendingFetch());
669}
670
671TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
672  MockGaiaConsumer consumer;
673  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
674      .Times(1);
675
676  net::TestURLFetcherFactory factory;
677
678  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
679  auth.StartMergeSession("myubertoken", std::string());
680
681  // Make sure the fetcher created has the expected flags.  Set its url()
682  // properties to reflect a redirect.
683  net::TestURLFetcher* test_fetcher = factory.GetFetcherByID(0);
684  EXPECT_TRUE(test_fetcher != NULL);
685  EXPECT_TRUE(test_fetcher->GetLoadFlags() == net::LOAD_NORMAL);
686  EXPECT_TRUE(auth.HasPendingFetch());
687
688  GURL final_url("http://www.google.com/CheckCookie");
689  test_fetcher->set_url(final_url);
690  test_fetcher->set_status(
691      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
692  test_fetcher->set_response_code(net::HTTP_OK);
693  test_fetcher->set_cookies(cookies_);
694  test_fetcher->SetResponseString("<html></html>");
695
696  auth.OnURLFetchComplete(test_fetcher);
697  EXPECT_FALSE(auth.HasPendingFetch());
698}
699
700TEST_F(GaiaAuthFetcherTest, UberAuthTokenSuccess) {
701  MockGaiaConsumer consumer;
702  EXPECT_CALL(consumer, OnUberAuthTokenSuccess("uberToken"))
703      .Times(1);
704
705  net::TestURLFetcherFactory factory;
706
707  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
708  auth.StartTokenFetchForUberAuthExchange("myAccessToken");
709
710  EXPECT_TRUE(auth.HasPendingFetch());
711  MockFetcher mock_fetcher(
712      uberauth_token_source_,
713      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
714      net::HTTP_OK, cookies_, "uberToken", net::URLFetcher::POST,
715      &auth);
716  auth.OnURLFetchComplete(&mock_fetcher);
717  EXPECT_FALSE(auth.HasPendingFetch());
718}
719
720TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) {
721  {  // No cookies.
722    std::string auth_code;
723    net::ResponseCookies cookies;
724    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
725        cookies, &auth_code));
726    EXPECT_EQ("", auth_code);
727  }
728  {  // Few cookies, nothing appropriate.
729    std::string auth_code;
730    net::ResponseCookies cookies;
731    cookies.push_back(kGetAuthCodeCookieNoSecure);
732    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
733    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
734    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
735        cookies, &auth_code));
736    EXPECT_EQ("", auth_code);
737  }
738  {  // Few cookies, one of them is valid.
739    std::string auth_code;
740    net::ResponseCookies cookies;
741    cookies.push_back(kGetAuthCodeCookieNoSecure);
742    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
743    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
744    cookies.push_back(kGetAuthCodeValidCookie);
745    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
746        cookies, &auth_code));
747    EXPECT_EQ("test-code", auth_code);
748  }
749  {  // Single valid cookie (like in real responses).
750    std::string auth_code;
751    net::ResponseCookies cookies;
752    cookies.push_back(kGetAuthCodeValidCookie);
753    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
754        cookies, &auth_code));
755    EXPECT_EQ("test-code", auth_code);
756  }
757}
758
759TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) {
760  // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA
761  // responses.
762  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
763
764  GaiaAuthConsumer::ClientLoginResult result;
765  result.lsid = "lsid";
766  result.sid = "sid";
767  result.token = "auth";
768  result.data = data;
769
770  MockGaiaConsumer consumer;
771  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
772      .Times(1);
773
774  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
775  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
776  MockFetcher mock_fetcher(
777      oauth_login_gurl_, status, net::HTTP_OK, cookies_, data,
778      net::URLFetcher::GET, &auth);
779  auth.OnURLFetchComplete(&mock_fetcher);
780}
781
782TEST_F(GaiaAuthFetcherTest, ListAccounts) {
783  std::string data("[\"gaia.l.a.r\", ["
784      "[\"gaia.l.a\", 1, \"First Last\", \"user@gmail.com\", "
785      "\"//googleusercontent.com/A/B/C/D/photo.jpg\", 1, 1, 0]]]");
786  MockGaiaConsumer consumer;
787  EXPECT_CALL(consumer, OnListAccountsSuccess(data)).Times(1);
788
789  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
790  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
791  MockFetcher mock_fetcher(GaiaUrls::GetInstance()->list_accounts_url(),
792      status, net::HTTP_OK, cookies_, data, net::URLFetcher::GET, &auth);
793  auth.OnURLFetchComplete(&mock_fetcher);
794}
795
796TEST_F(GaiaAuthFetcherTest, GetCheckConnectionInfo) {
797  std::string data(
798      "[{\"carryBackToken\": \"token1\", \"url\": \"http://www.google.com\"}]");
799  MockGaiaConsumer consumer;
800  EXPECT_CALL(consumer, OnGetCheckConnectionInfoSuccess(data)).Times(1);
801
802  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
803  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
804  MockFetcher mock_fetcher(
805      GaiaUrls::GetInstance()->get_check_connection_info_url(),
806      status, net::HTTP_OK, cookies_, data, net::URLFetcher::GET, &auth);
807  auth.OnURLFetchComplete(&mock_fetcher);
808}
809