root/google_apis/gaia/gaia_auth_fetcher_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. Start
  2. oauth_login_gurl_
  3. RunParsingTest
  4. RunErrorParsingTest
  5. GetRequestContext
  6. TEST_F
  7. TEST_F
  8. TEST_F
  9. TEST_F
  10. TEST_F
  11. TEST_F
  12. TEST_F
  13. TEST_F
  14. TEST_F
  15. TEST_F
  16. TEST_F
  17. TEST_F
  18. TEST_F
  19. TEST_F
  20. TEST_F
  21. TEST_F
  22. TEST_F
  23. TEST_F
  24. TEST_F
  25. TEST_F
  26. TEST_F
  27. TEST_F
  28. TEST_F
  29. TEST_F
  30. TEST_F
  31. TEST_F
  32. TEST_F
  33. TEST_F
  34. TEST_F
  35. TEST_F
  36. TEST_F
  37. TEST_F
  38. TEST_F
  39. TEST_F

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A complete set of unit tests for GaiaAuthFetcher.
// Originally ported from GoogleAuthenticator tests.

#include <string>

#include "base/json/json_reader.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/mock_url_fetcher_factory.h"
#include "google_apis/google_api_keys.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using ::testing::Invoke;
using ::testing::_;

const char kGetAuthCodeValidCookie[] =
    "oauth_code=test-code; Path=/test; Secure; HttpOnly";
const char kGetAuthCodeCookieNoSecure[] =
    "oauth_code=test-code; Path=/test; HttpOnly";
const char kGetAuthCodeCookieNoHttpOnly[] =
    "oauth_code=test-code; Path=/test; Secure";
const char kGetAuthCodeCookieNoOAuthCode[] =
    "Path=/test; Secure; HttpOnly";
const char kGetTokenPairValidResponse[] =
    "{"
    "  \"refresh_token\": \"rt1\","
    "  \"access_token\": \"at1\","
    "  \"expires_in\": 3600,"
    "  \"token_type\": \"Bearer\""
    "}";

MockFetcher::MockFetcher(bool success,
                         const GURL& url,
                         const std::string& results,
                         net::URLFetcher::RequestType request_type,
                         net::URLFetcherDelegate* d)
    : TestURLFetcher(0, url, d) {
  set_url(url);
  net::URLRequestStatus::Status code;

  if (success) {
    set_response_code(net::HTTP_OK);
    code = net::URLRequestStatus::SUCCESS;
  } else {
    set_response_code(net::HTTP_FORBIDDEN);
    code = net::URLRequestStatus::FAILED;
  }

  set_status(net::URLRequestStatus(code, 0));
  SetResponseString(results);
}

MockFetcher::MockFetcher(const GURL& url,
                         const net::URLRequestStatus& status,
                         int response_code,
                         const net::ResponseCookies& cookies,
                         const std::string& results,
                         net::URLFetcher::RequestType request_type,
                         net::URLFetcherDelegate* d)
    : TestURLFetcher(0, url, d) {
  set_url(url);
  set_status(status);
  set_response_code(response_code);
  set_cookies(cookies);
  SetResponseString(results);
}

MockFetcher::~MockFetcher() {}

void MockFetcher::Start() {
  delegate()->OnURLFetchComplete(this);
}

class GaiaAuthFetcherTest : public testing::Test {
 protected:
  GaiaAuthFetcherTest()
      : client_login_source_(GaiaUrls::GetInstance()->client_login_url()),
        issue_auth_token_source_(
            GaiaUrls::GetInstance()->issue_auth_token_url()),
        client_login_to_oauth2_source_(
            GaiaUrls::GetInstance()->client_login_to_oauth2_url()),
        oauth2_token_source_(GaiaUrls::GetInstance()->oauth2_token_url()),
        token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()),
        merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()),
        uberauth_token_source_(
            GaiaUrls::GetInstance()->oauth1_login_url().Resolve(
                "?source=&issueuberauth=1")),
        oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()) {}

  void RunParsingTest(const std::string& data,
                      const std::string& sid,
                      const std::string& lsid,
                      const std::string& token) {
    std::string out_sid;
    std::string out_lsid;
    std::string out_token;

    GaiaAuthFetcher::ParseClientLoginResponse(data,
                                              &out_sid,
                                              &out_lsid,
                                              &out_token);
    EXPECT_EQ(lsid, out_lsid);
    EXPECT_EQ(sid, out_sid);
    EXPECT_EQ(token, out_token);
  }

  void RunErrorParsingTest(const std::string& data,
                           const std::string& error,
                           const std::string& error_url,
                           const std::string& captcha_url,
                           const std::string& captcha_token) {
    std::string out_error;
    std::string out_error_url;
    std::string out_captcha_url;
    std::string out_captcha_token;

    GaiaAuthFetcher::ParseClientLoginFailure(data,
                                             &out_error,
                                             &out_error_url,
                                             &out_captcha_url,
                                             &out_captcha_token);
    EXPECT_EQ(error, out_error);
    EXPECT_EQ(error_url, out_error_url);
    EXPECT_EQ(captcha_url, out_captcha_url);
    EXPECT_EQ(captcha_token, out_captcha_token);
  }

  net::ResponseCookies cookies_;
  GURL client_login_source_;
  GURL issue_auth_token_source_;
  GURL client_login_to_oauth2_source_;
  GURL oauth2_token_source_;
  GURL token_auth_source_;
  GURL merge_session_source_;
  GURL uberauth_token_source_;
  GURL oauth_login_gurl_;

 protected:
  net::TestURLRequestContextGetter* GetRequestContext() {
    if (!request_context_getter_) {
      request_context_getter_ = new net::TestURLRequestContextGetter(
          message_loop_.message_loop_proxy());
    }
    return request_context_getter_;
  }

  base::MessageLoop message_loop_;
  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
};

class MockGaiaConsumer : public GaiaAuthConsumer {
 public:
  MockGaiaConsumer() {}
  ~MockGaiaConsumer() {}

  MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result));
  MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service,
      const std::string& token));
  MOCK_METHOD1(OnClientOAuthSuccess,
               void(const GaiaAuthConsumer::ClientOAuthResult& result));
  MOCK_METHOD1(OnClientOAuthCodeSuccess,
               void(const std::string& result));
  MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
  MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data));
  MOCK_METHOD1(OnClientLoginFailure,
      void(const GoogleServiceAuthError& error));
  MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
      const GoogleServiceAuthError& error));
  MOCK_METHOD1(OnClientOAuthFailure,
      void(const GoogleServiceAuthError& error));
  MOCK_METHOD1(OnClientOAuthCodeFailure,
      void(const GoogleServiceAuthError& error));
  MOCK_METHOD1(OnMergeSessionFailure, void(
      const GoogleServiceAuthError& error));
  MOCK_METHOD1(OnUberAuthTokenFailure, void(
      const GoogleServiceAuthError& error));
  MOCK_METHOD1(OnListAccountsSuccess, void(const std::string& data));
};

#if defined(OS_WIN)
#define MAYBE_ErrorComparator DISABLED_ErrorComparator
#else
#define MAYBE_ErrorComparator ErrorComparator
#endif

TEST_F(GaiaAuthFetcherTest, MAYBE_ErrorComparator) {
  GoogleServiceAuthError expected_error =
      GoogleServiceAuthError::FromConnectionError(-101);

  GoogleServiceAuthError matching_error =
      GoogleServiceAuthError::FromConnectionError(-101);

  EXPECT_TRUE(expected_error == matching_error);

  expected_error = GoogleServiceAuthError::FromConnectionError(6);

  EXPECT_FALSE(expected_error == matching_error);

  expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);

  EXPECT_FALSE(expected_error == matching_error);

  matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);

  EXPECT_TRUE(expected_error == matching_error);
}

TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
  int error_no = net::ERR_CONNECTION_RESET;
  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);

  GoogleServiceAuthError expected_error =
      GoogleServiceAuthError::FromConnectionError(error_no);

  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
      .Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());

  MockFetcher mock_fetcher(
      client_login_source_, status, 0, net::ResponseCookies(), std::string(),
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}

TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
  int error_no = net::ERR_CONNECTION_RESET;
  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);

  GoogleServiceAuthError expected_error =
      GoogleServiceAuthError::FromConnectionError(error_no);

  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
      .Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());

  MockFetcher mock_fetcher(
      issue_auth_token_source_, status, 0, cookies_, std::string(),
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}


TEST_F(GaiaAuthFetcherTest, LoginDenied) {
  std::string data("Error=BadAuthentication");
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);

  GoogleServiceAuthError expected_error(
      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);

  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
      .Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());

  MockFetcher mock_fetcher(
      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, data,
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}

TEST_F(GaiaAuthFetcherTest, ParseRequest) {
  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
  RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
  RunParsingTest("SID=sid\nAuth=auth\n", "sid", std::string(), "auth");
  RunParsingTest("LSID=lsid\nAuth=auth\n", std::string(), "lsid", "auth");
  RunParsingTest("\nAuth=auth\n", std::string(), std::string(), "auth");
  RunParsingTest("SID=sid", "sid", std::string(), std::string());
}

TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
  RunErrorParsingTest("Url=U\n"
                      "Error=E\n"
                      "CaptchaToken=T\n"
                      "CaptchaUrl=C\n", "E", "U", "C", "T");
  RunErrorParsingTest("CaptchaToken=T\n"
                      "Error=E\n"
                      "Url=U\n"
                      "CaptchaUrl=C\n", "E", "U", "C", "T");
  RunErrorParsingTest("\n\n\nCaptchaToken=T\n"
                      "\nError=E\n"
                      "\nUrl=U\n"
                      "CaptchaUrl=C\n", "E", "U", "C", "T");
}


TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");

  GaiaAuthConsumer::ClientLoginResult result;
  result.lsid = "lsid";
  result.sid = "sid";
  result.token = "auth";
  result.data = data;

  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
      .Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  MockFetcher mock_fetcher(
      client_login_source_, status, net::HTTP_OK, cookies_, data,
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}

TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
      .Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  MockFetcher mock_fetcher(
      issue_auth_token_source_, status, net::HTTP_OK, cookies_, "token",
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}

TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
  std::string response =
      base::StringPrintf("Error=BadAuthentication\n%s\n",
                         GaiaAuthFetcher::kSecondFactor);
  EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
}

TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
  std::string response = "Error=BadAuthentication\n";
  EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
}

TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
  std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
      GaiaAuthFetcher::kSecondFactor);

  GoogleServiceAuthError error =
      GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);

  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginFailure(error))
      .Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  MockFetcher mock_fetcher(
      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, response,
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}

TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  std::string data = "Url=http://www.google.com/login/captcha\n"
                     "Error=CaptchaRequired\n"
                     "CaptchaToken=CCTOKEN\n"
                     "CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
  GoogleServiceAuthError error =
      GaiaAuthFetcher::GenerateAuthError(data, status);

  std::string token = "CCTOKEN";
  GURL image_url("http://accounts.google.com/Captcha?ctoken=CCTOKEN");
  GURL unlock_url("http://www.google.com/login/captcha");

  EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED);
  EXPECT_EQ(error.captcha().token, token);
  EXPECT_EQ(error.captcha().image_url, image_url);
  EXPECT_EQ(error.captcha().unlock_url, unlock_url);
}

TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  std::string data = "Error=AccountDeleted\n";
  GoogleServiceAuthError error =
      GaiaAuthFetcher::GenerateAuthError(data, status);
  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
}

TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  std::string data = "Error=AccountDisabled\n";
  GoogleServiceAuthError error =
      GaiaAuthFetcher::GenerateAuthError(data, status);
  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
}

TEST_F(GaiaAuthFetcherTest, BadAuthenticationError) {
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  std::string data = "Error=BadAuthentication\n";
  GoogleServiceAuthError error =
      GaiaAuthFetcher::GenerateAuthError(data, status);
  EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
}

TEST_F(GaiaAuthFetcherTest, IncomprehensibleError) {
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  std::string data = "Error=Gobbledygook\n";
  GoogleServiceAuthError error =
      GaiaAuthFetcher::GenerateAuthError(data, status);
  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
}

TEST_F(GaiaAuthFetcherTest, ServiceUnavailableError) {
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  std::string data = "Error=ServiceUnavailable\n";
  GoogleServiceAuthError error =
      GaiaAuthFetcher::GenerateAuthError(data, status);
  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
}

TEST_F(GaiaAuthFetcherTest, FullLogin) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
      .Times(1);

  MockURLFetcherFactory<MockFetcher> factory;

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartClientLogin("username",
                        "password",
                        "service",
                        std::string(),
                        std::string(),
                        GaiaAuthFetcher::HostedAccountsAllowed);
}

TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginFailure(_))
      .Times(1);

  MockURLFetcherFactory<MockFetcher> factory;
  factory.set_success(false);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartClientLogin("username",
                        "password",
                        "service",
                        std::string(),
                        std::string(),
                        GaiaAuthFetcher::HostedAccountsAllowed);
}

TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
      .Times(1);

  net::TestURLFetcherFactory factory;

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartClientLogin("username",
                        "password",
                        "service",
                        std::string(),
                        std::string(),
                        GaiaAuthFetcher::HostedAccountsAllowed);

  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher(
      client_login_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK, cookies_, "SID=sid\nLSID=lsid\nAuth=auth\n",
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
      .Times(1);

  net::TestURLFetcherFactory factory;
  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartIssueAuthToken("sid", "lsid", "service");

  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher(
      issue_auth_token_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK, cookies_, "token",
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
      .Times(1);

  net::TestURLFetcherFactory factory;

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartIssueAuthToken("sid", "lsid", "service");

  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher(
      issue_auth_token_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_FORBIDDEN,
      cookies_,
      std::string(),
      net::URLFetcher::GET,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientOAuthSuccess(
      GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1);

  net::TestURLFetcherFactory factory;
  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  EXPECT_TRUE(NULL != fetcher);
  EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
            fetcher->GetLoadFlags());

  net::ResponseCookies cookies;
  cookies.push_back(kGetAuthCodeValidCookie);
  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher1(
      client_login_to_oauth2_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK,
      cookies,
      std::string(),
      net::URLFetcher::POST,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher1);
  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher2(
      oauth2_token_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK, cookies_, kGetTokenPairValidResponse,
      net::URLFetcher::POST, &auth);
  auth.OnURLFetchComplete(&mock_fetcher2);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies) {
  MockGaiaConsumer consumer;
  net::TestURLFetcherFactory factory;
  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartCookieForOAuthLoginTokenExchange("0");
  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  EXPECT_TRUE(NULL != fetcher);
  EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
}

TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
      .Times(1);

  net::TestURLFetcherFactory factory;
  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartLsoForOAuthLoginTokenExchange("lso_token");

  net::ResponseCookies cookies;
  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher(
      client_login_to_oauth2_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_FORBIDDEN,
      cookies,
      std::string(),
      net::URLFetcher::POST,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
      .Times(1);

  net::TestURLFetcherFactory factory;
  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartLsoForOAuthLoginTokenExchange("lso_token");

  net::ResponseCookies cookies;
  cookies.push_back(kGetAuthCodeValidCookie);
  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher1(
      client_login_to_oauth2_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK,
      cookies,
      std::string(),
      net::URLFetcher::POST,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher1);
  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher2(
      oauth2_token_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_FORBIDDEN,
      cookies_,
      std::string(),
      net::URLFetcher::POST,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher2);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, OAuthCodeWithCookiesSuccess) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientOAuthCodeSuccess("test-code")).Times(1);

  net::TestURLFetcherFactory factory;
  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartCookieForOAuthCodeExchange("");

  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
  EXPECT_TRUE(NULL != fetcher);
  EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
  EXPECT_TRUE(auth.HasPendingFetch());

  net::ResponseCookies cookies;
  cookies.push_back(kGetAuthCodeValidCookie);
  MockFetcher mock_fetcher(
      client_login_to_oauth2_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK,
      cookies,
      std::string(),
      net::URLFetcher::POST,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, OAuthCodeWithCookiesFailure) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientOAuthCodeFailure(_)).Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartCookieForOAuthCodeExchange("");

  EXPECT_TRUE(auth.HasPendingFetch());
  net::ResponseCookies cookies;
  MockFetcher mock_fetcher(
      client_login_to_oauth2_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_FORBIDDEN,
      cookies,
      std::string(),
      net::URLFetcher::POST,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
      .Times(1);

  net::TestURLFetcherFactory factory;

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartMergeSession("myubertoken");

  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher(
      merge_session_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK, cookies_, "<html></html>", net::URLFetcher::GET,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
      .Times(1);

  net::TestURLFetcherFactory factory;

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartMergeSession("myubertoken");

  // Make sure the fetcher created has the expected flags.  Set its url()
  // properties to reflect a redirect.
  net::TestURLFetcher* test_fetcher = factory.GetFetcherByID(0);
  EXPECT_TRUE(test_fetcher != NULL);
  EXPECT_TRUE(test_fetcher->GetLoadFlags() == net::LOAD_NORMAL);
  EXPECT_TRUE(auth.HasPendingFetch());

  GURL final_url("http://www.google.com/CheckCookie");
  test_fetcher->set_url(final_url);
  test_fetcher->set_status(
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
  test_fetcher->set_response_code(net::HTTP_OK);
  test_fetcher->set_cookies(cookies_);
  test_fetcher->SetResponseString("<html></html>");

  auth.OnURLFetchComplete(test_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, UberAuthTokenSuccess) {
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnUberAuthTokenSuccess("uberToken"))
      .Times(1);

  net::TestURLFetcherFactory factory;

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  auth.StartTokenFetchForUberAuthExchange("myAccessToken");

  EXPECT_TRUE(auth.HasPendingFetch());
  MockFetcher mock_fetcher(
      uberauth_token_source_,
      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
      net::HTTP_OK, cookies_, "uberToken", net::URLFetcher::POST,
      &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
  EXPECT_FALSE(auth.HasPendingFetch());
}

TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) {
  {  // No cookies.
    std::string auth_code;
    net::ResponseCookies cookies;
    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
        cookies, &auth_code));
    EXPECT_EQ("", auth_code);
  }
  {  // Few cookies, nothing appropriate.
    std::string auth_code;
    net::ResponseCookies cookies;
    cookies.push_back(kGetAuthCodeCookieNoSecure);
    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
        cookies, &auth_code));
    EXPECT_EQ("", auth_code);
  }
  {  // Few cookies, one of them is valid.
    std::string auth_code;
    net::ResponseCookies cookies;
    cookies.push_back(kGetAuthCodeCookieNoSecure);
    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
    cookies.push_back(kGetAuthCodeValidCookie);
    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
        cookies, &auth_code));
    EXPECT_EQ("test-code", auth_code);
  }
  {  // Single valid cookie (like in real responses).
    std::string auth_code;
    net::ResponseCookies cookies;
    cookies.push_back(kGetAuthCodeValidCookie);
    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
        cookies, &auth_code));
    EXPECT_EQ("test-code", auth_code);
  }
}

TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) {
  // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA
  // responses.
  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");

  GaiaAuthConsumer::ClientLoginResult result;
  result.lsid = "lsid";
  result.sid = "sid";
  result.token = "auth";
  result.data = data;

  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
      .Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  MockFetcher mock_fetcher(
      oauth_login_gurl_, status, net::HTTP_OK, cookies_, data,
      net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}

TEST_F(GaiaAuthFetcherTest, ListAccounts) {
  std::string data("[\"gaia.l.a.r\", ["
      "[\"gaia.l.a\", 1, \"First Last\", \"user@gmail.com\", "
      "\"//googleusercontent.com/A/B/C/D/photo.jpg\", 1, 1, 0]]]");
  MockGaiaConsumer consumer;
  EXPECT_CALL(consumer, OnListAccountsSuccess(data)).Times(1);

  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
  MockFetcher mock_fetcher(GaiaUrls::GetInstance()->list_accounts_url(),
      status, net::HTTP_OK, cookies_, data, net::URLFetcher::GET, &auth);
  auth.OnURLFetchComplete(&mock_fetcher);
}

/* [<][>][^][v][top][bottom][index][help] */