// Copyright 2014 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 "components/gcm_driver/account_tracker.h"

#include <algorithm>
#include <vector>

#include "base/strings/stringprintf.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "google_apis/gaia/gaia_oauth_client.h"
#include "net/http/http_status_code.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const char kOAuthURL[] = "https://www.googleapis.com/oauth2/v1/userinfo";
const char kPrimaryAccountEmail[] = "primary_account@example.com";

enum TrackingEventType { SIGN_IN, SIGN_OUT };

std::string AccountKeyToObfuscatedId(const std::string& email) {
  return "obfid-" + email;
}

class TrackingEvent {
 public:
  TrackingEvent(TrackingEventType type,
                const std::string& account_key,
                const std::string& gaia_id)
      : type_(type), account_key_(account_key), gaia_id_(gaia_id) {}

  TrackingEvent(TrackingEventType type, const std::string& account_key)
      : type_(type),
        account_key_(account_key),
        gaia_id_(AccountKeyToObfuscatedId(account_key)) {}

  bool operator==(const TrackingEvent& event) const {
    return type_ == event.type_ && account_key_ == event.account_key_ &&
           gaia_id_ == event.gaia_id_;
  }

  std::string ToString() const {
    const char* typestr = "INVALID";
    switch (type_) {
      case SIGN_IN:
        typestr = " IN";
        break;
      case SIGN_OUT:
        typestr = "OUT";
        break;
    }
    return base::StringPrintf("{ type: %s, email: %s, gaia: %s }", typestr,
                              account_key_.c_str(), gaia_id_.c_str());
  }

 private:
  friend bool CompareByUser(TrackingEvent a, TrackingEvent b);

  TrackingEventType type_;
  std::string account_key_;
  std::string gaia_id_;
};

bool CompareByUser(TrackingEvent a, TrackingEvent b) {
  return a.account_key_ < b.account_key_;
}

std::string Str(const std::vector<TrackingEvent>& events) {
  std::string str = "[";
  bool needs_comma = false;
  for (auto it = events.begin(); it != events.end(); ++it) {
    if (needs_comma)
      str += ",\n ";
    needs_comma = true;
    str += it->ToString();
  }
  str += "]";
  return str;
}

}  // namespace

namespace gcm {

class AccountTrackerObserver : public AccountTracker::Observer {
 public:
  AccountTrackerObserver() {}
  virtual ~AccountTrackerObserver() {}

  testing::AssertionResult CheckEvents();
  testing::AssertionResult CheckEvents(const TrackingEvent& e1);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3,
                                       const TrackingEvent& e4);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3,
                                       const TrackingEvent& e4,
                                       const TrackingEvent& e5);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3,
                                       const TrackingEvent& e4,
                                       const TrackingEvent& e5,
                                       const TrackingEvent& e6);
  void Clear();
  void SortEventsByUser();

  // AccountTracker::Observer implementation
  void OnAccountSignInChanged(const AccountIds& ids,
                              bool is_signed_in) override;

 private:
  testing::AssertionResult CheckEvents(
      const std::vector<TrackingEvent>& events);

  std::vector<TrackingEvent> events_;
};

void AccountTrackerObserver::OnAccountSignInChanged(const AccountIds& ids,
                                                    bool is_signed_in) {
  events_.push_back(
      TrackingEvent(is_signed_in ? SIGN_IN : SIGN_OUT, ids.email, ids.gaia));
}

void AccountTrackerObserver::Clear() {
  events_.clear();
}

void AccountTrackerObserver::SortEventsByUser() {
  std::stable_sort(events_.begin(), events_.end(), CompareByUser);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents() {
  std::vector<TrackingEvent> events;
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3,
    const TrackingEvent& e4) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  events.push_back(e4);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3,
    const TrackingEvent& e4,
    const TrackingEvent& e5) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  events.push_back(e4);
  events.push_back(e5);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3,
    const TrackingEvent& e4,
    const TrackingEvent& e5,
    const TrackingEvent& e6) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  events.push_back(e4);
  events.push_back(e5);
  events.push_back(e6);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const std::vector<TrackingEvent>& events) {
  std::string maybe_newline = (events.size() + events_.size()) > 2 ? "\n" : "";
  testing::AssertionResult result(
      (events_ == events)
          ? testing::AssertionSuccess()
          : (testing::AssertionFailure()
             << "Expected " << maybe_newline << Str(events) << ", "
             << maybe_newline << "Got " << maybe_newline << Str(events_)));
  events_.clear();
  return result;
}

class AccountTrackerTest : public testing::Test {
 public:
  AccountTrackerTest() {}

  ~AccountTrackerTest() override {}

  void SetUp() override {
    account_tracker_.reset(new AccountTracker(
        identity_test_env_.identity_manager(),
        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
            &test_url_loader_factory_)));
    account_tracker_->AddObserver(&observer_);
  }

  void TearDown() override {
    account_tracker_->RemoveObserver(&observer_);
    account_tracker_->Shutdown();
  }

  AccountTrackerObserver* observer() { return &observer_; }

  AccountTracker* account_tracker() { return account_tracker_.get(); }

  // Helpers to pass fake events to the tracker.

  // Sets the primary account info. Returns the account ID of the
  // newly-set account.
  // NOTE: On ChromeOS, the login callback is never fired in production (since
  // the underlying GoogleSigninSucceeded callback is never sent). Tests that
  // exercise functionality dependent on that callback firing are not relevant
  // on ChromeOS and should simply not run on that platform.
  std::string SetActiveAccount(const std::string& email) {
    return identity_test_env_.SetPrimaryAccount(email).account_id;
  }

// Helpers that go through a logout flow.
// NOTE: On ChromeOS, the logout callback is never fired in production (since
// the underlying GoogleSignedOut callback is never sent). Tests that exercise
// functionality dependent on that callback firing are not relevant on ChromeOS
// and should simply not run on that platform.
#if !defined(OS_CHROMEOS)
  void NotifyLogoutOfPrimaryAccountOnly() {
    identity_test_env_.ClearPrimaryAccount(
        identity::ClearPrimaryAccountPolicy::KEEP_ALL_ACCOUNTS);
  }

  void NotifyLogoutOfAllAccounts() {
    identity_test_env_.ClearPrimaryAccount(
        identity::ClearPrimaryAccountPolicy::REMOVE_ALL_ACCOUNTS);
  }
#endif

  std::string AddAccountWithToken(const std::string& email) {
    return identity_test_env_.MakeAccountAvailable(email).account_id;
  }

  void NotifyTokenAvailable(const std::string& account_id) {
    identity_test_env_.SetRefreshTokenForAccount(account_id);
  }

  void NotifyTokenRevoked(const std::string& account_id) {
    identity_test_env_.RemoveRefreshTokenForAccount(account_id);
  }

  // Helpers to fake access token and user info fetching
  void IssueAccessToken(const std::string& account_id) {
    identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
        account_id, "access_token-" + account_id, base::Time::Max());
  }

  std::string GetValidTokenInfoResponse(const std::string& account_id) {
    return std::string("{ \"id\": \"") + AccountKeyToObfuscatedId(account_id) +
           "\" }";
  }

  void ReturnOAuthUrlFetchResults(net::HttpStatusCode response_code,
                                  const std::string& response_string);

  void ReturnOAuthUrlFetchSuccess(const std::string& account_key);
  void ReturnOAuthUrlFetchFailure(const std::string& account_key);

  std::string SetupPrimaryLogin() {
    // Initial setup for tests that start with a signed in profile.
    std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
    NotifyTokenAvailable(primary_account_id);
    ReturnOAuthUrlFetchSuccess(primary_account_id);
    observer()->Clear();

    return primary_account_id;
  }

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

 private:
  // net:: stuff needs IO message loop.
  base::test::ScopedTaskEnvironment task_environment_{
      base::test::ScopedTaskEnvironment::MainThreadType::IO};
  network::TestURLLoaderFactory test_url_loader_factory_;
  identity::IdentityTestEnvironment identity_test_env_;

  std::unique_ptr<AccountTracker> account_tracker_;
  AccountTrackerObserver observer_;
};

void AccountTrackerTest::ReturnOAuthUrlFetchResults(
    net::HttpStatusCode response_code,
    const std::string& response_string) {
  EXPECT_TRUE(test_url_loader_factory()->SimulateResponseForPendingRequest(
      GURL(kOAuthURL), network::URLLoaderCompletionStatus(net::OK),
      network::CreateResourceResponseHead(response_code), response_string));
}

void AccountTrackerTest::ReturnOAuthUrlFetchSuccess(
    const std::string& account_id) {
  IssueAccessToken(account_id);
  ReturnOAuthUrlFetchResults(net::HTTP_OK,
                             GetValidTokenInfoResponse(account_id));
}

void AccountTrackerTest::ReturnOAuthUrlFetchFailure(
    const std::string& account_id) {
  IssueAccessToken(account_id);
  ReturnOAuthUrlFetchResults(net::HTTP_BAD_REQUEST, "");
}

// Primary tests just involve the Active account

TEST_F(AccountTrackerTest, PrimaryNoEventsBeforeLogin) {
  std::string account_id = AddAccountWithToken("me@dummy.com");
  NotifyTokenRevoked(account_id);

// Logout is not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
  NotifyLogoutOfAllAccounts();
#endif

  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, PrimaryLoginThenTokenAvailable) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  EXPECT_TRUE(observer()->CheckEvents());

  ReturnOAuthUrlFetchSuccess(primary_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account_id)));
}

TEST_F(AccountTrackerTest, PrimaryRevoke) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  observer()->Clear();

  NotifyTokenRevoked(primary_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account_id)));
}

TEST_F(AccountTrackerTest, PrimaryRevokeThenTokenAvailable) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  NotifyTokenRevoked(primary_account_id);
  observer()->Clear();

  NotifyTokenAvailable(primary_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account_id)));
}

// These tests exercise true login/logout, which are not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
TEST_F(AccountTrackerTest, PrimaryTokenAvailableThenLogin) {
  AddAccountWithToken(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());

  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account_id)));
}

TEST_F(AccountTrackerTest, PrimaryTokenAvailableAndRevokedThenLogin) {
  std::string primary_account_id = AddAccountWithToken(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());

  NotifyTokenRevoked(primary_account_id);
  EXPECT_TRUE(observer()->CheckEvents());

  SetActiveAccount(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, PrimaryRevokeThenLogin) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  NotifyLogoutOfAllAccounts();
  observer()->Clear();

  SetActiveAccount(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, PrimaryLogoutThenRevoke) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  observer()->Clear();

  NotifyLogoutOfAllAccounts();
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account_id)));

  NotifyTokenRevoked(primary_account_id);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, PrimaryLogoutFetchCancelAvailable) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  // TokenAvailable kicks off a fetch. Logout without satisfying it.
  NotifyLogoutOfAllAccounts();
  EXPECT_TRUE(observer()->CheckEvents());

  SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account_id)));
}
#endif

// Non-primary accounts

TEST_F(AccountTrackerTest, Available) {
  SetupPrimaryLogin();

  std::string account_id = AddAccountWithToken("user@example.com");
  EXPECT_TRUE(observer()->CheckEvents());

  ReturnOAuthUrlFetchSuccess(account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account_id)));
}

TEST_F(AccountTrackerTest, AvailableRevokeAvailable) {
  SetupPrimaryLogin();

  std::string account_id = AddAccountWithToken("user@example.com");
  ReturnOAuthUrlFetchSuccess(account_id);
  NotifyTokenRevoked(account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account_id),
                                      TrackingEvent(SIGN_OUT, account_id)));

  NotifyTokenAvailable(account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account_id)));
}

TEST_F(AccountTrackerTest, AvailableRevokeAvailableWithPendingFetch) {
  SetupPrimaryLogin();

  std::string account_id = AddAccountWithToken("user@example.com");
  NotifyTokenRevoked(account_id);
  EXPECT_TRUE(observer()->CheckEvents());

  NotifyTokenAvailable(account_id);
  ReturnOAuthUrlFetchSuccess(account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account_id)));
}

TEST_F(AccountTrackerTest, AvailableRevokeRevoke) {
  SetupPrimaryLogin();

  std::string account_id = AddAccountWithToken("user@example.com");
  ReturnOAuthUrlFetchSuccess(account_id);
  NotifyTokenRevoked(account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account_id),
                                      TrackingEvent(SIGN_OUT, account_id)));

  NotifyTokenRevoked(account_id);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, AvailableAvailable) {
  SetupPrimaryLogin();

  std::string account_id = AddAccountWithToken("user@example.com");
  ReturnOAuthUrlFetchSuccess(account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account_id)));

  NotifyTokenAvailable(account_id);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, TwoAccounts) {
  SetupPrimaryLogin();

  std::string alpha_account_id = AddAccountWithToken("alpha@example.com");
  ReturnOAuthUrlFetchSuccess(alpha_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_IN, alpha_account_id)));

  std::string beta_account_id = AddAccountWithToken("beta@example.com");
  ReturnOAuthUrlFetchSuccess(beta_account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, beta_account_id)));

  NotifyTokenRevoked(alpha_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, alpha_account_id)));

  NotifyTokenRevoked(beta_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, beta_account_id)));
}

TEST_F(AccountTrackerTest, AvailableTokenFetchFailAvailable) {
  SetupPrimaryLogin();

  std::string account_id = AddAccountWithToken("user@example.com");
  ReturnOAuthUrlFetchFailure(account_id);
  EXPECT_TRUE(observer()->CheckEvents());

  NotifyTokenAvailable(account_id);
  ReturnOAuthUrlFetchSuccess(account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account_id)));
}

// These tests exercise true login/logout, which are not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
TEST_F(AccountTrackerTest, MultiSignOutSignIn) {
  std::string primary_account_id = SetupPrimaryLogin();

  std::string alpha_account_id = AddAccountWithToken("alpha@example.com");
  ReturnOAuthUrlFetchSuccess(alpha_account_id);
  std::string beta_account_id = AddAccountWithToken("beta@example.com");
  ReturnOAuthUrlFetchSuccess(beta_account_id);

  observer()->SortEventsByUser();
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, alpha_account_id),
                                      TrackingEvent(SIGN_IN, beta_account_id)));

  // Log out of the primary account only (allows for testing that the account
  // tracker preserves knowledge of "beta@example.com").
  NotifyLogoutOfPrimaryAccountOnly();
  observer()->SortEventsByUser();
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, alpha_account_id),
                              TrackingEvent(SIGN_OUT, beta_account_id),
                              TrackingEvent(SIGN_OUT, primary_account_id)));

  // No events fire at all while profile is signed out.
  NotifyTokenRevoked(alpha_account_id);
  std::string gamma_account_id = AddAccountWithToken("gamma@example.com");
  EXPECT_TRUE(observer()->CheckEvents());

  // Signing the profile in again will resume tracking all accounts.
  SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(beta_account_id);
  ReturnOAuthUrlFetchSuccess(gamma_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  observer()->SortEventsByUser();
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_IN, beta_account_id),
                              TrackingEvent(SIGN_IN, gamma_account_id),
                              TrackingEvent(SIGN_IN, primary_account_id)));

  // Revoking the primary token does not affect other accounts.
  NotifyTokenRevoked(primary_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account_id)));

  NotifyTokenAvailable(primary_account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account_id)));
}
#endif

// Primary/non-primary interactions

TEST_F(AccountTrackerTest, MultiNoEventsBeforeLogin) {
  std::string account_id1 = AddAccountWithToken("user@example.com");
  std::string account_id2 = AddAccountWithToken("user2@example.com");
  NotifyTokenRevoked(account_id2);
  NotifyTokenRevoked(account_id1);

// Logout is not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
  NotifyLogoutOfAllAccounts();
#endif

  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, MultiRevokePrimaryDoesNotRemoveAllAccounts) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  std::string account_id = AddAccountWithToken("user@example.com");
  ReturnOAuthUrlFetchSuccess(account_id);
  observer()->Clear();

  NotifyTokenRevoked(primary_account_id);
  observer()->SortEventsByUser();
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account_id)));
}

TEST_F(AccountTrackerTest, GetAccountsPrimary) {
  std::string primary_account_id = SetupPrimaryLogin();

  std::vector<AccountIds> ids = account_tracker()->GetAccounts();
  EXPECT_EQ(1ul, ids.size());
  EXPECT_EQ(primary_account_id, ids[0].account_key);
  EXPECT_EQ(AccountKeyToObfuscatedId(primary_account_id), ids[0].gaia);
}

TEST_F(AccountTrackerTest, GetAccountsSignedOut) {
  std::vector<AccountIds> ids = account_tracker()->GetAccounts();
  EXPECT_EQ(0ul, ids.size());
}

TEST_F(AccountTrackerTest, GetAccountsOnlyReturnAccountsWithTokens) {
  std::string primary_account_id = SetupPrimaryLogin();

  std::string alpha_account_id = AddAccountWithToken("alpha@example.com");
  std::string beta_account_id = AddAccountWithToken("beta@example.com");
  ReturnOAuthUrlFetchSuccess(beta_account_id);

  std::vector<AccountIds> ids = account_tracker()->GetAccounts();
  EXPECT_EQ(2ul, ids.size());
  EXPECT_EQ(primary_account_id, ids[0].account_key);
  EXPECT_EQ(AccountKeyToObfuscatedId(primary_account_id), ids[0].gaia);
  EXPECT_EQ(beta_account_id, ids[1].account_key);
  EXPECT_EQ(AccountKeyToObfuscatedId(beta_account_id), ids[1].gaia);
}

TEST_F(AccountTrackerTest, GetAccountsSortOrder) {
  std::string primary_account_id = SetupPrimaryLogin();

  std::string zeta_account_id = AddAccountWithToken("zeta@example.com");
  ReturnOAuthUrlFetchSuccess(zeta_account_id);
  std::string alpha_account_id = AddAccountWithToken("alpha@example.com");
  ReturnOAuthUrlFetchSuccess(alpha_account_id);

  // The primary account will be first in the vector. Remaining accounts
  // will be sorted by gaia ID.
  std::vector<AccountIds> ids = account_tracker()->GetAccounts();
  EXPECT_EQ(3ul, ids.size());
  EXPECT_EQ(primary_account_id, ids[0].account_key);
  EXPECT_EQ(AccountKeyToObfuscatedId(primary_account_id), ids[0].gaia);
  EXPECT_EQ(alpha_account_id, ids[1].account_key);
  EXPECT_EQ(AccountKeyToObfuscatedId(alpha_account_id), ids[1].gaia);
  EXPECT_EQ(zeta_account_id, ids[2].account_key);
  EXPECT_EQ(AccountKeyToObfuscatedId(zeta_account_id), ids[2].gaia);
}

TEST_F(AccountTrackerTest, GetAccountsReturnNothingWhenPrimarySignedOut) {
  std::string primary_account_id = SetupPrimaryLogin();

  std::string zeta_account_id = AddAccountWithToken("zeta@example.com");
  ReturnOAuthUrlFetchSuccess(zeta_account_id);
  std::string alpha_account_id = AddAccountWithToken("alpha@example.com");
  ReturnOAuthUrlFetchSuccess(alpha_account_id);

  NotifyTokenRevoked(primary_account_id);

  std::vector<AccountIds> ids = account_tracker()->GetAccounts();
  EXPECT_EQ(0ul, ids.size());
}

// This test exercises true login/logout, which are not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
TEST_F(AccountTrackerTest, MultiLogoutRemovesAllAccounts) {
  std::string primary_account_id = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account_id);
  ReturnOAuthUrlFetchSuccess(primary_account_id);
  std::string account_id = AddAccountWithToken("user@example.com");
  ReturnOAuthUrlFetchSuccess(account_id);
  observer()->Clear();

  NotifyLogoutOfAllAccounts();
  observer()->SortEventsByUser();
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account_id),
                              TrackingEvent(SIGN_OUT, account_id)));
}
#endif

}  // namespace gcm
