// Copyright 2015 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 "chromecast/base/device_capabilities_impl.h"

#include <string>
#include <utility>

#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "chromecast/base/serializers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromecast {

namespace {

const char kSampleDictionaryCapability[] =
    "{"
    "  \"dummy_field_bool\": true,"
    "  \"dummy_field_int\": 99"
    "}";

void GetSampleDefaultCapability(std::string* key,
                                std::unique_ptr<base::Value>* init_value);
void TestBasicOperations(DeviceCapabilities* capabilities);

// Simple capability manager that implements the Validator interface. Either
// accepts or rejects all proposed changes based on |accept_changes| constructor
// argument.
class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator {
 public:
  // Registers itself as Validator in constructor. If init_value is not null,
  // the capability gets initialized to that value. Else capability remains
  // untouched.
  FakeCapabilityManagerSimple(DeviceCapabilities* capabilities,
                              const std::string& key,
                              std::unique_ptr<base::Value> init_value,
                              bool accept_changes,
                              bool validate_private)
      : DeviceCapabilities::Validator(capabilities),
        key_(key),
        accept_changes_(accept_changes),
        validate_private_(validate_private) {
    capabilities->Register(key, this);
    if (init_value) {
      if (validate_private_) {
        SetPrivateValidatedValue(key, std::move(init_value));
      } else {
        SetPublicValidatedValue(key, std::move(init_value));
      }
    }
  }

  // Unregisters itself as Validator.
  ~FakeCapabilityManagerSimple() override {
    capabilities()->Unregister(key_, this);
  }

  void Validate(const std::string& path,
                std::unique_ptr<base::Value> proposed_value) override {
    ASSERT_EQ(path.find(key_), 0ul);
    if (!accept_changes_)
      return;
    if (validate_private_) {
      SetPrivateValidatedValue(path, std::move(proposed_value));
    } else {
      SetPublicValidatedValue(path, std::move(proposed_value));
    }
  }

 private:
  const std::string key_;
  const bool accept_changes_;
  const bool validate_private_;
};

// Used to test that capabilities/validator can be read and written in
// Validate() without encountering deadlocks/unexpected behavior.
class FakeCapabilityManagerComplex : public DeviceCapabilities::Validator {
 public:
  FakeCapabilityManagerComplex(DeviceCapabilities* capabilities,
                               const std::string& key)
      : DeviceCapabilities::Validator(capabilities), key_(key) {
    capabilities->Register(key, this);
  }

  // Unregisters itself as Validator.
  ~FakeCapabilityManagerComplex() override {
    capabilities()->Unregister(key_, this);
  }

  // Runs TestBasicOperations().
  void Validate(const std::string& path,
                std::unique_ptr<base::Value> proposed_value) override {
    TestBasicOperations(capabilities());
  }

 private:
  const std::string key_;
};

// Used to test that capabilities/validators can be read and written in
// OnCapabilitiesChanged() without encountering deadlocks/unexpected behavior.
class FakeCapabilitiesObserver : public DeviceCapabilities::Observer {
 public:
  explicit FakeCapabilitiesObserver(DeviceCapabilities* capabilities)
      : capabilities_(capabilities), removed_as_observer(false) {
    capabilities_->AddCapabilitiesObserver(this);
  }

  ~FakeCapabilitiesObserver() override {
    if (!removed_as_observer)
      capabilities_->RemoveCapabilitiesObserver(this);
  }

  // Runs TestBasicOperations().
  void OnCapabilitiesChanged(const std::string& path) override {
    TestBasicOperations(capabilities_);
    // To prevent infinite loop of SetCapability() -> OnCapabilitiesChanged()
    // -> SetCapability() -> OnCapabilitiesChanged() etc.
    capabilities_->RemoveCapabilitiesObserver(this);
    removed_as_observer = true;
  }

 private:
  DeviceCapabilities* const capabilities_;
  bool removed_as_observer;
};

// Used to test that OnCapabilitiesChanged() is called when capabilities are
// modified
class MockCapabilitiesObserver : public DeviceCapabilities::Observer {
 public:
  MockCapabilitiesObserver() {}
  ~MockCapabilitiesObserver() override {}

  MOCK_METHOD1(OnCapabilitiesChanged, void(const std::string& path));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockCapabilitiesObserver);
};

// Test fixtures needs an example default capability to test DeviceCapabilities
// methods. Gets a sample key and initial value.
void GetSampleDefaultCapability(std::string* key,
                                std::unique_ptr<base::Value>* init_value) {
  DCHECK(key);
  DCHECK(init_value);
  *key = DeviceCapabilities::kKeyBluetoothSupported;
  *init_value = std::make_unique<base::Value>(true);
}

// For test fixtures that test dynamic capabilities, gets a sample key
// and initial value.
void GetSampleDynamicCapability(std::string* key,
                                std::unique_ptr<base::Value>* init_value) {
  DCHECK(key);
  DCHECK(init_value);
  *key = "dummy_dynamic_key";
  *init_value = std::make_unique<base::Value>(99);
}

// Gets a value for sample default capability different from |init_value|
// returned in GetSampleDefaultCapability(). Must be of same type as
// |init_value| of course.
std::unique_ptr<base::Value> GetSampleDefaultCapabilityNewValue() {
  return std::make_unique<base::Value>(false);
}

// Gets a value for sample dynamic capability different from |init_value|
// returned in GetSampleDynamicCapability(). Must be of same type as
// |init_value| of course.
std::unique_ptr<base::Value> GetSampleDynamicCapabilityNewValue() {
  return std::make_unique<base::Value>(100);
}

// Tests that |json| string matches contents of a DictionaryValue with one entry
// specified by |key| and |value|.
bool JsonStringEquals(const std::string& json,
                      const std::string& key,
                      const base::Value& value) {
  base::DictionaryValue dict_value;
  dict_value.Set(key, value.CreateDeepCopy());
  base::Optional<std::string> dict_json = SerializeToJson(dict_value);
  return dict_json && *dict_json == json;
}

// The function runs through the set of basic operations of DeviceCapabilities.
// Register validator for sample default capability, reads capability, writes
// capability, and unregister validator. After it has completed, use
// AssertBasicOperationsSuccessful() to ensure that all operations completed
// successfully. Sample default capability should not be added or registered in
// class before this function is called.
void TestBasicOperations(DeviceCapabilities* capabilities) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);

  ASSERT_FALSE(capabilities->GetCapability(key));
  ASSERT_FALSE(capabilities->GetValidator(key));

  // Register and write capability
  FakeCapabilityManagerSimple* manager(new FakeCapabilityManagerSimple(
      capabilities, key, init_value->CreateDeepCopy(), true, false));
  // Read Validator
  EXPECT_EQ(capabilities->GetValidator(key), manager);
  // Read Capability
  EXPECT_EQ(*capabilities->GetCapability(key), *init_value);
  // Unregister
  delete manager;

  // Write capability again. Provides way of checking that this function
  // ran and was successful.
  std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
  capabilities->SetCapability(key, std::move(new_value));
}

// See TestBasicOperations() comment.
void AssertBasicOperationsSuccessful(const DeviceCapabilities* capabilities) {
  base::RunLoop().RunUntilIdle();
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);
  std::unique_ptr<base::Value> value = capabilities->GetCapability(key);
  ASSERT_TRUE(value);
  std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
  EXPECT_EQ(*value, *new_value);
}

}  // namespace

class DeviceCapabilitiesImplTest : public ::testing::Test {
 protected:
  void SetUp() override {
    message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
    capabilities_ = DeviceCapabilities::Create();
    mock_capabilities_observer_.reset(new MockCapabilitiesObserver());
    capabilities_->AddCapabilitiesObserver(mock_capabilities_observer_.get());

    // We set the default gmock expected calls to any so that tests must
    // 'opt in' to checking the calls rather than 'opt out'. This avoids having
    // to add explicit calls in test cases that don't care in order to prevent
    // lots of useless mock warnings.
    EXPECT_CALL(*mock_capabilities_observer_, OnCapabilitiesChanged(testing::_))
        .Times(testing::AnyNumber());
  }

  void TearDown() override {
    capabilities_->RemoveCapabilitiesObserver(
        mock_capabilities_observer_.get());
    mock_capabilities_observer_.reset();
    capabilities_.reset();
    message_loop_.reset();
  }

  DeviceCapabilities* capabilities() const { return capabilities_.get(); }

  MockCapabilitiesObserver* capabilities_observer() const {
    return mock_capabilities_observer_.get();
  }

 private:
  std::unique_ptr<base::MessageLoop> message_loop_;
  std::unique_ptr<DeviceCapabilities> capabilities_;
  std::unique_ptr<MockCapabilitiesObserver> mock_capabilities_observer_;
};

// Tests that class is in correct state after Create().
TEST_F(DeviceCapabilitiesImplTest, Create) {
  std::string empty_dict_string = *SerializeToJson(base::DictionaryValue());
  EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string);
  EXPECT_TRUE(capabilities()->GetAllData()->dictionary().empty());
}

// Tests Register() of a default capability.
TEST_F(DeviceCapabilitiesImplTest, Register) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);

  EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0);
  FakeCapabilityManagerSimple manager(capabilities(), key, nullptr, true,
                                      false);

  EXPECT_EQ(capabilities()->GetValidator(key), &manager);
  std::string empty_dict_string = *SerializeToJson(base::DictionaryValue());
  EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string);
  EXPECT_FALSE(capabilities()->GetCapability(key));
}

// Tests Unregister() of a default capability.
TEST_F(DeviceCapabilitiesImplTest, Unregister) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);

  EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0);
  FakeCapabilityManagerSimple* manager = new FakeCapabilityManagerSimple(
      capabilities(), key, nullptr, true, false);

  delete manager;

  EXPECT_FALSE(capabilities()->GetValidator(key));
  std::string empty_dict_string = *SerializeToJson(base::DictionaryValue());
  EXPECT_EQ(capabilities()->GetAllData()->json_string(), empty_dict_string);
  EXPECT_FALSE(capabilities()->GetCapability(key));
}

// Tests GetCapability() and updating the value through SetCapability().
TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);
  FakeCapabilityManagerSimple manager(
      capabilities(), key, init_value->CreateDeepCopy(), true, false);

  EXPECT_EQ(*capabilities()->GetCapability(key), *init_value);

  std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
  capabilities()->SetCapability(key, new_value->CreateDeepCopy());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(*capabilities()->GetCapability(key), *new_value);
}

// Tests BluetoothSupported() and updating this value through SetCapability().
TEST_F(DeviceCapabilitiesImplTest, BluetoothSupportedAndSetCapability) {
  FakeCapabilityManagerSimple manager(
      capabilities(), DeviceCapabilities::kKeyBluetoothSupported,
      base::WrapUnique(new base::Value(true)), true, false);

  EXPECT_TRUE(capabilities()->BluetoothSupported());
  capabilities()->SetCapability(DeviceCapabilities::kKeyBluetoothSupported,
                                base::WrapUnique(new base::Value(false)));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(capabilities()->BluetoothSupported());
}

// Tests DisplaySupported() and updating this value through SetCapability().
TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) {
  FakeCapabilityManagerSimple manager(
      capabilities(), DeviceCapabilities::kKeyDisplaySupported,
      base::WrapUnique(new base::Value(true)), true, false);

  EXPECT_TRUE(capabilities()->DisplaySupported());
  capabilities()->SetCapability(DeviceCapabilities::kKeyDisplaySupported,
                                base::WrapUnique(new base::Value(false)));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(capabilities()->DisplaySupported());
}

// Tests HiResAudioSupported() and updating this value through SetCapability()
TEST_F(DeviceCapabilitiesImplTest, HiResAudioSupportedAndSetCapability) {
  FakeCapabilityManagerSimple manager(
      capabilities(), DeviceCapabilities::kKeyHiResAudioSupported,
      base::WrapUnique(new base::Value(true)), true, false);

  EXPECT_TRUE(capabilities()->HiResAudioSupported());
  capabilities()->SetCapability(DeviceCapabilities::kKeyHiResAudioSupported,
                                base::WrapUnique(new base::Value(false)));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(capabilities()->HiResAudioSupported());
}

// Tests AssistantSupported() and updating this value through SetCapability()
TEST_F(DeviceCapabilitiesImplTest, AssistantSupportedAndSetCapability) {
  FakeCapabilityManagerSimple manager(
      capabilities(), DeviceCapabilities::kKeyAssistantSupported,
      base::WrapUnique(new base::Value(true)), true, false);

  EXPECT_TRUE(capabilities()->AssistantSupported());
  capabilities()->SetCapability(DeviceCapabilities::kKeyAssistantSupported,
                                base::WrapUnique(new base::Value(false)));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(capabilities()->AssistantSupported());
}

// Tests SetCapability() for a default capability when the capability's manager
// rejects the proposed change.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityInvalid) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);
  FakeCapabilityManagerSimple manager(
      capabilities(), key, init_value->CreateDeepCopy(), false, false);

  capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(*capabilities()->GetCapability(key), *init_value);
}

// Test that SetCapability() updates the capabilities string correctly
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);
  FakeCapabilityManagerSimple manager(
      capabilities(), key, init_value->CreateDeepCopy(), true, false);

  EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
                               *init_value));

  std::unique_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue();
  capabilities()->SetCapability(key, new_value->CreateDeepCopy());
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
                               *new_value));
}

// Tests that GetPublicData() does not include private capabilities
TEST_F(DeviceCapabilitiesImplTest, SetPublicPrivateCapabilities) {
  std::string key_private = "private";
  std::string key_public = "public";
  std::unique_ptr<base::Value> init_value(new base::Value(true));

  // Dictionary of only public values.
  base::DictionaryValue public_dict;
  public_dict.Set(key_public, init_value->CreateDeepCopy());
  // Dictionary of public and private values.
  base::DictionaryValue full_dict;
  full_dict.Set(key_public, init_value->CreateDeepCopy());
  full_dict.Set(key_private, init_value->CreateDeepCopy());

  FakeCapabilityManagerSimple public_manager(
      capabilities(), key_public, init_value->CreateDeepCopy(), true, false);
  FakeCapabilityManagerSimple private_manager(
      capabilities(), key_private, init_value->CreateDeepCopy(), true, true);

  EXPECT_TRUE(capabilities()->GetAllData()->dictionary().Equals(&full_dict));
  EXPECT_TRUE(
      capabilities()->GetPublicData()->dictionary().Equals(&public_dict));
}

// Tests that SetCapability() defaults to making a capability public
TEST_F(DeviceCapabilitiesImplTest, NoValidatorDefaultsToPublicCapability) {
  std::string key_private = "private";
  std::string key_public = "public";
  std::unique_ptr<base::Value> init_value(new base::Value(true));

  // Dictionary of only public values.
  base::DictionaryValue public_dict;
  public_dict.Set(key_public, init_value->CreateDeepCopy());
  // Dictionary of public and private values.
  base::DictionaryValue full_dict;
  full_dict.Set(key_public, init_value->CreateDeepCopy());
  full_dict.Set(key_private, init_value->CreateDeepCopy());

  // We will not create a validator for the public capability; instead we will
  // set the capability directly. It will be registered as a public capability.
  capabilities()->SetCapability(key_public, init_value->CreateDeepCopy());

  FakeCapabilityManagerSimple private_manager(
      capabilities(), key_private, init_value->CreateDeepCopy(), true, true);

  EXPECT_TRUE(capabilities()->GetAllData()->dictionary().Equals(&full_dict));
  EXPECT_TRUE(
      capabilities()->GetPublicData()->dictionary().Equals(&public_dict));
}

// Test that SetCapability() notifies Observers when the capability's value
// changes
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);

  EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3);

  // 1st call (register)
  FakeCapabilityManagerSimple manager(
      capabilities(), key, init_value->CreateDeepCopy(), true, false);

  // 2nd call
  capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());

  // Observer should not get called when value does not change
  capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());

  // 3rd call
  capabilities()->SetCapability(key, std::move(init_value));
  base::RunLoop().RunUntilIdle();
}

// Test that SetCapability() notifies Observers when a private capability's
// value changes
TEST_F(DeviceCapabilitiesImplTest, SetPrivateCapabilityNotifiesObservers) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDefaultCapability(&key, &init_value);

  EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3);

  // 1st call (register), this manager validates and sets the capability
  // privately.
  FakeCapabilityManagerSimple manager(capabilities(), key,
                                      init_value->CreateDeepCopy(), true, true);

  // 2nd call
  capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());

  // Observer should not get called when value does not change
  capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue());

  // 3rd call
  capabilities()->SetCapability(key, std::move(init_value));
  base::RunLoop().RunUntilIdle();
}

// Test adding dynamic capabilities
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) {
  std::string key;
  std::unique_ptr<base::Value> init_value;
  GetSampleDynamicCapability(&key, &init_value);

  ASSERT_FALSE(capabilities()->GetCapability(key));
  capabilities()->SetCapability(key, init_value->CreateDeepCopy());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(*capabilities()->GetCapability(key), *init_value);
  EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
                               *init_value));

  std::unique_ptr<base::Value> new_value = GetSampleDynamicCapabilityNewValue();
  capabilities()->SetCapability(key, new_value->CreateDeepCopy());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(*capabilities()->GetCapability(key), *new_value);
  EXPECT_TRUE(JsonStringEquals(capabilities()->GetAllData()->json_string(), key,
                               *new_value));
}

// Tests that SetCapability() works with expanded paths when there is a
// capability of type DictionaryValue.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) {
  std::string key("dummy_dictionary_key");
  std::unique_ptr<base::Value> init_value =
      DeserializeFromJson(kSampleDictionaryCapability);
  ASSERT_TRUE(init_value);
  FakeCapabilityManagerSimple manager(capabilities(), key,
                                      std::move(init_value), true, false);

  capabilities()->SetCapability("dummy_dictionary_key.dummy_field_bool",
                                base::WrapUnique(new base::Value(false)));
  base::RunLoop().RunUntilIdle();
  bool value_bool = true;
  std::unique_ptr<base::Value> value =
      capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsBoolean(&value_bool));
  EXPECT_FALSE(value_bool);

  capabilities()->SetCapability("dummy_dictionary_key.dummy_field_int",
                                base::WrapUnique(new base::Value(100)));
  base::RunLoop().RunUntilIdle();
  int value_int = 0;
  value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsInteger(&value_int));
  EXPECT_EQ(value_int, 100);
}

// Tests that SetCapability() works with expanded paths when there is a
// capability of type DictionaryValue and invalid changes are proposed.
TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) {
  std::string key("dummy_dictionary_key");
  std::unique_ptr<base::Value> init_value =
      DeserializeFromJson(kSampleDictionaryCapability);
  ASSERT_TRUE(init_value);
  FakeCapabilityManagerSimple manager(capabilities(), key,
                                      std::move(init_value), false, false);

  capabilities()->SetCapability("dummy_dictionary_key.dummy_field_bool",
                                base::WrapUnique(new base::Value(false)));
  base::RunLoop().RunUntilIdle();
  bool value_bool = false;
  std::unique_ptr<base::Value> value =
      capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsBoolean(&value_bool));
  EXPECT_TRUE(value_bool);

  capabilities()->SetCapability("dummy_dictionary_key.dummy_field_int",
                                base::WrapUnique(new base::Value(100)));
  base::RunLoop().RunUntilIdle();
  int value_int = 0;
  value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsInteger(&value_int));
  EXPECT_EQ(value_int, 99);
}

// Test  MergeDictionary.
TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) {
  std::unique_ptr<base::Value> deserialized_value =
      DeserializeFromJson(kSampleDictionaryCapability);
  ASSERT_TRUE(deserialized_value);
  base::DictionaryValue* dict_value = nullptr;
  ASSERT_TRUE(deserialized_value->GetAsDictionary(&dict_value));
  ASSERT_TRUE(dict_value);

  capabilities()->MergeDictionary(*dict_value);
  base::RunLoop().RunUntilIdle();

  // First make sure that capabilities get created if they do not exist
  bool value_bool = false;
  std::unique_ptr<base::Value> value =
      capabilities()->GetCapability("dummy_field_bool");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsBoolean(&value_bool));
  EXPECT_TRUE(value_bool);

  int value_int = 0;
  value = capabilities()->GetCapability("dummy_field_int");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsInteger(&value_int));
  EXPECT_EQ(value_int, 99);

  // Now just update one of the fields. Make sure the updated value is changed
  // in DeviceCapabilities and the other field remains untouched.
  dict_value->SetInteger("dummy_field_int", 100);
  ASSERT_TRUE(dict_value->Remove("dummy_field_bool", nullptr));

  capabilities()->MergeDictionary(*dict_value);
  base::RunLoop().RunUntilIdle();

  value_bool = false;
  value = capabilities()->GetCapability("dummy_field_bool");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsBoolean(&value_bool));
  EXPECT_TRUE(value_bool);

  value = capabilities()->GetCapability("dummy_field_int");
  ASSERT_TRUE(value);
  EXPECT_TRUE(value->GetAsInteger(&value_int));
  EXPECT_EQ(value_int, 100);
}

// Tests that it is safe to call DeviceCapabilities methods in
// an Observer's OnCapabilitiesChanged() implementation safely with correct
// behavior and without deadlocking.
TEST_F(DeviceCapabilitiesImplTest, OnCapabilitiesChangedSafe) {
  FakeCapabilitiesObserver observer(capabilities());

  // Trigger FakeCapabilitiesObserver::OnCapabilitiesChanged()
  capabilities()->SetCapability("dummy_trigger_key",
                                base::WrapUnique(new base::Value(true)));
  base::RunLoop().RunUntilIdle();

  // Check that FakeCapabilitiesObserver::OnCapabilitiesChanged() ran and that
  // behavior was successful
  AssertBasicOperationsSuccessful(capabilities());
}

// Tests that it is safe to call DeviceCapabilities methods in a Validator's
// Validate() implementation safely with correct behavior and without
// deadlocking.
TEST_F(DeviceCapabilitiesImplTest, ValidateSafe) {
  FakeCapabilityManagerComplex manager(capabilities(), "dummy_validate_key");

  // Trigger FakeCapabilityManagerComplex::Validate()
  capabilities()->SetCapability("dummy_validate_key",
                                base::WrapUnique(new base::Value(true)));
  base::RunLoop().RunUntilIdle();

  // Check that FakeCapabilityManagerComplex::Validate() ran and that behavior
  // was successful
  AssertBasicOperationsSuccessful(capabilities());
}

}  // namespace chromecast
