// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/gcm_driver/gcm_client_impl.h"

#include <stdint.h>

#include <initializer_list>
#include <memory>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/gcm_driver/features.h"
#include "google_apis/gcm/base/fake_encryptor.h"
#include "google_apis/gcm/base/mcs_message.h"
#include "google_apis/gcm/base/mcs_util.h"
#include "google_apis/gcm/engine/checkin_request.h"
#include "google_apis/gcm/engine/fake_connection_factory.h"
#include "google_apis/gcm/engine/fake_connection_handler.h"
#include "google_apis/gcm/engine/gservices_settings.h"
#include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
#include "google_apis/gcm/protocol/android_checkin.pb.h"
#include "google_apis/gcm/protocol/checkin.pb.h"
#include "google_apis/gcm/protocol/mcs.pb.h"
#include "net/test/gtest_util.h"
#include "net/test/scoped_disable_exit_on_dfatal.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/test/test_network_connection_tracker.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest-spi.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/leveldb_chrome.h"

namespace gcm {
namespace {

enum LastEvent {
  NONE,
  LOADING_COMPLETED,
  REGISTRATION_COMPLETED,
  UNREGISTRATION_COMPLETED,
  MESSAGE_SEND_ERROR,
  MESSAGE_SEND_ACK,
  MESSAGE_RECEIVED,
  MESSAGES_DELETED,
};

const char kChromeVersion[] = "45.0.0.1";
const uint64_t kDeviceAndroidId = 54321;
const uint64_t kDeviceSecurityToken = 12345;
const uint64_t kDeviceAndroidId2 = 11111;
const uint64_t kDeviceSecurityToken2 = 2222;
const int64_t kSettingsCheckinInterval = 16 * 60 * 60;
const char kProductCategoryForSubtypes[] = "com.chrome.macosx";
const char kExtensionAppId[] = "abcdefghijklmnopabcdefghijklmnop";
const char kRegistrationId[] = "reg_id";
const char kSubtypeAppId[] = "app_id";
const char kSender[] = "project_id";
const char kSender2[] = "project_id2";
const char kRegistrationResponsePrefix[] = "token=";
const char kUnregistrationResponsePrefix[] = "deleted=";
const char kRawData[] = "example raw data";

const char kInstanceID[] = "iid_1";
const char kScope[] = "GCM";
const char kDeleteTokenResponse[] = "token=foo";
const int kTestTokenInvalidationPeriod = 5;
const char kMessageId[] = "0:12345%5678";

const char kRegisterUrl[] = "https://android.clients.google.com/c2dm/register3";

// Helper for building arbitrary data messages.
MCSMessage BuildDownstreamMessage(
    const std::string& project_id,
    const std::string& category,
    const std::string& subtype,
    const std::map<std::string, std::string>& data,
    const std::string& raw_data) {
  mcs_proto::DataMessageStanza data_message;
  data_message.set_from(project_id);
  data_message.set_category(category);
  for (auto iter = data.begin(); iter != data.end(); ++iter) {
    mcs_proto::AppData* app_data = data_message.add_app_data();
    app_data->set_key(iter->first);
    app_data->set_value(iter->second);
  }
  if (!subtype.empty()) {
    mcs_proto::AppData* app_data = data_message.add_app_data();
    app_data->set_key("subtype");
    app_data->set_value(subtype);
  }
  data_message.set_raw_data(raw_data);
  data_message.set_persistent_id(kMessageId);
  return MCSMessage(kDataMessageStanzaTag, data_message);
}

GCMClient::AccountTokenInfo MakeAccountToken(const std::string& email,
                                             const std::string& token) {
  GCMClient::AccountTokenInfo account_token;
  account_token.email = email;
  account_token.access_token = token;
  return account_token;
}

std::map<std::string, std::string> MakeEmailToTokenMap(
    const std::vector<GCMClient::AccountTokenInfo>& account_tokens) {
  std::map<std::string, std::string> email_token_map;
  for (auto iter = account_tokens.begin(); iter != account_tokens.end();
       ++iter) {
    email_token_map[iter->email] = iter->access_token;
  }
  return email_token_map;
}

class FakeMCSClient : public MCSClient {
 public:
  FakeMCSClient(base::Clock* clock,
                ConnectionFactory* connection_factory,
                GCMStore* gcm_store,
                scoped_refptr<base::SequencedTaskRunner> io_task_runner,
                GCMStatsRecorder* recorder);
  ~FakeMCSClient() override;
  void Login(uint64_t android_id, uint64_t security_token) override;
  void SendMessage(const MCSMessage& message) override;

  uint64_t last_android_id() const { return last_android_id_; }
  uint64_t last_security_token() const { return last_security_token_; }
  uint8_t last_message_tag() const { return last_message_tag_; }
  const mcs_proto::DataMessageStanza& last_data_message_stanza() const {
    return last_data_message_stanza_;
  }

 private:
  uint64_t last_android_id_;
  uint64_t last_security_token_;
  uint8_t last_message_tag_;
  mcs_proto::DataMessageStanza last_data_message_stanza_;
};

FakeMCSClient::FakeMCSClient(
    base::Clock* clock,
    ConnectionFactory* connection_factory,
    GCMStore* gcm_store,
    scoped_refptr<base::SequencedTaskRunner> io_task_runner,
    GCMStatsRecorder* recorder)
    : MCSClient("",
                clock,
                connection_factory,
                gcm_store,
                io_task_runner,
                recorder),
      last_android_id_(0u),
      last_security_token_(0u),
      last_message_tag_(kNumProtoTypes) {}

FakeMCSClient::~FakeMCSClient() {
}

void FakeMCSClient::Login(uint64_t android_id, uint64_t security_token) {
  last_android_id_ = android_id;
  last_security_token_ = security_token;
}

void FakeMCSClient::SendMessage(const MCSMessage& message) {
  last_message_tag_ = message.tag();
  if (last_message_tag_ == kDataMessageStanzaTag) {
    last_data_message_stanza_.CopyFrom(
        reinterpret_cast<const mcs_proto::DataMessageStanza&>(
            message.GetProtobuf()));
  }
}

class AutoAdvancingTestClock : public base::Clock {
 public:
  explicit AutoAdvancingTestClock(base::TimeDelta auto_increment_time_delta);

  AutoAdvancingTestClock(const AutoAdvancingTestClock&) = delete;
  AutoAdvancingTestClock& operator=(const AutoAdvancingTestClock&) = delete;

  ~AutoAdvancingTestClock() override;

  base::Time Now() const override;
  void Advance(base::TimeDelta delta);
  int call_count() const { return call_count_; }

 private:
  mutable int call_count_;
  base::TimeDelta auto_increment_time_delta_;
  mutable base::Time now_;
};

AutoAdvancingTestClock::AutoAdvancingTestClock(
    base::TimeDelta auto_increment_time_delta)
    : call_count_(0), auto_increment_time_delta_(auto_increment_time_delta) {
}

AutoAdvancingTestClock::~AutoAdvancingTestClock() {
}

base::Time AutoAdvancingTestClock::Now() const {
  call_count_++;
  now_ += auto_increment_time_delta_;
  return now_;
}

void AutoAdvancingTestClock::Advance(base::TimeDelta delta) {
  now_ += delta;
}

class FakeGCMInternalsBuilder : public GCMInternalsBuilder {
 public:
  explicit FakeGCMInternalsBuilder(base::TimeDelta clock_step);
  ~FakeGCMInternalsBuilder() override;

  base::Clock* GetClock() override;
  std::unique_ptr<MCSClient> BuildMCSClient(
      const std::string& version,
      base::Clock* clock,
      ConnectionFactory* connection_factory,
      GCMStore* gcm_store,
      scoped_refptr<base::SequencedTaskRunner> io_task_runner,
      GCMStatsRecorder* recorder) override;
  std::unique_ptr<ConnectionFactory> BuildConnectionFactory(
      const std::vector<GURL>& endpoints,
      const net::BackoffEntry::Policy& backoff_policy,
      base::RepeatingCallback<void(
          mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
          get_socket_factory_callback,
      scoped_refptr<base::SequencedTaskRunner> io_task_runner,
      GCMStatsRecorder* recorder,
      network::NetworkConnectionTracker* network_connection_tracker) override;

 private:
  AutoAdvancingTestClock clock_;
};

FakeGCMInternalsBuilder::FakeGCMInternalsBuilder(base::TimeDelta clock_step)
    : clock_(clock_step) {}

FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {}

base::Clock* FakeGCMInternalsBuilder::GetClock() {
  return &clock_;
}

std::unique_ptr<MCSClient> FakeGCMInternalsBuilder::BuildMCSClient(
    const std::string& version,
    base::Clock* clock,
    ConnectionFactory* connection_factory,
    GCMStore* gcm_store,
    scoped_refptr<base::SequencedTaskRunner> io_task_runner,
    GCMStatsRecorder* recorder) {
  return base::WrapUnique<MCSClient>(new FakeMCSClient(
      clock, connection_factory, gcm_store, io_task_runner, recorder));
}

std::unique_ptr<ConnectionFactory>
FakeGCMInternalsBuilder::BuildConnectionFactory(
    const std::vector<GURL>& endpoints,
    const net::BackoffEntry::Policy& backoff_policy,
    base::RepeatingCallback<void(
        mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
        get_socket_factory_callback,
    scoped_refptr<base::SequencedTaskRunner> io_task_runner,
    GCMStatsRecorder* recorder,
    network::NetworkConnectionTracker* network_connection_tracker) {
  return base::WrapUnique<ConnectionFactory>(new FakeConnectionFactory());
}

}  // namespace

class GCMClientImplTest : public testing::Test,
                          public GCMClient::Delegate {
 public:
  GCMClientImplTest();
  ~GCMClientImplTest() override;

  void SetUp() override;
  void TearDown() override;

  void SetFeatureParams(const base::Feature& feature,
                        const base::FieldTrialParams& params);

  void InitializeInvalidationFieldTrial();

  void BuildGCMClient(base::TimeDelta clock_step);
  void InitializeGCMClient();
  void StartGCMClient();
  void Register(const std::string& app_id,
                const std::vector<std::string>& senders);
  void Unregister(const std::string& app_id);
  void ReceiveMessageFromMCS(const MCSMessage& message);
  void ReceiveOnMessageSentToMCS(
      const std::string& app_id,
      const std::string& message_id,
      const MCSClient::MessageSendStatus status);
  void FailCheckin(net::HttpStatusCode response_code);
  void CompleteCheckin(uint64_t android_id,
                       uint64_t security_token,
                       const std::string& digest,
                       const std::map<std::string, std::string>& settings);
  void CompleteCheckinImpl(uint64_t android_id,
                           uint64_t security_token,
                           const std::string& digest,
                           const std::map<std::string, std::string>& settings,
                           net::HttpStatusCode response_code);
  void CompleteRegistration(const std::string& registration_id);
  void CompleteUnregistration(const std::string& app_id);

  bool ExistsRegistration(const std::string& app_id) const;
  void AddRegistration(const std::string& app_id,
                       const std::vector<std::string>& sender_ids,
                       const std::string& registration_id);

  // GCMClient::Delegate overrides (for verification).
  void OnRegisterFinished(scoped_refptr<RegistrationInfo> registration_info,
                          const std::string& registration_id,
                          GCMClient::Result result) override;
  void OnUnregisterFinished(scoped_refptr<RegistrationInfo> registration_info,
                            GCMClient::Result result) override;
  void OnSendFinished(const std::string& app_id,
                      const std::string& message_id,
                      GCMClient::Result result) override {}
  void OnMessageReceived(const std::string& registration_id,
                         const IncomingMessage& message) override;
  void OnMessagesDeleted(const std::string& app_id) override;
  void OnMessageSendError(
      const std::string& app_id,
      const gcm::GCMClient::SendErrorDetails& send_error_details) override;
  void OnSendAcknowledged(const std::string& app_id,
                          const std::string& message_id) override;
  void OnGCMReady(const std::vector<AccountMapping>& account_mappings,
                  const base::Time& last_token_fetch_time) override;
  void OnActivityRecorded() override {}
  void OnConnected(const net::IPEndPoint& ip_endpoint) override {}
  void OnDisconnected() override {}
  void OnStoreReset() override {}

  GCMClientImpl* gcm_client() const { return gcm_client_.get(); }
  GCMClientImpl::State gcm_client_state() const {
    return gcm_client_->state_;
  }
  FakeMCSClient* mcs_client() const {
    return static_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get());
  }
  ConnectionFactory* connection_factory() const {
    return gcm_client_->connection_factory_.get();
  }

  const GCMClientImpl::CheckinInfo& device_checkin_info() const {
    return gcm_client_->device_checkin_info_;
  }

  const CheckinRequest& checkin_request() const {
    return *gcm_client_->checkin_request_;
  }

  base::test::ScopedFeatureList& scoped_feature_list() {
    return scoped_feature_list_;
  }

  void reset_last_event() {
    last_event_ = NONE;
    last_app_id_.clear();
    last_registration_id_.clear();
    last_message_id_.clear();
    last_result_ = GCMClient::UNKNOWN_ERROR;
    last_account_mappings_.clear();
    last_token_fetch_time_ = base::Time();
  }

  LastEvent last_event() const { return last_event_; }
  const std::string& last_app_id() const { return last_app_id_; }
  const std::string& last_registration_id() const {
    return last_registration_id_;
  }
  const std::string& last_message_id() const { return last_message_id_; }
  GCMClient::Result last_result() const { return last_result_; }
  const IncomingMessage& last_message() const { return last_message_; }
  const GCMClient::SendErrorDetails& last_error_details() const {
    return last_error_details_;
  }
  const base::Time& last_token_fetch_time() const {
    return last_token_fetch_time_;
  }
  const std::vector<AccountMapping>& last_account_mappings() {
    return last_account_mappings_;
  }

  const GServicesSettings& gservices_settings() const {
    return gcm_client_->gservices_settings_;
  }

  const base::FilePath& temp_directory_path() const {
    return temp_directory_.GetPath();
  }

  base::FilePath gcm_store_path() const {
    // Pass an non-existent directory as store path to match the exact
    // behavior in the production code. Currently GCMStoreImpl checks if
    // the directory exist or not to determine the store existence.
    return temp_directory_.GetPath().Append(FILE_PATH_LITERAL("GCM Store"));
  }

  int64_t CurrentTime();

  // Tooling.
  void PumpLoopUntilIdle();
  bool CreateUniqueTempDir();
  AutoAdvancingTestClock* clock() const {
    return static_cast<AutoAdvancingTestClock*>(gcm_client_->clock_);
  }
  network::TestURLLoaderFactory* url_loader_factory() {
    return &test_url_loader_factory_;
  }

  void FastForwardBy(const base::TimeDelta& duration) {
    task_environment_.FastForwardBy(duration);
  }

 private:
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  // Must be declared first so that it is destroyed last. Injected to
  // GCM client.
  base::ScopedTempDir temp_directory_;

  // Variables used for verification.
  LastEvent last_event_;
  std::string last_app_id_;
  std::string last_registration_id_;
  std::string last_message_id_;
  GCMClient::Result last_result_;
  IncomingMessage last_message_;
  GCMClient::SendErrorDetails last_error_details_;
  base::Time last_token_fetch_time_;
  std::vector<AccountMapping> last_account_mappings_;

  std::unique_ptr<GCMClientImpl> gcm_client_;

  // Injected to GCM client.
  network::TestURLLoaderFactory test_url_loader_factory_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

GCMClientImplTest::GCMClientImplTest()
    : last_event_(NONE), last_result_(GCMClient::UNKNOWN_ERROR) {}

GCMClientImplTest::~GCMClientImplTest() {}

void GCMClientImplTest::SetUp() {
  testing::Test::SetUp();
  ASSERT_TRUE(CreateUniqueTempDir());
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  StartGCMClient();
  InitializeInvalidationFieldTrial();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, std::string(),
                      std::map<std::string, std::string>()));
}

void GCMClientImplTest::TearDown() {
  gcm_client_.reset();
  PumpLoopUntilIdle();
  testing::Test::TearDown();
}

void GCMClientImplTest::SetFeatureParams(const base::Feature& feature,
                                         const base::FieldTrialParams& params) {
  scoped_feature_list_.InitAndEnableFeatureWithParameters(feature, params);

  base::FieldTrialParams actual_params;
  EXPECT_TRUE(base::GetFieldTrialParamsByFeature(
      features::kInvalidateTokenFeature, &actual_params));
  EXPECT_EQ(params, actual_params);
}

void GCMClientImplTest::InitializeInvalidationFieldTrial() {
  std::map<std::string, std::string> params;
  params[features::kParamNameTokenInvalidationPeriodDays] =
      std::to_string(kTestTokenInvalidationPeriod);
  ASSERT_NO_FATAL_FAILURE(
      SetFeatureParams(features::kInvalidateTokenFeature, std::move(params)));
}

void GCMClientImplTest::PumpLoopUntilIdle() {
  task_environment_.RunUntilIdle();
}

bool GCMClientImplTest::CreateUniqueTempDir() {
  return temp_directory_.CreateUniqueTempDir();
}

void GCMClientImplTest::BuildGCMClient(base::TimeDelta clock_step) {
  gcm_client_ =
      std::make_unique<GCMClientImpl>(base::WrapUnique<GCMInternalsBuilder>(
          new FakeGCMInternalsBuilder(clock_step)));
}

void GCMClientImplTest::FailCheckin(net::HttpStatusCode response_code) {
  std::map<std::string, std::string> settings;
  CompleteCheckinImpl(0, 0, GServicesSettings::CalculateDigest(settings),
                      settings, response_code);
}

void GCMClientImplTest::CompleteCheckin(
    uint64_t android_id,
    uint64_t security_token,
    const std::string& digest,
    const std::map<std::string, std::string>& settings) {
  CompleteCheckinImpl(android_id, security_token, digest, settings,
                      net::HTTP_OK);
}

void GCMClientImplTest::CompleteCheckinImpl(
    uint64_t android_id,
    uint64_t security_token,
    const std::string& digest,
    const std::map<std::string, std::string>& settings,
    net::HttpStatusCode response_code) {
  checkin_proto::AndroidCheckinResponse response;
  response.set_stats_ok(true);
  response.set_android_id(android_id);
  response.set_security_token(security_token);

  // For testing G-services settings.
  if (!digest.empty()) {
    response.set_digest(digest);
    for (auto it = settings.begin(); it != settings.end(); ++it) {
      checkin_proto::GservicesSetting* setting = response.add_setting();
      setting->set_name(it->first);
      setting->set_value(it->second);
    }
    response.set_settings_diff(false);
  }

  std::string response_string;
  response.SerializeToString(&response_string);

  EXPECT_TRUE(url_loader_factory()->SimulateResponseForPendingRequest(
      gservices_settings().GetCheckinURL(),
      network::URLLoaderCompletionStatus(net::OK),
      network::CreateURLResponseHead(response_code), response_string));
  // Give a chance for GCMStoreImpl::Backend to finish persisting data.
  PumpLoopUntilIdle();
}

void GCMClientImplTest::CompleteRegistration(
    const std::string& registration_id) {
  std::string response(kRegistrationResponsePrefix);
  response.append(registration_id);

  EXPECT_TRUE(url_loader_factory()->SimulateResponseForPendingRequest(
      GURL(kRegisterUrl), network::URLLoaderCompletionStatus(net::OK),
      network::CreateURLResponseHead(net::HTTP_OK), response));

  // Give a chance for GCMStoreImpl::Backend to finish persisting data.
  PumpLoopUntilIdle();
}

void GCMClientImplTest::CompleteUnregistration(
    const std::string& app_id) {
  std::string response(kUnregistrationResponsePrefix);
  response.append(app_id);

  EXPECT_TRUE(url_loader_factory()->SimulateResponseForPendingRequest(
      GURL(kRegisterUrl), network::URLLoaderCompletionStatus(net::OK),
      network::CreateURLResponseHead(net::HTTP_OK), response));

  // Give a chance for GCMStoreImpl::Backend to finish persisting data.
  PumpLoopUntilIdle();
}

bool GCMClientImplTest::ExistsRegistration(const std::string& app_id) const {
  return ExistsGCMRegistrationInMap(gcm_client_->registrations_, app_id);
}

void GCMClientImplTest::AddRegistration(
    const std::string& app_id,
    const std::vector<std::string>& sender_ids,
    const std::string& registration_id) {
  auto registration = base::MakeRefCounted<GCMRegistrationInfo>();
  registration->app_id = app_id;
  registration->sender_ids = sender_ids;
  gcm_client_->registrations_.emplace(std::move(registration), registration_id);
}

void GCMClientImplTest::InitializeGCMClient() {
  clock()->Advance(base::Milliseconds(1));

  // Actual initialization.
  GCMClient::ChromeBuildInfo chrome_build_info;
  chrome_build_info.version = kChromeVersion;
  chrome_build_info.product_category_for_subtypes = kProductCategoryForSubtypes;
  gcm_client_->Initialize(
      chrome_build_info, gcm_store_path(),
      task_environment_.GetMainThreadTaskRunner(),
      base::SingleThreadTaskRunner::GetCurrentDefault(), base::DoNothing(),
      base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
          &test_url_loader_factory_),
      network::TestNetworkConnectionTracker::GetInstance(),
      base::WrapUnique<Encryptor>(new FakeEncryptor), this);
}

void GCMClientImplTest::StartGCMClient() {
  // Start loading and check-in.
  gcm_client_->Start(GCMClient::IMMEDIATE_START);

  PumpLoopUntilIdle();
}

void GCMClientImplTest::Register(const std::string& app_id,
                                 const std::vector<std::string>& senders) {
  auto gcm_info = base::MakeRefCounted<GCMRegistrationInfo>();
  gcm_info->app_id = app_id;
  gcm_info->sender_ids = senders;
  gcm_client()->Register(std::move(gcm_info));
}

void GCMClientImplTest::Unregister(const std::string& app_id) {
  auto gcm_info = base::MakeRefCounted<GCMRegistrationInfo>();
  gcm_info->app_id = app_id;
  gcm_client()->Unregister(std::move(gcm_info));
}

void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage& message) {
  gcm_client_->recorder_.RecordConnectionInitiated(std::string());
  gcm_client_->recorder_.RecordConnectionSuccess();
  gcm_client_->OnMessageReceivedFromMCS(message);
}

void GCMClientImplTest::ReceiveOnMessageSentToMCS(
      const std::string& app_id,
      const std::string& message_id,
      const MCSClient::MessageSendStatus status) {
  gcm_client_->OnMessageSentToMCS(0LL, app_id, message_id, status);
}

void GCMClientImplTest::OnGCMReady(
    const std::vector<AccountMapping>& account_mappings,
    const base::Time& last_token_fetch_time) {
  last_event_ = LOADING_COMPLETED;
  last_account_mappings_ = account_mappings;
  last_token_fetch_time_ = last_token_fetch_time;
}

void GCMClientImplTest::OnMessageReceived(const std::string& registration_id,
                                          const IncomingMessage& message) {
  last_event_ = MESSAGE_RECEIVED;
  last_app_id_ = registration_id;
  last_message_ = message;
}

void GCMClientImplTest::OnRegisterFinished(
    scoped_refptr<RegistrationInfo> registration_info,
    const std::string& registration_id,
    GCMClient::Result result) {
  last_event_ = REGISTRATION_COMPLETED;
  last_app_id_ = registration_info->app_id;
  last_registration_id_ = registration_id;
  last_result_ = result;
}

void GCMClientImplTest::OnUnregisterFinished(
    scoped_refptr<RegistrationInfo> registration_info,
    GCMClient::Result result) {
  last_event_ = UNREGISTRATION_COMPLETED;
  last_app_id_ = registration_info->app_id;
  last_result_ = result;
}

void GCMClientImplTest::OnMessagesDeleted(const std::string& app_id) {
  last_event_ = MESSAGES_DELETED;
  last_app_id_ = app_id;
}

void GCMClientImplTest::OnMessageSendError(
    const std::string& app_id,
    const gcm::GCMClient::SendErrorDetails& send_error_details) {
  last_event_ = MESSAGE_SEND_ERROR;
  last_app_id_ = app_id;
  last_error_details_ = send_error_details;
}

void GCMClientImplTest::OnSendAcknowledged(const std::string& app_id,
                                           const std::string& message_id) {
  last_event_ = MESSAGE_SEND_ACK;
  last_app_id_ = app_id;
  last_message_id_ = message_id;
}

int64_t GCMClientImplTest::CurrentTime() {
  return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond;
}

TEST_F(GCMClientImplTest, LoadingCompleted) {
  EXPECT_EQ(LOADING_COMPLETED, last_event());
  EXPECT_EQ(kDeviceAndroidId, mcs_client()->last_android_id());
  EXPECT_EQ(kDeviceSecurityToken, mcs_client()->last_security_token());

  // Checking freshly loaded CheckinInfo.
  EXPECT_EQ(kDeviceAndroidId, device_checkin_info().android_id);
  EXPECT_EQ(kDeviceSecurityToken, device_checkin_info().secret);
  EXPECT_TRUE(device_checkin_info().last_checkin_accounts.empty());
  EXPECT_TRUE(device_checkin_info().accounts_set);
  EXPECT_TRUE(device_checkin_info().account_tokens.empty());
}

TEST_F(GCMClientImplTest, LoadingBusted) {
  // Close the GCM store.
  gcm_client()->Stop();
  PumpLoopUntilIdle();

  // Mess up the store.
  EXPECT_TRUE(leveldb_chrome::CorruptClosedDBForTesting(gcm_store_path()));

  // Restart GCM client. The store should be reset and the loading should
  // complete successfully.
  reset_last_event();
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  StartGCMClient();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId2, kDeviceSecurityToken2, std::string(),
                      std::map<std::string, std::string>()));

  EXPECT_EQ(LOADING_COMPLETED, last_event());
  EXPECT_EQ(kDeviceAndroidId2, mcs_client()->last_android_id());
  EXPECT_EQ(kDeviceSecurityToken2, mcs_client()->last_security_token());
}

TEST_F(GCMClientImplTest, LoadingWithEmptyDirectory) {
  // Close the GCM store.
  gcm_client()->Stop();
  PumpLoopUntilIdle();

  // Make the store directory empty, to simulate a previous destroy store
  // operation failing to delete the store directory.
  ASSERT_TRUE(base::DeletePathRecursively(gcm_store_path()));
  ASSERT_TRUE(base::CreateDirectory(gcm_store_path()));

  base::HistogramTester histogram_tester;

  // Restart GCM client. The store should be considered to not exist.
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  gcm_client()->Start(GCMClient::DELAYED_START);
  PumpLoopUntilIdle();
  // Since the store does not exist, the database should not have been opened.
  histogram_tester.ExpectTotalCount("GCM.Database.Open", 0);
  // Without a store, DELAYED_START loading should only reach INITIALIZED state.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // The store directory should still exist (and be empty). If not, then the
  // DELAYED_START load has probably reset the store, rather than leaving that
  // to the next IMMEDIATE_START load as expected.
  ASSERT_TRUE(base::DirectoryExists(gcm_store_path()));
  ASSERT_FALSE(
      base::PathExists(gcm_store_path().Append(FILE_PATH_LITERAL("CURRENT"))));

  // IMMEDIATE_START loading should successfully create a new store despite the
  // empty directory.
  reset_last_event();
  StartGCMClient();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId2, kDeviceSecurityToken2, std::string(),
                      std::map<std::string, std::string>()));
  EXPECT_EQ(LOADING_COMPLETED, last_event());
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
  EXPECT_EQ(kDeviceAndroidId2, mcs_client()->last_android_id());
  EXPECT_EQ(kDeviceSecurityToken2, mcs_client()->last_security_token());
}

TEST_F(GCMClientImplTest, DestroyStoreWhenNotNeeded) {
  // Close the GCM store.
  gcm_client()->Stop();
  PumpLoopUntilIdle();

  // Restart GCM client. The store is loaded successfully.
  reset_last_event();
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  gcm_client()->Start(GCMClient::DELAYED_START);
  PumpLoopUntilIdle();

  EXPECT_EQ(GCMClientImpl::LOADED, gcm_client_state());
  EXPECT_TRUE(device_checkin_info().android_id);
  EXPECT_TRUE(device_checkin_info().secret);

  // Fast forward the clock to trigger the store destroying logic.
  FastForwardBy(base::Milliseconds(300000));
  PumpLoopUntilIdle();

  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
  EXPECT_FALSE(device_checkin_info().android_id);
  EXPECT_FALSE(device_checkin_info().secret);
}

TEST_F(GCMClientImplTest, SerializeAndDeserialize) {
  std::vector<std::string> senders{"sender"};
  auto gcm_info = base::MakeRefCounted<GCMRegistrationInfo>();
  gcm_info->app_id = kExtensionAppId;
  gcm_info->sender_ids = senders;
  gcm_info->last_validated = clock()->Now();

  auto gcm_info_deserialized = base::MakeRefCounted<GCMRegistrationInfo>();
  std::string gcm_registration_id_deserialized;
  {
    std::string serialized_key = gcm_info->GetSerializedKey();
    std::string serialized_value =
        gcm_info->GetSerializedValue(kRegistrationId);

    ASSERT_TRUE(gcm_info_deserialized->Deserialize(
        serialized_key, serialized_value, &gcm_registration_id_deserialized));
  }

  EXPECT_EQ(gcm_info->app_id, gcm_info_deserialized->app_id);
  EXPECT_EQ(gcm_info->sender_ids, gcm_info_deserialized->sender_ids);
  EXPECT_EQ(gcm_info->last_validated, gcm_info_deserialized->last_validated);
  EXPECT_EQ(kRegistrationId, gcm_registration_id_deserialized);

  auto instance_id_info = base::MakeRefCounted<InstanceIDTokenInfo>();
  instance_id_info->app_id = kExtensionAppId;
  instance_id_info->last_validated = clock()->Now();
  instance_id_info->authorized_entity = "different_sender";
  instance_id_info->scope = "scope";

  auto instance_id_info_deserialized =
      base::MakeRefCounted<InstanceIDTokenInfo>();
  std::string instance_id_registration_id_deserialized;
  {
    std::string serialized_key = instance_id_info->GetSerializedKey();
    std::string serialized_value =
        instance_id_info->GetSerializedValue(kRegistrationId);

    ASSERT_TRUE(instance_id_info_deserialized->Deserialize(
        serialized_key, serialized_value,
        &instance_id_registration_id_deserialized));
  }

  EXPECT_EQ(instance_id_info->app_id, instance_id_info_deserialized->app_id);
  EXPECT_EQ(instance_id_info->last_validated,
            instance_id_info_deserialized->last_validated);
  EXPECT_EQ(instance_id_info->authorized_entity,
            instance_id_info_deserialized->authorized_entity);
  EXPECT_EQ(instance_id_info->scope, instance_id_info_deserialized->scope);
  EXPECT_EQ(kRegistrationId, instance_id_registration_id_deserialized);
}

TEST_F(GCMClientImplTest, RegisterApp) {
  EXPECT_FALSE(ExistsRegistration(kExtensionAppId));

  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
}

TEST_F(GCMClientImplTest, RegisterAppFromCache) {
  EXPECT_FALSE(ExistsRegistration(kExtensionAppId));

  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));

  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());

  // Recreate GCMClient in order to load from the persistent store.
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  StartGCMClient();

  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
}

TEST_F(GCMClientImplTest, RegisterPreviousSenderAgain) {
  EXPECT_FALSE(ExistsRegistration(kExtensionAppId));

  // Register a sender.
  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));

  reset_last_event();

  // Register a different sender. Different registration ID from previous one
  // should be returned.
  std::vector<std::string> senders2;
  senders2.push_back("sender2");
  Register(kExtensionAppId, senders2);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id2"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id2", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));

  reset_last_event();

  // Register the 1st sender again. Different registration ID from previous one
  // should be returned.
  std::vector<std::string> senders3;
  senders3.push_back("sender");
  Register(kExtensionAppId, senders3);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
}

TEST_F(GCMClientImplTest, RegisterAgainWhenTokenIsFresh) {
  // Register a sender.
  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));

  reset_last_event();

  // Advance time by (kTestTokenInvalidationPeriod)/2
  clock()->Advance(base::Days(kTestTokenInvalidationPeriod / 2));

  // Register the same sender again. The same registration ID as the
  // previous one should be returned, and we should *not* send a
  // registration request to the GCM server.
  Register(kExtensionAppId, senders);
  PumpLoopUntilIdle();

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
}

TEST_F(GCMClientImplTest, RegisterAgainWhenTokenIsStale) {
  // Register a sender.
  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));

  reset_last_event();

  // Advance time by kTestTokenInvalidationPeriod
  clock()->Advance(base::Days(kTestTokenInvalidationPeriod));

  // Register the same sender again. Different registration ID from the
  // previous one should be returned.
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id2"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("reg_id2", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
}

TEST_F(GCMClientImplTest, UnregisterApp) {
  EXPECT_FALSE(ExistsRegistration(kExtensionAppId));

  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
  EXPECT_TRUE(ExistsRegistration(kExtensionAppId));

  Unregister(kExtensionAppId);
  ASSERT_NO_FATAL_FAILURE(CompleteUnregistration(kExtensionAppId));

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_FALSE(ExistsRegistration(kExtensionAppId));
}

// Tests that stopping the GCMClient also deletes pending registration requests.
// This is tested by checking that url fetcher contained in the request was
// deleted.
TEST_F(GCMClientImplTest, DeletePendingRequestsWhenStopping) {
  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);

  gcm_client()->Stop();
  PumpLoopUntilIdle();
  EXPECT_EQ(0, url_loader_factory()->NumPending());
}

TEST_F(GCMClientImplTest, DispatchDownstreamMessage) {
  // Register to receive messages from kSender and kSender2 only.
  std::vector<std::string> senders;
  senders.push_back(kSender);
  senders.push_back(kSender2);
  AddRegistration(kExtensionAppId, senders, "reg_id");

  std::map<std::string, std::string> expected_data;
  expected_data["message_type"] = "gcm";
  expected_data["key"] = "value";
  expected_data["key2"] = "value2";

  // Message for kSender will be received.
  MCSMessage message(BuildDownstreamMessage(
      kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
      std::string() /* raw_data */));
  EXPECT_TRUE(message.IsValid());
  ReceiveMessageFromMCS(message);

  expected_data.erase(expected_data.find("message_type"));
  EXPECT_EQ(MESSAGE_RECEIVED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(expected_data.size(), last_message().data.size());
  EXPECT_EQ(expected_data, last_message().data);
  EXPECT_EQ(kSender, last_message().sender_id);

  reset_last_event();

  // Message for kSender2 will be received.
  MCSMessage message2(BuildDownstreamMessage(
      kSender2, kExtensionAppId, std::string() /* subtype */, expected_data,
      std::string() /* raw_data */));
  EXPECT_TRUE(message2.IsValid());
  ReceiveMessageFromMCS(message2);

  EXPECT_EQ(MESSAGE_RECEIVED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(expected_data.size(), last_message().data.size());
  EXPECT_EQ(expected_data, last_message().data);
  EXPECT_EQ(kSender2, last_message().sender_id);
}

TEST_F(GCMClientImplTest, DispatchDownstreamMessageRawData) {
  std::vector<std::string> senders(1, kSender);
  AddRegistration(kExtensionAppId, senders, "reg_id");

  std::map<std::string, std::string> expected_data;

  MCSMessage message(BuildDownstreamMessage(kSender, kExtensionAppId,
                                            std::string() /* subtype */,
                                            expected_data, kRawData));
  EXPECT_TRUE(message.IsValid());
  ReceiveMessageFromMCS(message);

  EXPECT_EQ(MESSAGE_RECEIVED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(expected_data.size(), last_message().data.size());
  EXPECT_EQ(kSender, last_message().sender_id);
  EXPECT_EQ(kRawData, last_message().raw_data);
}

TEST_F(GCMClientImplTest, DispatchDownstreamMessageSendError) {
  std::map<std::string, std::string> expected_data = {
      {"message_type", "send_error"}, {"error_details", "some details"}};

  MCSMessage message(BuildDownstreamMessage(
      kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
      std::string() /* raw_data */));
  EXPECT_TRUE(message.IsValid());
  ReceiveMessageFromMCS(message);

  EXPECT_EQ(MESSAGE_SEND_ERROR, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(kMessageId, last_error_details().message_id);
  EXPECT_EQ(1UL, last_error_details().additional_data.size());
  auto iter = last_error_details().additional_data.find("error_details");
  EXPECT_TRUE(iter != last_error_details().additional_data.end());
  EXPECT_EQ("some details", iter->second);
}

TEST_F(GCMClientImplTest, DispatchDownstreamMessgaesDeleted) {
  std::map<std::string, std::string> expected_data;
  expected_data["message_type"] = "deleted_messages";
  MCSMessage message(BuildDownstreamMessage(
      kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
      std::string() /* raw_data */));
  EXPECT_TRUE(message.IsValid());
  ReceiveMessageFromMCS(message);

  EXPECT_EQ(MESSAGES_DELETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
}

TEST_F(GCMClientImplTest, SendMessage) {
  OutgoingMessage message;
  message.id = "007";
  message.time_to_live = 500;
  message.data["key"] = "value";
  gcm_client()->Send(kExtensionAppId, kSender, message);

  EXPECT_EQ(kDataMessageStanzaTag, mcs_client()->last_message_tag());
  EXPECT_EQ(kExtensionAppId,
            mcs_client()->last_data_message_stanza().category());
  EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
  EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
  EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
  EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
  EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from());
  EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
  EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
  EXPECT_EQ("value",
            mcs_client()->last_data_message_stanza().app_data(0).value());
}

TEST_F(GCMClientImplTest, SendMessageAcknowledged) {
  ReceiveOnMessageSentToMCS(kExtensionAppId, "007", MCSClient::SENT);
  EXPECT_EQ(MESSAGE_SEND_ACK, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("007", last_message_id());
}

class GCMClientImplCheckinTest : public GCMClientImplTest {
 public:
  GCMClientImplCheckinTest();
  ~GCMClientImplCheckinTest() override;

  void SetUp() override;
};

GCMClientImplCheckinTest::GCMClientImplCheckinTest() {
}

GCMClientImplCheckinTest::~GCMClientImplCheckinTest() {
}

void GCMClientImplCheckinTest::SetUp() {
  testing::Test::SetUp();
  // Creating unique temp directory that will be used by GCMStore shared between
  // GCM Client and G-services settings.
  ASSERT_TRUE(CreateUniqueTempDir());
  // Time will be advancing one hour every time it is checked.
  BuildGCMClient(base::Seconds(kSettingsCheckinInterval));
  InitializeGCMClient();
  StartGCMClient();
}

TEST_F(GCMClientImplCheckinTest, GServicesSettingsAfterInitialCheckin) {
  std::map<std::string, std::string> settings;
  settings["checkin_interval"] = base::NumberToString(kSettingsCheckinInterval);
  settings["checkin_url"] = "http://alternative.url/checkin";
  settings["gcm_hostname"] = "alternative.gcm.host";
  settings["gcm_secure_port"] = "7777";
  settings["gcm_registration_url"] = "http://alternative.url/registration";
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));
  EXPECT_EQ(base::Seconds(kSettingsCheckinInterval),
            gservices_settings().GetCheckinInterval());
  EXPECT_EQ(GURL("http://alternative.url/checkin"),
            gservices_settings().GetCheckinURL());
  EXPECT_EQ(GURL("http://alternative.url/registration"),
            gservices_settings().GetRegistrationURL());
  EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
            gservices_settings().GetMCSMainEndpoint());
  EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
            gservices_settings().GetMCSFallbackEndpoint());
}

// This test only checks that periodic checkin happens.
TEST_F(GCMClientImplCheckinTest, PeriodicCheckin) {
  std::map<std::string, std::string> settings;
  settings["checkin_interval"] = base::NumberToString(kSettingsCheckinInterval);
  settings["checkin_url"] = "http://alternative.url/checkin";
  settings["gcm_hostname"] = "alternative.gcm.host";
  settings["gcm_secure_port"] = "7777";
  settings["gcm_registration_url"] = "http://alternative.url/registration";
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  EXPECT_EQ(2, clock()->call_count());

  PumpLoopUntilIdle();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));
}

TEST_F(GCMClientImplCheckinTest, LoadGSettingsFromStore) {
  std::map<std::string, std::string> settings;
  settings["checkin_interval"] = base::NumberToString(kSettingsCheckinInterval);
  settings["checkin_url"] = "http://alternative.url/checkin";
  settings["gcm_hostname"] = "alternative.gcm.host";
  settings["gcm_secure_port"] = "7777";
  settings["gcm_registration_url"] = "http://alternative.url/registration";
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  StartGCMClient();

  EXPECT_EQ(base::Seconds(kSettingsCheckinInterval),
            gservices_settings().GetCheckinInterval());
  EXPECT_EQ(GURL("http://alternative.url/checkin"),
            gservices_settings().GetCheckinURL());
  EXPECT_EQ(GURL("http://alternative.url/registration"),
            gservices_settings().GetRegistrationURL());
  EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
            gservices_settings().GetMCSMainEndpoint());
  EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
            gservices_settings().GetMCSFallbackEndpoint());
}

// This test only checks that periodic checkin happens.
TEST_F(GCMClientImplCheckinTest, CheckinWithAccountsEmpty) {
  std::map<std::string, std::string> settings;
  settings["checkin_interval"] = base::NumberToString(kSettingsCheckinInterval);
  settings["checkin_url"] = "http://alternative.url/checkin";
  settings["gcm_hostname"] = "alternative.gcm.host";
  settings["gcm_secure_port"] = "7777";
  settings["gcm_registration_url"] = "http://alternative.url/registration";
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  std::vector<GCMClient::AccountTokenInfo> account_tokens;
  account_tokens.push_back(MakeAccountToken("test_user1@gmail.com", "token1"));
  account_tokens.push_back(MakeAccountToken("test_user2@gmail.com", "token2"));
  gcm_client()->SetAccountTokens(account_tokens);

  EXPECT_TRUE(device_checkin_info().last_checkin_accounts.empty());
  EXPECT_TRUE(device_checkin_info().accounts_set);
  EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
            device_checkin_info().account_tokens);

  PumpLoopUntilIdle();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  std::set<std::string> accounts;
  accounts.insert("test_user1@gmail.com");
  accounts.insert("test_user2@gmail.com");
  EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
  EXPECT_TRUE(device_checkin_info().accounts_set);
  EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
            device_checkin_info().account_tokens);

  // Make sure the checkin request does not have the account info.
  EXPECT_TRUE(checkin_request().request_info_.account_tokens.empty());
}

// This test only checks that periodic checkin happens.
TEST_F(GCMClientImplCheckinTest, CheckinWhenAccountRemoved) {
  std::map<std::string, std::string> settings;
  settings["checkin_interval"] = base::NumberToString(kSettingsCheckinInterval);
  settings["checkin_url"] = "http://alternative.url/checkin";
  settings["gcm_hostname"] = "alternative.gcm.host";
  settings["gcm_secure_port"] = "7777";
  settings["gcm_registration_url"] = "http://alternative.url/registration";
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  std::vector<GCMClient::AccountTokenInfo> account_tokens;
  account_tokens.push_back(MakeAccountToken("test_user1@gmail.com", "token1"));
  account_tokens.push_back(MakeAccountToken("test_user2@gmail.com", "token2"));
  gcm_client()->SetAccountTokens(account_tokens);
  PumpLoopUntilIdle();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  EXPECT_EQ(2UL, device_checkin_info().last_checkin_accounts.size());
  EXPECT_TRUE(device_checkin_info().accounts_set);
  EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
            device_checkin_info().account_tokens);

  account_tokens.erase(account_tokens.begin() + 1);
  gcm_client()->SetAccountTokens(account_tokens);

  PumpLoopUntilIdle();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  std::set<std::string> accounts;
  accounts.insert("test_user1@gmail.com");
  EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
  EXPECT_TRUE(device_checkin_info().accounts_set);
  EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
            device_checkin_info().account_tokens);
}

// This test only checks that periodic checkin happens.
TEST_F(GCMClientImplCheckinTest, CheckinWhenAccountReplaced) {
  std::map<std::string, std::string> settings;
  settings["checkin_interval"] = base::NumberToString(kSettingsCheckinInterval);
  settings["checkin_url"] = "http://alternative.url/checkin";
  settings["gcm_hostname"] = "alternative.gcm.host";
  settings["gcm_secure_port"] = "7777";
  settings["gcm_registration_url"] = "http://alternative.url/registration";
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  std::vector<GCMClient::AccountTokenInfo> account_tokens;
  account_tokens.push_back(MakeAccountToken("test_user1@gmail.com", "token1"));
  gcm_client()->SetAccountTokens(account_tokens);

  PumpLoopUntilIdle();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  std::set<std::string> accounts;
  accounts.insert("test_user1@gmail.com");
  EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);

  // This should trigger another checkin, because the list of accounts is
  // different.
  account_tokens.clear();
  account_tokens.push_back(MakeAccountToken("test_user2@gmail.com", "token2"));
  gcm_client()->SetAccountTokens(account_tokens);

  PumpLoopUntilIdle();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
                      GServicesSettings::CalculateDigest(settings), settings));

  accounts.clear();
  accounts.insert("test_user2@gmail.com");
  EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
  EXPECT_TRUE(device_checkin_info().accounts_set);
  EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
            device_checkin_info().account_tokens);
}

TEST_F(GCMClientImplCheckinTest, ResetStoreWhenCheckinRejected) {
  base::HistogramTester histogram_tester;
  std::map<std::string, std::string> settings;
  ASSERT_NO_FATAL_FAILURE(FailCheckin(net::HTTP_UNAUTHORIZED));
  PumpLoopUntilIdle();

  // Store should have been destroyed. Restart client and verify the initial
  // checkin response is persisted.
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  StartGCMClient();
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId2, kDeviceSecurityToken2,
                      GServicesSettings::CalculateDigest(settings), settings));

  EXPECT_EQ(LOADING_COMPLETED, last_event());
  EXPECT_EQ(kDeviceAndroidId2, mcs_client()->last_android_id());
  EXPECT_EQ(kDeviceSecurityToken2, mcs_client()->last_security_token());
}

class GCMClientImplStartAndStopTest : public GCMClientImplTest {
 public:
  GCMClientImplStartAndStopTest();
  ~GCMClientImplStartAndStopTest() override;

  void SetUp() override;

  void DefaultCompleteCheckin();
};

GCMClientImplStartAndStopTest::GCMClientImplStartAndStopTest() {
}

GCMClientImplStartAndStopTest::~GCMClientImplStartAndStopTest() {
}

void GCMClientImplStartAndStopTest::SetUp() {
  testing::Test::SetUp();
  ASSERT_TRUE(CreateUniqueTempDir());
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
}

void GCMClientImplStartAndStopTest::DefaultCompleteCheckin() {
  ASSERT_NO_FATAL_FAILURE(
      CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, std::string(),
                      std::map<std::string, std::string>()));
  PumpLoopUntilIdle();
}

TEST_F(GCMClientImplStartAndStopTest, StartStopAndRestart) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Delay start the GCM.
  gcm_client()->Start(GCMClient::DELAYED_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Stop the GCM.
  gcm_client()->Stop();
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Restart the GCM without delay.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, DelayedStartAndStopImmediately) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Delay start the GCM and then stop it immediately.
  gcm_client()->Start(GCMClient::DELAYED_START);
  gcm_client()->Stop();
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, ImmediateStartAndStopImmediately) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Start the GCM and then stop it immediately.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  gcm_client()->Stop();
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, DelayedStartStopAndRestart) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Delay start the GCM and then stop and restart it immediately.
  gcm_client()->Start(GCMClient::DELAYED_START);
  gcm_client()->Stop();
  gcm_client()->Start(GCMClient::DELAYED_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, ImmediateStartStopAndRestart) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Start the GCM and then stop and restart it immediately.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  gcm_client()->Stop();
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, ImmediateStartAndThenImmediateStart) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Start the GCM immediately and complete the checkin.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
  ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());

  // Stop the GCM.
  gcm_client()->Stop();
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Start the GCM immediately. GCMClientImpl should be in READY state.
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, ImmediateStartAndThenDelayStart) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Start the GCM immediately and complete the checkin.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
  ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());

  // Stop the GCM.
  gcm_client()->Stop();
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Delay start the GCM. GCMClientImpl should be in LOADED state.
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  gcm_client()->Start(GCMClient::DELAYED_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::LOADED, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, DelayedStartRace) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Delay start the GCM, then start it immediately while it's still loading.
  gcm_client()->Start(GCMClient::DELAYED_START);
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
  ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
}

TEST_F(GCMClientImplStartAndStopTest, DelayedStart) {
  // GCMClientImpl should be in INITIALIZED state at first.
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Delay start the GCM. The store will not be loaded and GCMClientImpl should
  // still be in INITIALIZED state.
  gcm_client()->Start(GCMClient::DELAYED_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Start the GCM immediately and complete the checkin.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
  ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());

  // Registration.
  std::vector<std::string> senders;
  senders.push_back("sender");
  Register(kExtensionAppId, senders);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());

  // Stop the GCM.
  gcm_client()->Stop();
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());

  // Delay start the GCM. GCM is indeed started without delay because the
  // registration record has been found.
  BuildGCMClient(base::TimeDelta());
  InitializeGCMClient();
  gcm_client()->Start(GCMClient::DELAYED_START);
  PumpLoopUntilIdle();
  EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
}

// Test for known account mappings and last token fetching time being passed
// to OnGCMReady.
TEST_F(GCMClientImplStartAndStopTest, OnGCMReadyAccountsAndTokenFetchingTime) {
  // Start the GCM and wait until it is ready.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();
  ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());

  base::Time expected_time = base::Time::Now();
  gcm_client()->SetLastTokenFetchTime(expected_time);
  AccountMapping expected_mapping;
  expected_mapping.account_id = CoreAccountId::FromGaiaId("accId");
  expected_mapping.email = "email@gmail.com";
  expected_mapping.status = AccountMapping::MAPPED;
  expected_mapping.status_change_timestamp = expected_time;
  gcm_client()->UpdateAccountMapping(expected_mapping);
  PumpLoopUntilIdle();

  // Stop the GCM.
  gcm_client()->Stop();
  PumpLoopUntilIdle();

  // Restart the GCM.
  gcm_client()->Start(GCMClient::IMMEDIATE_START);
  PumpLoopUntilIdle();

  EXPECT_EQ(LOADING_COMPLETED, last_event());
  EXPECT_EQ(expected_time, last_token_fetch_time());
  ASSERT_EQ(1UL, last_account_mappings().size());
  const AccountMapping& actual_mapping = last_account_mappings()[0];
  EXPECT_EQ(expected_mapping.account_id, actual_mapping.account_id);
  EXPECT_EQ(expected_mapping.email, actual_mapping.email);
  EXPECT_EQ(expected_mapping.status, actual_mapping.status);
  EXPECT_EQ(expected_mapping.status_change_timestamp,
            actual_mapping.status_change_timestamp);
}


class GCMClientInstanceIDTest : public GCMClientImplTest {
 public:
  GCMClientInstanceIDTest();
  ~GCMClientInstanceIDTest() override;

  void AddInstanceID(const std::string& app_id,
                     const std::string& instance_id);
  void RemoveInstanceID(const std::string& app_id);
  void GetToken(const std::string& app_id,
                const std::string& authorized_entity,
                const std::string& scope);
  void DeleteToken(const std::string& app_id,
                   const std::string& authorized_entity,
                   const std::string& scope);
  void CompleteDeleteToken();
  bool ExistsToken(const std::string& app_id,
                   const std::string& authorized_entity,
                   const std::string& scope) const;
};

GCMClientInstanceIDTest::GCMClientInstanceIDTest() {
}

GCMClientInstanceIDTest::~GCMClientInstanceIDTest() {
}

void GCMClientInstanceIDTest::AddInstanceID(const std::string& app_id,
                                            const std::string& instance_id) {
  gcm_client()->AddInstanceIDData(app_id, instance_id, "123");
}

void GCMClientInstanceIDTest::RemoveInstanceID(const std::string& app_id) {
  gcm_client()->RemoveInstanceIDData(app_id);
}

void GCMClientInstanceIDTest::GetToken(const std::string& app_id,
                                       const std::string& authorized_entity,
                                       const std::string& scope) {
  auto instance_id_info = base::MakeRefCounted<InstanceIDTokenInfo>();
  instance_id_info->app_id = app_id;
  instance_id_info->authorized_entity = authorized_entity;
  instance_id_info->scope = scope;
  gcm_client()->Register(std::move(instance_id_info));
}

void GCMClientInstanceIDTest::DeleteToken(const std::string& app_id,
                                          const std::string& authorized_entity,
                                          const std::string& scope) {
  auto instance_id_info = base::MakeRefCounted<InstanceIDTokenInfo>();
  instance_id_info->app_id = app_id;
  instance_id_info->authorized_entity = authorized_entity;
  instance_id_info->scope = scope;
  gcm_client()->Unregister(std::move(instance_id_info));
}

void GCMClientInstanceIDTest::CompleteDeleteToken() {
  std::string response(kDeleteTokenResponse);

  EXPECT_TRUE(url_loader_factory()->SimulateResponseForPendingRequest(
      GURL(kRegisterUrl), network::URLLoaderCompletionStatus(net::OK),
      network::CreateURLResponseHead(net::HTTP_OK), response));

  // Give a chance for GCMStoreImpl::Backend to finish persisting data.
  PumpLoopUntilIdle();
}

bool GCMClientInstanceIDTest::ExistsToken(const std::string& app_id,
                                          const std::string& authorized_entity,
                                          const std::string& scope) const {
  auto instance_id_info = base::MakeRefCounted<InstanceIDTokenInfo>();
  instance_id_info->app_id = app_id;
  instance_id_info->authorized_entity = authorized_entity;
  instance_id_info->scope = scope;
  return gcm_client()->registrations_.count(std::move(instance_id_info)) > 0;
}

TEST_F(GCMClientInstanceIDTest, GetToken) {
  AddInstanceID(kExtensionAppId, kInstanceID);

  // Get a token.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
  GetToken(kExtensionAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("token1", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));

  // Get another token.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));
  GetToken(kExtensionAppId, kSender2, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("token2", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender2, kScope));
  // The 1st token still exists.
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
}

// Most tests in this file use kExtensionAppId which is special-cased by
// InstanceIDUsesSubtypeForAppId in gcm_client_impl.cc. This test uses
// kSubtypeAppId to cover the alternate case.
TEST_F(GCMClientInstanceIDTest, GetTokenWithSubtype) {
  ASSERT_EQ(GCMClientImpl::READY, gcm_client_state());

  AddInstanceID(kSubtypeAppId, kInstanceID);

  EXPECT_FALSE(ExistsToken(kSubtypeAppId, kSender, kScope));

  // Get a token.
  GetToken(kSubtypeAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kSubtypeAppId, last_app_id());
  EXPECT_EQ("token1", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsToken(kSubtypeAppId, kSender, kScope));

  // Delete the token.
  DeleteToken(kSubtypeAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());
  EXPECT_FALSE(ExistsToken(kSubtypeAppId, kSender, kScope));
}

TEST_F(GCMClientInstanceIDTest, DeleteInvalidToken) {
  AddInstanceID(kExtensionAppId, kInstanceID);

  // Delete an invalid token.
  DeleteToken(kExtensionAppId, "Foo@#$", kScope);
  PumpLoopUntilIdle();

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::INVALID_PARAMETER, last_result());

  reset_last_event();

  // Delete a non-existing token.
  DeleteToken(kExtensionAppId, kSender, kScope);
  PumpLoopUntilIdle();

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::INVALID_PARAMETER, last_result());
}

TEST_F(GCMClientInstanceIDTest, DeleteSingleToken) {
  AddInstanceID(kExtensionAppId, kInstanceID);

  // Get a token.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
  GetToken(kExtensionAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("token1", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));

  reset_last_event();

  // Get another token.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));
  GetToken(kExtensionAppId, kSender2, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("token2", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender2, kScope));
  // The 1st token still exists.
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));

  reset_last_event();

  // Delete the 2nd token.
  DeleteToken(kExtensionAppId, kSender2, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  // The 2nd token is gone while the 1st token still exists.
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));

  reset_last_event();

  // Delete the 1st token.
  DeleteToken(kExtensionAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  // Both tokens are gone now.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));

  reset_last_event();

  // Trying to delete the token again will get an error.
  DeleteToken(kExtensionAppId, kSender, kScope);
  PumpLoopUntilIdle();

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::INVALID_PARAMETER, last_result());
}

TEST_F(GCMClientInstanceIDTest, DeleteAllTokens) {
  AddInstanceID(kExtensionAppId, kInstanceID);

  // Get a token.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
  GetToken(kExtensionAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("token1", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));

  reset_last_event();

  // Get another token.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));
  GetToken(kExtensionAppId, kSender2, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));

  EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ("token2", last_registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender2, kScope));
  // The 1st token still exists.
  EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));

  reset_last_event();

  // Delete all tokens.
  DeleteToken(kExtensionAppId, "*", "*");
  ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
  // All tokens are gone now.
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
  EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
}

TEST_F(GCMClientInstanceIDTest, DeleteAllTokensBeforeGetAnyToken) {
  AddInstanceID(kExtensionAppId, kInstanceID);

  // Delete all tokens without getting a token first.
  DeleteToken(kExtensionAppId, "*", "*");
  // No need to call CompleteDeleteToken since unregistration request should
  // not be triggered.
  PumpLoopUntilIdle();

  EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(GCMClient::SUCCESS, last_result());
}

TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithoutSubtype) {
  AddInstanceID(kExtensionAppId, kInstanceID);
  GetToken(kExtensionAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));

  std::map<std::string, std::string> expected_data;

  MCSMessage message(BuildDownstreamMessage(
      kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
      std::string() /* raw_data */));
  EXPECT_TRUE(message.IsValid());
  ReceiveMessageFromMCS(message);

  EXPECT_EQ(MESSAGE_RECEIVED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(expected_data.size(), last_message().data.size());
  EXPECT_EQ(expected_data, last_message().data);
  EXPECT_EQ(kSender, last_message().sender_id);
}

TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithSubtype) {
  AddInstanceID(kSubtypeAppId, kInstanceID);
  GetToken(kSubtypeAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));

  std::map<std::string, std::string> expected_data;

  MCSMessage message(BuildDownstreamMessage(
      kSender, kProductCategoryForSubtypes, kSubtypeAppId /* subtype */,
      expected_data, std::string() /* raw_data */));
  EXPECT_TRUE(message.IsValid());
  ReceiveMessageFromMCS(message);

  EXPECT_EQ(MESSAGE_RECEIVED, last_event());
  EXPECT_EQ(kSubtypeAppId, last_app_id());
  EXPECT_EQ(expected_data.size(), last_message().data.size());
  EXPECT_EQ(expected_data, last_message().data);
  EXPECT_EQ(kSender, last_message().sender_id);
}

TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithFakeSubtype) {
  // Victim non-extension registration.
  AddInstanceID(kSubtypeAppId, "iid_1");
  GetToken(kSubtypeAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));

  // Malicious extension registration.
  AddInstanceID(kExtensionAppId, "iid_2");
  GetToken(kExtensionAppId, kSender, kScope);
  ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));

  std::map<std::string, std::string> expected_data;

  // Message for kExtensionAppId should be delivered to the extension rather
  // than the victim app, despite the malicious subtype property attempting to
  // impersonate victim app.
  MCSMessage message(BuildDownstreamMessage(
      kSender, kExtensionAppId /* category */, kSubtypeAppId /* subtype */,
      expected_data, std::string() /* raw_data */));
  EXPECT_TRUE(message.IsValid());
  ReceiveMessageFromMCS(message);

  EXPECT_EQ(MESSAGE_RECEIVED, last_event());
  EXPECT_EQ(kExtensionAppId, last_app_id());
  EXPECT_EQ(expected_data.size(), last_message().data.size());
  EXPECT_EQ(expected_data, last_message().data);
  EXPECT_EQ(kSender, last_message().sender_id);
}

}  // namespace gcm
