// 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/gcm_driver_desktop.h"

#include <stdint.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/message_loop/message_loop_current.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/gcm_driver/crypto/gcm_encryption_provider.h"
#include "components/gcm_driver/fake_gcm_app_handler.h"
#include "components/gcm_driver/fake_gcm_client.h"
#include "components/gcm_driver/fake_gcm_client_factory.h"
#include "components/gcm_driver/gcm_app_handler.h"
#include "components/gcm_driver/gcm_channel_status_request.h"
#include "components/gcm_driver/gcm_channel_status_syncer.h"
#include "components/gcm_driver/gcm_client_factory.h"
#include "components/gcm_driver/gcm_connection_observer.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync/protocol/experiment_status.pb.h"
#include "components/sync/protocol/experiments_specifics.pb.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_network_connection_tracker.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace gcm {

namespace {

const char kTestChannelStatusRequestURL[] = "http://channel.status.request.com";
const char kTestAppID1[] = "TestApp1";
const char kTestAppID2[] = "TestApp2";
const char kUserID1[] = "user1";
const char kScope[] = "GCM";
const char kInstanceID1[] = "IID1";
const char kInstanceID2[] = "IID2";

class FakeGCMConnectionObserver : public GCMConnectionObserver {
 public:
  FakeGCMConnectionObserver();
  ~FakeGCMConnectionObserver() override;

  // gcm::GCMConnectionObserver implementation:
  void OnConnected(const net::IPEndPoint& ip_endpoint) override;
  void OnDisconnected() override;

  bool connected() const { return connected_; }

 private:
  bool connected_;
};

FakeGCMConnectionObserver::FakeGCMConnectionObserver() : connected_(false) {
}

FakeGCMConnectionObserver::~FakeGCMConnectionObserver() {
}

void FakeGCMConnectionObserver::OnConnected(
    const net::IPEndPoint& ip_endpoint) {
  connected_ = true;
}

void FakeGCMConnectionObserver::OnDisconnected() {
  connected_ = false;
}

void PumpCurrentLoop() {
  base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
}

void PumpUILoop() {
  PumpCurrentLoop();
}

std::vector<std::string> ToSenderList(const std::string& sender_ids) {
  return base::SplitString(
      sender_ids, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}

}  // namespace

class GCMDriverTest : public testing::Test {
 public:
  enum WaitToFinish {
    DO_NOT_WAIT,
    WAIT
  };

  GCMDriverTest();
  ~GCMDriverTest() override;

  // testing::Test:
  void SetUp() override;
  void TearDown() override;

  GCMDriverDesktop* driver() { return driver_.get(); }
  FakeGCMAppHandler* gcm_app_handler() { return gcm_app_handler_.get(); }
  FakeGCMConnectionObserver* gcm_connection_observer() {
    return gcm_connection_observer_.get();
  }
  const std::string& registration_id() const { return registration_id_; }
  GCMClient::Result registration_result() const { return registration_result_; }
  const std::string& send_message_id() const { return send_message_id_; }
  GCMClient::Result send_result() const { return send_result_; }
  GCMClient::Result unregistration_result() const {
    return unregistration_result_;
  }
  const std::string& p256dh() const { return p256dh_; }
  const std::string& auth_secret() const { return auth_secret_; }

  void PumpIOLoop();

  void ClearResults();

  bool HasAppHandlers() const;
  FakeGCMClient* GetGCMClient();

  void CreateDriver();
  void ShutdownDriver();
  void AddAppHandlers();
  void RemoveAppHandlers();

  void Register(const std::string& app_id,
                const std::vector<std::string>& sender_ids,
                WaitToFinish wait_to_finish);
  void Send(const std::string& app_id,
            const std::string& receiver_id,
            const OutgoingMessage& message,
            WaitToFinish wait_to_finish);
  void GetEncryptionInfo(const std::string& app_id,
                         WaitToFinish wait_to_finish);
  void Unregister(const std::string& app_id, WaitToFinish wait_to_finish);

  void WaitForAsyncOperation();

  void RegisterCompleted(const std::string& registration_id,
                         GCMClient::Result result);
  void SendCompleted(const std::string& message_id, GCMClient::Result result);
  void GetEncryptionInfoCompleted(const std::string& p256dh,
                                  const std::string& auth_secret);
  void UnregisterCompleted(GCMClient::Result result);

  const base::Closure& async_operation_completed_callback() const {
    return async_operation_completed_callback_;
  }
  void set_async_operation_completed_callback(const base::Closure& callback) {
    async_operation_completed_callback_ = callback;
  }

 private:
  base::ScopedTempDir temp_dir_;
  TestingPrefServiceSimple prefs_;
  base::test::ScopedTaskEnvironment task_environment_{
      base::test::ScopedTaskEnvironment::MainThreadType::UI};
  base::Thread io_thread_;
  network::TestURLLoaderFactory test_url_loader_factory_;

  std::unique_ptr<GCMDriverDesktop> driver_;
  std::unique_ptr<FakeGCMAppHandler> gcm_app_handler_;
  std::unique_ptr<FakeGCMConnectionObserver> gcm_connection_observer_;

  base::Closure async_operation_completed_callback_;

  std::string registration_id_;
  GCMClient::Result registration_result_;
  std::string send_message_id_;
  GCMClient::Result send_result_;
  GCMClient::Result unregistration_result_;
  std::string p256dh_;
  std::string auth_secret_;

  DISALLOW_COPY_AND_ASSIGN(GCMDriverTest);
};

GCMDriverTest::GCMDriverTest()
    : io_thread_("IOThread"),
      registration_result_(GCMClient::UNKNOWN_ERROR),
      send_result_(GCMClient::UNKNOWN_ERROR),
      unregistration_result_(GCMClient::UNKNOWN_ERROR) {}

GCMDriverTest::~GCMDriverTest() {
}

void GCMDriverTest::SetUp() {
  GCMChannelStatusSyncer::RegisterPrefs(prefs_.registry());
  io_thread_.Start();
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
}

void GCMDriverTest::TearDown() {
  if (!driver_)
    return;

  ShutdownDriver();
  driver_.reset();
  PumpIOLoop();

  io_thread_.Stop();
}

void GCMDriverTest::PumpIOLoop() {
  base::RunLoop run_loop;
  io_thread_.task_runner()->PostTaskAndReply(
      FROM_HERE, base::BindOnce(&PumpCurrentLoop), run_loop.QuitClosure());
  run_loop.Run();
}

void GCMDriverTest::ClearResults() {
  registration_id_.clear();
  registration_result_ = GCMClient::UNKNOWN_ERROR;

  send_message_id_.clear();
  send_result_ = GCMClient::UNKNOWN_ERROR;

  unregistration_result_ = GCMClient::UNKNOWN_ERROR;
}

bool GCMDriverTest::HasAppHandlers() const {
  return !driver_->app_handlers().empty();
}

FakeGCMClient* GCMDriverTest::GetGCMClient() {
  return static_cast<FakeGCMClient*>(driver_->GetGCMClientForTesting());
}

void GCMDriverTest::CreateDriver() {
  scoped_refptr<net::URLRequestContextGetter> request_context =
      new net::TestURLRequestContextGetter(io_thread_.task_runner());
  GCMClient::ChromeBuildInfo chrome_build_info;
  chrome_build_info.product_category_for_subtypes = "com.chrome.macosx";
  driver_ = std::make_unique<GCMDriverDesktop>(
      std::unique_ptr<GCMClientFactory>(new FakeGCMClientFactory(
          base::ThreadTaskRunnerHandle::Get(), io_thread_.task_runner())),
      chrome_build_info, kTestChannelStatusRequestURL, "user-agent-string",
      &prefs_, temp_dir_.GetPath(), base::DoNothing(),
      base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
          &test_url_loader_factory_),
      network::TestNetworkConnectionTracker::GetInstance(),
      base::ThreadTaskRunnerHandle::Get(), io_thread_.task_runner(),
      task_environment_.GetMainThreadTaskRunner());

  gcm_app_handler_.reset(new FakeGCMAppHandler);
  gcm_connection_observer_.reset(new FakeGCMConnectionObserver);

  driver_->AddConnectionObserver(gcm_connection_observer_.get());
}

void GCMDriverTest::ShutdownDriver() {
  if (gcm_connection_observer())
    driver()->RemoveConnectionObserver(gcm_connection_observer());
  driver()->Shutdown();
}

void GCMDriverTest::AddAppHandlers() {
  driver_->AddAppHandler(kTestAppID1, gcm_app_handler_.get());
  driver_->AddAppHandler(kTestAppID2, gcm_app_handler_.get());
}

void GCMDriverTest::RemoveAppHandlers() {
  driver_->RemoveAppHandler(kTestAppID1);
  driver_->RemoveAppHandler(kTestAppID2);
}

void GCMDriverTest::Register(const std::string& app_id,
                             const std::vector<std::string>& sender_ids,
                             WaitToFinish wait_to_finish) {
  base::RunLoop run_loop;
  async_operation_completed_callback_ = run_loop.QuitClosure();
  driver_->Register(app_id,
                    sender_ids,
                    base::Bind(&GCMDriverTest::RegisterCompleted,
                               base::Unretained(this)));
  if (wait_to_finish == WAIT)
    run_loop.Run();
}

void GCMDriverTest::Send(const std::string& app_id,
                         const std::string& receiver_id,
                         const OutgoingMessage& message,
                         WaitToFinish wait_to_finish) {
  base::RunLoop run_loop;
  async_operation_completed_callback_ = run_loop.QuitClosure();
  driver_->Send(app_id,
                receiver_id,
                message,
                base::Bind(&GCMDriverTest::SendCompleted,
                           base::Unretained(this)));
  if (wait_to_finish == WAIT)
    run_loop.Run();
}

void GCMDriverTest::GetEncryptionInfo(const std::string& app_id,
                                      WaitToFinish wait_to_finish) {
  base::RunLoop run_loop;
  async_operation_completed_callback_ = run_loop.QuitClosure();
  driver_->GetEncryptionInfo(
      app_id, base::Bind(&GCMDriverTest::GetEncryptionInfoCompleted,
                         base::Unretained(this)));
  if (wait_to_finish == WAIT)
    run_loop.Run();
}

void GCMDriverTest::Unregister(const std::string& app_id,
                               WaitToFinish wait_to_finish) {
  base::RunLoop run_loop;
  async_operation_completed_callback_ = run_loop.QuitClosure();
  driver_->Unregister(app_id,
                      base::Bind(&GCMDriverTest::UnregisterCompleted,
                                 base::Unretained(this)));
  if (wait_to_finish == WAIT)
    run_loop.Run();
}

void GCMDriverTest::WaitForAsyncOperation() {
  base::RunLoop run_loop;
  async_operation_completed_callback_ = run_loop.QuitClosure();
  run_loop.Run();
}

void GCMDriverTest::RegisterCompleted(const std::string& registration_id,
                                      GCMClient::Result result) {
  registration_id_ = registration_id;
  registration_result_ = result;
  if (!async_operation_completed_callback_.is_null())
    async_operation_completed_callback_.Run();
}

void GCMDriverTest::SendCompleted(const std::string& message_id,
                                  GCMClient::Result result) {
  send_message_id_ = message_id;
  send_result_ = result;
  if (!async_operation_completed_callback_.is_null())
    async_operation_completed_callback_.Run();
}

void GCMDriverTest::GetEncryptionInfoCompleted(const std::string& p256dh,
                                               const std::string& auth_secret) {
  p256dh_ = p256dh;
  auth_secret_ = auth_secret;
  if (!async_operation_completed_callback_.is_null())
    async_operation_completed_callback_.Run();
}

void GCMDriverTest::UnregisterCompleted(GCMClient::Result result) {
  unregistration_result_ = result;
  if (!async_operation_completed_callback_.is_null())
    async_operation_completed_callback_.Run();
}

TEST_F(GCMDriverTest, Create) {
  // Create GCMDriver first. By default GCM is set to delay start.
  CreateDriver();
  EXPECT_FALSE(driver()->IsStarted());

  // Adding an app handler will not start GCM.
  AddAppHandlers();
  PumpIOLoop();
  PumpUILoop();
  EXPECT_FALSE(driver()->IsStarted());
  EXPECT_FALSE(driver()->IsConnected());
  EXPECT_FALSE(gcm_connection_observer()->connected());

  // The GCM registration will kick off the GCM.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
  EXPECT_TRUE(driver()->IsStarted());
  EXPECT_TRUE(driver()->IsConnected());
  EXPECT_TRUE(gcm_connection_observer()->connected());
}

TEST_F(GCMDriverTest, Shutdown) {
  CreateDriver();
  EXPECT_FALSE(HasAppHandlers());

  AddAppHandlers();
  EXPECT_TRUE(HasAppHandlers());

  ShutdownDriver();
  EXPECT_FALSE(HasAppHandlers());
  EXPECT_FALSE(driver()->IsConnected());
  EXPECT_FALSE(gcm_connection_observer()->connected());
}

TEST_F(GCMDriverTest, DisableAndReenableGCM) {
  CreateDriver();
  AddAppHandlers();
  PumpIOLoop();
  PumpUILoop();
  EXPECT_FALSE(driver()->IsStarted());

  // The GCM registration will kick off the GCM.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
  EXPECT_TRUE(driver()->IsStarted());

  // Disables the GCM. GCM will be stopped.
  driver()->Disable();
  PumpIOLoop();
  PumpUILoop();
  EXPECT_FALSE(driver()->IsStarted());

  // Enables the GCM. GCM will be started.
  driver()->Enable();
  PumpIOLoop();
  PumpUILoop();
  EXPECT_TRUE(driver()->IsStarted());
}

TEST_F(GCMDriverTest, StartOrStopGCMOnDemand) {
  CreateDriver();
  PumpIOLoop();
  PumpUILoop();
  EXPECT_FALSE(driver()->IsStarted());

  // Adding an app handler will not start GCM.
  driver()->AddAppHandler(kTestAppID1, gcm_app_handler());
  PumpIOLoop();
  PumpUILoop();
  EXPECT_FALSE(driver()->IsStarted());

  // The GCM registration will kick off the GCM.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
  EXPECT_TRUE(driver()->IsStarted());

  // Add another app handler.
  driver()->AddAppHandler(kTestAppID2, gcm_app_handler());
  PumpIOLoop();
  PumpUILoop();
  EXPECT_TRUE(driver()->IsStarted());

  // GCMClient remains active after one app handler is gone.
  driver()->RemoveAppHandler(kTestAppID1);
  PumpIOLoop();
  PumpUILoop();
  EXPECT_TRUE(driver()->IsStarted());

  // GCMClient should be stopped after the last app handler is gone.
  driver()->RemoveAppHandler(kTestAppID2);
  PumpIOLoop();
  PumpUILoop();
  EXPECT_FALSE(driver()->IsStarted());

  // GCMClient is restarted after an app handler has been added.
  driver()->AddAppHandler(kTestAppID2, gcm_app_handler());
  PumpIOLoop();
  PumpUILoop();
  EXPECT_TRUE(driver()->IsStarted());
}

TEST_F(GCMDriverTest, RegisterFailed) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");

  CreateDriver();

  // Registration fails when the no app handler is added.
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  EXPECT_TRUE(registration_id().empty());
  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, registration_result());

  ClearResults();

  // Registration fails when GCM is disabled.
  AddAppHandlers();
  driver()->Disable();
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  EXPECT_TRUE(registration_id().empty());
  EXPECT_EQ(GCMClient::GCM_DISABLED, registration_result());
}

TEST_F(GCMDriverTest, UnregisterFailed) {
  CreateDriver();

  // Unregistration fails when the no app handler is added.
  Unregister(kTestAppID1, GCMDriverTest::WAIT);
  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, unregistration_result());

  ClearResults();

  // Unregistration fails when GCM is disabled.
  AddAppHandlers();
  driver()->Disable();
  Unregister(kTestAppID1, GCMDriverTest::WAIT);
  EXPECT_EQ(GCMClient::GCM_DISABLED, unregistration_result());
}

TEST_F(GCMDriverTest, SendFailed) {
  OutgoingMessage message;
  message.id = "1";
  message.data["key1"] = "value1";

  CreateDriver();

  // Sending fails when the no app handler is added.
  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
  EXPECT_TRUE(send_message_id().empty());
  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, send_result());

  ClearResults();

  // Sending fails when GCM is disabled.
  AddAppHandlers();
  driver()->Disable();
  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
  EXPECT_TRUE(send_message_id().empty());
  EXPECT_EQ(GCMClient::GCM_DISABLED, send_result());
}

TEST_F(GCMDriverTest, GCMClientNotReadyBeforeRegistration) {
  CreateDriver();
  PumpIOLoop();
  PumpUILoop();

  // Make GCMClient not ready until PerformDelayedStart is called.
  GetGCMClient()->set_start_mode_overridding(
      FakeGCMClient::FORCE_TO_ALWAYS_DELAY_START_GCM);

  AddAppHandlers();

  // The registration is on hold until GCMClient is ready.
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  Register(kTestAppID1,
                     sender_ids,
                     GCMDriverTest::DO_NOT_WAIT);
  PumpIOLoop();
  PumpUILoop();
  EXPECT_TRUE(registration_id().empty());
  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, registration_result());

  // Register operation will be invoked after GCMClient becomes ready.
  GetGCMClient()->PerformDelayedStart();
  WaitForAsyncOperation();
  EXPECT_FALSE(registration_id().empty());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverTest, GCMClientNotReadyBeforeSending) {
  CreateDriver();
  PumpIOLoop();
  PumpUILoop();

  // Make GCMClient not ready until PerformDelayedStart is called.
  GetGCMClient()->set_start_mode_overridding(
      FakeGCMClient::FORCE_TO_ALWAYS_DELAY_START_GCM);

  AddAppHandlers();

  // The sending is on hold until GCMClient is ready.
  OutgoingMessage message;
  message.id = "1";
  message.data["key1"] = "value1";
  message.data["key2"] = "value2";
  Send(kTestAppID1, kUserID1, message, GCMDriverTest::DO_NOT_WAIT);
  PumpIOLoop();
  PumpUILoop();

  EXPECT_TRUE(send_message_id().empty());
  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, send_result());

  // Send operation will be invoked after GCMClient becomes ready.
  GetGCMClient()->PerformDelayedStart();
  WaitForAsyncOperation();
  EXPECT_EQ(message.id, send_message_id());
  EXPECT_EQ(GCMClient::SUCCESS, send_result());
}

// Tests a single instance of GCMDriver.
class GCMDriverFunctionalTest : public GCMDriverTest {
 public:
  GCMDriverFunctionalTest();
  ~GCMDriverFunctionalTest() override;

  // GCMDriverTest:
  void SetUp() override;

 private:
  DISALLOW_COPY_AND_ASSIGN(GCMDriverFunctionalTest);
};

GCMDriverFunctionalTest::GCMDriverFunctionalTest() {
}

GCMDriverFunctionalTest::~GCMDriverFunctionalTest() {
}

void GCMDriverFunctionalTest::SetUp() {
  GCMDriverTest::SetUp();

  CreateDriver();
  AddAppHandlers();
  PumpIOLoop();
  PumpUILoop();
}

TEST_F(GCMDriverFunctionalTest, Register) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  const std::string expected_registration_id =
      FakeGCMClient::GenerateGCMRegistrationID(sender_ids);

  EXPECT_EQ(expected_registration_id, registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverFunctionalTest, RegisterError) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1@error");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);

  EXPECT_TRUE(registration_id().empty());
  EXPECT_NE(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverFunctionalTest, RegisterAgainWithSameSenderIDs) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  sender_ids.push_back("sender2");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  const std::string expected_registration_id =
      FakeGCMClient::GenerateGCMRegistrationID(sender_ids);

  EXPECT_EQ(expected_registration_id, registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());

  // Clears the results the would be set by the Register callback in preparation
  // to call register 2nd time.
  ClearResults();

  // Calling register 2nd time with the same set of sender IDs but different
  // ordering will get back the same registration ID.
  std::vector<std::string> another_sender_ids;
  another_sender_ids.push_back("sender2");
  another_sender_ids.push_back("sender1");
  Register(kTestAppID1, another_sender_ids, GCMDriverTest::WAIT);

  EXPECT_EQ(expected_registration_id, registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverFunctionalTest, RegisterAgainWithDifferentSenderIDs) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  const std::string expected_registration_id =
      FakeGCMClient::GenerateGCMRegistrationID(sender_ids);

  EXPECT_EQ(expected_registration_id, registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());

  // Make sender IDs different.
  sender_ids.push_back("sender2");
  const std::string expected_registration_id2 =
      FakeGCMClient::GenerateGCMRegistrationID(sender_ids);

  // Calling register 2nd time with the different sender IDs will get back a new
  // registration ID.
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  EXPECT_EQ(expected_registration_id2, registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverFunctionalTest, UnregisterExplicitly) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);

  EXPECT_FALSE(registration_id().empty());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());

  Unregister(kTestAppID1, GCMDriverTest::WAIT);

  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
}

TEST_F(GCMDriverFunctionalTest, UnregisterRemovesEncryptionInfo) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);

  EXPECT_FALSE(registration_id().empty());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());

  GetEncryptionInfo(kTestAppID1, GCMDriverTest::WAIT);

  EXPECT_FALSE(p256dh().empty());
  EXPECT_FALSE(auth_secret().empty());

  const std::string app_p256dh = p256dh();
  const std::string app_auth_secret = auth_secret();

  GetEncryptionInfo(kTestAppID1, GCMDriverTest::WAIT);

  EXPECT_EQ(app_p256dh, p256dh());
  EXPECT_EQ(app_auth_secret, auth_secret());

  Unregister(kTestAppID1, GCMDriverTest::WAIT);

  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());

  GetEncryptionInfo(kTestAppID1, GCMDriverTest::WAIT);

  // The GCMKeyStore eagerly creates new keying material for registrations that
  // don't have any associated with them, so the most appropriate check to do is
  // to verify that the returned material is different from before.

  EXPECT_NE(app_p256dh, p256dh());
  EXPECT_NE(app_auth_secret, auth_secret());
}

TEST_F(GCMDriverFunctionalTest, UnregisterWhenAsyncOperationPending) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  // First start registration without waiting for it to complete.
  Register(kTestAppID1, sender_ids, GCMDriverTest::DO_NOT_WAIT);

  // Test that unregistration fails with async operation pending when there is a
  // registration already in progress.
  Unregister(kTestAppID1, GCMDriverTest::WAIT);
  EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
            unregistration_result());

  // Complete the unregistration.
  WaitForAsyncOperation();
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());

  // Start unregistration without waiting for it to complete. This time no async
  // operation is pending.
  Unregister(kTestAppID1, GCMDriverTest::DO_NOT_WAIT);

  // Test that unregistration fails with async operation pending when there is
  // an unregistration already in progress.
  Unregister(kTestAppID1, GCMDriverTest::WAIT);
  EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
            unregistration_result());
  ClearResults();

  // Complete unregistration.
  WaitForAsyncOperation();
  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
}

TEST_F(GCMDriverFunctionalTest, RegisterWhenAsyncOperationPending) {
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  // First start registration without waiting for it to complete.
  Register(kTestAppID1, sender_ids, GCMDriverTest::DO_NOT_WAIT);

  // Test that registration fails with async operation pending when there is a
  // registration already in progress.
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
            registration_result());
  ClearResults();

  // Complete the registration.
  WaitForAsyncOperation();
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverFunctionalTest, RegisterAfterUnfinishedUnregister) {
  // Register and wait for it to complete.
  std::vector<std::string> sender_ids;
  sender_ids.push_back("sender1");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
  EXPECT_EQ(FakeGCMClient::GenerateGCMRegistrationID(sender_ids),
            registration_id());

  // Clears the results the would be set by the Register callback in preparation
  // to call register 2nd time.
  ClearResults();

  // Start unregistration without waiting for it to complete.
  Unregister(kTestAppID1, GCMDriverTest::DO_NOT_WAIT);

  // Register immeidately after unregistration is not completed.
  sender_ids.push_back("sender2");
  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);

  // We need one more waiting since the waiting in Register is indeed for
  // uncompleted Unregister.
  WaitForAsyncOperation();
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
  EXPECT_EQ(FakeGCMClient::GenerateGCMRegistrationID(sender_ids),
            registration_id());
}

TEST_F(GCMDriverFunctionalTest, Send) {
  OutgoingMessage message;
  message.id = "1@ack";
  message.data["key1"] = "value1";
  message.data["key2"] = "value2";
  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);

  EXPECT_EQ(message.id, send_message_id());
  EXPECT_EQ(GCMClient::SUCCESS, send_result());

  gcm_app_handler()->WaitForNotification();
  EXPECT_EQ(message.id, gcm_app_handler()->acked_message_id());
  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
}

TEST_F(GCMDriverFunctionalTest, SendError) {
  OutgoingMessage message;
  // Embedding error in id will tell the mock to simulate the send error.
  message.id = "1@error";
  message.data["key1"] = "value1";
  message.data["key2"] = "value2";
  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);

  EXPECT_EQ(message.id, send_message_id());
  EXPECT_EQ(GCMClient::SUCCESS, send_result());

  // Wait for the send error.
  gcm_app_handler()->WaitForNotification();
  EXPECT_EQ(FakeGCMAppHandler::SEND_ERROR_EVENT,
            gcm_app_handler()->received_event());
  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
  EXPECT_EQ(message.id,
            gcm_app_handler()->send_error_details().message_id);
  EXPECT_NE(GCMClient::SUCCESS,
            gcm_app_handler()->send_error_details().result);
  EXPECT_EQ(message.data,
            gcm_app_handler()->send_error_details().additional_data);
}

TEST_F(GCMDriverFunctionalTest, MessageReceived) {
  // GCM registration has to be performed otherwise GCM will not be started.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);

  IncomingMessage message;
  message.data["key1"] = "value1";
  message.data["key2"] = "value2";
  message.sender_id = "sender";
  GetGCMClient()->ReceiveMessage(kTestAppID1, message);
  gcm_app_handler()->WaitForNotification();
  EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT,
            gcm_app_handler()->received_event());
  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
  EXPECT_EQ(message.data, gcm_app_handler()->message().data);
  EXPECT_TRUE(gcm_app_handler()->message().collapse_key.empty());
  EXPECT_EQ(message.sender_id, gcm_app_handler()->message().sender_id);
}

TEST_F(GCMDriverFunctionalTest, MessageWithCollapseKeyReceived) {
  // GCM registration has to be performed otherwise GCM will not be started.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);

  IncomingMessage message;
  message.data["key1"] = "value1";
  message.collapse_key = "collapse_key_value";
  message.sender_id = "sender";
  GetGCMClient()->ReceiveMessage(kTestAppID1, message);
  gcm_app_handler()->WaitForNotification();
  EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT,
            gcm_app_handler()->received_event());
  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
  EXPECT_EQ(message.data, gcm_app_handler()->message().data);
  EXPECT_EQ(message.collapse_key,
            gcm_app_handler()->message().collapse_key);
}

TEST_F(GCMDriverFunctionalTest, EncryptedMessageReceivedError) {
  // GCM registration has to be performed otherwise GCM will not be started.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);

  IncomingMessage message;

  // All required information to trigger the encryption path, but with an
  // invalid Crypto-Key header value to trigger an error.
  message.data["encryption"] = "salt=ysyxqlYTgE0WvcZrmHbUbg";
  message.data["crypto-key"] = "hey=thereisnopublickey";
  message.sender_id = "sender";
  message.raw_data = "foobar";

  GetGCMClient()->SetRecording(true);
  GetGCMClient()->ReceiveMessage(kTestAppID1, message);

  PumpIOLoop();
  PumpUILoop();
  PumpIOLoop();

  EXPECT_EQ(FakeGCMAppHandler::DECRYPTION_FAILED_EVENT,
            gcm_app_handler()->received_event());

  GCMClient::GCMStatistics statistics = GetGCMClient()->GetStatistics();
  EXPECT_TRUE(statistics.is_recording);
  EXPECT_EQ(
      1u, statistics.recorded_activities.decryption_failure_activities.size());
}

TEST_F(GCMDriverFunctionalTest, MessagesDeleted) {
  // GCM registration has to be performed otherwise GCM will not be started.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);

  GetGCMClient()->DeleteMessages(kTestAppID1);
  gcm_app_handler()->WaitForNotification();
  EXPECT_EQ(FakeGCMAppHandler::MESSAGES_DELETED_EVENT,
            gcm_app_handler()->received_event());
  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
}

TEST_F(GCMDriverFunctionalTest, LastTokenFetchTime) {
  // GCM registration has to be performed otherwise GCM will not be started.
  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);

  EXPECT_EQ(base::Time(), driver()->GetLastTokenFetchTime());
  base::Time fetch_time = base::Time::Now();
  driver()->SetLastTokenFetchTime(fetch_time);
  EXPECT_EQ(fetch_time, driver()->GetLastTokenFetchTime());
}

// Tests a single instance of GCMDriver.
class GCMChannelStatusSyncerTest : public GCMDriverTest {
 public:
  GCMChannelStatusSyncerTest();
  ~GCMChannelStatusSyncerTest() override;

  // testing::Test:
  void SetUp() override;

  void CompleteGCMChannelStatusRequest(bool enabled, int poll_interval_seconds);
  bool CompareDelaySeconds(int64_t expected_delay_seconds,
                           int64_t actual_delay_seconds);

  GCMChannelStatusSyncer* syncer() {
    return driver()->gcm_channel_status_syncer_for_testing();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(GCMChannelStatusSyncerTest);
};

GCMChannelStatusSyncerTest::GCMChannelStatusSyncerTest() {
}

GCMChannelStatusSyncerTest::~GCMChannelStatusSyncerTest() {
}

void GCMChannelStatusSyncerTest::SetUp() {
  GCMDriverTest::SetUp();
}

void GCMChannelStatusSyncerTest::CompleteGCMChannelStatusRequest(
    bool enabled, int poll_interval_seconds) {
  sync_pb::ExperimentStatusResponse response_proto;
  sync_pb::ExperimentsSpecifics* experiment_specifics =
      response_proto.add_experiment();
  experiment_specifics->mutable_gcm_channel()->set_enabled(enabled);

  if (poll_interval_seconds)
    response_proto.set_poll_interval_seconds(poll_interval_seconds);

  syncer()->request_for_testing()->ParseResponseProto(response_proto);
}

bool GCMChannelStatusSyncerTest::CompareDelaySeconds(
    int64_t expected_delay_seconds,
    int64_t actual_delay_seconds) {
  // Most of time, the actual delay should not be smaller than the expected
  // delay.
  if (actual_delay_seconds >= expected_delay_seconds)
    return true;
  // It is also OK that the actual delay is a bit smaller than the expected
  // delay in case that the test runs slowly.
  return expected_delay_seconds - actual_delay_seconds < 30;
}

TEST_F(GCMChannelStatusSyncerTest, DisableAndEnable) {
  // Create GCMDriver first. By default, GCM is enabled.
  CreateDriver();
  EXPECT_TRUE(driver()->gcm_enabled());
  EXPECT_TRUE(syncer()->gcm_enabled());

  // Remove delay such that the request could be executed immediately.
  syncer()->set_delay_removed_for_testing(true);

  // GCM is still enabled at this point.
  AddAppHandlers();
  EXPECT_TRUE(driver()->gcm_enabled());
  EXPECT_TRUE(syncer()->gcm_enabled());

  // Wait until the GCM channel status request gets triggered.
  PumpUILoop();

  // Complete the request that disables the GCM.
  CompleteGCMChannelStatusRequest(false, 0);
  EXPECT_FALSE(driver()->gcm_enabled());
  EXPECT_FALSE(syncer()->gcm_enabled());
  EXPECT_FALSE(driver()->IsStarted());

  // Wait until next GCM channel status request gets triggered.
  PumpUILoop();

  // Complete the request that enables the GCM.
  CompleteGCMChannelStatusRequest(true, 0);
  EXPECT_TRUE(driver()->gcm_enabled());
  EXPECT_TRUE(syncer()->gcm_enabled());
}

TEST_F(GCMChannelStatusSyncerTest, DisableRestartAndEnable) {
  // Create GCMDriver first. By default, GCM is enabled.
  CreateDriver();
  EXPECT_TRUE(driver()->gcm_enabled());
  EXPECT_TRUE(syncer()->gcm_enabled());

  // Remove delay such that the request could be executed immediately.
  syncer()->set_delay_removed_for_testing(true);

  // GCM is still enabled at this point.
  AddAppHandlers();
  EXPECT_TRUE(driver()->gcm_enabled());
  EXPECT_TRUE(syncer()->gcm_enabled());

  // Wait until the GCM channel status request gets triggered.
  PumpUILoop();

  // Complete the request that disables the GCM.
  CompleteGCMChannelStatusRequest(false, 0);
  EXPECT_FALSE(driver()->gcm_enabled());
  EXPECT_FALSE(syncer()->gcm_enabled());

  // Simulate browser start by recreating GCMDriver.
  ShutdownDriver();
  CreateDriver();

  // Remove delay such that the request could be executed immediately.
  syncer()->set_delay_removed_for_testing(true);

  // GCM is still disabled.
  EXPECT_FALSE(driver()->gcm_enabled());
  EXPECT_FALSE(syncer()->gcm_enabled());

  AddAppHandlers();
  EXPECT_FALSE(driver()->gcm_enabled());
  EXPECT_FALSE(syncer()->gcm_enabled());

  // Wait until the GCM channel status request gets triggered.
  PumpUILoop();

  // Complete the request that re-enables the GCM.
  CompleteGCMChannelStatusRequest(true, 0);
  EXPECT_TRUE(driver()->gcm_enabled());
  EXPECT_TRUE(syncer()->gcm_enabled());
}

TEST_F(GCMChannelStatusSyncerTest, FirstTimePolling) {
  // Start GCM.
  CreateDriver();
  AddAppHandlers();

  // The 1st request should be triggered shortly without jittering.
  EXPECT_EQ(GCMChannelStatusSyncer::first_time_delay_seconds(),
            syncer()->current_request_delay_interval().InSeconds());
}

TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithDefaultInterval) {
  // Create GCMDriver first. GCM is not started.
  CreateDriver();

  // Remove delay such that the request could be executed immediately.
  syncer()->set_delay_removed_for_testing(true);

  // Now GCM is started.
  AddAppHandlers();

  // Wait until the GCM channel status request gets triggered.
  PumpUILoop();

  // Keep delay such that we can find out the computed delay time.
  syncer()->set_delay_removed_for_testing(false);

  // Complete the request. The default interval is intact.
  CompleteGCMChannelStatusRequest(true, 0);

  // The next request should be scheduled at the expected default interval.
  int64_t actual_delay_seconds =
      syncer()->current_request_delay_interval().InSeconds();
  int64_t expected_delay_seconds =
      GCMChannelStatusRequest::default_poll_interval_seconds();
  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
      << "expected delay: " << expected_delay_seconds
      << " actual delay: " << actual_delay_seconds;

  // Simulate browser start by recreating GCMDriver.
  ShutdownDriver();
  CreateDriver();
  AddAppHandlers();

  // After start-up, the request should still be scheduled at the expected
  // default interval.
  actual_delay_seconds =
      syncer()->current_request_delay_interval().InSeconds();
  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
      << "expected delay: " << expected_delay_seconds
      << " actual delay: " << actual_delay_seconds;
}

TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithUpdatedInterval) {
  // Create GCMDriver first. GCM is not started.
  CreateDriver();

  // Remove delay such that the request could be executed immediately.
  syncer()->set_delay_removed_for_testing(true);

  // Now GCM is started.
  AddAppHandlers();

  // Wait until the GCM channel status request gets triggered.
  PumpUILoop();

  // Keep delay such that we can find out the computed delay time.
  syncer()->set_delay_removed_for_testing(false);

  // Complete the request. The interval is being changed.
  int new_poll_interval_seconds =
      GCMChannelStatusRequest::default_poll_interval_seconds() * 2;
  CompleteGCMChannelStatusRequest(true, new_poll_interval_seconds);

  // The next request should be scheduled at the expected updated interval.
  int64_t actual_delay_seconds =
      syncer()->current_request_delay_interval().InSeconds();
  int64_t expected_delay_seconds = new_poll_interval_seconds;
  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
      << "expected delay: " << expected_delay_seconds
      << " actual delay: " << actual_delay_seconds;

  // Simulate browser start by recreating GCMDriver.
  ShutdownDriver();
  CreateDriver();
  AddAppHandlers();

  // After start-up, the request should still be scheduled at the expected
  // updated interval.
  actual_delay_seconds =
      syncer()->current_request_delay_interval().InSeconds();
  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
      << "expected delay: " << expected_delay_seconds
      << " actual delay: " << actual_delay_seconds;
}

class GCMDriverInstanceIDTest : public GCMDriverTest {
 public:
  GCMDriverInstanceIDTest();
  ~GCMDriverInstanceIDTest() override;

  void GetReady();
  void GetInstanceID(const std::string& app_id, WaitToFinish wait_to_finish);
  void GetInstanceIDDataCompleted(const std::string& instance_id,
                                  const std::string& extra_data);
  void GetToken(const std::string& app_id,
                const std::string& authorized_entity,
                const std::string& scope,
                WaitToFinish wait_to_finish);
  void DeleteToken(const std::string& app_id,
                   const std::string& authorized_entity,
                   const std::string& scope,
                   WaitToFinish wait_to_finish);
  void AddInstanceIDData(const std::string& app_id,
                         const std::string& instance_id,
                         const std::string& extra_data);
  void RemoveInstanceIDData(const std::string& app_id);

  std::string instance_id() const { return instance_id_; }
  std::string extra_data() const { return extra_data_; }

 private:
  std::string instance_id_;
  std::string extra_data_;

  DISALLOW_COPY_AND_ASSIGN(GCMDriverInstanceIDTest);
};

GCMDriverInstanceIDTest::GCMDriverInstanceIDTest() {
}

GCMDriverInstanceIDTest::~GCMDriverInstanceIDTest() {
}

void GCMDriverInstanceIDTest::GetReady() {
  CreateDriver();
  AddAppHandlers();
  PumpIOLoop();
  PumpUILoop();
}

void GCMDriverInstanceIDTest::GetInstanceID(const std::string& app_id,
                                            WaitToFinish wait_to_finish) {
  base::RunLoop run_loop;
  set_async_operation_completed_callback(run_loop.QuitClosure());
  driver()->GetInstanceIDHandlerInternal()->GetInstanceIDData(
      app_id, base::Bind(&GCMDriverInstanceIDTest::GetInstanceIDDataCompleted,
                         base::Unretained(this)));
  if (wait_to_finish == WAIT)
    run_loop.Run();
}

void GCMDriverInstanceIDTest::GetInstanceIDDataCompleted(
    const std::string& instance_id, const std::string& extra_data) {
  instance_id_ = instance_id;
  extra_data_ = extra_data;
  if (!async_operation_completed_callback().is_null())
    async_operation_completed_callback().Run();
}

void GCMDriverInstanceIDTest::GetToken(const std::string& app_id,
                                       const std::string& authorized_entity,
                                       const std::string& scope,
                                       WaitToFinish wait_to_finish) {
  base::RunLoop run_loop;
  set_async_operation_completed_callback(run_loop.QuitClosure());
  std::map<std::string, std::string> options;
  driver()->GetInstanceIDHandlerInternal()->GetToken(
      app_id, authorized_entity, scope, options,
      base::Bind(&GCMDriverTest::RegisterCompleted, base::Unretained(this)));
  if (wait_to_finish == WAIT)
    run_loop.Run();
}

void GCMDriverInstanceIDTest::DeleteToken(const std::string& app_id,
                                          const std::string& authorized_entity,
                                          const std::string& scope,
                                          WaitToFinish wait_to_finish) {
  base::RunLoop run_loop;
  set_async_operation_completed_callback(run_loop.QuitClosure());
  driver()->GetInstanceIDHandlerInternal()->DeleteToken(
      app_id, authorized_entity, scope,
      base::Bind(&GCMDriverTest::UnregisterCompleted, base::Unretained(this)));
  if (wait_to_finish == WAIT)
    run_loop.Run();
}

void GCMDriverInstanceIDTest::AddInstanceIDData(const std::string& app_id,
                                                const std::string& instance_id,
                                                const std::string& extra_data) {
  driver()->GetInstanceIDHandlerInternal()->AddInstanceIDData(
      app_id, instance_id, extra_data);
}

void GCMDriverInstanceIDTest::RemoveInstanceIDData(const std::string& app_id) {
  driver()->GetInstanceIDHandlerInternal()->RemoveInstanceIDData(app_id);
}

TEST_F(GCMDriverInstanceIDTest, InstanceIDData) {
  GetReady();

  AddInstanceIDData(kTestAppID1, kInstanceID1, "Foo");
  GetInstanceID(kTestAppID1, GCMDriverTest::WAIT);

  EXPECT_EQ(kInstanceID1, instance_id());
  EXPECT_EQ("Foo", extra_data());

  RemoveInstanceIDData(kTestAppID1);
  GetInstanceID(kTestAppID1, GCMDriverTest::WAIT);

  EXPECT_TRUE(instance_id().empty());
  EXPECT_TRUE(extra_data().empty());
}

TEST_F(GCMDriverInstanceIDTest, GCMClientNotReadyBeforeInstanceIDData) {
  CreateDriver();
  PumpIOLoop();
  PumpUILoop();

  // Make GCMClient not ready until PerformDelayedStart is called.
  GetGCMClient()->set_start_mode_overridding(
      FakeGCMClient::FORCE_TO_ALWAYS_DELAY_START_GCM);

  AddAppHandlers();

  // All operations are on hold until GCMClient is ready.
  AddInstanceIDData(kTestAppID1, kInstanceID1, "Foo");
  AddInstanceIDData(kTestAppID2, kInstanceID2, "Bar");
  RemoveInstanceIDData(kTestAppID1);
  GetInstanceID(kTestAppID2, GCMDriverTest::DO_NOT_WAIT);
  PumpIOLoop();
  PumpUILoop();
  EXPECT_TRUE(instance_id().empty());
  EXPECT_TRUE(extra_data().empty());

  // All operations will be performed after GCMClient becomes ready.
  GetGCMClient()->PerformDelayedStart();
  WaitForAsyncOperation();
  EXPECT_EQ(kInstanceID2, instance_id());
  EXPECT_EQ("Bar", extra_data());
}

TEST_F(GCMDriverInstanceIDTest, GetToken) {
  GetReady();

  const std::string expected_token =
      FakeGCMClient::GenerateInstanceIDToken(kUserID1, kScope);
  GetToken(kTestAppID1, kUserID1, kScope, GCMDriverTest::WAIT);

  EXPECT_EQ(expected_token, registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverInstanceIDTest, GetTokenError) {
  GetReady();

  std::string error_entity = "sender@error";
  GetToken(kTestAppID1, error_entity, kScope, GCMDriverTest::WAIT);

  EXPECT_TRUE(registration_id().empty());
  EXPECT_NE(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverInstanceIDTest, GCMClientNotReadyBeforeGetToken) {
  CreateDriver();
  PumpIOLoop();
  PumpUILoop();

  // Make GCMClient not ready until PerformDelayedStart is called.
  GetGCMClient()->set_start_mode_overridding(
      FakeGCMClient::FORCE_TO_ALWAYS_DELAY_START_GCM);

  AddAppHandlers();

  // GetToken operation is on hold until GCMClient is ready.
  GetToken(kTestAppID1, kUserID1, kScope, GCMDriverTest::DO_NOT_WAIT);
  PumpIOLoop();
  PumpUILoop();
  EXPECT_TRUE(registration_id().empty());
  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, registration_result());

  // GetToken operation will be invoked after GCMClient becomes ready.
  GetGCMClient()->PerformDelayedStart();
  WaitForAsyncOperation();
  EXPECT_FALSE(registration_id().empty());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
}

TEST_F(GCMDriverInstanceIDTest, DeleteToken) {
  GetReady();

  const std::string expected_token =
      FakeGCMClient::GenerateInstanceIDToken(kUserID1, kScope);
  GetToken(kTestAppID1, kUserID1, kScope, GCMDriverTest::WAIT);
  EXPECT_EQ(expected_token, registration_id());
  EXPECT_EQ(GCMClient::SUCCESS, registration_result());

  DeleteToken(kTestAppID1, kUserID1, kScope, GCMDriverTest::WAIT);
  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
}

TEST_F(GCMDriverInstanceIDTest, GCMClientNotReadyBeforeDeleteToken) {
  CreateDriver();
  PumpIOLoop();
  PumpUILoop();

  // Make GCMClient not ready until PerformDelayedStart is called.
  GetGCMClient()->set_start_mode_overridding(
      FakeGCMClient::FORCE_TO_ALWAYS_DELAY_START_GCM);

  AddAppHandlers();

  // DeleteToken operation is on hold until GCMClient is ready.
  DeleteToken(kTestAppID1, kUserID1, kScope, GCMDriverTest::DO_NOT_WAIT);
  PumpIOLoop();
  PumpUILoop();
  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, unregistration_result());

  // DeleteToken operation will be invoked after GCMClient becomes ready.
  GetGCMClient()->PerformDelayedStart();
  WaitForAsyncOperation();
  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
}

}  // namespace gcm
