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_) {
    158       request_context_getter_ = new net::TestURLRequestContextGetter(
    159           message_loop_.message_loop_proxy());
    160     }
    161     return request_context_getter_;
    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 };
    192 
    193 #if defined(OS_WIN)
    194 #define MAYBE_ErrorComparator DISABLED_ErrorComparator
    195 #else
    196 #define MAYBE_ErrorComparator ErrorComparator
    197 #endif
    198 
    199 TEST_F(GaiaAuthFetcherTest, MAYBE_ErrorComparator) {
    200   GoogleServiceAuthError expected_error =
    201       GoogleServiceAuthError::FromConnectionError(-101);
    202 
    203   GoogleServiceAuthError matching_error =
    204       GoogleServiceAuthError::FromConnectionError(-101);
    205 
    206   EXPECT_TRUE(expected_error == matching_error);
    207 
    208   expected_error = GoogleServiceAuthError::FromConnectionError(6);
    209 
    210   EXPECT_FALSE(expected_error == matching_error);
    211 
    212   expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
    213 
    214   EXPECT_FALSE(expected_error == matching_error);
    215 
    216   matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
    217 
    218   EXPECT_TRUE(expected_error == matching_error);
    219 }
    220 
    221 TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
    222   int error_no = net::ERR_CONNECTION_RESET;
    223   net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
    224 
    225   GoogleServiceAuthError expected_error =
    226       GoogleServiceAuthError::FromConnectionError(error_no);
    227 
    228   MockGaiaConsumer consumer;
    229   EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
    230       .Times(1);
    231 
    232   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    233 
    234   MockFetcher mock_fetcher(
    235       client_login_source_, status, 0, net::ResponseCookies(), std::string(),
    236       net::URLFetcher::GET, &auth);
    237   auth.OnURLFetchComplete(&mock_fetcher);
    238 }
    239 
    240 TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
    241   int error_no = net::ERR_CONNECTION_RESET;
    242   net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
    243 
    244   GoogleServiceAuthError expected_error =
    245       GoogleServiceAuthError::FromConnectionError(error_no);
    246 
    247   MockGaiaConsumer consumer;
    248   EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
    249       .Times(1);
    250 
    251   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    252 
    253   MockFetcher mock_fetcher(
    254       issue_auth_token_source_, status, 0, cookies_, std::string(),
    255       net::URLFetcher::GET, &auth);
    256   auth.OnURLFetchComplete(&mock_fetcher);
    257 }
    258 
    259 
    260 TEST_F(GaiaAuthFetcherTest, LoginDenied) {
    261   std::string data("Error=BadAuthentication");
    262   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    263 
    264   GoogleServiceAuthError expected_error(
    265       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
    266 
    267   MockGaiaConsumer consumer;
    268   EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
    269       .Times(1);
    270 
    271   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    272 
    273   MockFetcher mock_fetcher(
    274       client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, data,
    275       net::URLFetcher::GET, &auth);
    276   auth.OnURLFetchComplete(&mock_fetcher);
    277 }
    278 
    279 TEST_F(GaiaAuthFetcherTest, ParseRequest) {
    280   RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
    281   RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
    282   RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
    283   RunParsingTest("SID=sid\nAuth=auth\n", "sid", std::string(), "auth");
    284   RunParsingTest("LSID=lsid\nAuth=auth\n", std::string(), "lsid", "auth");
    285   RunParsingTest("\nAuth=auth\n", std::string(), std::string(), "auth");
    286   RunParsingTest("SID=sid", "sid", std::string(), std::string());
    287 }
    288 
    289 TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
    290   RunErrorParsingTest("Url=U\n"
    291                       "Error=E\n"
    292                       "CaptchaToken=T\n"
    293                       "CaptchaUrl=C\n", "E", "U", "C", "T");
    294   RunErrorParsingTest("CaptchaToken=T\n"
    295                       "Error=E\n"
    296                       "Url=U\n"
    297                       "CaptchaUrl=C\n", "E", "U", "C", "T");
    298   RunErrorParsingTest("\n\n\nCaptchaToken=T\n"
    299                       "\nError=E\n"
    300                       "\nUrl=U\n"
    301                       "CaptchaUrl=C\n", "E", "U", "C", "T");
    302 }
    303 
    304 
    305 TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
    306   std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
    307 
    308   GaiaAuthConsumer::ClientLoginResult result;
    309   result.lsid = "lsid";
    310   result.sid = "sid";
    311   result.token = "auth";
    312   result.data = data;
    313 
    314   MockGaiaConsumer consumer;
    315   EXPECT_CALL(consumer, OnClientLoginSuccess(result))
    316       .Times(1);
    317 
    318   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    319   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    320   MockFetcher mock_fetcher(
    321       client_login_source_, status, net::HTTP_OK, cookies_, data,
    322       net::URLFetcher::GET, &auth);
    323   auth.OnURLFetchComplete(&mock_fetcher);
    324 }
    325 
    326 TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
    327   MockGaiaConsumer consumer;
    328   EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
    329       .Times(1);
    330 
    331   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    332   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    333   MockFetcher mock_fetcher(
    334       issue_auth_token_source_, status, net::HTTP_OK, cookies_, "token",
    335       net::URLFetcher::GET, &auth);
    336   auth.OnURLFetchComplete(&mock_fetcher);
    337 }
    338 
    339 TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
    340   std::string response =
    341       base::StringPrintf("Error=BadAuthentication\n%s\n",
    342                          GaiaAuthFetcher::kSecondFactor);
    343   EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
    344 }
    345 
    346 TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
    347   std::string response = "Error=BadAuthentication\n";
    348   EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
    349 }
    350 
    351 TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
    352   std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
    353       GaiaAuthFetcher::kSecondFactor);
    354 
    355   GoogleServiceAuthError error =
    356       GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);
    357 
    358   MockGaiaConsumer consumer;
    359   EXPECT_CALL(consumer, OnClientLoginFailure(error))
    360       .Times(1);
    361 
    362   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    363   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    364   MockFetcher mock_fetcher(
    365       client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, response,
    366       net::URLFetcher::GET, &auth);
    367   auth.OnURLFetchComplete(&mock_fetcher);
    368 }
    369 
    370 TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
    371   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    372   std::string data = "Url=http://www.google.com/login/captcha\n"
    373                      "Error=CaptchaRequired\n"
    374                      "CaptchaToken=CCTOKEN\n"
    375                      "CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
    376   GoogleServiceAuthError error =
    377       GaiaAuthFetcher::GenerateAuthError(data, status);
    378 
    379   std::string token = "CCTOKEN";
    380   GURL image_url("http://accounts.google.com/Captcha?ctoken=CCTOKEN");
    381   GURL unlock_url("http://www.google.com/login/captcha");
    382 
    383   EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED);
    384   EXPECT_EQ(error.captcha().token, token);
    385   EXPECT_EQ(error.captcha().image_url, image_url);
    386   EXPECT_EQ(error.captcha().unlock_url, unlock_url);
    387 }
    388 
    389 TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
    390   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    391   std::string data = "Error=AccountDeleted\n";
    392   GoogleServiceAuthError error =
    393       GaiaAuthFetcher::GenerateAuthError(data, status);
    394   EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
    395 }
    396 
    397 TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
    398   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    399   std::string data = "Error=AccountDisabled\n";
    400   GoogleServiceAuthError error =
    401       GaiaAuthFetcher::GenerateAuthError(data, status);
    402   EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
    403 }
    404 
    405 TEST_F(GaiaAuthFetcherTest, BadAuthenticationError) {
    406   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    407   std::string data = "Error=BadAuthentication\n";
    408   GoogleServiceAuthError error =
    409       GaiaAuthFetcher::GenerateAuthError(data, status);
    410   EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
    411 }
    412 
    413 TEST_F(GaiaAuthFetcherTest, IncomprehensibleError) {
    414   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    415   std::string data = "Error=Gobbledygook\n";
    416   GoogleServiceAuthError error =
    417       GaiaAuthFetcher::GenerateAuthError(data, status);
    418   EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
    419 }
    420 
    421 TEST_F(GaiaAuthFetcherTest, ServiceUnavailableError) {
    422   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    423   std::string data = "Error=ServiceUnavailable\n";
    424   GoogleServiceAuthError error =
    425       GaiaAuthFetcher::GenerateAuthError(data, status);
    426   EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
    427 }
    428 
    429 TEST_F(GaiaAuthFetcherTest, FullLogin) {
    430   MockGaiaConsumer consumer;
    431   EXPECT_CALL(consumer, OnClientLoginSuccess(_))
    432       .Times(1);
    433 
    434   MockURLFetcherFactory<MockFetcher> factory;
    435 
    436   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    437   auth.StartClientLogin("username",
    438                         "password",
    439                         "service",
    440                         std::string(),
    441                         std::string(),
    442                         GaiaAuthFetcher::HostedAccountsAllowed);
    443 }
    444 
    445 TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
    446   MockGaiaConsumer consumer;
    447   EXPECT_CALL(consumer, OnClientLoginFailure(_))
    448       .Times(1);
    449 
    450   MockURLFetcherFactory<MockFetcher> factory;
    451   factory.set_success(false);
    452 
    453   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    454   auth.StartClientLogin("username",
    455                         "password",
    456                         "service",
    457                         std::string(),
    458                         std::string(),
    459                         GaiaAuthFetcher::HostedAccountsAllowed);
    460 }
    461 
    462 TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
    463   MockGaiaConsumer consumer;
    464   EXPECT_CALL(consumer, OnClientLoginSuccess(_))
    465       .Times(1);
    466 
    467   net::TestURLFetcherFactory factory;
    468 
    469   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    470   auth.StartClientLogin("username",
    471                         "password",
    472                         "service",
    473                         std::string(),
    474                         std::string(),
    475                         GaiaAuthFetcher::HostedAccountsAllowed);
    476 
    477   EXPECT_TRUE(auth.HasPendingFetch());
    478   MockFetcher mock_fetcher(
    479       client_login_source_,
    480       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    481       net::HTTP_OK, cookies_, "SID=sid\nLSID=lsid\nAuth=auth\n",
    482       net::URLFetcher::GET, &auth);
    483   auth.OnURLFetchComplete(&mock_fetcher);
    484   EXPECT_FALSE(auth.HasPendingFetch());
    485 }
    486 
    487 TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
    488   MockGaiaConsumer consumer;
    489   EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
    490       .Times(1);
    491 
    492   net::TestURLFetcherFactory factory;
    493   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    494   auth.StartIssueAuthToken("sid", "lsid", "service");
    495 
    496   EXPECT_TRUE(auth.HasPendingFetch());
    497   MockFetcher mock_fetcher(
    498       issue_auth_token_source_,
    499       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    500       net::HTTP_OK, cookies_, "token",
    501       net::URLFetcher::GET, &auth);
    502   auth.OnURLFetchComplete(&mock_fetcher);
    503   EXPECT_FALSE(auth.HasPendingFetch());
    504 }
    505 
    506 TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
    507   MockGaiaConsumer consumer;
    508   EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
    509       .Times(1);
    510 
    511   net::TestURLFetcherFactory factory;
    512 
    513   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    514   auth.StartIssueAuthToken("sid", "lsid", "service");
    515 
    516   EXPECT_TRUE(auth.HasPendingFetch());
    517   MockFetcher mock_fetcher(
    518       issue_auth_token_source_,
    519       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    520       net::HTTP_FORBIDDEN,
    521       cookies_,
    522       std::string(),
    523       net::URLFetcher::GET,
    524       &auth);
    525   auth.OnURLFetchComplete(&mock_fetcher);
    526   EXPECT_FALSE(auth.HasPendingFetch());
    527 }
    528 
    529 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
    530   MockGaiaConsumer consumer;
    531   EXPECT_CALL(consumer, OnClientOAuthSuccess(
    532       GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1);
    533 
    534   net::TestURLFetcherFactory factory;
    535   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    536   auth.StartLsoForOAuthLoginTokenExchange("lso_token");
    537   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
    538   EXPECT_TRUE(NULL != fetcher);
    539   EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
    540             fetcher->GetLoadFlags());
    541 
    542   net::ResponseCookies cookies;
    543   cookies.push_back(kGetAuthCodeValidCookie);
    544   EXPECT_TRUE(auth.HasPendingFetch());
    545   MockFetcher mock_fetcher1(
    546       client_login_to_oauth2_source_,
    547       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    548       net::HTTP_OK,
    549       cookies,
    550       std::string(),
    551       net::URLFetcher::POST,
    552       &auth);
    553   auth.OnURLFetchComplete(&mock_fetcher1);
    554   EXPECT_TRUE(auth.HasPendingFetch());
    555   MockFetcher mock_fetcher2(
    556       oauth2_token_source_,
    557       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    558       net::HTTP_OK, cookies_, kGetTokenPairValidResponse,
    559       net::URLFetcher::POST, &auth);
    560   auth.OnURLFetchComplete(&mock_fetcher2);
    561   EXPECT_FALSE(auth.HasPendingFetch());
    562 }
    563 
    564 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies) {
    565   MockGaiaConsumer consumer;
    566   net::TestURLFetcherFactory factory;
    567   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    568   auth.StartCookieForOAuthLoginTokenExchange("0");
    569   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
    570   EXPECT_TRUE(NULL != fetcher);
    571   EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
    572   EXPECT_FALSE(EndsWith(fetcher->upload_data(), "device_type=chrome", true));
    573 }
    574 
    575 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies_DeviceId) {
    576   MockGaiaConsumer consumer;
    577   net::TestURLFetcherFactory factory;
    578   std::string expected_device_id("ABCDE-12345");
    579   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    580   auth.StartCookieForOAuthLoginTokenExchangeWithDeviceId("0",
    581                                                          expected_device_id);
    582   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
    583   EXPECT_TRUE(NULL != fetcher);
    584   EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
    585   EXPECT_TRUE(EndsWith(fetcher->upload_data(), "device_type=chrome", true));
    586   net::HttpRequestHeaders extra_request_headers;
    587   fetcher->GetExtraRequestHeaders(&extra_request_headers);
    588   std::string device_id;
    589   EXPECT_TRUE(extra_request_headers.GetHeader("X-Device-ID", &device_id));
    590   EXPECT_EQ(device_id, expected_device_id);
    591 }
    592 
    593 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
    594   MockGaiaConsumer consumer;
    595   EXPECT_CALL(consumer, OnClientOAuthFailure(_))
    596       .Times(1);
    597 
    598   net::TestURLFetcherFactory factory;
    599   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    600   auth.StartLsoForOAuthLoginTokenExchange("lso_token");
    601 
    602   net::ResponseCookies cookies;
    603   EXPECT_TRUE(auth.HasPendingFetch());
    604   MockFetcher mock_fetcher(
    605       client_login_to_oauth2_source_,
    606       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    607       net::HTTP_FORBIDDEN,
    608       cookies,
    609       std::string(),
    610       net::URLFetcher::POST,
    611       &auth);
    612   auth.OnURLFetchComplete(&mock_fetcher);
    613   EXPECT_FALSE(auth.HasPendingFetch());
    614 }
    615 
    616 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
    617   MockGaiaConsumer consumer;
    618   EXPECT_CALL(consumer, OnClientOAuthFailure(_))
    619       .Times(1);
    620 
    621   net::TestURLFetcherFactory factory;
    622   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    623   auth.StartLsoForOAuthLoginTokenExchange("lso_token");
    624 
    625   net::ResponseCookies cookies;
    626   cookies.push_back(kGetAuthCodeValidCookie);
    627   EXPECT_TRUE(auth.HasPendingFetch());
    628   MockFetcher mock_fetcher1(
    629       client_login_to_oauth2_source_,
    630       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    631       net::HTTP_OK,
    632       cookies,
    633       std::string(),
    634       net::URLFetcher::POST,
    635       &auth);
    636   auth.OnURLFetchComplete(&mock_fetcher1);
    637   EXPECT_TRUE(auth.HasPendingFetch());
    638   MockFetcher mock_fetcher2(
    639       oauth2_token_source_,
    640       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    641       net::HTTP_FORBIDDEN,
    642       cookies_,
    643       std::string(),
    644       net::URLFetcher::POST,
    645       &auth);
    646   auth.OnURLFetchComplete(&mock_fetcher2);
    647   EXPECT_FALSE(auth.HasPendingFetch());
    648 }
    649 
    650 TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) {
    651   MockGaiaConsumer consumer;
    652   EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
    653       .Times(1);
    654 
    655   net::TestURLFetcherFactory factory;
    656 
    657   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    658   auth.StartMergeSession("myubertoken");
    659 
    660   EXPECT_TRUE(auth.HasPendingFetch());
    661   MockFetcher mock_fetcher(
    662       merge_session_source_,
    663       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    664       net::HTTP_OK, cookies_, "<html></html>", net::URLFetcher::GET,
    665       &auth);
    666   auth.OnURLFetchComplete(&mock_fetcher);
    667   EXPECT_FALSE(auth.HasPendingFetch());
    668 }
    669 
    670 TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
    671   MockGaiaConsumer consumer;
    672   EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
    673       .Times(1);
    674 
    675   net::TestURLFetcherFactory factory;
    676 
    677   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    678   auth.StartMergeSession("myubertoken");
    679 
    680   // Make sure the fetcher created has the expected flags.  Set its url()
    681   // properties to reflect a redirect.
    682   net::TestURLFetcher* test_fetcher = factory.GetFetcherByID(0);
    683   EXPECT_TRUE(test_fetcher != NULL);
    684   EXPECT_TRUE(test_fetcher->GetLoadFlags() == net::LOAD_NORMAL);
    685   EXPECT_TRUE(auth.HasPendingFetch());
    686 
    687   GURL final_url("http://www.google.com/CheckCookie");
    688   test_fetcher->set_url(final_url);
    689   test_fetcher->set_status(
    690       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
    691   test_fetcher->set_response_code(net::HTTP_OK);
    692   test_fetcher->set_cookies(cookies_);
    693   test_fetcher->SetResponseString("<html></html>");
    694 
    695   auth.OnURLFetchComplete(test_fetcher);
    696   EXPECT_FALSE(auth.HasPendingFetch());
    697 }
    698 
    699 TEST_F(GaiaAuthFetcherTest, UberAuthTokenSuccess) {
    700   MockGaiaConsumer consumer;
    701   EXPECT_CALL(consumer, OnUberAuthTokenSuccess("uberToken"))
    702       .Times(1);
    703 
    704   net::TestURLFetcherFactory factory;
    705 
    706   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    707   auth.StartTokenFetchForUberAuthExchange("myAccessToken");
    708 
    709   EXPECT_TRUE(auth.HasPendingFetch());
    710   MockFetcher mock_fetcher(
    711       uberauth_token_source_,
    712       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
    713       net::HTTP_OK, cookies_, "uberToken", net::URLFetcher::POST,
    714       &auth);
    715   auth.OnURLFetchComplete(&mock_fetcher);
    716   EXPECT_FALSE(auth.HasPendingFetch());
    717 }
    718 
    719 TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) {
    720   {  // No cookies.
    721     std::string auth_code;
    722     net::ResponseCookies cookies;
    723     EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
    724         cookies, &auth_code));
    725     EXPECT_EQ("", auth_code);
    726   }
    727   {  // Few cookies, nothing appropriate.
    728     std::string auth_code;
    729     net::ResponseCookies cookies;
    730     cookies.push_back(kGetAuthCodeCookieNoSecure);
    731     cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
    732     cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
    733     EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
    734         cookies, &auth_code));
    735     EXPECT_EQ("", auth_code);
    736   }
    737   {  // Few cookies, one of them is valid.
    738     std::string auth_code;
    739     net::ResponseCookies cookies;
    740     cookies.push_back(kGetAuthCodeCookieNoSecure);
    741     cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
    742     cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
    743     cookies.push_back(kGetAuthCodeValidCookie);
    744     EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
    745         cookies, &auth_code));
    746     EXPECT_EQ("test-code", auth_code);
    747   }
    748   {  // Single valid cookie (like in real responses).
    749     std::string auth_code;
    750     net::ResponseCookies cookies;
    751     cookies.push_back(kGetAuthCodeValidCookie);
    752     EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
    753         cookies, &auth_code));
    754     EXPECT_EQ("test-code", auth_code);
    755   }
    756 }
    757 
    758 TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) {
    759   // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA
    760   // responses.
    761   std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
    762 
    763   GaiaAuthConsumer::ClientLoginResult result;
    764   result.lsid = "lsid";
    765   result.sid = "sid";
    766   result.token = "auth";
    767   result.data = data;
    768 
    769   MockGaiaConsumer consumer;
    770   EXPECT_CALL(consumer, OnClientLoginSuccess(result))
    771       .Times(1);
    772 
    773   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    774   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    775   MockFetcher mock_fetcher(
    776       oauth_login_gurl_, status, net::HTTP_OK, cookies_, data,
    777       net::URLFetcher::GET, &auth);
    778   auth.OnURLFetchComplete(&mock_fetcher);
    779 }
    780 
    781 TEST_F(GaiaAuthFetcherTest, ListAccounts) {
    782   std::string data("[\"gaia.l.a.r\", ["
    783       "[\"gaia.l.a\", 1, \"First Last\", \"user (at) gmail.com\", "
    784       "\"//googleusercontent.com/A/B/C/D/photo.jpg\", 1, 1, 0]]]");
    785   MockGaiaConsumer consumer;
    786   EXPECT_CALL(consumer, OnListAccountsSuccess(data)).Times(1);
    787 
    788   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
    789   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    790   MockFetcher mock_fetcher(GaiaUrls::GetInstance()->list_accounts_url(),
    791       status, net::HTTP_OK, cookies_, data, net::URLFetcher::GET, &auth);
    792   auth.OnURLFetchComplete(&mock_fetcher);
    793 }
    794