Chromium Code Reviews| Index: chromeos/dbus/cups_client_unittest.cc |
| diff --git a/chromeos/dbus/cups_client_unittest.cc b/chromeos/dbus/cups_client_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e07f9a097832aa29d166fe7c173eb0eb45094dda |
| --- /dev/null |
| +++ b/chromeos/dbus/cups_client_unittest.cc |
| @@ -0,0 +1,312 @@ |
| +// Copyright 2016 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 "chromeos/dbus/cups_client.h" |
| + |
| +#include <memory> |
| + |
| +#include "base/bind.h" |
| +#include "dbus/mock_bus.h" |
| +#include "dbus/mock_object_proxy.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "third_party/cros_system_api/dbus/debugd/dbus-constants.h" |
| + |
| +namespace chromeos { |
| + |
| +using testing::_; |
| +using testing::Return; |
| + |
| +namespace { |
| + |
| +class CallbackHelper { |
| + public: |
| + CallbackHelper() |
| + : callback_called_(false), error_called_(false), weak_factory_(this) {} |
| + |
| + CupsClient::AddPrinterCallback MockAddCallback(); |
| + CupsClient::RemovePrinterCallback MockRemoveCallback(); |
| + base::Closure MockErrorCallback(); |
| + |
| + bool error_called() const; |
| + bool callback_called() const; |
| + bool actual_result() const; |
| + |
| + private: |
| + void RecordResult(bool result); |
| + void ErrorStub(); |
| + |
| + // The result of the callback. |
| + bool actual_result_; |
| + |
| + bool callback_called_; |
| + bool error_called_; |
| + |
| + base::WeakPtrFactory<CallbackHelper> weak_factory_; |
| +}; |
| + |
| +CupsClient::AddPrinterCallback CallbackHelper::MockAddCallback() { |
| + return base::Bind(&CallbackHelper::RecordResult, weak_factory_.GetWeakPtr()); |
| +} |
| + |
| +CupsClient::RemovePrinterCallback CallbackHelper::MockRemoveCallback() { |
| + return base::Bind(&CallbackHelper::RecordResult, weak_factory_.GetWeakPtr()); |
| +} |
| + |
| +base::Closure CallbackHelper::MockErrorCallback() { |
| + return base::Bind(&CallbackHelper::ErrorStub, weak_factory_.GetWeakPtr()); |
| +} |
| + |
| +bool CallbackHelper::error_called() const { |
| + return error_called_; |
| +} |
| + |
| +bool CallbackHelper::callback_called() const { |
| + return callback_called_; |
| +} |
| + |
| +bool CallbackHelper::actual_result() const { |
| + return actual_result_; |
| +} |
| + |
| +void CallbackHelper::RecordResult(bool result) { |
| + actual_result_ = result; |
| + callback_called_ = true; |
| +} |
| + |
| +void CallbackHelper::ErrorStub() { |
| + error_called_ = true; |
| +} |
| + |
| +void NopVerify(dbus::MessageReader* reader) {} |
| + |
| +void VerifyAddArgs(const std::string& name, |
| + const std::string& uri, |
| + const std::string& ppd, |
| + const bool everywhere, |
| + dbus::MessageReader* reader) { |
| + ASSERT_NE(nullptr, reader); |
| + |
| + std::string actual_name; |
| + std::string actual_uri; |
| + std::string actual_ppd; |
| + bool actual_everywhere; |
| + |
| + ASSERT_TRUE(reader->PopString(&actual_name)); |
| + EXPECT_EQ(name, actual_name); |
| + |
| + ASSERT_TRUE(reader->PopString(&actual_uri)); |
| + EXPECT_EQ(uri, actual_uri); |
| + |
| + ASSERT_TRUE(reader->PopString(&actual_ppd)); |
| + EXPECT_EQ(ppd, actual_ppd); |
| + |
| + ASSERT_TRUE(reader->PopBool(&actual_everywhere)); |
| + EXPECT_EQ(everywhere, actual_everywhere); |
| + |
| + EXPECT_FALSE(reader->HasMoreData()); |
| +} |
| + |
| +void VerifyRemoveArgs(const std::string& name, dbus::MessageReader* reader) { |
| + ASSERT_NE(nullptr, reader); |
| + |
| + std::string actual_name; |
| + ASSERT_TRUE(reader->PopString(&actual_name)); |
| + EXPECT_EQ(name, actual_name); |
| + |
| + EXPECT_FALSE(reader->HasMoreData()); |
| +} |
| + |
| +} // namespace |
| + |
| +class CupsClientTest : public testing::Test { |
| + public: |
| + CupsClientTest() {} |
| + |
| + void SetUp() override { |
| + // Create a mock bus. |
| + dbus::Bus::Options options; |
| + options.bus_type = dbus::Bus::SYSTEM; |
| + mock_bus_ = new dbus::MockBus(options); |
| + |
| + // Create a mock cups proxy. |
| + mock_cups_proxy_ = |
| + new dbus::MockObjectProxy(mock_bus_.get(), debugd::kDebugdInterface, |
| + dbus::ObjectPath(debugd::kDebugdServicePath)); |
| + |
| + // Set an expectation so mock_cups_proxy's CallMethodWithErrorCallback() |
| + // will use OnCallMethodWithErrorCallback() to return responses. |
| + EXPECT_CALL(*mock_cups_proxy_.get(), |
| + CallMethodWithErrorCallback(_, _, _, _)) |
| + .WillRepeatedly( |
| + Invoke(this, &CupsClientTest::OnCallMethodWithErrorCallback)); |
| + |
| + // Set an expectation so mock_bus's GetObjectProxy() for the given |
| + // service name and the object path will return mock_cups_proxy_. |
| + EXPECT_CALL(*mock_bus_.get(), |
| + GetObjectProxy("org.chromium.debugd", |
| + dbus::ObjectPath("/org/chromium/debugd"))) |
| + .WillOnce(Return(mock_cups_proxy_.get())); |
| + |
| + // ShutdownAndBlock() will be called in TearDown(). |
| + EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); |
| + |
| + // Create a client with the mock bus. |
| + client_.reset(CupsClient::Create()); |
| + client_->Init(mock_bus_.get()); |
| + |
| + actual_interface_ = ""; |
| + actual_method_name_ = ""; |
| + throw_error_ = false; |
| + result_ = false; |
| + argument_callback_ = base::Bind(&NopVerify); |
| + } |
| + |
| + void TearDown() override { mock_bus_->ShutdownAndBlock(); } |
| + |
| + const std::string& actual_interface() { return actual_interface_; } |
| + |
| + const std::string& actual_method() { return actual_method_name_; } |
| + |
| + CupsClient* client() { return client_.get(); } |
| + |
| + // If |error| is true, the error callback will be triggered |
| + // instead of the normal callback. |
| + void ThrowError(bool error) { throw_error_ = error; } |
| + |
| + // Set the result for the response. |
| + void SetResult(bool result) { result_ = result; } |
| + |
| + void SetArgumentCallback( |
| + base::Callback<void(dbus::MessageReader* reader)> callback) { |
| + argument_callback_ = callback; |
| + } |
| + |
| + private: |
| + void OnCallMethodWithErrorCallback( |
| + dbus::MethodCall* method_call, |
| + int timeout_ms, |
| + const dbus::ObjectProxy::ResponseCallback& response_callback, |
| + const dbus::ObjectProxy::ErrorCallback& error_callback) { |
| + actual_interface_ = method_call->GetInterface(); |
| + actual_method_name_ = method_call->GetMember(); |
| + dbus::MessageReader reader(method_call); |
| + argument_callback_.Run(&reader); |
| + if (throw_error_) { |
| + std::unique_ptr<dbus::ErrorResponse> response = |
| + dbus::ErrorResponse::FromMethodCall(method_call, "", ""); |
| + // this will be synchronous so response stays in scope. |
| + error_callback.Run(response.get()); |
| + return; |
| + } |
| + |
| + std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); |
| + dbus::MessageWriter writer(response.get()); |
| + writer.AppendBool(result_); |
| + response_callback.Run(response.get()); |
| + } |
| + |
| + // The interface of the called method. |
| + std::string actual_interface_; |
| + |
| + // The name of the method which was called. |
| + std::string actual_method_name_; |
| + |
| + // The client to be tested. |
| + std::unique_ptr<CupsClient> client_; |
| + |
| + // The mock bus. |
| + scoped_refptr<dbus::MockBus> mock_bus_; |
| + |
| + // The mock object proxy. |
| + scoped_refptr<dbus::MockObjectProxy> mock_cups_proxy_; |
| + |
| + base::Callback<void(dbus::MessageReader*)> argument_callback_; |
| + |
| + bool throw_error_; |
| + bool result_; |
| +}; |
| + |
| +TEST_F(CupsClientTest, AddPrinterCallsAdd) { |
|
hashimoto
2016/09/07 05:53:17
Thank you for trying to add test code for this new
skau
2016/09/09 15:25:32
Okay. We're going to cover this with an integrati
|
| + CallbackHelper helper; |
| + client()->AddPrinter("printer name", "ipp://1.1.1.1", "", true, |
| + helper.MockAddCallback(), helper.MockErrorCallback()); |
| + EXPECT_EQ("org.chromium.debugd", actual_interface()); |
| + EXPECT_EQ("CupsAddPrinter", actual_method()); |
| +} |
| + |
| +TEST_F(CupsClientTest, AddPrinterCallbackIsCalled) { |
| + CallbackHelper helper; |
| + ThrowError(false); |
| + SetResult(true); |
| + |
| + client()->AddPrinter("printer name", "ipp://1.1.1.1", "", true, |
| + helper.MockAddCallback(), helper.MockErrorCallback()); |
| + EXPECT_TRUE(helper.callback_called()); |
| + EXPECT_TRUE(helper.actual_result()); |
| +} |
| + |
| +TEST_F(CupsClientTest, AddPrinterArgumentsPassed) { |
| + CallbackHelper helper; |
| + std::string printer_name = "added printer"; |
| + std::string uri = "ipp://printer-p.com/"; |
| + std::string ppd = "/manufacturer/model/filename.ppd"; |
| + bool everywhere = false; |
| + SetArgumentCallback( |
| + base::Bind(&VerifyAddArgs, printer_name, uri, ppd, everywhere)); |
| + |
| + client()->AddPrinter(printer_name, uri, ppd, everywhere, |
| + helper.MockRemoveCallback(), helper.MockErrorCallback()); |
| +} |
| + |
| +TEST_F(CupsClientTest, AddCallsError) { |
| + CallbackHelper helper; |
| + ThrowError(true); |
| + |
| + client()->AddPrinter("printer name", "ipp://1.1.1.1", "", true, |
| + helper.MockAddCallback(), helper.MockErrorCallback()); |
| + |
| + EXPECT_TRUE(helper.error_called()); |
| + EXPECT_FALSE(helper.callback_called()); |
| +} |
| + |
| +TEST_F(CupsClientTest, RemovePrinterCallsRemove) { |
| + CallbackHelper helper; |
| + client()->RemovePrinter("printer name", helper.MockRemoveCallback(), |
| + helper.MockErrorCallback()); |
| + EXPECT_EQ("org.chromium.debugd", actual_interface()); |
| + EXPECT_EQ("CupsRemovePrinter", actual_method()); |
| +} |
| + |
| +TEST_F(CupsClientTest, RemovePrinterCallbackIsCalled) { |
| + CallbackHelper helper; |
| + ThrowError(false); |
| + SetResult(false); |
| + |
| + client()->RemovePrinter("printer", helper.MockRemoveCallback(), |
| + helper.MockErrorCallback()); |
| + EXPECT_TRUE(helper.callback_called()); |
| + EXPECT_FALSE(helper.actual_result()); |
| +} |
| + |
| +TEST_F(CupsClientTest, RemoveCallsError) { |
| + CallbackHelper helper; |
| + ThrowError(true); |
| + |
| + client()->RemovePrinter("Printer", helper.MockRemoveCallback(), |
| + helper.MockErrorCallback()); |
| + |
| + EXPECT_TRUE(helper.error_called()); |
| + EXPECT_FALSE(helper.callback_called()); |
| +} |
| + |
| +TEST_F(CupsClientTest, RemovePrinterArgumentsPassed) { |
| + CallbackHelper helper; |
| + std::string printer_name = "deletable printer"; |
| + SetArgumentCallback(base::Bind(&VerifyRemoveArgs, printer_name)); |
| + |
| + client()->RemovePrinter(printer_name, helper.MockRemoveCallback(), |
| + helper.MockErrorCallback()); |
| +} |
| + |
| +} // namespace chromeos |