// Copyright 2013 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.

#include <stddef.h>

#include <string>

#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/platform_thread.h"
#include "google_apis/gaia/fake_oauth2_token_service_delegate.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_access_token_consumer.h"
#include "google_apis/gaia/oauth2_access_token_fetcher_immediate_error.h"
#include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "google_apis/gaia/oauth2_token_service_test_util.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_test_util.h"
#include "services/network/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

// A testing consumer that retries on error.
class RetryingTestingOAuth2TokenServiceConsumer
    : public TestingOAuth2TokenServiceConsumer {
 public:
  RetryingTestingOAuth2TokenServiceConsumer(
      OAuth2TokenService* oauth2_service,
      const std::string& account_id)
      : oauth2_service_(oauth2_service),
        account_id_(account_id) {}
  ~RetryingTestingOAuth2TokenServiceConsumer() override {}

  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
                         const GoogleServiceAuthError& error) override {
    if (retry_counter_ <= 0)
      return;
    retry_counter_--;
    TestingOAuth2TokenServiceConsumer::OnGetTokenFailure(request, error);
    request_ = oauth2_service_->StartRequest(
        account_id_, OAuth2TokenService::ScopeSet(), this);
  }

  int retry_counter_ = 2;
  OAuth2TokenService* oauth2_service_;
  std::string account_id_;
  std::unique_ptr<OAuth2TokenService::Request> request_;
};

class FakeOAuth2TokenServiceObserver : public OAuth2TokenService::Observer {
 public:
  MOCK_METHOD2(OnAuthErrorChanged,
               void(const std::string&, const GoogleServiceAuthError&));
};

class TestOAuth2TokenService : public OAuth2TokenService {
 public:
  explicit TestOAuth2TokenService(
      std::unique_ptr<FakeOAuth2TokenServiceDelegate> delegate)
      : OAuth2TokenService(std::move(delegate)) {}

  void CancelAllRequestsForTest() { CancelAllRequests(); }

  void CancelRequestsForAccountForTest(const std::string& account_id) {
    CancelRequestsForAccount(account_id);
  }

  FakeOAuth2TokenServiceDelegate* GetFakeOAuth2TokenServiceDelegate() {
    return static_cast<FakeOAuth2TokenServiceDelegate*>(GetDelegate());
  }
};

// This class fakes the behaviour of a MutableProfileOAuth2TokenServiceDelegate
// used on Desktop.
class FakeOAuth2TokenServiceDelegateDesktop
    : public FakeOAuth2TokenServiceDelegate {
  std::string GetTokenForMultilogin(
      const std::string& account_id) const override {
    if (GetAuthError(account_id) == GoogleServiceAuthError::AuthErrorNone())
      return GetRefreshToken(account_id);
    return std::string();
  }

  OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
      const std::string& account_id,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      OAuth2AccessTokenConsumer* consumer) override {
    if (GetAuthError(account_id).IsPersistentError()) {
      return new OAuth2AccessTokenFetcherImmediateError(
          consumer, GetAuthError(account_id));
    }
    return FakeOAuth2TokenServiceDelegate::CreateAccessTokenFetcher(
        account_id, url_loader_factory, consumer);
  }
  void InvalidateTokenForMultilogin(
      const std::string& failed_account) override {
    UpdateAuthError(failed_account,
                    GoogleServiceAuthError(
                        GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
  }
};

class OAuth2TokenServiceTest : public testing::Test {
 public:
  void SetUp() override {
    auto delegate = std::make_unique<FakeOAuth2TokenServiceDelegate>();
    // Save raw delegate pointer for later.
    delegate_ptr_ = delegate.get();

    test_url_loader_factory_ = delegate->test_url_loader_factory();
    oauth2_service_ =
        std::make_unique<TestOAuth2TokenService>(std::move(delegate));
    account_id_ = "test_user@gmail.com";
  }

  void TearDown() override {
    // Makes sure that all the clean up tasks are run.
    base::RunLoop().RunUntilIdle();
  }

  void SimulateOAuthTokenResponse(const std::string& token,
                                  net::HttpStatusCode status = net::HTTP_OK) {
    test_url_loader_factory_->AddResponse(
        GaiaUrls::GetInstance()->oauth2_token_url().spec(), token, status);
  }

 protected:
  base::MessageLoopForIO message_loop_;  // net:: stuff needs IO message loop.
  network::TestURLLoaderFactory* test_url_loader_factory_ = nullptr;
  FakeOAuth2TokenServiceDelegate* delegate_ptr_ = nullptr;  // Not owned.
  std::unique_ptr<TestOAuth2TokenService> oauth2_service_;
  std::string account_id_;
  TestingOAuth2TokenServiceConsumer consumer_;
};

TEST_F(OAuth2TokenServiceTest, NoOAuth2RefreshToken) {
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(1, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, FailureShouldNotRetry) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  SimulateOAuthTokenResponse("", net::HTTP_UNAUTHORIZED);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(1, consumer_.number_of_errors_);
  EXPECT_EQ(0, test_url_loader_factory_->NumPending());
}

TEST_F(OAuth2TokenServiceTest, SuccessWithoutCaching) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);
}

TEST_F(OAuth2TokenServiceTest, SuccessWithCaching) {
  OAuth2TokenService::ScopeSet scopes1;
  scopes1.insert("s1");
  scopes1.insert("s2");
  OAuth2TokenService::ScopeSet scopes1_same;
  scopes1_same.insert("s2");
  scopes1_same.insert("s1");
  OAuth2TokenService::ScopeSet scopes2;
  scopes2.insert("s3");

  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  // First request.
  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, scopes1, &consumer_));
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  // Second request to the same set of scopes, should return the same token
  // without needing a network request.
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, scopes1_same, &consumer_));
  base::RunLoop().RunUntilIdle();

  // No new network fetcher.
  EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  // Third request to a new set of scopes, should return another token.
  SimulateOAuthTokenResponse(GetValidTokenResponse("token2", 3600));
  std::unique_ptr<OAuth2TokenService::Request> request3(
      oauth2_service_->StartRequest(account_id_, scopes2, &consumer_));
  EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(3, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token2", consumer_.last_token_);
}

TEST_F(OAuth2TokenServiceTest, SuccessAndExpirationAndFailure) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  // First request.
  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 0));
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  // Second request must try to access the network as the token has expired.
  SimulateOAuthTokenResponse("", net::HTTP_UNAUTHORIZED);  // Network failure.
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(1, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, SuccessAndExpirationAndSuccess) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  // First request.
  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 0));
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  // Second request must try to access the network as the token has expired.
  SimulateOAuthTokenResponse(GetValidTokenResponse("another token", 0));
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("another token", consumer_.last_token_);
}

TEST_F(OAuth2TokenServiceTest, RequestDeletedBeforeCompletion) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ(1, test_url_loader_factory_->NumPending());

  request.reset();

  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, RequestDeletedAfterCompletion) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  request.reset();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);
}

TEST_F(OAuth2TokenServiceTest, MultipleRequestsForTheSameScopesWithOneDeleted) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  base::RunLoop().RunUntilIdle();
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  base::RunLoop().RunUntilIdle();

  request.reset();

  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, ClearedRefreshTokenFailsSubsequentRequests) {
  // We have a valid refresh token; the first request is successful.
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  // The refresh token is no longer available; subsequent requests fail.
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "");
  request = oauth2_service_->StartRequest(account_id_,
      OAuth2TokenService::ScopeSet(), &consumer_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(1, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest,
       ChangedRefreshTokenDoesNotAffectInFlightRequests) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "first refreshToken");
  OAuth2TokenService::ScopeSet scopes;
  scopes.insert("s1");
  scopes.insert("s2");
  OAuth2TokenService::ScopeSet scopes1;
  scopes.insert("s3");
  scopes.insert("s4");

  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, scopes, &consumer_));
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(1, test_url_loader_factory_->NumPending());

  // Note |request| is still pending when the refresh token changes.
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "second refreshToken");

  // A 2nd request (using the new refresh token) that occurs and completes
  // while the 1st request is in flight is successful.
  TestingOAuth2TokenServiceConsumer consumer2;
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, scopes1, &consumer2));
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(2, test_url_loader_factory_->NumPending());

  network::URLLoaderCompletionStatus ok_status(net::OK);
  network::ResourceResponseHead response_head =
      network::CreateResourceResponseHead(net::HTTP_OK);
  EXPECT_TRUE(test_url_loader_factory_->SimulateResponseForPendingRequest(
      GaiaUrls::GetInstance()->oauth2_token_url(), ok_status, response_head,
      GetValidTokenResponse("second token", 3600),
      network::TestURLLoaderFactory::kMostRecentMatch));
  EXPECT_EQ(1, consumer2.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer2.number_of_errors_);
  EXPECT_EQ("second token", consumer2.last_token_);

  EXPECT_TRUE(test_url_loader_factory_->SimulateResponseForPendingRequest(
      GaiaUrls::GetInstance()->oauth2_token_url(), ok_status, response_head,
      GetValidTokenResponse("first token", 3600),
      network::TestURLLoaderFactory::kMostRecentMatch));
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("first token", consumer_.last_token_);
}

TEST_F(OAuth2TokenServiceTest, StartRequestForMultiloginDesktop) {
  class MockOAuth2AccessTokenConsumer
      : public TestingOAuth2TokenServiceConsumer {
   public:
    MockOAuth2AccessTokenConsumer() = default;
    ~MockOAuth2AccessTokenConsumer() = default;

    MOCK_METHOD2(
        OnGetTokenSuccess,
        void(const OAuth2TokenService::Request* request,
             const OAuth2AccessTokenConsumer::TokenResponse& token_response));

    MOCK_METHOD2(OnGetTokenFailure,
                 void(const OAuth2TokenService::Request* request,
                      const GoogleServiceAuthError& error));

    DISALLOW_COPY_AND_ASSIGN(MockOAuth2AccessTokenConsumer);
  };
  TestOAuth2TokenService token_service(
      std::make_unique<FakeOAuth2TokenServiceDelegateDesktop>());

  token_service.GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  const std::string account_id_2 = "account_id_2";
  token_service.GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_2, "refreshToken");
  token_service.GetFakeOAuth2TokenServiceDelegate()->UpdateAuthError(
      account_id_2,
      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));

  MockOAuth2AccessTokenConsumer consumer;

  EXPECT_CALL(consumer, OnGetTokenSuccess(::testing::_, ::testing::_)).Times(1);
  EXPECT_CALL(
      consumer,
      OnGetTokenFailure(
          ::testing::_,
          GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP)))
      .Times(1);
  EXPECT_CALL(
      consumer,
      OnGetTokenFailure(::testing::_,
                        GoogleServiceAuthError(
                            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)))
      .Times(1);

  std::unique_ptr<OAuth2TokenService::Request> request1(
      token_service.StartRequestForMultilogin(account_id_, &consumer));
  std::unique_ptr<OAuth2TokenService::Request> request2(
      token_service.StartRequestForMultilogin(account_id_2, &consumer));
  std::unique_ptr<OAuth2TokenService::Request> request3(
      token_service.StartRequestForMultilogin("unknown_account", &consumer));
  base::RunLoop().RunUntilIdle();
}

TEST_F(OAuth2TokenServiceTest, StartRequestForMultiloginMobile) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequestForMultilogin(account_id_, &consumer_));

  base::RunLoop().RunUntilIdle();
  network::URLLoaderCompletionStatus ok_status(net::OK);
  network::ResourceResponseHead response_head =
      network::CreateResourceResponseHead(net::HTTP_OK);
  EXPECT_TRUE(test_url_loader_factory_->SimulateResponseForPendingRequest(
      GaiaUrls::GetInstance()->oauth2_token_url(), ok_status, response_head,
      GetValidTokenResponse("second token", 3600),
      network::TestURLLoaderFactory::kMostRecentMatch));
  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, ServiceShutDownBeforeFetchComplete) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  // The destructor should cancel all in-flight fetchers.
  oauth2_service_.reset(NULL);

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(1, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, RetryingConsumer) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  RetryingTestingOAuth2TokenServiceConsumer consumer(oauth2_service_.get(),
      account_id_);
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer));
  EXPECT_EQ(0, consumer.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer.number_of_errors_);

  SimulateOAuthTokenResponse("", net::HTTP_UNAUTHORIZED);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer.number_of_successful_tokens_);
  EXPECT_EQ(2, consumer.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, InvalidateTokensForMultiloginDesktop) {
  auto delegate = std::make_unique<FakeOAuth2TokenServiceDelegateDesktop>();
  TestOAuth2TokenService token_service(std::move(delegate));
  FakeOAuth2TokenServiceObserver observer;
  token_service.GetFakeOAuth2TokenServiceDelegate()->AddObserver(&observer);
  EXPECT_CALL(
      observer,
      OnAuthErrorChanged(account_id_,
                         GoogleServiceAuthError(
                             GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)))
      .Times(1);

  token_service.GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  const std::string account_id_2 = "account_id_2";
  token_service.GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_2, "refreshToken2");
  token_service.InvalidateTokenForMultilogin(account_id_, "refreshToken");
  // Check that refresh tokens for failed accounts are set in error.
  EXPECT_EQ(token_service.GetFakeOAuth2TokenServiceDelegate()
                ->GetAuthError(account_id_)
                .state(),
            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
  EXPECT_EQ(token_service.GetFakeOAuth2TokenServiceDelegate()
                ->GetAuthError(account_id_2)
                .state(),
            GoogleServiceAuthError::NONE);

  token_service.GetFakeOAuth2TokenServiceDelegate()->RemoveObserver(&observer);
}

TEST_F(OAuth2TokenServiceTest, InvalidateTokensForMultiloginMobile) {
  FakeOAuth2TokenServiceObserver observer;
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->AddObserver(&observer);
  EXPECT_CALL(
      observer,
      OnAuthErrorChanged(account_id_,
                         GoogleServiceAuthError(
                             GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)))
      .Times(0);

  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  const std::string account_id_2 = "account_id_2";
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_2, "refreshToken2");
  ;
  oauth2_service_->InvalidateTokenForMultilogin(account_id_, "refreshToken");
  // Check that refresh tokens are not affected.
  EXPECT_EQ(oauth2_service_->GetFakeOAuth2TokenServiceDelegate()
                ->GetAuthError(account_id_)
                .state(),
            GoogleServiceAuthError::NONE);
  EXPECT_EQ(oauth2_service_->GetFakeOAuth2TokenServiceDelegate()
                ->GetAuthError(account_id_2)
                .state(),
            GoogleServiceAuthError::NONE);

  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->RemoveObserver(
      &observer);
}

TEST_F(OAuth2TokenServiceTest, InvalidateToken) {
  OAuth2TokenService::ScopeSet scopes;
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");

  // First request.
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, scopes, &consumer_));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  // Second request, should return the same token without needing a network
  // request.
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, scopes, &consumer_));
  base::RunLoop().RunUntilIdle();

  // No new network fetcher.
  EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);

  // Clear previous response so the token request will be pending and we can
  // simulate a response after it started.
  test_url_loader_factory_->ClearResponses();

  // Invalidating the token should return a new token on the next request.
  oauth2_service_->InvalidateAccessToken(account_id_, scopes,
                                         consumer_.last_token_);
  std::unique_ptr<OAuth2TokenService::Request> request3(
      oauth2_service_->StartRequest(account_id_, scopes, &consumer_));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  SimulateOAuthTokenResponse(GetValidTokenResponse("token2", 3600));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(3, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token2", consumer_.last_token_);
}

TEST_F(OAuth2TokenServiceTest, CancelAllRequests) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));

  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      "account_id_2", "refreshToken2");
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  oauth2_service_->CancelAllRequestsForTest();

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(2, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, CancelRequestsForAccount) {
  OAuth2TokenService::ScopeSet scope_set_1;
  scope_set_1.insert("scope1");
  scope_set_1.insert("scope2");
  OAuth2TokenService::ScopeSet scope_set_2(scope_set_1.begin(),
                                           scope_set_1.end());
  scope_set_2.insert("scope3");

  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request1(
      oauth2_service_->StartRequest(account_id_, scope_set_1, &consumer_));
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequest(account_id_, scope_set_2, &consumer_));

  std::string account_id_2("account_id_2");
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_2, "refreshToken2");
  std::unique_ptr<OAuth2TokenService::Request> request3(
      oauth2_service_->StartRequest(account_id_2, scope_set_1, &consumer_));

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  oauth2_service_->CancelRequestsForAccountForTest(account_id_);

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(2, consumer_.number_of_errors_);

  oauth2_service_->CancelRequestsForAccountForTest(account_id_2);

  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(3, consumer_.number_of_errors_);
}

TEST_F(OAuth2TokenServiceTest, SameScopesRequestedForDifferentClients) {
  std::string client_id_1("client1");
  std::string client_secret_1("secret1");
  std::string client_id_2("client2");
  std::string client_secret_2("secret2");
  std::set<std::string> scope_set;
  scope_set.insert("scope1");
  scope_set.insert("scope2");

  std::string refresh_token("refreshToken");
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, refresh_token);

  std::unique_ptr<OAuth2TokenService::Request> request1(
      oauth2_service_->StartRequestForClient(
          account_id_, client_id_1, client_secret_1, scope_set, &consumer_));
  std::unique_ptr<OAuth2TokenService::Request> request2(
      oauth2_service_->StartRequestForClient(
          account_id_, client_id_2, client_secret_2, scope_set, &consumer_));
  // Start a request that should be duplicate of |request1|.
  std::unique_ptr<OAuth2TokenService::Request> request3(
      oauth2_service_->StartRequestForClient(
          account_id_, client_id_1, client_secret_1, scope_set, &consumer_));
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(2U,
            oauth2_service_->GetNumPendingRequestsForTesting(
                client_id_1,
                account_id_,
                scope_set));
   ASSERT_EQ(1U,
             oauth2_service_->GetNumPendingRequestsForTesting(
                client_id_2,
                account_id_,
                scope_set));
}

TEST_F(OAuth2TokenServiceTest, RequestParametersOrderTest) {
  OAuth2TokenService::ScopeSet set_0;
  OAuth2TokenService::ScopeSet set_1;
  set_1.insert("1");

  OAuth2TokenService::RequestParameters params[] = {
      OAuth2TokenService::RequestParameters("0", "0", set_0),
      OAuth2TokenService::RequestParameters("0", "0", set_1),
      OAuth2TokenService::RequestParameters("0", "1", set_0),
      OAuth2TokenService::RequestParameters("0", "1", set_1),
      OAuth2TokenService::RequestParameters("1", "0", set_0),
      OAuth2TokenService::RequestParameters("1", "0", set_1),
      OAuth2TokenService::RequestParameters("1", "1", set_0),
      OAuth2TokenService::RequestParameters("1", "1", set_1),
  };

  for (size_t i = 0; i < base::size(params); i++) {
    for (size_t j = 0; j < base::size(params); j++) {
      if (i == j) {
        EXPECT_FALSE(params[i] < params[j]) << " i=" << i << ", j=" << j;
        EXPECT_FALSE(params[j] < params[i]) << " i=" << i << ", j=" << j;
      } else if (i < j) {
        EXPECT_TRUE(params[i] < params[j]) << " i=" << i << ", j=" << j;
        EXPECT_FALSE(params[j] < params[i]) << " i=" << i << ", j=" << j;
      } else {
        EXPECT_TRUE(params[j] < params[i]) << " i=" << i << ", j=" << j;
        EXPECT_FALSE(params[i] < params[j]) << " i=" << i << ", j=" << j;
      }
    }
  }
}

TEST_F(OAuth2TokenServiceTest, UpdateClearsCache) {
  std::string kEmail = "test@gmail.com";
  std::set<std::string> scope_list;
  scope_list.insert("scope");
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      kEmail, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(kEmail, scope_list, &consumer_));
  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);
  EXPECT_EQ(1, (int)oauth2_service_->token_cache_.size());

  oauth2_service_->ClearCache();

  EXPECT_EQ(0, (int)oauth2_service_->token_cache_.size());
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      kEmail, "refreshToken");
  SimulateOAuthTokenResponse(GetValidTokenResponse("another token", 3600));
  request = oauth2_service_->StartRequest(kEmail, scope_list, &consumer_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("another token", consumer_.last_token_);
  EXPECT_EQ(1, (int)oauth2_service_->token_cache_.size());
}

TEST_F(OAuth2TokenServiceTest, FixRequestErrorIfPossible) {
  oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials(
      account_id_, "refreshToken");
  std::unique_ptr<OAuth2TokenService::Request> request(
      oauth2_service_->StartRequest(account_id_, OAuth2TokenService::ScopeSet(),
                                    &consumer_));
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  delegate_ptr_->set_fix_request_if_possible(true);
  SimulateOAuthTokenResponse("", net::HTTP_UNAUTHORIZED);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);

  SimulateOAuthTokenResponse(GetValidTokenResponse("token", 3600));
  base::RunLoop().RunUntilIdle();
  for (int max_reties = 5;
       max_reties >= 0 && consumer_.number_of_successful_tokens_ != 1;
       --max_reties) {
    base::RunLoop().RunUntilIdle();
    base::PlatformThread::Sleep(TimeDelta::FromSeconds(1));
  }

  EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
  EXPECT_EQ(0, consumer_.number_of_errors_);
  EXPECT_EQ("token", consumer_.last_token_);
}
