Home | History | Annotate | Download | only in gaia
      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 
     30 using ::testing::Invoke;
     31 using ::testing::_;
     32 
     33 const char kGetAuthCodeValidCookie[] =
     34     "oauth_code=test-code; Path=/test; Secure; HttpOnly";
     35 const char kGetAuthCodeCookieNoSecure[] =
     36     "oauth_code=test-code; Path=/test; HttpOnly";
     37 const char kGetAuthCodeCookieNoHttpOnly[] =
     38     "oauth_code=test-code; Path=/test; Secure";
     39 const char kGetAuthCodeCookieNoOAuthCode[] =
     40     "Path=/test; Secure; HttpOnly";
     41 const char kGetTokenPairValidResponse[] =
     42     "{"
     43     "  \"refresh_token\": \"rt1\","
     44     "  \"access_token\": \"at1\","
     45     "  \"expires_in\": 3600,"
     46     "  \"token_type\": \"Bearer\""
     47     "}";
     48 
     49 MockFetcher::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 
     70 MockFetcher::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 
     85 MockFetcher::~MockFetcher() {}
     86 
     87 void MockFetcher::Start() {
     88   delegate()->OnURLFetchComplete(this);
     89 }
     90 
     91 class 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 
    168 class 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 
    200 TEST_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 
    222 TEST_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 
    241 TEST_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 
    261 TEST_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 
    280 TEST_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 
    290 TEST_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 
    306 TEST_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 
    327 TEST_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 
    340 TEST_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 
    347 TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
    348   std::string response = "Error=BadAuthentication\n";
    349   EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
    350 }
    351 
    352 TEST_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 
    371 TEST_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 
    390 TEST_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 
    398 TEST_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 
    406 TEST_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 
    414 TEST_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 
    422 TEST_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 
    430 TEST_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 
    446 TEST_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 
    463 TEST_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 
    488 TEST_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 
    507 TEST_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 
    530 TEST_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 
    565 TEST_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 
    576 TEST_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 
    594 TEST_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 
    617 TEST_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 
    651 TEST_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 
    671 TEST_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 
    700 TEST_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 
    720 TEST_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 
    759 TEST_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 
    782 TEST_F(GaiaAuthFetcherTest, ListAccounts) {
    783   std::string data("[\"gaia.l.a.r\", ["
    784       "[\"gaia.l.a\", 1, \"First Last\", \"user (at) 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 
    796 TEST_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