// Copyright 2017 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 "services/identity/public/cpp/identity_manager.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/test/bind_test_util.h"
#include "build/build_config.h"
#include "components/image_fetcher/core/fake_image_decoder.h"
#include "components/signin/core/browser/account_consistency_method.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "components/signin/core/browser/list_accounts_test_utils.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/browser/signin_switches.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service_delegate.h"
#include "services/identity/public/cpp/accounts_cookie_mutator.h"
#include "services/identity/public/cpp/accounts_cookie_mutator_impl.h"
#include "services/identity/public/cpp/accounts_mutator.h"
#include "services/identity/public/cpp/diagnostics_provider_impl.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/identity_test_utils.h"
#include "services/identity/public/cpp/primary_account_mutator.h"
#include "services/identity/public/cpp/test_identity_manager_observer.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_cookie_manager.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_ANDROID)
#include "components/signin/core/browser/child_account_info_fetcher_android.h"
#endif

namespace identity {
namespace {

const char kTestConsumerId[] = "dummy_consumer";
const char kTestConsumerId2[] = "dummy_consumer 2";
const char kTestGaiaId[] = "dummyId";
const char kTestGaiaId2[] = "dummyId2";
const char kTestGaiaId3[] = "dummyId3";
const char kTestEmail[] = "me@gmail.com";
const char kTestEmail2[] = "me2@gmail.com";
const char kTestEmail3[] = "me3@gmail.com";

const char kTestHostedDomain[] = "example.com";
const char kTestFullName[] = "full_name";
const char kTestGivenName[] = "given_name";
const char kTestLocale[] = "locale";
const char kTestPictureUrl[] = "http://picture.example.com/picture.jpg";

#if defined(OS_CHROMEOS)
const char kTestEmailWithPeriod[] = "m.e@gmail.com";
#endif

// Subclass of FakeProfileOAuth2TokenService with bespoke behavior.
class CustomFakeProfileOAuth2TokenService
    : public FakeProfileOAuth2TokenService {
 public:
  CustomFakeProfileOAuth2TokenService(PrefService* user_prefs)
      : FakeProfileOAuth2TokenService(user_prefs) {}

  void set_on_access_token_invalidated_info(
      std::string expected_account_id_to_invalidate,
      std::set<std::string> expected_scopes_to_invalidate,
      std::string expected_access_token_to_invalidate,
      base::OnceClosure callback) {
    expected_account_id_to_invalidate_ = expected_account_id_to_invalidate;
    expected_scopes_to_invalidate_ = expected_scopes_to_invalidate;
    expected_access_token_to_invalidate_ = expected_access_token_to_invalidate;
    on_access_token_invalidated_callback_ = std::move(callback);
  }

 private:
  // OAuth2TokenService:
  void InvalidateAccessTokenImpl(const std::string& account_id,
                                 const std::string& client_id,
                                 const ScopeSet& scopes,
                                 const std::string& access_token) override {
    if (on_access_token_invalidated_callback_) {
      EXPECT_EQ(expected_account_id_to_invalidate_, account_id);
      EXPECT_EQ(expected_scopes_to_invalidate_, scopes);
      EXPECT_EQ(expected_access_token_to_invalidate_, access_token);

      // It should trigger OnAccessTokenRemovedFromCache from
      // IdentityManager::DiagnosticsObserver.
      for (auto& observer : GetDiagnicsObservers())
        observer.OnAccessTokenRemoved(account_id, scopes);

      std::move(on_access_token_invalidated_callback_).Run();
    }
  }

  std::string expected_account_id_to_invalidate_;
  std::set<std::string> expected_scopes_to_invalidate_;
  std::string expected_access_token_to_invalidate_;
  base::OnceClosure on_access_token_invalidated_callback_;
};

// Class that observes updates from ProfileOAuth2TokenService and and verifies
// thereby that IdentityManager receives updates before direct observers of
// ProfileOAuth2TokenService.
class TestTokenServiceObserver : public OAuth2TokenService::Observer,
                                 public identity::IdentityManager::Observer {
 public:
  explicit TestTokenServiceObserver(OAuth2TokenService* token_service)
      : token_service_(token_service) {
    token_service_->AddObserver(this);
  }
  ~TestTokenServiceObserver() override { token_service_->RemoveObserver(this); }

  void set_identity_manager(IdentityManager* identity_manager) {
    identity_manager_ = identity_manager;
  }

  void set_on_refresh_token_available_callback(base::OnceClosure callback) {
    on_refresh_token_available_callback_ = std::move(callback);
  }
  void set_on_refresh_token_revoked_callback(base::OnceClosure callback) {
    on_refresh_token_revoked_callback_ = std::move(callback);
  }

 private:
  // OAuth2TokenService::Observer:
  void OnRefreshTokenAvailable(const std::string& account_id) override {
    // IdentityManager should have already updated its state.
    EXPECT_TRUE(identity_manager_->HasAccountWithRefreshToken(account_id));
    if (on_refresh_token_available_callback_)
      std::move(on_refresh_token_available_callback_).Run();
  }
  void OnRefreshTokenRevoked(const std::string& account_id) override {
    // IdentityManager should have already updated its state.
    EXPECT_FALSE(identity_manager_->HasAccountWithRefreshToken(account_id));
    if (on_refresh_token_revoked_callback_)
      std::move(on_refresh_token_revoked_callback_).Run();
  }

  OAuth2TokenService* token_service_;
  IdentityManager* identity_manager_;
  base::OnceClosure on_refresh_token_available_callback_;
  base::OnceClosure on_refresh_token_revoked_callback_;
};

class TestIdentityManagerDiagnosticsObserver
    : IdentityManager::DiagnosticsObserver {
 public:
  explicit TestIdentityManagerDiagnosticsObserver(
      IdentityManager* identity_manager)
      : identity_manager_(identity_manager) {
    identity_manager_->AddDiagnosticsObserver(this);
  }
  ~TestIdentityManagerDiagnosticsObserver() override {
    identity_manager_->RemoveDiagnosticsObserver(this);
  }

  void set_on_access_token_requested_callback(base::OnceClosure callback) {
    on_access_token_requested_callback_ = std::move(callback);
  }

  void set_on_access_token_request_completed_callback(
      base::OnceClosure callback) {
    on_access_token_request_completed_callback_ = std::move(callback);
  }

  const std::string& token_requestor_account_id() {
    return token_requestor_account_id_;
  }
  const std::string& token_requestor_consumer_id() {
    return token_requestor_consumer_id_;
  }
  const identity::ScopeSet& token_requestor_scopes() {
    return token_requestor_scopes_;
  }
  const std::string& token_remover_account_id() {
    return token_remover_account_id_;
  }
  const identity::ScopeSet& token_remover_scopes() {
    return token_remover_scopes_;
  }
  const std::string& on_access_token_request_completed_account_id() {
    return access_token_request_completed_account_id_;
  }
  const std::string& on_access_token_request_completed_consumer_id() {
    return access_token_request_completed_consumer_id_;
  }
  const identity::ScopeSet& on_access_token_request_completed_scopes() {
    return access_token_request_completed_scopes_;
  }
  const GoogleServiceAuthError& on_access_token_request_completed_error() {
    return access_token_request_completed_error_;
  }

 private:
  // IdentityManager::DiagnosticsObserver:
  void OnAccessTokenRequested(const std::string& account_id,
                              const std::string& consumer_id,
                              const identity::ScopeSet& scopes) override {
    token_requestor_account_id_ = account_id;
    token_requestor_consumer_id_ = consumer_id;
    token_requestor_scopes_ = scopes;

    if (on_access_token_requested_callback_)
      std::move(on_access_token_requested_callback_).Run();
  }

  void OnAccessTokenRemovedFromCache(const std::string& account_id,
                                     const ScopeSet& scopes) override {
    token_remover_account_id_ = account_id;
    token_remover_scopes_ = scopes;
  }

  void OnAccessTokenRequestCompleted(const std::string& account_id,
                                     const std::string& consumer_id,
                                     const ScopeSet& scopes,
                                     GoogleServiceAuthError error,
                                     base::Time expiration_time) override {
    access_token_request_completed_account_id_ = account_id;
    access_token_request_completed_consumer_id_ = consumer_id;
    access_token_request_completed_scopes_ = scopes;
    access_token_request_completed_error_ = error;

    if (on_access_token_request_completed_callback_)
      std::move(on_access_token_request_completed_callback_).Run();
  }

  IdentityManager* identity_manager_;
  base::OnceClosure on_access_token_requested_callback_;
  base::OnceClosure on_access_token_request_completed_callback_;
  std::string token_requestor_account_id_;
  std::string token_requestor_consumer_id_;
  std::string token_remover_account_id_;
  identity::ScopeSet token_requestor_scopes_;
  identity::ScopeSet token_remover_scopes_;
  std::string access_token_request_completed_account_id_;
  std::string access_token_request_completed_consumer_id_;
  identity::ScopeSet access_token_request_completed_scopes_;
  GoogleServiceAuthError access_token_request_completed_error_;
};

}  // namespace

class IdentityManagerTest : public testing::Test {
 protected:
  IdentityManagerTest()
      : signin_client_(&pref_service_), token_service_(&pref_service_) {
    AccountTrackerService::RegisterPrefs(pref_service_.registry());
    AccountFetcherService::RegisterPrefs(pref_service_.registry());
    ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry());
    SigninManagerBase::RegisterProfilePrefs(pref_service_.registry());
    SigninManagerBase::RegisterPrefs(pref_service_.registry());

    account_tracker_.Initialize(&pref_service_, base::FilePath());
    account_fetcher_.Initialize(
        &signin_client_, &token_service_, &account_tracker_,
        std::make_unique<image_fetcher::FakeImageDecoder>());

    RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled,
                            SigninManagerSetup::kWithAuthenticatedAccout);
  }

  ~IdentityManagerTest() override {
    signin_client_.Shutdown();
    token_service_.Shutdown();
    account_tracker_.Shutdown();
    account_fetcher_.Shutdown();
  }

  void SetUp() override {
    primary_account_id_ =
        identity_manager_->PickAccountIdForAccount(kTestGaiaId, kTestEmail);
  }

  IdentityManager* identity_manager() { return identity_manager_.get(); }

  TestIdentityManagerObserver* identity_manager_observer() {
    return identity_manager_observer_.get();
  }

  TestIdentityManagerDiagnosticsObserver*
  identity_manager_diagnostics_observer() {
    return identity_manager_diagnostics_observer_.get();
  }

  AccountTrackerService* account_tracker() { return &account_tracker_; }

  AccountFetcherService* account_fetcher() { return &account_fetcher_; }
  CustomFakeProfileOAuth2TokenService* token_service() {
    return &token_service_;
  }

  // See RecreateIdentityManager.
  enum class SigninManagerSetup {
    kWithAuthenticatedAccout,
    kNoAuthenticatedAccount
  };

  // Used by some tests that need to re-instantiate IdentityManager after
  // performing some other setup.
  void RecreateIdentityManager() {
    RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled,
                            SigninManagerSetup::kNoAuthenticatedAccount);
  }

  // Recreates IdentityManager with given |account_consistency| and optionally
  // seeds with an authenticated account depending on |singin_manager_setup|.
  // This process destroys any existing IdentityManager and its dependencies,
  // then remakes them. Dependencies that outlive SigninManager (e.g.
  // SigninClient) will be reused.
  void RecreateIdentityManager(
      signin::AccountConsistencyMethod account_consistency,
      SigninManagerSetup signin_manager_setup) {
    // Remove observers first, otherwise IdentityManager destruction might
    // trigger a DCHECK because there are still living observers.
    identity_manager_observer_.reset();
    identity_manager_diagnostics_observer_.reset();
    identity_manager_.reset();

    auto gaia_cookie_manager_service =
        std::make_unique<GaiaCookieManagerService>(
            &token_service_, &signin_client_,
            base::BindRepeating(
                [](network::TestURLLoaderFactory* test_url_loader_factory)
                    -> scoped_refptr<network::SharedURLLoaderFactory> {
                  return test_url_loader_factory->GetSafeWeakWrapper();
                },
                test_url_loader_factory()));

#if defined(OS_CHROMEOS)
    DCHECK_EQ(account_consistency, signin::AccountConsistencyMethod::kDisabled)
        << "AccountConsistency is not used by SigninManagerBase";
    auto signin_manager = std::make_unique<SigninManagerBase>(
        &signin_client_, &token_service_, &account_tracker_);
#else
    auto signin_manager = std::make_unique<SigninManager>(
        &signin_client_, &token_service_, &account_tracker_,
        gaia_cookie_manager_service.get(), account_consistency);
#endif

    // Passing this switch ensures that the new SigninManager starts with a
    // clean slate. Otherwise SigninManagerBase::Initialize will use the account
    // id stored in prefs::kGoogleServicesAccountId.
    base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
    cmd_line->AppendSwitch(switches::kClearTokenService);

    signin_manager->Initialize(&pref_service_);

    if (signin_manager_setup == SigninManagerSetup::kWithAuthenticatedAccout) {
      signin_manager->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
    }

    auto accounts_cookie_mutator = std::make_unique<AccountsCookieMutatorImpl>(
        gaia_cookie_manager_service.get());

    auto diagnostics_provider = std::make_unique<DiagnosticsProviderImpl>(
        &token_service_, gaia_cookie_manager_service.get());

    identity_manager_.reset(new IdentityManager(
        std::move(gaia_cookie_manager_service), std::move(signin_manager),
        &token_service_, &account_fetcher_, &account_tracker_, nullptr, nullptr,
        std::move(accounts_cookie_mutator), std::move(diagnostics_provider)));
    identity_manager_observer_.reset(
        new TestIdentityManagerObserver(identity_manager_.get()));
    identity_manager_diagnostics_observer_.reset(
        new TestIdentityManagerDiagnosticsObserver(identity_manager_.get()));
  }

  void SimulateAdditionOfAccountToCookieSuccess(GaiaAuthConsumer* consumer,
                                                const std::string& data) {
    consumer->OnMergeSessionSuccess(data);
  }

  void SimulateAdditionOfAccountToCookieSuccessFailure(
      GaiaAuthConsumer* consumer,
      const GoogleServiceAuthError& error) {
    consumer->OnMergeSessionFailure(error);
  }

  void SimulateCookieDeletedByUser(
      network::mojom::CookieChangeListener* listener,
      const net::CanonicalCookie& cookie) {
    listener->OnCookieChange(cookie,
                             network::mojom::CookieChangeCause::EXPLICIT);
  }

  void SimulateOAuthMultiloginFinished(GaiaAuthConsumer* consumer,
                                       const OAuthMultiloginResult& result) {
    consumer->OnOAuthMultiloginFinished(result);
  }

  std::string primary_account_id() { return primary_account_id_; }

  TestSigninClient* signin_client() { return &signin_client_; }

  network::TestURLLoaderFactory* test_url_loader_factory() {
    return &test_url_loader_factory_;
  }

 private:
  base::MessageLoop message_loop_;
  sync_preferences::TestingPrefServiceSyncable pref_service_;
  AccountTrackerService account_tracker_;
  AccountFetcherService account_fetcher_;
  TestSigninClient signin_client_;
  CustomFakeProfileOAuth2TokenService token_service_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  std::unique_ptr<IdentityManager> identity_manager_;
  std::unique_ptr<TestIdentityManagerObserver> identity_manager_observer_;
  std::unique_ptr<TestIdentityManagerDiagnosticsObserver>
      identity_manager_diagnostics_observer_;
  std::string primary_account_id_;

  DISALLOW_COPY_AND_ASSIGN(IdentityManagerTest);
};

// Test that IdentityManager starts off with the information in SigninManager.
TEST_F(IdentityManagerTest, PrimaryAccountInfoAtStartup) {
  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
  EXPECT_EQ(kTestEmail, primary_account_info.email);
}

// Signin/signout tests aren't relevant and cannot build on ChromeOS, which
// doesn't support signin/signout.
#if !defined(OS_CHROMEOS)
// Test that the user signing in results in firing of the IdentityManager
// observer callback and the IdentityManager's state being updated.
TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSignin) {
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);

  SetPrimaryAccount(identity_manager(), kTestEmail);

  CoreAccountInfo primary_account_from_set_callback =
      identity_manager_observer()->PrimaryAccountFromSetCallback();
  EXPECT_EQ(kTestGaiaId, primary_account_from_set_callback.gaia);
  EXPECT_EQ(kTestEmail, primary_account_from_set_callback.email);

  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
  EXPECT_EQ(kTestEmail, primary_account_info.email);

  std::string primary_account_id = identity_manager()->GetPrimaryAccountId();
  EXPECT_EQ(primary_account_id, kTestGaiaId);
  EXPECT_EQ(primary_account_id, primary_account_info.account_id);
}

// Test that the user signing out results in firing of the IdentityManager
// observer callback and the IdentityManager's state being updated.
TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSigninAndSignout) {
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);
  // First ensure that the user is signed in from the POV of the
  // IdentityManager.
  SetPrimaryAccount(identity_manager(), kTestEmail);

  // Sign the user out and check that the IdentityManager responds
  // appropriately.
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);

  CoreAccountInfo primary_account_from_cleared_callback =
      identity_manager_observer()->PrimaryAccountFromClearedCallback();
  EXPECT_EQ(kTestGaiaId, primary_account_from_cleared_callback.gaia);
  EXPECT_EQ(kTestEmail, primary_account_from_cleared_callback.email);

  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  EXPECT_EQ("", primary_account_info.gaia);
  EXPECT_EQ("", primary_account_info.email);

  std::string primary_account_id = identity_manager()->GetPrimaryAccountId();
  EXPECT_EQ("", primary_account_id);
  EXPECT_EQ(primary_account_id, primary_account_info.account_id);
}

// Test that the primary account's ID remains tracked by the IdentityManager
// after signing in even after having removed the account without signing out.
TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSigninAndAccountRemoval) {
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);
  // First ensure that the user is signed in from the POV of the
  // IdentityManager.
  SetPrimaryAccount(identity_manager(), kTestEmail);

  // Remove the account from the AccountTrackerService and check that
  // the returned AccountInfo won't have a valid ID anymore, even if
  // the IdentityManager is still storing the primary account's ID.
  account_tracker()->RemoveAccount(kTestGaiaId);

  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  EXPECT_EQ("", primary_account_info.gaia);
  EXPECT_EQ("", primary_account_info.email);
  EXPECT_EQ("", primary_account_info.account_id);

  std::string primary_account_id = identity_manager()->GetPrimaryAccountId();
  EXPECT_EQ(primary_account_id, kTestGaiaId);
}
#endif  // !defined(OS_CHROMEOS)

TEST_F(IdentityManagerTest, HasPrimaryAccount) {
  EXPECT_TRUE(identity_manager()->HasPrimaryAccount());

  // Removing the account from the AccountTrackerService should not cause
  // IdentityManager to think that there is no longer a primary account.
  account_tracker()->RemoveAccount(identity_manager()->GetPrimaryAccountId());
  EXPECT_TRUE(identity_manager()->HasPrimaryAccount());

#if !defined(OS_CHROMEOS)
  // Signing out should cause IdentityManager to recognize that there is no
  // longer a primary account.
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);
  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
#endif
}

TEST_F(IdentityManagerTest, GetAccountsInteractionWithPrimaryAccount) {
  // Should not have any refresh tokens at initialization.
  EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty());

  // Add a refresh token for the primary account and check that it shows up in
  // GetAccountsWithRefreshTokens().
  SetRefreshTokenForPrimaryAccount(identity_manager());

  std::vector<AccountInfo> accounts_after_update =
      identity_manager()->GetAccountsWithRefreshTokens();

  EXPECT_EQ(1u, accounts_after_update.size());
  EXPECT_EQ(accounts_after_update[0].account_id, primary_account_id());
  EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId);
  EXPECT_EQ(accounts_after_update[0].email, kTestEmail);

  // Update the token and check that it doesn't change the state (or blow up).
  SetRefreshTokenForPrimaryAccount(identity_manager());

  std::vector<AccountInfo> accounts_after_second_update =
      identity_manager()->GetAccountsWithRefreshTokens();

  EXPECT_EQ(1u, accounts_after_second_update.size());
  EXPECT_EQ(accounts_after_second_update[0].account_id, primary_account_id());
  EXPECT_EQ(accounts_after_second_update[0].gaia, kTestGaiaId);
  EXPECT_EQ(accounts_after_second_update[0].email, kTestEmail);

  // Remove the token for the primary account and check that this is likewise
  // reflected.
  RemoveRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty());
}

TEST_F(IdentityManagerTest,
       QueryingOfRefreshTokensInteractionWithPrimaryAccount) {
  CoreAccountInfo account_info = identity_manager()->GetPrimaryAccountInfo();
  std::string account_id = account_info.account_id;

  // Should not have a refresh token for the primary account at initialization.
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Add a refresh token for the primary account and check that it affects this
  // state.
  SetRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
  EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Update the token and check that it doesn't change the state (or blow up).
  SetRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
  EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Remove the token for the primary account and check that this is likewise
  // reflected.
  RemoveRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
}

TEST_F(IdentityManagerTest, GetAccountsReflectsNonemptyInitialState) {
  EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty());

  // Add a refresh token for the primary account and sanity-check that it shows
  // up in GetAccountsWithRefreshTokens().
  SetRefreshTokenForPrimaryAccount(identity_manager());

  std::vector<AccountInfo> accounts_after_update =
      identity_manager()->GetAccountsWithRefreshTokens();

  EXPECT_EQ(1u, accounts_after_update.size());
  EXPECT_EQ(accounts_after_update[0].account_id, primary_account_id());
  EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId);
  EXPECT_EQ(accounts_after_update[0].email, kTestEmail);

  // Recreate the IdentityManager and check that the newly-created instance
  // reflects the current state.
  RecreateIdentityManager();

  std::vector<AccountInfo> accounts_after_recreation =
      identity_manager()->GetAccountsWithRefreshTokens();
  EXPECT_EQ(1u, accounts_after_recreation.size());
  EXPECT_EQ(accounts_after_recreation[0].account_id, primary_account_id());
  EXPECT_EQ(accounts_after_recreation[0].gaia, kTestGaiaId);
  EXPECT_EQ(accounts_after_recreation[0].email, kTestEmail);
}

TEST_F(IdentityManagerTest,
       QueryingOfRefreshTokensReflectsNonemptyInitialState) {
  CoreAccountInfo account_info = identity_manager()->GetPrimaryAccountInfo();
  std::string account_id = account_info.account_id;

  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  SetRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
  EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Recreate the IdentityManager and check that the newly-created instance
  // reflects the current state.
  RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled,
                          SigninManagerSetup::kWithAuthenticatedAccout);

  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
  EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());
}

TEST_F(IdentityManagerTest, GetAccountsInteractionWithSecondaryAccounts) {
  // Should not have any refresh tokens at initialization.
  EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty());

  // Add a refresh token for a secondary account and check that it shows up in
  // GetAccountsWithRefreshTokens().
  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  std::string account_id2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
  SetRefreshTokenForAccount(identity_manager(), account_id2);

  std::vector<AccountInfo> accounts_after_update =
      identity_manager()->GetAccountsWithRefreshTokens();

  EXPECT_EQ(1u, accounts_after_update.size());
  EXPECT_EQ(accounts_after_update[0].account_id, account_id2);
  EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId2);
  EXPECT_EQ(accounts_after_update[0].email, kTestEmail2);

  // Add a refresh token for a different secondary account and check that it
  // also shows up in GetAccountsWithRefreshTokens().
  account_tracker()->SeedAccountInfo(kTestGaiaId3, kTestEmail3);
  std::string account_id3 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId3).account_id;
  SetRefreshTokenForAccount(identity_manager(), account_id3);

  std::vector<AccountInfo> accounts_after_second_update =
      identity_manager()->GetAccountsWithRefreshTokens();
  EXPECT_EQ(2u, accounts_after_second_update.size());

  for (AccountInfo account_info : accounts_after_second_update) {
    if (account_info.account_id == account_id2) {
      EXPECT_EQ(account_info.gaia, kTestGaiaId2);
      EXPECT_EQ(account_info.email, kTestEmail2);
    } else {
      EXPECT_EQ(account_info.gaia, kTestGaiaId3);
      EXPECT_EQ(account_info.email, kTestEmail3);
    }
  }

  // Remove the token for account2 and check that account3 is still present.
  RemoveRefreshTokenForAccount(identity_manager(), account_id2);

  std::vector<AccountInfo> accounts_after_third_update =
      identity_manager()->GetAccountsWithRefreshTokens();

  EXPECT_EQ(1u, accounts_after_third_update.size());
  EXPECT_EQ(accounts_after_third_update[0].account_id, account_id3);
  EXPECT_EQ(accounts_after_third_update[0].gaia, kTestGaiaId3);
  EXPECT_EQ(accounts_after_third_update[0].email, kTestEmail3);
}

TEST_F(IdentityManagerTest,
       HasPrimaryAccountWithRefreshTokenInteractionWithSecondaryAccounts) {
  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Adding a refresh token for a secondary account shouldn't change anything
  // about the primary account
  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  std::string account_id2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
  SetRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Adding a refresh token for a different secondary account should not do so
  // either.
  account_tracker()->SeedAccountInfo(kTestGaiaId3, kTestEmail3);
  std::string account_id3 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId3).account_id;
  SetRefreshTokenForAccount(identity_manager(), account_id3);

  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Removing the token for account2 should have no effect.
  RemoveRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
}

TEST_F(IdentityManagerTest,
       HasAccountWithRefreshTokenInteractionWithSecondaryAccounts) {
  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  AccountInfo account_info2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2);
  std::string account_id2 = account_info2.account_id;

  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));

  // Add a refresh token for account_info2 and check that this is reflected by
  // HasAccountWithRefreshToken(.account_id).
  SetRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));

  // Go through the same process for a different secondary account.
  account_tracker()->SeedAccountInfo(kTestGaiaId3, kTestEmail3);
  AccountInfo account_info3 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId3);
  std::string account_id3 = account_info3.account_id;

  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info3.account_id));

  SetRefreshTokenForAccount(identity_manager(), account_id3);

  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info3.account_id));

  // Remove the token for account2.
  RemoveRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info3.account_id));
}

TEST_F(IdentityManagerTest,
       GetAccountsInteractionBetweenPrimaryAndSecondaryAccounts) {
  // Should not have any refresh tokens at initialization.
  EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty());

  // Add a refresh token for a secondary account and check that it shows up in
  // GetAccountsWithRefreshTokens().
  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  std::string account_id2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
  SetRefreshTokenForAccount(identity_manager(), account_id2);

  std::vector<AccountInfo> accounts_after_update =
      identity_manager()->GetAccountsWithRefreshTokens();

  EXPECT_EQ(1u, accounts_after_update.size());
  EXPECT_EQ(accounts_after_update[0].account_id, account_id2);
  EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId2);
  EXPECT_EQ(accounts_after_update[0].email, kTestEmail2);

  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Add a refresh token for the primary account and check that it
  // also shows up in GetAccountsWithRefreshTokens().
  SetRefreshTokenForPrimaryAccount(identity_manager());

  std::vector<AccountInfo> accounts_after_second_update =
      identity_manager()->GetAccountsWithRefreshTokens();
  EXPECT_EQ(2u, accounts_after_second_update.size());

  for (AccountInfo account_info : accounts_after_second_update) {
    if (account_info.account_id == account_id2) {
      EXPECT_EQ(account_info.gaia, kTestGaiaId2);
      EXPECT_EQ(account_info.email, kTestEmail2);
    } else {
      EXPECT_EQ(account_info.gaia, kTestGaiaId);
      EXPECT_EQ(account_info.email, kTestEmail);
    }
  }

  EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Remove the token for the primary account and check that account2 is still
  // present.
  RemoveRefreshTokenForPrimaryAccount(identity_manager());

  std::vector<AccountInfo> accounts_after_third_update =
      identity_manager()->GetAccountsWithRefreshTokens();

  EXPECT_EQ(1u, accounts_after_third_update.size());
  EXPECT_EQ(accounts_after_update[0].account_id, account_id2);
  EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId2);
  EXPECT_EQ(accounts_after_update[0].email, kTestEmail2);

  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
}

TEST_F(
    IdentityManagerTest,
    HasPrimaryAccountWithRefreshTokenInteractionBetweenPrimaryAndSecondaryAccounts) {
  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Add a refresh token for a secondary account and check that it doesn't
  // impact the above state.
  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  std::string account_id2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
  SetRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Add a refresh token for the primary account and check that it
  // *does* impact the stsate of HasPrimaryAccountWithRefreshToken().
  SetRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Remove the token for the secondary account and check that this doesn't flip
  // the state.
  RemoveRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());

  // Remove the token for the primary account and check that this flips the
  // state.
  RemoveRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
}

TEST_F(
    IdentityManagerTest,
    HasAccountWithRefreshTokenInteractionBetweenPrimaryAndSecondaryAccounts) {
  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  std::string primary_account_id = primary_account_info.account_id;

  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  AccountInfo account_info2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2);
  std::string account_id2 = account_info2.account_id;

  EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(
      primary_account_info.account_id));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));

  // Add a refresh token for account_info2 and check that this is reflected by
  // HasAccountWithRefreshToken(.account_id).
  SetRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(
      primary_account_info.account_id));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));

  // Go through the same process for the primary account.
  SetRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
      primary_account_info.account_id));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));

  // Remove the token for account2.
  RemoveRefreshTokenForAccount(identity_manager(), account_id2);

  EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
      primary_account_info.account_id));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshToken(account_info2.account_id));
}

TEST_F(IdentityManagerTest,
       CallbackSentOnUpdateToErrorStateOfRefreshTokenForAccount) {
  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  std::string primary_account_id = primary_account_info.account_id;
  SetRefreshTokenForPrimaryAccount(identity_manager());

  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  AccountInfo account_info2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2);
  std::string account_id2 = account_info2.account_id;
  SetRefreshTokenForAccount(identity_manager(), account_id2);

  GoogleServiceAuthError account_deleted_error =
      GoogleServiceAuthError(GoogleServiceAuthError::State::ACCOUNT_DELETED);
  GoogleServiceAuthError account_disabled_error =
      GoogleServiceAuthError(GoogleServiceAuthError::State::ACCOUNT_DISABLED);
  GoogleServiceAuthError transient_error = GoogleServiceAuthError(
      GoogleServiceAuthError::State::SERVICE_UNAVAILABLE);

  // Set a persistent error for |account_id2| and check that it's reflected.
  token_service()->UpdateAuthErrorForTesting(account_id2,
                                             account_deleted_error);
  EXPECT_EQ(account_id2,
            identity_manager_observer()
                ->AccountFromErrorStateOfRefreshTokenUpdatedCallback()
                .account_id);
  EXPECT_EQ(account_deleted_error,
            identity_manager_observer()
                ->ErrorFromErrorStateOfRefreshTokenUpdatedCallback());

  // A transient error should not cause a callback.
  token_service()->UpdateAuthErrorForTesting(primary_account_id,
                                             transient_error);
  EXPECT_EQ(account_id2,
            identity_manager_observer()
                ->AccountFromErrorStateOfRefreshTokenUpdatedCallback()
                .account_id);
  EXPECT_EQ(account_deleted_error,
            identity_manager_observer()
                ->ErrorFromErrorStateOfRefreshTokenUpdatedCallback());

  // Set a different persistent error for the primary account and check that
  // it's reflected.
  token_service()->UpdateAuthErrorForTesting(primary_account_id,
                                             account_disabled_error);
  EXPECT_EQ(primary_account_id,
            identity_manager_observer()
                ->AccountFromErrorStateOfRefreshTokenUpdatedCallback()
                .account_id);
  EXPECT_EQ(account_disabled_error,
            identity_manager_observer()
                ->ErrorFromErrorStateOfRefreshTokenUpdatedCallback());
}

TEST_F(IdentityManagerTest, GetErrorStateOfRefreshTokenForAccount) {
  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  std::string primary_account_id = primary_account_info.account_id;

  // A primary account without a refresh token should not be in an error
  // state, and setting a refresh token should not affect that.
  EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
            identity_manager()->GetErrorStateOfRefreshTokenForAccount(
                primary_account_id));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          primary_account_id));

  SetRefreshTokenForPrimaryAccount(identity_manager());
  EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
            identity_manager()->GetErrorStateOfRefreshTokenForAccount(
                primary_account_id));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          primary_account_id));

  // A secondary account without a refresh token should not be in an error
  // state, and setting a refresh token should not affect that.
  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  AccountInfo account_info2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2);
  std::string account_id2 = account_info2.account_id;
  EXPECT_EQ(
      GoogleServiceAuthError::AuthErrorNone(),
      identity_manager()->GetErrorStateOfRefreshTokenForAccount(account_id2));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          account_id2));

  SetRefreshTokenForAccount(identity_manager(), account_id2);
  EXPECT_EQ(
      GoogleServiceAuthError::AuthErrorNone(),
      identity_manager()->GetErrorStateOfRefreshTokenForAccount(account_id2));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          account_id2));

  GoogleServiceAuthError account_deleted_error =
      GoogleServiceAuthError(GoogleServiceAuthError::State::ACCOUNT_DELETED);
  GoogleServiceAuthError account_disabled_error =
      GoogleServiceAuthError(GoogleServiceAuthError::State::ACCOUNT_DISABLED);
  GoogleServiceAuthError transient_error = GoogleServiceAuthError(
      GoogleServiceAuthError::State::SERVICE_UNAVAILABLE);

  // Set a persistent error for |account_id2| and check that it's reflected.
  token_service()->UpdateAuthErrorForTesting(account_id2,
                                             account_deleted_error);
  EXPECT_EQ(
      account_deleted_error,
      identity_manager()->GetErrorStateOfRefreshTokenForAccount(account_id2));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          account_id2));
  EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
            identity_manager()->GetErrorStateOfRefreshTokenForAccount(
                primary_account_id));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          primary_account_id));

  // A transient error should cause no change in the error state.
  token_service()->UpdateAuthErrorForTesting(primary_account_id,
                                             transient_error);
  EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
            identity_manager()->GetErrorStateOfRefreshTokenForAccount(
                primary_account_id));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          primary_account_id));

  // Set a different persistent error for the primary account and check that
  // it's reflected.
  token_service()->UpdateAuthErrorForTesting(primary_account_id,
                                             account_disabled_error);
  EXPECT_EQ(
      account_deleted_error,
      identity_manager()->GetErrorStateOfRefreshTokenForAccount(account_id2));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          account_id2));
  EXPECT_EQ(account_disabled_error,
            identity_manager()->GetErrorStateOfRefreshTokenForAccount(
                primary_account_id));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          primary_account_id));

  // Remove the token for account2 and check that it goes back to having no
  // error.
  RemoveRefreshTokenForAccount(identity_manager(), account_id2);
  EXPECT_EQ(
      GoogleServiceAuthError::AuthErrorNone(),
      identity_manager()->GetErrorStateOfRefreshTokenForAccount(account_id2));
  EXPECT_FALSE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          account_id2));
  EXPECT_EQ(account_disabled_error,
            identity_manager()->GetErrorStateOfRefreshTokenForAccount(
                primary_account_id));
  EXPECT_TRUE(
      identity_manager()->HasAccountWithRefreshTokenInPersistentErrorState(
          primary_account_id));
}

TEST_F(IdentityManagerTest, RemoveAccessTokenFromCache) {
  std::set<std::string> scopes{"scope"};
  std::string access_token = "access_token";

  identity_manager()->GetSigninManager()->SetAuthenticatedAccountInfo(
      kTestGaiaId, kTestEmail);
  token_service()->UpdateCredentials(primary_account_id(), "refresh_token");

  base::RunLoop run_loop;
  token_service()->set_on_access_token_invalidated_info(
      primary_account_id(), scopes, access_token, run_loop.QuitClosure());

  identity_manager()->RemoveAccessTokenFromCache(primary_account_id(), scopes,
                                                 access_token);

  run_loop.Run();

  // RemoveAccessTokenFromCache should lead to OnAccessTokenRemovedFromCache
  // from IdentityManager::DiagnosticsObserver.
  EXPECT_EQ(
      primary_account_id(),
      identity_manager_diagnostics_observer()->token_remover_account_id());
  EXPECT_EQ(scopes,
            identity_manager_diagnostics_observer()->token_remover_scopes());
}

TEST_F(IdentityManagerTest, CreateAccessTokenFetcher) {
  std::set<std::string> scopes{"scope"};
  AccessTokenFetcher::TokenCallback callback = base::BindOnce(
      [](GoogleServiceAuthError error, AccessTokenInfo access_token_info) {});
  std::unique_ptr<AccessTokenFetcher> token_fetcher =
      identity_manager()->CreateAccessTokenFetcherForAccount(
          identity_manager()->GetPrimaryAccountId(), kTestConsumerId, scopes,
          std::move(callback), AccessTokenFetcher::Mode::kImmediate);
  EXPECT_TRUE(token_fetcher);
}

TEST_F(IdentityManagerTest,
       CreateAccessTokenFetcherWithCustomURLLoaderFactory) {
  base::RunLoop run_loop;
  identity_manager_diagnostics_observer()
      ->set_on_access_token_requested_callback(run_loop.QuitClosure());

  identity_manager()->GetSigninManager()->SetAuthenticatedAccountInfo(
      kTestGaiaId, kTestEmail);
  token_service()->UpdateCredentials(primary_account_id(), "refresh_token");

  std::set<std::string> scopes{"scope"};
  AccessTokenFetcher::TokenCallback callback = base::BindOnce(
      [](GoogleServiceAuthError error, AccessTokenInfo access_token_info) {});

  // We first create and AccessTokenFetcher with a custom URLLoaderFactory,
  // to check that such factory is actually used in the requests generated.
  network::TestURLLoaderFactory test_url_loader_factory;
  scoped_refptr<network::SharedURLLoaderFactory> test_shared_url_loader_factory(
      base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
          &test_url_loader_factory));
  std::unique_ptr<AccessTokenFetcher> token_fetcher =
      identity_manager()->CreateAccessTokenFetcherForAccount(
          primary_account_id(), kTestConsumerId, test_shared_url_loader_factory,
          scopes, std::move(callback), AccessTokenFetcher::Mode::kImmediate);

  run_loop.Run();

  // The URLLoaderFactory present in the pending request should match
  // the one we specified when creating the AccessTokenFetcher.
  std::vector<FakeProfileOAuth2TokenService::PendingRequest> pending_requests =
      token_service()->GetPendingRequests();
  EXPECT_EQ(pending_requests.size(), 1U);
  EXPECT_EQ(pending_requests[0].url_loader_factory,
            test_shared_url_loader_factory);

  // The account ID and consumer's name should match the data passed as well.
  EXPECT_EQ(
      primary_account_id(),
      identity_manager_diagnostics_observer()->token_requestor_account_id());
  EXPECT_EQ(
      kTestConsumerId,
      identity_manager_diagnostics_observer()->token_requestor_consumer_id());

  // Cancel the pending request in preparation to check that creating an
  // AccessTokenFetcher without a custom factory works as expected as well.
  token_service()->IssueErrorForAllPendingRequestsForAccount(
      primary_account_id(),
      GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));

  // Now add a second account and request an access token for it to test
  // that the default URLLoaderFactory is used if none is specified.
  base::RunLoop run_loop2;
  identity_manager_diagnostics_observer()
      ->set_on_access_token_requested_callback(run_loop2.QuitClosure());

  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  std::string account_id2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
  token_service()->UpdateCredentials(account_id2, "refresh_token");

  // No changes to the declared scopes and callback, we can reuse them.
  std::unique_ptr<AccessTokenFetcher> token_fetcher2 =
      identity_manager()->CreateAccessTokenFetcherForAccount(
          account_id2, kTestConsumerId2, scopes, std::move(callback),
          AccessTokenFetcher::Mode::kImmediate);

  run_loop2.Run();

  // There should be one pending request now as well, just like before.
  std::vector<FakeProfileOAuth2TokenService::PendingRequest> pending_requests2 =
      token_service()->GetPendingRequests();
  EXPECT_EQ(pending_requests2.size(), 1U);

  // The URLLoaderFactory present in the pending request should match
  // the one created by default for the token service's delegate.
  OAuth2TokenServiceDelegate* service_delegate = token_service()->GetDelegate();
  EXPECT_EQ(pending_requests2[0].url_loader_factory,
            service_delegate->GetURLLoaderFactory());

  // The account ID and consumer's name should match the data passed again.
  EXPECT_EQ(
      account_id2,
      identity_manager_diagnostics_observer()->token_requestor_account_id());
  EXPECT_EQ(
      kTestConsumerId2,
      identity_manager_diagnostics_observer()->token_requestor_consumer_id());
}

TEST_F(IdentityManagerTest, ObserveAccessTokenFetch) {
  base::RunLoop run_loop;
  identity_manager_diagnostics_observer()
      ->set_on_access_token_requested_callback(run_loop.QuitClosure());

  identity_manager()->GetSigninManager()->SetAuthenticatedAccountInfo(
      kTestGaiaId, kTestEmail);
  token_service()->UpdateCredentials(primary_account_id(), "refresh_token");

  std::set<std::string> scopes{"scope"};
  AccessTokenFetcher::TokenCallback callback = base::BindOnce(
      [](GoogleServiceAuthError error, AccessTokenInfo access_token_info) {});
  std::unique_ptr<AccessTokenFetcher> token_fetcher =
      identity_manager()->CreateAccessTokenFetcherForAccount(
          identity_manager()->GetPrimaryAccountId(), kTestConsumerId, scopes,
          std::move(callback), AccessTokenFetcher::Mode::kImmediate);

  run_loop.Run();

  EXPECT_EQ(
      primary_account_id(),
      identity_manager_diagnostics_observer()->token_requestor_account_id());
  EXPECT_EQ(
      kTestConsumerId,
      identity_manager_diagnostics_observer()->token_requestor_consumer_id());
  EXPECT_EQ(scopes,
            identity_manager_diagnostics_observer()->token_requestor_scopes());
}

TEST_F(IdentityManagerTest,
       ObserveAccessTokenRequestCompletionWithoutRefreshToken) {
  base::RunLoop run_loop;
  identity_manager_diagnostics_observer()
      ->set_on_access_token_request_completed_callback(run_loop.QuitClosure());

  std::set<std::string> scopes{"scope"};
  AccessTokenFetcher::TokenCallback callback = base::BindOnce(
      [](GoogleServiceAuthError error, AccessTokenInfo access_token_info) {});
  // Account has no refresh token.
  std::unique_ptr<AccessTokenFetcher> token_fetcher =
      identity_manager()->CreateAccessTokenFetcherForAccount(
          identity_manager()->GetPrimaryAccountId(), kTestConsumerId, scopes,
          std::move(callback), AccessTokenFetcher::Mode::kImmediate);

  run_loop.Run();

  EXPECT_TRUE(token_fetcher);
  EXPECT_EQ(GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP),
            identity_manager_diagnostics_observer()
                ->on_access_token_request_completed_error());
}

TEST_F(IdentityManagerTest,
       ObserveAccessTokenRequestCompletionWithRefreshToken) {
  base::RunLoop run_loop;
  identity_manager_diagnostics_observer()
      ->set_on_access_token_request_completed_callback(run_loop.QuitClosure());

  identity_manager()->GetSigninManager()->SetAuthenticatedAccountInfo(
      kTestGaiaId, kTestEmail);
  token_service()->UpdateCredentials(primary_account_id(), "refresh_token");
  token_service()->set_auto_post_fetch_response_on_message_loop(true);

  std::set<std::string> scopes{"scope"};
  AccessTokenFetcher::TokenCallback callback = base::BindOnce(
      [](GoogleServiceAuthError error, AccessTokenInfo access_token_info) {});
  // This should result in a request for an access token without an error.
  std::unique_ptr<AccessTokenFetcher> token_fetcher =
      identity_manager()->CreateAccessTokenFetcherForAccount(
          identity_manager()->GetPrimaryAccountId(), kTestConsumerId, scopes,
          std::move(callback), AccessTokenFetcher::Mode::kImmediate);

  run_loop.Run();

  EXPECT_TRUE(token_fetcher);
  EXPECT_EQ(primary_account_id(),
            identity_manager_diagnostics_observer()
                ->on_access_token_request_completed_account_id());
  EXPECT_EQ(kTestConsumerId,
            identity_manager_diagnostics_observer()
                ->on_access_token_request_completed_consumer_id());
  EXPECT_EQ(scopes, identity_manager_diagnostics_observer()
                        ->on_access_token_request_completed_scopes());
  EXPECT_EQ(GoogleServiceAuthError(GoogleServiceAuthError::NONE),
            identity_manager_diagnostics_observer()
                ->on_access_token_request_completed_error());
}

TEST_F(IdentityManagerTest,
       ObserveAccessTokenRequestCompletionAfterRevokingRefreshToken) {
  base::RunLoop run_loop;
  identity_manager_diagnostics_observer()
      ->set_on_access_token_request_completed_callback(run_loop.QuitClosure());

  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
  std::string account_id2 =
      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
  token_service()->UpdateCredentials(account_id2, "refresh_token");

  std::set<std::string> scopes{"scope"};
  AccessTokenFetcher::TokenCallback callback = base::BindOnce(
      [](GoogleServiceAuthError error, AccessTokenInfo access_token_info) {});
  // This should result in a request for an access token.
  std::unique_ptr<AccessTokenFetcher> token_fetcher =
      identity_manager()->CreateAccessTokenFetcherForAccount(
          account_id2, kTestConsumerId2, scopes, std::move(callback),
          AccessTokenFetcher::Mode::kImmediate);

  // Revoke the refresh token result cancelling access token request.
  token_service()->RevokeCredentials(account_id2);

  run_loop.Run();

  EXPECT_TRUE(token_fetcher);
  EXPECT_EQ(GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED),
            identity_manager_diagnostics_observer()
                ->on_access_token_request_completed_error());
}

TEST_F(IdentityManagerTest, GetAccountsCookieMutator) {
  AccountsCookieMutator* mutator =
      identity_manager()->GetAccountsCookieMutator();
  EXPECT_TRUE(mutator);
}

#if !defined(OS_IOS) && !defined(OS_ANDROID)
// Tests that requesting a load of accounts results in the notification
// firing that tokens were loaded.
TEST_F(IdentityManagerTest, DeprecatedLoadCredentialsForSupervisedUser) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
      run_loop.QuitClosure());

  // Load the accounts and ensure that we see the resulting notification that
  // they were loaded.
  identity_manager()->DeprecatedLoadCredentialsForSupervisedUser("");
  run_loop.Run();
}
#endif

TEST_F(IdentityManagerTest, LegacySeedAccountInfo) {
  ASSERT_FALSE(
      identity_manager()
          ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(kTestEmail2)
          .has_value());
  ASSERT_FALSE(
      identity_manager()
          ->FindAccountInfoForAccountWithRefreshTokenByGaiaId(kTestGaiaId2)
          .has_value());

  AccountInfo input_info;
  input_info.email = kTestEmail2;
  input_info.gaia = kTestGaiaId2;
  const std::string account_id =
      identity_manager()->LegacySeedAccountInfo(input_info);

  AccountInfo account_info = account_tracker()->GetAccountInfo(account_id);

  EXPECT_EQ(account_info.account_id, account_id);
  EXPECT_EQ(account_info.email, kTestEmail2);
  EXPECT_EQ(account_info.gaia, kTestGaiaId2);
}

#if defined(OS_IOS)
TEST_F(IdentityManagerTest, ForceTriggerOnCookieChange) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());
  // Forces the processing of OnCookieChange and it calls
  // OnGaiaAccountsInCookieUpdated.
  identity_manager()->ForceTriggerOnCookieChange();
  run_loop.Run();
}
#endif

#if defined(OS_CHROMEOS)
// On ChromeOS, AccountTrackerService first receives the normalized email
// address from GAIA and then later has it updated with the user's
// originally-specified version of their email address (at the time of that
// address' creation). This latter will differ if the user's originally-
// specified address was not in normalized form (e.g., if it contained
// periods). This test simulates such a flow in order to verify that
// IdentityManager correctly reflects the updated version. See crbug.com/842041
// and crbug.com/842670 for further details.
TEST_F(IdentityManagerTest, IdentityManagerReflectsUpdatedEmailAddress) {
  CoreAccountInfo primary_account_info =
      identity_manager()->GetPrimaryAccountInfo();
  EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
  EXPECT_EQ(kTestEmail, primary_account_info.email);

  // Simulate the flow wherein the user's email address was updated
  // to the originally-created non-normalized version.
  SimulateSuccessfulFetchOfAccountInfo(
      identity_manager(), primary_account_info.account_id, kTestEmailWithPeriod,
      kTestGaiaId, kTestHostedDomain, kTestFullName, kTestGivenName,
      kTestLocale, kTestPictureUrl);
  // Verify that IdentityManager reflects the update.
  primary_account_info = identity_manager()->GetPrimaryAccountInfo();
  EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
  EXPECT_EQ(kTestEmailWithPeriod, primary_account_info.email);
}
#endif

TEST_F(IdentityManagerTest,
       CallbackSentOnPrimaryAccountRefreshTokenUpdateWithValidToken) {
  SetRefreshTokenForPrimaryAccount(identity_manager());

  CoreAccountInfo account_info =
      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
  EXPECT_EQ(kTestGaiaId, account_info.gaia);
  EXPECT_EQ(kTestEmail, account_info.email);
}

TEST_F(IdentityManagerTest,
       CallbackSentOnPrimaryAccountRefreshTokenUpdateWithInvalidToken) {
  SetInvalidRefreshTokenForPrimaryAccount(identity_manager());

  CoreAccountInfo account_info =
      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
  EXPECT_EQ(kTestGaiaId, account_info.gaia);
  EXPECT_EQ(kTestEmail, account_info.email);
}

TEST_F(IdentityManagerTest, CallbackSentOnPrimaryAccountRefreshTokenRemoval) {
  SetRefreshTokenForPrimaryAccount(identity_manager());

  RemoveRefreshTokenForPrimaryAccount(identity_manager());

  EXPECT_EQ(
      primary_account_id(),
      identity_manager_observer()->AccountIdFromRefreshTokenRemovedCallback());
}

TEST_F(IdentityManagerTest,
       CallbackSentOnSecondaryAccountRefreshTokenUpdateWithValidToken) {
  AccountInfo expected_account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);
  EXPECT_EQ(kTestEmail2, expected_account_info.email);

  CoreAccountInfo account_info =
      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
  EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
  EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
  EXPECT_EQ(expected_account_info.email, account_info.email);
}

TEST_F(IdentityManagerTest,
       CallbackSentOnSecondaryAccountRefreshTokenUpdateWithInvalidToken) {
  AccountInfo expected_account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);
  EXPECT_EQ(kTestEmail2, expected_account_info.email);

  SetInvalidRefreshTokenForAccount(identity_manager(),
                                   expected_account_info.account_id);

  CoreAccountInfo account_info =
      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
  EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
  EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
  EXPECT_EQ(expected_account_info.email, account_info.email);
}

TEST_F(IdentityManagerTest, CallbackSentOnSecondaryAccountRefreshTokenRemoval) {
  AccountInfo expected_account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);
  EXPECT_EQ(kTestEmail2, expected_account_info.email);

  RemoveRefreshTokenForAccount(identity_manager(),
                               expected_account_info.account_id);

  EXPECT_EQ(
      expected_account_info.account_id,
      identity_manager_observer()->AccountIdFromRefreshTokenRemovedCallback());
}

#if !defined(OS_CHROMEOS)
TEST_F(
    IdentityManagerTest,
    CallbackSentOnSecondaryAccountRefreshTokenUpdateWithValidTokenWhenNoPrimaryAccount) {
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);

  AccountInfo expected_account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);
  EXPECT_EQ(kTestEmail2, expected_account_info.email);

  CoreAccountInfo account_info =
      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
  EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
  EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
  EXPECT_EQ(expected_account_info.email, account_info.email);
}

TEST_F(
    IdentityManagerTest,
    CallbackSentOnSecondaryAccountRefreshTokenUpdateWithInvalidTokenWhenNoPrimaryAccount) {
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);

  AccountInfo expected_account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);
  EXPECT_EQ(kTestEmail2, expected_account_info.email);

  SetInvalidRefreshTokenForAccount(identity_manager(),
                                   expected_account_info.account_id);

  CoreAccountInfo account_info =
      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
  EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
  EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
  EXPECT_EQ(expected_account_info.email, account_info.email);
}

TEST_F(IdentityManagerTest,
       CallbackSentOnSecondaryAccountRefreshTokenRemovalWhenNoPrimaryAccount) {
  ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);

  AccountInfo expected_account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);
  EXPECT_EQ(kTestEmail2, expected_account_info.email);

  RemoveRefreshTokenForAccount(identity_manager(),
                               expected_account_info.account_id);

  EXPECT_EQ(
      expected_account_info.account_id,
      identity_manager_observer()->AccountIdFromRefreshTokenRemovedCallback());
}
#endif

TEST_F(IdentityManagerTest, CallbackSentOnRefreshTokenRemovalOfUnknownAccount) {
  // When the token service is still loading credentials, it may send token
  // revoked callbacks for accounts that it has never sent a token available
  // callback. Our common test setup actually completes this loading, so use the
  // *for_testing() method below to simulate the race condition and ensure that
  // IdentityManager passes on the callback in this case.
  token_service()->set_all_credentials_loaded_for_testing(false);

  std::string dummy_account_id = "dummy_account";

  base::RunLoop run_loop;
  token_service()->RevokeCredentials(dummy_account_id);
  run_loop.RunUntilIdle();

  EXPECT_EQ(
      dummy_account_id,
      identity_manager_observer()->AccountIdFromRefreshTokenRemovedCallback());
}

TEST_F(
    IdentityManagerTest,
    IdentityManagerGivesConsistentValuesFromTokenServiceObserverNotificationOfTokenUpdate) {
  base::RunLoop run_loop;
  TestTokenServiceObserver token_service_observer(token_service());
  token_service_observer.set_on_refresh_token_available_callback(
      run_loop.QuitClosure());

  // NOTE: For this test to be meaningful, TestTokenServiceObserver
  // needs to be created before the IdentityManager instance that it's
  // interacting with. Otherwise, even an implementation where they're
  // both TokenService::Observers would work as IdentityManager would
  // get notified first during the observer callbacks.
  RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled,
                          SigninManagerSetup::kWithAuthenticatedAccout);
  EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty());
  token_service_observer.set_identity_manager(identity_manager());

  // When the observer receives the callback directly from the token service,
  // IdentityManager should have already received the event and forwarded it on
  // to its own observers. This is checked internally by
  // TestTokenServiceObserver.
  token_service()->UpdateCredentials(primary_account_id(), "refresh_token");
  run_loop.Run();
}

TEST_F(
    IdentityManagerTest,
    IdentityManagerGivesConsistentValuesFromTokenServiceObserverNotificationOfTokenRemoval) {
  base::RunLoop run_loop;
  TestTokenServiceObserver token_service_observer(token_service());
  token_service_observer.set_on_refresh_token_available_callback(
      run_loop.QuitClosure());

  // NOTE: For this test to be meaningful, TestTokenServiceObserver
  // needs to be created before the IdentityManager instance that it's
  // interacting with. Otherwise, even an implementation where they're
  // both TokenService::Observers would work as IdentityManager would
  // get notified first during the observer callbacks.
  RecreateIdentityManager(signin::AccountConsistencyMethod::kDisabled,
                          SigninManagerSetup::kWithAuthenticatedAccout);
  token_service_observer.set_identity_manager(identity_manager());

  token_service()->UpdateCredentials(primary_account_id(), "refresh_token");
  run_loop.Run();

  // When the observer receives the callback directly from the token service,
  // IdentityManager should have already received the event and forwarded it on
  // to its own observers. This is checked internally by
  // TestTokenServiceObserver.
  base::RunLoop run_loop2;
  token_service_observer.set_on_refresh_token_revoked_callback(
      run_loop2.QuitClosure());
  token_service()->RevokeCredentials(primary_account_id());
  run_loop2.Run();
}

TEST_F(IdentityManagerTest, IdentityManagerGetsTokensLoadedEvent) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
      run_loop.QuitClosure());

  // Credentials are already loaded in SigninManager::Initialize()
  // which runs even before the IdentityManager is created. That's why
  // we fake the credentials loaded state and force another load in
  // order to be able to capture the TokensLoaded event.
  token_service()->set_all_credentials_loaded_for_testing(false);
  token_service()->LoadCredentials("");
  run_loop.Run();
}

TEST_F(IdentityManagerTest,
       CallbackSentOnUpdateToAccountsInCookieWithNoAccounts) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());
  identity_manager()->GetGaiaCookieManagerService()->TriggerListAccounts();
  run_loop.Run();

  const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
      identity_manager_observer()
          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
  EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
  EXPECT_TRUE(accounts_in_cookie_jar_info.signed_in_accounts.empty());
}

TEST_F(IdentityManagerTest,
       CallbackSentOnUpdateToAccountsInCookieWithOneAccount) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  signin::SetListAccountsResponseOneAccount(kTestEmail, kTestGaiaId,
                                            test_url_loader_factory());
  identity_manager()->GetGaiaCookieManagerService()->TriggerListAccounts();
  run_loop.Run();

  const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
      identity_manager_observer()
          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
  EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
  ASSERT_EQ(1u, accounts_in_cookie_jar_info.signed_in_accounts.size());
  ASSERT_TRUE(accounts_in_cookie_jar_info.signed_out_accounts.empty());

  gaia::ListedAccount listed_account =
      accounts_in_cookie_jar_info.signed_in_accounts[0];
  EXPECT_EQ(
      identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail),
      listed_account.id);
  EXPECT_EQ(kTestGaiaId, listed_account.gaia_id);
  EXPECT_EQ(kTestEmail, listed_account.email);
}

TEST_F(IdentityManagerTest,
       CallbackSentOnUpdateToAccountsInCookieWithTwoAccounts) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  signin::SetListAccountsResponseTwoAccounts(kTestEmail, kTestGaiaId,
                                             kTestEmail2, kTestGaiaId2,
                                             test_url_loader_factory());
  identity_manager()->GetGaiaCookieManagerService()->TriggerListAccounts();
  run_loop.Run();

  const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
      identity_manager_observer()
          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
  EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
  ASSERT_EQ(2u, accounts_in_cookie_jar_info.signed_in_accounts.size());
  ASSERT_TRUE(accounts_in_cookie_jar_info.signed_out_accounts.empty());

  // Verify not only that both accounts are present but that they are listed in
  // the expected order as well.
  gaia::ListedAccount listed_account1 =
      accounts_in_cookie_jar_info.signed_in_accounts[0];
  EXPECT_EQ(
      identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail),
      listed_account1.id);
  EXPECT_EQ(kTestGaiaId, listed_account1.gaia_id);
  EXPECT_EQ(kTestEmail, listed_account1.email);

  gaia::ListedAccount account_info2 =
      accounts_in_cookie_jar_info.signed_in_accounts[1];
  EXPECT_EQ(
      identity_manager()->PickAccountIdForAccount(kTestGaiaId2, kTestEmail2),
      account_info2.id);
  EXPECT_EQ(kTestGaiaId2, account_info2.gaia_id);
  EXPECT_EQ(kTestEmail2, account_info2.email);
}

TEST_F(IdentityManagerTest, CallbackSentOnUpdateToSignOutAccountsInCookie) {
  struct SignedOutStatus {
    int account_1;
    int account_2;
  } signed_out_status_set[] = {{0, 0}, {1, 0}, {0, 1}, {1, 1}};

  for (const auto& signed_out_status : signed_out_status_set) {
    base::RunLoop run_loop;
    identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
        run_loop.QuitClosure());

    signin::SetListAccountsResponseWithParams(
        {{kTestEmail, kTestGaiaId, true /* valid */,
          signed_out_status.account_1 /* signed_out */, true /* verified */},
         {kTestEmail2, kTestGaiaId2, true /* valid */,
          signed_out_status.account_2 /* signed_out */, true /* verified */}},
        test_url_loader_factory());

    identity_manager()->GetGaiaCookieManagerService()->TriggerListAccounts();
    run_loop.Run();

    unsigned int accounts_signed_out =
        signed_out_status.account_1 + signed_out_status.account_2;
    const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
        identity_manager_observer()
            ->AccountsInfoFromAccountsInCookieUpdatedCallback();
    EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
    ASSERT_EQ(2 - accounts_signed_out,
              accounts_in_cookie_jar_info.signed_in_accounts.size());
    ASSERT_EQ(accounts_signed_out,
              accounts_in_cookie_jar_info.signed_out_accounts.size());

    // Verify not only that both accounts are present but that they are listed
    // in the expected order as well.
    //
    // The two variables below, control the lookup indexes signed in and signed
    // out accounts list, respectively.
    int i = 0, j = 0;
    gaia::ListedAccount listed_account1 =
        signed_out_status.account_1
            ? accounts_in_cookie_jar_info.signed_out_accounts[i++]
            : accounts_in_cookie_jar_info.signed_in_accounts[j++];
    if (!signed_out_status.account_1)
      EXPECT_EQ(
          identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail),
          listed_account1.id);
    EXPECT_EQ(kTestGaiaId, listed_account1.gaia_id);
    EXPECT_EQ(kTestEmail, listed_account1.email);

    gaia::ListedAccount listed_account2 =
        signed_out_status.account_2
            ? accounts_in_cookie_jar_info.signed_out_accounts[i++]
            : accounts_in_cookie_jar_info.signed_in_accounts[j++];
    if (!signed_out_status.account_2)
      EXPECT_EQ(identity_manager()->PickAccountIdForAccount(kTestGaiaId2,
                                                            kTestEmail2),
                listed_account2.id);
    EXPECT_EQ(kTestGaiaId2, listed_account2.gaia_id);
    EXPECT_EQ(kTestEmail2, listed_account2.email);
  }
}

TEST_F(IdentityManagerTest,
       CallbackSentOnUpdateToAccountsInCookieWithStaleAccounts) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  // Configure list accounts to return a permanent Gaia auth error.
  signin::SetListAccountsResponseWebLoginRequired(test_url_loader_factory());
  identity_manager()->GetGaiaCookieManagerService()->TriggerListAccounts();
  run_loop.Run();

  const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
      identity_manager_observer()
          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
  EXPECT_FALSE(accounts_in_cookie_jar_info.accounts_are_fresh);
  EXPECT_TRUE(accounts_in_cookie_jar_info.signed_in_accounts.empty());
  EXPECT_TRUE(accounts_in_cookie_jar_info.signed_out_accounts.empty());
}

TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithNoAccounts) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());

  // Do an initial call to GetAccountsInCookieJar(). This call should return no
  // accounts but should also trigger an internal update and eventual
  // notification that the accounts in the cookie jar have been updated.
  const AccountsInCookieJarInfo& accounts_in_cookie_jar =
      identity_manager()->GetAccountsInCookieJar();
  EXPECT_FALSE(accounts_in_cookie_jar.accounts_are_fresh);
  EXPECT_TRUE(accounts_in_cookie_jar.signed_in_accounts.empty());
  EXPECT_TRUE(accounts_in_cookie_jar.signed_out_accounts.empty());

  run_loop.Run();

  // The state of the accounts in IdentityManager should now reflect the
  // internal update.
  const AccountsInCookieJarInfo updated_accounts_in_cookie_jar =
      identity_manager()->GetAccountsInCookieJar();

  EXPECT_TRUE(updated_accounts_in_cookie_jar.accounts_are_fresh);
  EXPECT_TRUE(updated_accounts_in_cookie_jar.signed_in_accounts.empty());
  EXPECT_TRUE(updated_accounts_in_cookie_jar.signed_out_accounts.empty());
}

TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithOneAccount) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  signin::SetListAccountsResponseOneAccount(kTestEmail, kTestGaiaId,
                                            test_url_loader_factory());

  // Do an initial call to GetAccountsInCookieJar(). This call should return no
  // accounts but should also trigger an internal update and eventual
  // notification that the accounts in the cookie jar have been updated.
  const AccountsInCookieJarInfo& accounts_in_cookie_jar =
      identity_manager()->GetAccountsInCookieJar();
  EXPECT_FALSE(accounts_in_cookie_jar.accounts_are_fresh);
  EXPECT_TRUE(accounts_in_cookie_jar.signed_in_accounts.empty());
  EXPECT_TRUE(accounts_in_cookie_jar.signed_out_accounts.empty());

  run_loop.Run();

  // The state of the accounts in IdentityManager should now reflect the
  // internal update.
  const AccountsInCookieJarInfo& updated_accounts_in_cookie_jar =
      identity_manager()->GetAccountsInCookieJar();

  EXPECT_TRUE(updated_accounts_in_cookie_jar.accounts_are_fresh);
  ASSERT_EQ(1u, updated_accounts_in_cookie_jar.signed_in_accounts.size());
  ASSERT_TRUE(updated_accounts_in_cookie_jar.signed_out_accounts.empty());

  gaia::ListedAccount listed_account =
      updated_accounts_in_cookie_jar.signed_in_accounts[0];
  EXPECT_EQ(
      identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail),
      listed_account.id);
  EXPECT_EQ(kTestGaiaId, listed_account.gaia_id);
  EXPECT_EQ(kTestEmail, listed_account.email);
}

TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithTwoAccounts) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
      run_loop.QuitClosure());

  signin::SetListAccountsResponseTwoAccounts(kTestEmail, kTestGaiaId,
                                             kTestEmail2, kTestGaiaId2,
                                             test_url_loader_factory());

  // Do an initial call to GetAccountsInCookieJar(). This call should return no
  // accounts but should also trigger an internal update and eventual
  // notification that the accounts in the cookie jar have been updated.
  const AccountsInCookieJarInfo& accounts_in_cookie_jar =
      identity_manager()->GetAccountsInCookieJar();
  EXPECT_FALSE(accounts_in_cookie_jar.accounts_are_fresh);
  EXPECT_TRUE(accounts_in_cookie_jar.signed_in_accounts.empty());
  EXPECT_TRUE(accounts_in_cookie_jar.signed_out_accounts.empty());

  run_loop.Run();

  // The state of the accounts in IdentityManager should now reflect the
  // internal update.
  const AccountsInCookieJarInfo& updated_accounts_in_cookie_jar =
      identity_manager()->GetAccountsInCookieJar();

  EXPECT_TRUE(updated_accounts_in_cookie_jar.accounts_are_fresh);
  ASSERT_EQ(2u, updated_accounts_in_cookie_jar.signed_in_accounts.size());
  ASSERT_TRUE(updated_accounts_in_cookie_jar.signed_out_accounts.empty());

  // Verify not only that both accounts are present but that they are listed in
  // the expected order as well.
  gaia::ListedAccount listed_account1 =
      updated_accounts_in_cookie_jar.signed_in_accounts[0];
  EXPECT_EQ(
      identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail),
      listed_account1.id);
  EXPECT_EQ(kTestGaiaId, listed_account1.gaia_id);
  EXPECT_EQ(kTestEmail, listed_account1.email);

  gaia::ListedAccount listed_account2 =
      updated_accounts_in_cookie_jar.signed_in_accounts[1];
  EXPECT_EQ(
      identity_manager()->PickAccountIdForAccount(kTestGaiaId2, kTestEmail2),
      listed_account2.id);
  EXPECT_EQ(kTestGaiaId2, listed_account2.gaia_id);
  EXPECT_EQ(kTestEmail2, listed_account2.email);
}

TEST_F(IdentityManagerTest, CallbackSentOnSuccessfulAdditionOfAccountToCookie) {
  const char kTestAccountId[] = "account_id";

  std::string account_from_add_account_to_cookie_completed_callback;
  GoogleServiceAuthError error_from_add_account_to_cookie_completed_callback;
  auto completion_callback = base::BindLambdaForTesting(
      [&](const std::string& account_id, const GoogleServiceAuthError& error) {
        account_from_add_account_to_cookie_completed_callback = account_id;
        error_from_add_account_to_cookie_completed_callback = error;
      });

  identity_manager()->GetGaiaCookieManagerService()->AddAccountToCookie(
      kTestAccountId, gaia::GaiaSource::kChrome,
      std::move(completion_callback));
  SimulateAdditionOfAccountToCookieSuccess(
      identity_manager()->GetGaiaCookieManagerService(), "token");
  EXPECT_EQ(account_from_add_account_to_cookie_completed_callback,
            kTestAccountId);
  EXPECT_EQ(error_from_add_account_to_cookie_completed_callback,
            GoogleServiceAuthError::AuthErrorNone());
}

TEST_F(IdentityManagerTest, CallbackSentOnFailureAdditionOfAccountToCookie) {
  const char kTestAccountId[] = "account_id";

  std::string account_from_add_account_to_cookie_completed_callback;
  GoogleServiceAuthError error_from_add_account_to_cookie_completed_callback;
  auto completion_callback = base::BindLambdaForTesting(
      [&](const std::string& account_id, const GoogleServiceAuthError& error) {
        account_from_add_account_to_cookie_completed_callback = account_id;
        error_from_add_account_to_cookie_completed_callback = error;
      });

  identity_manager()->GetGaiaCookieManagerService()->AddAccountToCookie(
      kTestAccountId, gaia::GaiaSource::kChrome,
      std::move(completion_callback));

  GoogleServiceAuthError error(GoogleServiceAuthError::SERVICE_ERROR);
  SimulateAdditionOfAccountToCookieSuccessFailure(
      identity_manager()->GetGaiaCookieManagerService(), error);

  EXPECT_EQ(account_from_add_account_to_cookie_completed_callback,
            kTestAccountId);
  EXPECT_EQ(error_from_add_account_to_cookie_completed_callback, error);
}

TEST_F(IdentityManagerTest,
       CallbackSentOnSetAccountsInCookieCompleted_Success) {
  const char kTestAccountId[] = "account_id";
  const char kTestAccountId2[] = "account_id2";
  const std::vector<std::string> account_ids = {kTestAccountId,
                                                kTestAccountId2};

  GoogleServiceAuthError error_from_set_accounts_in_cookie_completed_callback;
  auto completion_callback = base::BindLambdaForTesting(
      [&error_from_set_accounts_in_cookie_completed_callback](
          const GoogleServiceAuthError& error) {
        error_from_set_accounts_in_cookie_completed_callback = error;
      });

  // Needed to insert request in the queue.
  identity_manager()->GetGaiaCookieManagerService()->SetAccountsInCookie(
      account_ids, gaia::GaiaSource::kChrome, std::move(completion_callback));

  // Sample success cookie response.
  std::string data =
      R"()]}'
      {
        "status": "OK",
        "cookies":[
        {
            "name":"SID",
            "value":"vAlUe1",
            "domain":".google.ru",
            "path":"/",
            "isSecure":true,
            "isHttpOnly":false,
            "priority":"HIGH",
            "maxAge":63070000
          }
        ]
      }
    )";
  OAuthMultiloginResult result(data);

  SimulateOAuthMultiloginFinished(
      identity_manager()->GetGaiaCookieManagerService(), result);

  EXPECT_EQ(error_from_set_accounts_in_cookie_completed_callback,
            GoogleServiceAuthError::AuthErrorNone());
}

TEST_F(IdentityManagerTest,
       CallbackSentOnSetAccountsInCookieCompleted_Failure) {
  const char kTestAccountId[] = "account_id";
  const char kTestAccountId2[] = "account_id2";
  const std::vector<std::string> account_ids = {kTestAccountId,
                                                kTestAccountId2};

  GoogleServiceAuthError error_from_set_accounts_in_cookie_completed_callback;
  auto completion_callback = base::BindLambdaForTesting(
      [&error_from_set_accounts_in_cookie_completed_callback](
          const GoogleServiceAuthError& error) {
        error_from_set_accounts_in_cookie_completed_callback = error;
      });

  // Needed to insert request in the queue.
  identity_manager()->GetGaiaCookieManagerService()->SetAccountsInCookie(
      account_ids, gaia::GaiaSource::kChrome, std::move(completion_callback));

  // Sample an erroneous response.
  GoogleServiceAuthError error(GoogleServiceAuthError::SERVICE_ERROR);
  OAuthMultiloginResult result(error);

  SimulateOAuthMultiloginFinished(
      identity_manager()->GetGaiaCookieManagerService(), result);

  EXPECT_EQ(error_from_set_accounts_in_cookie_completed_callback, error);
}

TEST_F(IdentityManagerTest, CallbackSentOnAccountsCookieDeletedByUserAction) {
  const char kTestAccountId[] = "account_id";
  const char kTestAccountId2[] = "account_id2";
  const std::vector<std::string> account_ids = {kTestAccountId,
                                                kTestAccountId2};

  // Needed to insert request in the queue.
  identity_manager()->GetGaiaCookieManagerService()->SetAccountsInCookie(
      account_ids, gaia::GaiaSource::kChrome,
      GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());

  // Sample success cookie response.
  std::string data =
      R"()]}'
      {
        "status": "OK",
        "cookies":[
        {
            "name":"APISID",
            "value":"vAlUe1",
            "domain":".google.com",
            "path":"/",
            "isSecure":true,
            "isHttpOnly":false,
            "priority":"HIGH",
            "maxAge":63070000
          }
        ]
      }
    )";
  OAuthMultiloginResult result(data);

  SimulateOAuthMultiloginFinished(
      identity_manager()->GetGaiaCookieManagerService(), result);
  base::RunLoop().RunUntilIdle();

  base::RunLoop run_loop;
  identity_manager_observer()->SetOnCookieDeletedByUserCallback(
      run_loop.QuitClosure());

  const std::vector<net::CanonicalCookie>& cookies = result.cookies();
  SimulateCookieDeletedByUser(identity_manager()->GetGaiaCookieManagerService(),
                              cookies[0]);
  run_loop.Run();
}

TEST_F(IdentityManagerTest, OnNetworkInitialized) {
  const char kTestAccountId[] = "account_id";
  const char kTestAccountId2[] = "account_id2";
  const std::vector<std::string> account_ids = {kTestAccountId,
                                                kTestAccountId2};

  auto test_cookie_manager = std::make_unique<network::TestCookieManager>();
  network::TestCookieManager* test_cookie_manager_ptr =
      test_cookie_manager.get();
  signin_client()->set_cookie_manager(std::move(test_cookie_manager));

  identity_manager()->OnNetworkInitialized();

  // Needed to insert request in the queue.
  identity_manager()->GetGaiaCookieManagerService()->SetAccountsInCookie(
      account_ids, gaia::GaiaSource::kChrome,
      GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());

  // Sample success cookie response.
  std::string data =
      R"()]}'
      {
        "status": "OK",
        "cookies":[
        {
            "name":"APISID",
            "value":"vAlUe1",
            "domain":".google.com",
            "path":"/",
            "isSecure":true,
            "isHttpOnly":false,
            "priority":"HIGH",
            "maxAge":63070000
          }
        ]
      }
    )";
  OAuthMultiloginResult result(data);

  SimulateOAuthMultiloginFinished(
      identity_manager()->GetGaiaCookieManagerService(), result);
  base::RunLoop().RunUntilIdle();

  base::RunLoop run_loop;
  identity_manager_observer()->SetOnCookieDeletedByUserCallback(
      run_loop.QuitClosure());

  const std::vector<net::CanonicalCookie>& cookies = result.cookies();

  // Dispatch a known change of a known cookie instance *through the mojo
  // pipe* in order to ensure the GCMS is listening to CookieManager changes.
  //
  // It is important the the cause of the change is known here (ie
  // network::mojom::CookieChangeCause::EXPLICIT) so the test can block of the
  // proper IdentityManager observer callback to be called (in this case
  // OnAccountsCookieDeletedByUserAction).
  //
  // Note that this call differs from calling SimulateCookieDeletedByUser()
  // directly in the sense that SimulateCookieDeletedByUser() does not go
  // through any mojo pipe.
  test_cookie_manager_ptr->DispatchCookieChange(
      cookies[0], network::mojom::CookieChangeCause::EXPLICIT);
  run_loop.Run();
}

TEST_F(IdentityManagerTest,
       BatchChangeObserversAreNotifiedOnCredentialsUpdate) {
  identity_manager()->GetSigninManager()->SetAuthenticatedAccountInfo(
      kTestGaiaId, kTestEmail);
  token_service()->UpdateCredentials(primary_account_id(), "refresh_token");

  EXPECT_EQ(1ul, identity_manager_observer()->BatchChangeRecords().size());
  EXPECT_EQ(1ul,
            identity_manager_observer()->BatchChangeRecords().at(0).size());
  EXPECT_EQ(primary_account_id(),
            identity_manager_observer()->BatchChangeRecords().at(0).at(0));
}

// Checks that FindAccountInfoForAccountWithRefreshTokenByAccountId() returns
// information about the account if the account is found or nullopt if there
// are no accounts with requested |account_id|.
TEST_F(IdentityManagerTest,
       FindAccountInfoForAccountWithRefreshTokenByAccountId) {
  // Add an account (note: cannot use kTestEmail as it is already inserted
  // by the fixture common code, so use a different address).
  const AccountInfo foo_account_info =
      MakeAccountAvailable(identity_manager(), "foo@bar.com");

  base::Optional<AccountInfo> maybe_account_info;
  maybe_account_info =
      identity_manager()->FindAccountInfoForAccountWithRefreshTokenByAccountId(
          "dummy_value");
  EXPECT_FALSE(maybe_account_info.has_value());

  maybe_account_info =
      identity_manager()->FindAccountInfoForAccountWithRefreshTokenByAccountId(
          foo_account_info.account_id);
  EXPECT_TRUE(maybe_account_info.has_value());
  EXPECT_EQ(foo_account_info.account_id, maybe_account_info.value().account_id);
  EXPECT_EQ(foo_account_info.email, maybe_account_info.value().email);
  EXPECT_EQ(foo_account_info.gaia, maybe_account_info.value().gaia);
}

// Checks that FindAccountInfoForAccountWithRefreshTokenByEmailAddress() returns
// information about the account if the account is found or nullopt if there
// are no accounts with requested |email_address|.
TEST_F(IdentityManagerTest,
       FindAccountInfoForAccountWithRefreshTokenByEmailAddress) {
  // Add an account (note: cannot use kTestEmail as it is already inserted
  // by the fixture common code, so use a different address).
  const AccountInfo foo_account_info =
      MakeAccountAvailable(identity_manager(), "foo@bar.com");

  base::Optional<AccountInfo> maybe_account_info;
  maybe_account_info =
      identity_manager()
          ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(
              "dummy_value");
  EXPECT_FALSE(maybe_account_info.has_value());

  maybe_account_info =
      identity_manager()
          ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(
              foo_account_info.email);
  EXPECT_TRUE(maybe_account_info.has_value());
  EXPECT_EQ(foo_account_info.account_id, maybe_account_info.value().account_id);
  EXPECT_EQ(foo_account_info.email, maybe_account_info.value().email);
  EXPECT_EQ(foo_account_info.gaia, maybe_account_info.value().gaia);
}

// Checks that FindAccountInfoForAccountWithRefreshTokenByGaiaId() returns
// information about the account if the account is found or nullopt if there
// are no accounts with requested |gaia_id|.
TEST_F(IdentityManagerTest, FindAccountInfoForAccountWithRefreshTokenByGaiaId) {
  // Add an account (note: cannot use kTestEmail as it is already inserted
  // by the fixture common code, so use a different address).
  const AccountInfo foo_account_info =
      MakeAccountAvailable(identity_manager(), "foo@bar.com");

  base::Optional<AccountInfo> maybe_account_info;
  maybe_account_info =
      identity_manager()->FindAccountInfoForAccountWithRefreshTokenByGaiaId(
          "dummy_value");
  EXPECT_FALSE(maybe_account_info.has_value());

  maybe_account_info =
      identity_manager()->FindAccountInfoForAccountWithRefreshTokenByGaiaId(
          foo_account_info.gaia);
  EXPECT_TRUE(maybe_account_info.has_value());
  EXPECT_EQ(foo_account_info.account_id, maybe_account_info.value().account_id);
  EXPECT_EQ(foo_account_info.email, maybe_account_info.value().email);
  EXPECT_EQ(foo_account_info.gaia, maybe_account_info.value().gaia);
}

// Checks that AreRefreshTokensLoaded() returns true after LoadCredentials.
TEST_F(IdentityManagerTest, AreRefreshTokensLoaded) {
  base::RunLoop run_loop;
  identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
      run_loop.QuitClosure());

  // Credentials are already loaded in SigninManager::Initialize()
  // which runs even before the IdentityManager is created. That's why
  // we fake the credentials loaded state and force another load in
  // order to test AreRefreshTokensLoaded.
  token_service()->set_all_credentials_loaded_for_testing(false);
  EXPECT_FALSE(identity_manager()->AreRefreshTokensLoaded());
  token_service()->LoadCredentials("");
  run_loop.Run();
  EXPECT_TRUE(identity_manager()->AreRefreshTokensLoaded());
}

TEST_F(IdentityManagerTest, AccountIdMigration_DoneOnInitialization) {
  // Migration gets marked as DONE while initializing the AccountTrackerService
  // on platforms supporting account ID migration only.
  if (IdentityManager::IsAccountIdMigrationSupported()) {
    EXPECT_EQ(identity_manager()->GetAccountIdMigrationState(),
              IdentityManager::AccountIdMigrationState::MIGRATION_DONE);
  } else {
    EXPECT_EQ(identity_manager()->GetAccountIdMigrationState(),
              IdentityManager::AccountIdMigrationState::MIGRATION_NOT_STARTED);
  }
}

// Checks that IdentityManager::Observer gets OnAccountUpdated when account info
// is updated.
TEST_F(IdentityManagerTest, ObserveOnAccountUpdated) {
  const AccountInfo account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail3);

  SimulateSuccessfulFetchOfAccountInfo(
      identity_manager(), account_info.account_id, account_info.email,
      account_info.account_id, kTestHostedDomain, kTestFullName, kTestGivenName,
      kTestLocale, kTestPictureUrl);

  EXPECT_EQ(account_info.account_id, identity_manager_observer()
                                         ->AccountFromAccountUpdatedCallback()
                                         .account_id);
  EXPECT_EQ(
      account_info.email,
      identity_manager_observer()->AccountFromAccountUpdatedCallback().email);
}

TEST_F(IdentityManagerTest, TestOnAccountRemovedWithInfoCallback) {
  AccountInfo account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);
  EXPECT_EQ(kTestEmail2, account_info.email);

  account_tracker()->RemoveAccount(account_info.account_id);

  // Check if OnAccountRemovedWithInfo is called after removing |account_info|
  // by RemoveAccount().
  EXPECT_TRUE(
      identity_manager_observer()->WasCalledAccountRemovedWithInfoCallback());

  // Check if the passed AccountInfo is the same to the removing one.
  EXPECT_EQ(account_info.account_id,
            identity_manager_observer()
                ->AccountFromAccountRemovedWithInfoCallback()
                .account_id);
  EXPECT_EQ(account_info.email,
            identity_manager_observer()
                ->AccountFromAccountRemovedWithInfoCallback()
                .email);
}

TEST_F(IdentityManagerTest, TestPickAccountIdForAccount) {
  const std::string account_id =
      identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail);
  const bool account_id_migration_done =
      identity_manager()->GetAccountIdMigrationState() ==
      IdentityManager::AccountIdMigrationState::MIGRATION_DONE;
  if (account_id_migration_done) {
    EXPECT_EQ(account_id, kTestGaiaId);
  } else {
    EXPECT_TRUE(gaia::AreEmailsSame(account_id, kTestEmail));
  }
}

// Check that FindExtendedAccountInfoForAccount returns a valid account info
// iff the account is known, has refresh token and all the extended information
// is available.
TEST_F(IdentityManagerTest, FindExtendedAccountInfoForAccount) {
  CoreAccountInfo account_info;
  account_info.email = kTestEmail;
  account_info.gaia = kTestGaiaId;
  account_info.account_id =
      identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail);

  // FindExtendedAccountInfoForAccount() returns empty optional if the
  // account_info is invalid.
  EXPECT_FALSE(identity_manager()
                   ->FindExtendedAccountInfoForAccount(CoreAccountInfo{})
                   .has_value());

  // FindExtendedAccountInfoForAccount() returns empty optional if the
  // account_info is unknown.
  EXPECT_FALSE(identity_manager()
                   ->FindExtendedAccountInfoForAccount(account_info)
                   .has_value());

  // Insert the core account information in the AccountTrackerService.
  const std::string account_id =
      account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail);
  ASSERT_EQ(account_info.account_id, account_id);

  // FindExtendedAccountInfoForAccount() returns empty optional if the account
  // has no refresh token.
  EXPECT_FALSE(identity_manager()
                   ->FindExtendedAccountInfoForAccount(account_info)
                   .has_value());

  // Insert refresh token for account.
  SetRefreshTokenForAccount(identity_manager(), account_info.account_id,
                            "refresh-token");

  // FindExtendedAccountInfoForAccount() returns extended account information if
  // the account is known and has valid refresh token.
  const base::Optional<AccountInfo> extended_account_info =
      identity_manager()->FindExtendedAccountInfoForAccount(account_info);

  ASSERT_TRUE(extended_account_info.has_value());
  EXPECT_EQ(account_info.gaia, extended_account_info.value().gaia);
  EXPECT_EQ(account_info.email, extended_account_info.value().email);
  EXPECT_EQ(account_info.account_id, extended_account_info.value().account_id);
}

#if defined(OS_ANDROID)
TEST_F(IdentityManagerTest, ForceRefreshOfExtendedAccountInfo) {
  // The flow of this test results in an interaction with
  // ChildAccountInfoFetcherAndroid, which requires initialization in order to
  // avoid a crash.
  ChildAccountInfoFetcherAndroid::InitializeForTests();

  account_fetcher()->OnNetworkInitialized();
  AccountInfo account_info =
      MakeAccountAvailable(identity_manager(), kTestEmail2);

  identity_manager()->ForceRefreshOfExtendedAccountInfo(
      account_info.account_id);

  SimulateSuccessfulFetchOfAccountInfo(
      identity_manager(), account_info.account_id, account_info.email,
      account_info.account_id, kTestHostedDomain, kTestFullName, kTestGivenName,
      kTestLocale, kTestPictureUrl);

  const AccountInfo& refreshed_account_info =
      identity_manager_observer()->AccountFromAccountUpdatedCallback();
  EXPECT_EQ(account_info.account_id, refreshed_account_info.account_id);
  EXPECT_EQ(account_info.email, refreshed_account_info.email);
  EXPECT_EQ(account_info.gaia, refreshed_account_info.gaia);
  EXPECT_EQ(kTestHostedDomain, refreshed_account_info.hosted_domain);
  EXPECT_EQ(kTestFullName, refreshed_account_info.full_name);
  EXPECT_EQ(kTestGivenName, refreshed_account_info.given_name);
  EXPECT_EQ(kTestLocale, refreshed_account_info.locale);
  EXPECT_EQ(kTestPictureUrl, refreshed_account_info.picture_url);
}
#endif

}  // namespace identity
