// Copyright 2014 The Chromium OS 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 <chromeos/dbus/exported_property_set.h>

#include <string>
#include <vector>

#include <base/bind.h>
#include <base/macros.h>
#include <chromeos/dbus/dbus_object.h>
#include <chromeos/dbus/dbus_object_test_helpers.h>
#include <chromeos/errors/error_codes.h>
#include <dbus/message.h>
#include <dbus/property.h>
#include <dbus/object_path.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using ::testing::AnyNumber;
using ::testing::Return;
using ::testing::Invoke;
using ::testing::_;
using ::testing::Unused;

namespace chromeos {

namespace dbus_utils {

namespace {

const char kBoolPropName[] = "BoolProp";
const char kUint8PropName[] = "Uint8Prop";
const char kInt16PropName[] = "Int16Prop";
const char kUint16PropName[] = "Uint16Prop";
const char kInt32PropName[] = "Int32Prop";
const char kUint32PropName[] = "Uint32Prop";
const char kInt64PropName[] = "Int64Prop";
const char kUint64PropName[] = "Uint64Prop";
const char kDoublePropName[] = "DoubleProp";
const char kStringPropName[] = "StringProp";
const char kPathPropName[] = "PathProp";
const char kStringListPropName[] = "StringListProp";
const char kPathListPropName[] = "PathListProp";
const char kUint8ListPropName[] = "Uint8ListProp";

const char kTestInterface1[] = "org.chromium.TestInterface1";
const char kTestInterface2[] = "org.chromium.TestInterface2";
const char kTestInterface3[] = "org.chromium.TestInterface3";

const std::string kTestString("lies");
const dbus::ObjectPath kMethodsExportedOnPath(std::string("/export"));
const dbus::ObjectPath kTestObjectPathInit(std::string("/path_init"));
const dbus::ObjectPath kTestObjectPathUpdate(std::string("/path_update"));

}  // namespace

class ExportedPropertySetTest : public ::testing::Test {
 public:
  struct Properties {
   public:
    ExportedProperty<bool> bool_prop_;
    ExportedProperty<uint8_t> uint8_prop_;
    ExportedProperty<int16_t> int16_prop_;
    ExportedProperty<uint16_t> uint16_prop_;
    ExportedProperty<int32_t> int32_prop_;
    ExportedProperty<uint32_t> uint32_prop_;
    ExportedProperty<int64_t> int64_prop_;
    ExportedProperty<uint64_t> uint64_prop_;
    ExportedProperty<double> double_prop_;
    ExportedProperty<std::string> string_prop_;
    ExportedProperty<dbus::ObjectPath> path_prop_;
    ExportedProperty<std::vector<std::string>> stringlist_prop_;
    ExportedProperty<std::vector<dbus::ObjectPath>> pathlist_prop_;
    ExportedProperty<std::vector<uint8_t>> uint8list_prop_;

    Properties(scoped_refptr<dbus::Bus> bus, const dbus::ObjectPath& path)
        : dbus_object_(nullptr, bus, path) {
      // The empty string is not a valid value for an ObjectPath.
      path_prop_.SetValue(kTestObjectPathInit);
      DBusInterface* itf1 = dbus_object_.AddOrGetInterface(kTestInterface1);
      itf1->AddProperty(kBoolPropName, &bool_prop_);
      itf1->AddProperty(kUint8PropName, &uint8_prop_);
      itf1->AddProperty(kInt16PropName, &int16_prop_);
      // I chose this weird grouping because N=2 is about all the permutations
      // of GetAll that I want to anticipate.
      DBusInterface* itf2 = dbus_object_.AddOrGetInterface(kTestInterface2);
      itf2->AddProperty(kUint16PropName, &uint16_prop_);
      itf2->AddProperty(kInt32PropName, &int32_prop_);
      DBusInterface* itf3 = dbus_object_.AddOrGetInterface(kTestInterface3);
      itf3->AddProperty(kUint32PropName, &uint32_prop_);
      itf3->AddProperty(kInt64PropName, &int64_prop_);
      itf3->AddProperty(kUint64PropName, &uint64_prop_);
      itf3->AddProperty(kDoublePropName, &double_prop_);
      itf3->AddProperty(kStringPropName, &string_prop_);
      itf3->AddProperty(kPathPropName, &path_prop_);
      itf3->AddProperty(kStringListPropName, &stringlist_prop_);
      itf3->AddProperty(kPathListPropName, &pathlist_prop_);
      itf3->AddProperty(kUint8ListPropName, &uint8list_prop_);
      dbus_object_.RegisterAsync(
          AsyncEventSequencer::GetDefaultCompletionAction());
    }
    virtual ~Properties() {}

    DBusObject dbus_object_;
  };

  void SetUp() override {
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    bus_ = new dbus::MockBus(options);
    // By default, don't worry about threading assertions.
    EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
    // Use a mock exported object.
    mock_exported_object_ =
        new dbus::MockExportedObject(bus_.get(), kMethodsExportedOnPath);
    EXPECT_CALL(*bus_, GetExportedObject(kMethodsExportedOnPath))
        .Times(1).WillOnce(Return(mock_exported_object_.get()));

    EXPECT_CALL(*mock_exported_object_,
                ExportMethod(dbus::kPropertiesInterface, _, _, _)).Times(3);
    p_.reset(new Properties(bus_, kMethodsExportedOnPath));
  }

  void TearDown() override {
    EXPECT_CALL(*mock_exported_object_, Unregister()).Times(1);
  }

  void AssertMethodReturnsError(dbus::MethodCall* method_call) {
    method_call->SetSerial(123);
    auto response = testing::CallMethod(p_->dbus_object_, method_call);
    ASSERT_NE(dynamic_cast<dbus::ErrorResponse*>(response.get()), nullptr);
  }

  std::unique_ptr<dbus::Response> GetPropertyOnInterface(
      const std::string& interface_name,
      const std::string& property_name) {
    dbus::MethodCall method_call(dbus::kPropertiesInterface,
                                 dbus::kPropertiesGet);
    method_call.SetSerial(123);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(interface_name);
    writer.AppendString(property_name);
    return testing::CallMethod(p_->dbus_object_, &method_call);
  }

  std::unique_ptr<dbus::Response> SetPropertyOnInterface(
      const std::string& interface_name,
      const std::string& property_name,
      const chromeos::Any& value) {
    dbus::MethodCall method_call(dbus::kPropertiesInterface,
                                 dbus::kPropertiesSet);
    method_call.SetSerial(123);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(interface_name);
    writer.AppendString(property_name);
    dbus_utils::AppendValueToWriter(&writer, value);
    return testing::CallMethod(p_->dbus_object_, &method_call);
  }

  std::unique_ptr<dbus::Response> last_response_;
  scoped_refptr<dbus::MockBus> bus_;
  scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
  std::unique_ptr<Properties> p_;
};

template<typename T>
class PropertyValidatorObserver {
 public:
  PropertyValidatorObserver()
      : validate_property_callback_(
            base::Bind(&PropertyValidatorObserver::ValidateProperty,
                       base::Unretained(this))) {}
  virtual ~PropertyValidatorObserver() {}

  MOCK_METHOD2_T(ValidateProperty,
                 bool(chromeos::ErrorPtr* error, const T& value));

  const base::Callback<bool(chromeos::ErrorPtr*, const T&)>&
  validate_property_callback() const {
    return validate_property_callback_;
  }

 private:
  base::Callback<bool(chromeos::ErrorPtr*, const T&)>
      validate_property_callback_;

  DISALLOW_COPY_AND_ASSIGN(PropertyValidatorObserver);
};

TEST_F(ExportedPropertySetTest, UpdateNotifications) {
  EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(14);
  p_->bool_prop_.SetValue(true);
  p_->uint8_prop_.SetValue(1);
  p_->int16_prop_.SetValue(1);
  p_->uint16_prop_.SetValue(1);
  p_->int32_prop_.SetValue(1);
  p_->uint32_prop_.SetValue(1);
  p_->int64_prop_.SetValue(1);
  p_->uint64_prop_.SetValue(1);
  p_->double_prop_.SetValue(1.0);
  p_->string_prop_.SetValue(kTestString);
  p_->path_prop_.SetValue(kTestObjectPathUpdate);
  p_->stringlist_prop_.SetValue({kTestString});
  p_->pathlist_prop_.SetValue({kTestObjectPathUpdate});
  p_->uint8list_prop_.SetValue({1});
}

TEST_F(ExportedPropertySetTest, UpdateToSameValue) {
  EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1);
  p_->bool_prop_.SetValue(true);
  p_->bool_prop_.SetValue(true);
}

TEST_F(ExportedPropertySetTest, GetAllNoArgs) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGetAll);
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetAllInvalidInterface) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGetAll);
  method_call.SetSerial(123);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString("org.chromium.BadInterface");
  auto response = testing::CallMethod(p_->dbus_object_, &method_call);
  dbus::MessageReader response_reader(response.get());
  dbus::MessageReader dict_reader(nullptr);
  ASSERT_TRUE(response_reader.PopArray(&dict_reader));
  // The response should just be a an empty array, since there are no properties
  // on this interface.  The spec doesn't say much about error conditions here,
  // so I'm going to assume this is a valid implementation.
  ASSERT_FALSE(dict_reader.HasMoreData());
  ASSERT_FALSE(response_reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetAllExtraArgs) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGetAll);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kTestInterface1);
  writer.AppendString(kTestInterface1);
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetAllCorrectness) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGetAll);
  method_call.SetSerial(123);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kTestInterface2);
  auto response = testing::CallMethod(p_->dbus_object_, &method_call);
  dbus::MessageReader response_reader(response.get());
  dbus::MessageReader dict_reader(nullptr);
  dbus::MessageReader entry_reader(nullptr);
  ASSERT_TRUE(response_reader.PopArray(&dict_reader));
  ASSERT_TRUE(dict_reader.PopDictEntry(&entry_reader));
  std::string property_name;
  ASSERT_TRUE(entry_reader.PopString(&property_name));
  uint16_t value16;
  int32_t value32;
  if (property_name.compare(kUint16PropName) == 0) {
    ASSERT_TRUE(entry_reader.PopVariantOfUint16(&value16));
    ASSERT_FALSE(entry_reader.HasMoreData());
    ASSERT_TRUE(dict_reader.PopDictEntry(&entry_reader));
    ASSERT_TRUE(entry_reader.PopString(&property_name));
    ASSERT_EQ(property_name.compare(kInt32PropName), 0);
    ASSERT_TRUE(entry_reader.PopVariantOfInt32(&value32));
  } else {
    ASSERT_EQ(property_name.compare(kInt32PropName), 0);
    ASSERT_TRUE(entry_reader.PopVariantOfInt32(&value32));
    ASSERT_FALSE(entry_reader.HasMoreData());
    ASSERT_TRUE(dict_reader.PopDictEntry(&entry_reader));
    ASSERT_TRUE(entry_reader.PopString(&property_name));
    ASSERT_EQ(property_name.compare(kUint16PropName), 0);
    ASSERT_TRUE(entry_reader.PopVariantOfUint16(&value16));
  }
  ASSERT_FALSE(entry_reader.HasMoreData());
  ASSERT_FALSE(dict_reader.HasMoreData());
  ASSERT_FALSE(response_reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetNoArgs) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGet);
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetInvalidInterface) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGet);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString("org.chromium.BadInterface");
  writer.AppendString(kInt16PropName);
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetBadPropertyName) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGet);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kTestInterface1);
  writer.AppendString("IAmNotAProperty");
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetPropIfMismatch) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGet);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kTestInterface1);
  writer.AppendString(kStringPropName);
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetNoPropertyName) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGet);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kTestInterface1);
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetExtraArgs) {
  dbus::MethodCall method_call(dbus::kPropertiesInterface,
                               dbus::kPropertiesGet);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kTestInterface1);
  writer.AppendString(kBoolPropName);
  writer.AppendString("Extra param");
  AssertMethodReturnsError(&method_call);
}

TEST_F(ExportedPropertySetTest, GetWorksWithBool) {
  auto response = GetPropertyOnInterface(kTestInterface1, kBoolPropName);
  dbus::MessageReader reader(response.get());
  bool value;
  ASSERT_TRUE(reader.PopVariantOfBool(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithUint8) {
  auto response = GetPropertyOnInterface(kTestInterface1, kUint8PropName);
  dbus::MessageReader reader(response.get());
  uint8_t value;
  ASSERT_TRUE(reader.PopVariantOfByte(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithInt16) {
  auto response = GetPropertyOnInterface(kTestInterface1, kInt16PropName);
  dbus::MessageReader reader(response.get());
  int16_t value;
  ASSERT_TRUE(reader.PopVariantOfInt16(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithUint16) {
  auto response = GetPropertyOnInterface(kTestInterface2, kUint16PropName);
  dbus::MessageReader reader(response.get());
  uint16_t value;
  ASSERT_TRUE(reader.PopVariantOfUint16(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithInt32) {
  auto response = GetPropertyOnInterface(kTestInterface2, kInt32PropName);
  dbus::MessageReader reader(response.get());
  int32_t value;
  ASSERT_TRUE(reader.PopVariantOfInt32(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithUint32) {
  auto response = GetPropertyOnInterface(kTestInterface3, kUint32PropName);
  dbus::MessageReader reader(response.get());
  uint32_t value;
  ASSERT_TRUE(reader.PopVariantOfUint32(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithInt64) {
  auto response = GetPropertyOnInterface(kTestInterface3, kInt64PropName);
  dbus::MessageReader reader(response.get());
  int64_t value;
  ASSERT_TRUE(reader.PopVariantOfInt64(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithUint64) {
  auto response = GetPropertyOnInterface(kTestInterface3, kUint64PropName);
  dbus::MessageReader reader(response.get());
  uint64_t value;
  ASSERT_TRUE(reader.PopVariantOfUint64(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithDouble) {
  auto response = GetPropertyOnInterface(kTestInterface3, kDoublePropName);
  dbus::MessageReader reader(response.get());
  double value;
  ASSERT_TRUE(reader.PopVariantOfDouble(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithString) {
  auto response = GetPropertyOnInterface(kTestInterface3, kStringPropName);
  dbus::MessageReader reader(response.get());
  std::string value;
  ASSERT_TRUE(reader.PopVariantOfString(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithPath) {
  auto response = GetPropertyOnInterface(kTestInterface3, kPathPropName);
  dbus::MessageReader reader(response.get());
  dbus::ObjectPath value;
  ASSERT_TRUE(reader.PopVariantOfObjectPath(&value));
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithStringList) {
  auto response = GetPropertyOnInterface(kTestInterface3, kStringListPropName);
  dbus::MessageReader reader(response.get());
  dbus::MessageReader variant_reader(nullptr);
  std::vector<std::string> value;
  ASSERT_TRUE(reader.PopVariant(&variant_reader));
  ASSERT_TRUE(variant_reader.PopArrayOfStrings(&value));
  ASSERT_FALSE(variant_reader.HasMoreData());
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithPathList) {
  auto response = GetPropertyOnInterface(kTestInterface3, kPathListPropName);
  dbus::MessageReader reader(response.get());
  dbus::MessageReader variant_reader(nullptr);
  std::vector<dbus::ObjectPath> value;
  ASSERT_TRUE(reader.PopVariant(&variant_reader));
  ASSERT_TRUE(variant_reader.PopArrayOfObjectPaths(&value));
  ASSERT_FALSE(variant_reader.HasMoreData());
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, GetWorksWithUint8List) {
  auto response = GetPropertyOnInterface(kTestInterface3, kPathListPropName);
  dbus::MessageReader reader(response.get());
  dbus::MessageReader variant_reader(nullptr);
  const uint8_t* buffer;
  size_t buffer_len;
  ASSERT_TRUE(reader.PopVariant(&variant_reader));
  // |buffer| remains under the control of the MessageReader.
  ASSERT_TRUE(variant_reader.PopArrayOfBytes(&buffer, &buffer_len));
  ASSERT_FALSE(variant_reader.HasMoreData());
  ASSERT_FALSE(reader.HasMoreData());
}

TEST_F(ExportedPropertySetTest, SetInvalidInterface) {
  auto response = SetPropertyOnInterface(
      "BadInterfaceName", kStringPropName, chromeos::Any(kTestString));
  ASSERT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(DBUS_ERROR_UNKNOWN_INTERFACE, response->GetErrorName());
}

TEST_F(ExportedPropertySetTest, SetBadPropertyName) {
  auto response = SetPropertyOnInterface(
      kTestInterface3, "IAmNotAProperty", chromeos::Any(kTestString));
  ASSERT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(DBUS_ERROR_UNKNOWN_PROPERTY, response->GetErrorName());
}

TEST_F(ExportedPropertySetTest, SetFailsWithReadOnlyProperty) {
  auto response = SetPropertyOnInterface(
      kTestInterface3, kStringPropName, chromeos::Any(kTestString));
  ASSERT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(DBUS_ERROR_PROPERTY_READ_ONLY, response->GetErrorName());
}

TEST_F(ExportedPropertySetTest, SetFailsWithMismatchedValueType) {
  p_->string_prop_.SetAccessMode(ExportedPropertyBase::Access::kReadWrite);
  auto response = SetPropertyOnInterface(
      kTestInterface3, kStringPropName, chromeos::Any(true));
  ASSERT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(DBUS_ERROR_INVALID_ARGS, response->GetErrorName());
}

namespace {

bool SetInvalidProperty(chromeos::ErrorPtr* error, Unused) {
  chromeos::Error::AddTo(error,
                         FROM_HERE,
                         errors::dbus::kDomain,
                         DBUS_ERROR_INVALID_ARGS,
                         "Invalid value");
  return false;
}

}  // namespace

TEST_F(ExportedPropertySetTest, SetFailsWithValidator) {
  PropertyValidatorObserver<std::string> property_validator;
  p_->string_prop_.SetAccessMode(ExportedPropertyBase::Access::kReadWrite);
  p_->string_prop_.SetValidator(
      property_validator.validate_property_callback());

  chromeos::ErrorPtr error = chromeos::Error::Create(
      FROM_HERE, errors::dbus::kDomain, DBUS_ERROR_INVALID_ARGS, "");
  EXPECT_CALL(property_validator, ValidateProperty(_, kTestString))
      .WillOnce(Invoke(SetInvalidProperty));
  auto response = SetPropertyOnInterface(
      kTestInterface3, kStringPropName, chromeos::Any(kTestString));
  ASSERT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(DBUS_ERROR_INVALID_ARGS, response->GetErrorName());
}

TEST_F(ExportedPropertySetTest, SetWorksWithValidator) {
  PropertyValidatorObserver<std::string> property_validator;
  p_->string_prop_.SetAccessMode(ExportedPropertyBase::Access::kReadWrite);
  p_->string_prop_.SetValidator(
      property_validator.validate_property_callback());

  EXPECT_CALL(property_validator, ValidateProperty(_, kTestString))
      .WillOnce(Return(true));
  auto response = SetPropertyOnInterface(
      kTestInterface3, kStringPropName, chromeos::Any(kTestString));
  ASSERT_NE(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(kTestString, p_->string_prop_.value());
}

TEST_F(ExportedPropertySetTest, SetWorksWithSameValue) {
  PropertyValidatorObserver<std::string> property_validator;
  p_->string_prop_.SetAccessMode(ExportedPropertyBase::Access::kReadWrite);
  p_->string_prop_.SetValidator(
      property_validator.validate_property_callback());
  EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1);
  p_->string_prop_.SetValue(kTestString);

  // No need to validate the value if it is the same as the current one.
  EXPECT_CALL(property_validator, ValidateProperty(_, _)).Times(0);
  auto response = SetPropertyOnInterface(
      kTestInterface3, kStringPropName, chromeos::Any(kTestString));
  ASSERT_NE(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(kTestString, p_->string_prop_.value());
}

TEST_F(ExportedPropertySetTest, SetWorksWithoutValidator) {
  p_->string_prop_.SetAccessMode(ExportedPropertyBase::Access::kReadWrite);
  auto response = SetPropertyOnInterface(
      kTestInterface3, kStringPropName, chromeos::Any(kTestString));
  ASSERT_NE(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
  ASSERT_EQ(kTestString, p_->string_prop_.value());
}

namespace {

void VerifySignal(dbus::Signal* signal) {
  ASSERT_NE(signal, nullptr);
  std::string interface_name;
  std::string property_name;
  uint8_t value;
  dbus::MessageReader reader(signal);
  dbus::MessageReader array_reader(signal);
  dbus::MessageReader dict_reader(signal);
  ASSERT_TRUE(reader.PopString(&interface_name));
  ASSERT_TRUE(reader.PopArray(&array_reader));
  ASSERT_TRUE(array_reader.PopDictEntry(&dict_reader));
  ASSERT_TRUE(dict_reader.PopString(&property_name));
  ASSERT_TRUE(dict_reader.PopVariantOfByte(&value));
  ASSERT_FALSE(dict_reader.HasMoreData());
  ASSERT_FALSE(array_reader.HasMoreData());
  ASSERT_TRUE(reader.HasMoreData());
  // Read the (empty) list of invalidated property names.
  ASSERT_TRUE(reader.PopArray(&array_reader));
  ASSERT_FALSE(array_reader.HasMoreData());
  ASSERT_FALSE(reader.HasMoreData());
  ASSERT_EQ(value, 57);
  ASSERT_EQ(property_name, std::string(kUint8PropName));
  ASSERT_EQ(interface_name, std::string(kTestInterface1));
}

}  // namespace

TEST_F(ExportedPropertySetTest, SignalsAreParsable) {
  EXPECT_CALL(*mock_exported_object_, SendSignal(_))
      .Times(1).WillOnce(Invoke(&VerifySignal));
  p_->uint8_prop_.SetValue(57);
}

}  // namespace dbus_utils

}  // namespace chromeos
