// Copyright (c) 2012 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 "base/bind.h" #include "base/values.h" #include "chromeos/dbus/shill_client_unittest_base.h" #include "chromeos/dbus/shill_profile_client.h" #include "dbus/message.h" #include "dbus/object_path.h" #include "dbus/values_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/cros_system_api/dbus/service_constants.h" using testing::_; namespace chromeos { namespace { const char kDefaultProfilePath[] = "/profile/default"; const char kExampleEntryPath[] = "example_entry_path"; void AppendVariantOfArrayOfStrings(dbus::MessageWriter* writer, const std::vector& strings) { dbus::MessageWriter variant_writer(NULL); writer->OpenVariant("as", &variant_writer); variant_writer.AppendArrayOfStrings(strings); writer->CloseContainer(&variant_writer); } } // namespace class ShillProfileClientTest : public ShillClientUnittestBase { public: ShillProfileClientTest() : ShillClientUnittestBase(shill::kFlimflamProfileInterface, dbus::ObjectPath(kDefaultProfilePath)) { } void SetUp() override { ShillClientUnittestBase::SetUp(); // Create a client with the mock bus. client_.reset(ShillProfileClient::Create()); client_->Init(mock_bus_.get()); // Run the message loop to run the signal connection result callback. message_loop_.RunUntilIdle(); } void TearDown() override { ShillClientUnittestBase::TearDown(); } protected: scoped_ptr client_; }; TEST_F(ShillProfileClientTest, PropertyChanged) { // Create a signal. dbus::Signal signal(shill::kFlimflamProfileInterface, shill::kMonitorPropertyChanged); dbus::MessageWriter writer(&signal); writer.AppendString(shill::kEntriesProperty); AppendVariantOfArrayOfStrings(&writer, std::vector(1, kExampleEntryPath)); // Set expectations. base::ListValue value; value.Append(new base::StringValue(kExampleEntryPath)); MockPropertyChangeObserver observer; EXPECT_CALL(observer, OnPropertyChanged( shill::kEntriesProperty, ValueEq(value))).Times(1); // Add the observer client_->AddPropertyChangedObserver( dbus::ObjectPath(kDefaultProfilePath), &observer); // Run the signal callback. SendPropertyChangedSignal(&signal); // Remove the observer. client_->RemovePropertyChangedObserver( dbus::ObjectPath(kDefaultProfilePath), &observer); EXPECT_CALL(observer, OnPropertyChanged(_, _)).Times(0); // Run the signal callback again and make sure the observer isn't called. SendPropertyChangedSignal(&signal); } TEST_F(ShillProfileClientTest, GetProperties) { // Create response. scoped_ptr response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); dbus::MessageWriter array_writer(NULL); writer.OpenArray("{sv}", &array_writer); dbus::MessageWriter entry_writer(NULL); array_writer.OpenDictEntry(&entry_writer); entry_writer.AppendString(shill::kEntriesProperty); AppendVariantOfArrayOfStrings(&entry_writer, std::vector(1, kExampleEntryPath)); array_writer.CloseContainer(&entry_writer); writer.CloseContainer(&array_writer); // Create the expected value. base::ListValue* entries = new base::ListValue; entries->Append(new base::StringValue(kExampleEntryPath)); base::DictionaryValue value; value.SetWithoutPathExpansion(shill::kEntriesProperty, entries); // Set expectations. PrepareForMethodCall(shill::kGetPropertiesFunction, base::Bind(&ExpectNoArgument), response.get()); // Call method. MockErrorCallback error_callback; client_->GetProperties(dbus::ObjectPath(kDefaultProfilePath), base::Bind(&ExpectDictionaryValueResultWithoutStatus, &value), error_callback.GetCallback()); EXPECT_CALL(error_callback, Run(_, _)).Times(0); // Run the message loop. message_loop_.RunUntilIdle(); } TEST_F(ShillProfileClientTest, GetEntry) { // Create response. scoped_ptr response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); dbus::MessageWriter array_writer(NULL); writer.OpenArray("{sv}", &array_writer); dbus::MessageWriter entry_writer(NULL); array_writer.OpenDictEntry(&entry_writer); entry_writer.AppendString(shill::kTypeProperty); entry_writer.AppendVariantOfString(shill::kTypeWifi); array_writer.CloseContainer(&entry_writer); writer.CloseContainer(&array_writer); // Create the expected value. base::DictionaryValue value; value.SetWithoutPathExpansion(shill::kTypeProperty, new base::StringValue(shill::kTypeWifi)); // Set expectations. PrepareForMethodCall(shill::kGetEntryFunction, base::Bind(&ExpectStringArgument, kExampleEntryPath), response.get()); // Call method. MockErrorCallback error_callback; client_->GetEntry(dbus::ObjectPath(kDefaultProfilePath), kExampleEntryPath, base::Bind(&ExpectDictionaryValueResultWithoutStatus, &value), error_callback.GetCallback()); EXPECT_CALL(error_callback, Run(_, _)).Times(0); // Run the message loop. message_loop_.RunUntilIdle(); } TEST_F(ShillProfileClientTest, DeleteEntry) { // Create response. scoped_ptr response(dbus::Response::CreateEmpty()); // Create the expected value. base::DictionaryValue value; value.SetWithoutPathExpansion(shill::kOfflineModeProperty, new base::FundamentalValue(true)); // Set expectations. PrepareForMethodCall(shill::kDeleteEntryFunction, base::Bind(&ExpectStringArgument, kExampleEntryPath), response.get()); // Call method. MockClosure mock_closure; MockErrorCallback mock_error_callback; client_->DeleteEntry(dbus::ObjectPath(kDefaultProfilePath), kExampleEntryPath, mock_closure.GetCallback(), mock_error_callback.GetCallback()); EXPECT_CALL(mock_closure, Run()).Times(1); EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); // Run the message loop. message_loop_.RunUntilIdle(); } } // namespace chromeos