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