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 |