OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chromeos/dbus/cups_client.h" | |
6 | |
7 #include <memory> | |
8 | |
9 #include "base/bind.h" | |
10 #include "dbus/mock_bus.h" | |
11 #include "dbus/mock_object_proxy.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "third_party/cros_system_api/dbus/debugd/dbus-constants.h" | |
14 | |
15 namespace chromeos { | |
16 | |
17 using testing::_; | |
18 using testing::Return; | |
19 | |
20 namespace { | |
21 | |
22 class CallbackHelper { | |
23 public: | |
24 CallbackHelper() | |
25 : callback_called_(false), error_called_(false), weak_factory_(this) {} | |
26 | |
27 CupsClient::AddPrinterCallback MockAddCallback(); | |
28 CupsClient::RemovePrinterCallback MockRemoveCallback(); | |
29 base::Closure MockErrorCallback(); | |
30 | |
31 bool error_called() const; | |
32 bool callback_called() const; | |
33 bool actual_result() const; | |
34 | |
35 private: | |
36 void RecordResult(bool result); | |
37 void ErrorStub(); | |
38 | |
39 // The result of the callback. | |
40 bool actual_result_; | |
41 | |
42 bool callback_called_; | |
43 bool error_called_; | |
44 | |
45 base::WeakPtrFactory<CallbackHelper> weak_factory_; | |
46 }; | |
47 | |
48 CupsClient::AddPrinterCallback CallbackHelper::MockAddCallback() { | |
49 return base::Bind(&CallbackHelper::RecordResult, weak_factory_.GetWeakPtr()); | |
50 } | |
51 | |
52 CupsClient::RemovePrinterCallback CallbackHelper::MockRemoveCallback() { | |
53 return base::Bind(&CallbackHelper::RecordResult, weak_factory_.GetWeakPtr()); | |
54 } | |
55 | |
56 base::Closure CallbackHelper::MockErrorCallback() { | |
57 return base::Bind(&CallbackHelper::ErrorStub, weak_factory_.GetWeakPtr()); | |
58 } | |
59 | |
60 bool CallbackHelper::error_called() const { | |
61 return error_called_; | |
62 } | |
63 | |
64 bool CallbackHelper::callback_called() const { | |
65 return callback_called_; | |
66 } | |
67 | |
68 bool CallbackHelper::actual_result() const { | |
69 return actual_result_; | |
70 } | |
71 | |
72 void CallbackHelper::RecordResult(bool result) { | |
73 actual_result_ = result; | |
74 callback_called_ = true; | |
75 } | |
76 | |
77 void CallbackHelper::ErrorStub() { | |
78 error_called_ = true; | |
79 } | |
80 | |
81 void NopVerify(dbus::MessageReader* reader) {} | |
82 | |
83 void VerifyAddArgs(const std::string& name, | |
84 const std::string& uri, | |
85 const std::string& ppd, | |
86 const bool everywhere, | |
87 dbus::MessageReader* reader) { | |
88 ASSERT_NE(nullptr, reader); | |
89 | |
90 std::string actual_name; | |
91 std::string actual_uri; | |
92 std::string actual_ppd; | |
93 bool actual_everywhere; | |
94 | |
95 ASSERT_TRUE(reader->PopString(&actual_name)); | |
96 EXPECT_EQ(name, actual_name); | |
97 | |
98 ASSERT_TRUE(reader->PopString(&actual_uri)); | |
99 EXPECT_EQ(uri, actual_uri); | |
100 | |
101 ASSERT_TRUE(reader->PopString(&actual_ppd)); | |
102 EXPECT_EQ(ppd, actual_ppd); | |
103 | |
104 ASSERT_TRUE(reader->PopBool(&actual_everywhere)); | |
105 EXPECT_EQ(everywhere, actual_everywhere); | |
106 | |
107 EXPECT_FALSE(reader->HasMoreData()); | |
108 } | |
109 | |
110 void VerifyRemoveArgs(const std::string& name, dbus::MessageReader* reader) { | |
111 ASSERT_NE(nullptr, reader); | |
112 | |
113 std::string actual_name; | |
114 ASSERT_TRUE(reader->PopString(&actual_name)); | |
115 EXPECT_EQ(name, actual_name); | |
116 | |
117 EXPECT_FALSE(reader->HasMoreData()); | |
118 } | |
119 | |
120 } // namespace | |
121 | |
122 class CupsClientTest : public testing::Test { | |
123 public: | |
124 CupsClientTest() {} | |
125 | |
126 void SetUp() override { | |
127 // Create a mock bus. | |
128 dbus::Bus::Options options; | |
129 options.bus_type = dbus::Bus::SYSTEM; | |
130 mock_bus_ = new dbus::MockBus(options); | |
131 | |
132 // Create a mock cups proxy. | |
133 mock_cups_proxy_ = | |
134 new dbus::MockObjectProxy(mock_bus_.get(), debugd::kDebugdInterface, | |
135 dbus::ObjectPath(debugd::kDebugdServicePath)); | |
136 | |
137 // Set an expectation so mock_cups_proxy's CallMethodWithErrorCallback() | |
138 // will use OnCallMethodWithErrorCallback() to return responses. | |
139 EXPECT_CALL(*mock_cups_proxy_.get(), | |
140 CallMethodWithErrorCallback(_, _, _, _)) | |
141 .WillRepeatedly( | |
142 Invoke(this, &CupsClientTest::OnCallMethodWithErrorCallback)); | |
143 | |
144 // Set an expectation so mock_bus's GetObjectProxy() for the given | |
145 // service name and the object path will return mock_cups_proxy_. | |
146 EXPECT_CALL(*mock_bus_.get(), | |
147 GetObjectProxy("org.chromium.debugd", | |
148 dbus::ObjectPath("/org/chromium/debugd"))) | |
149 .WillOnce(Return(mock_cups_proxy_.get())); | |
150 | |
151 // ShutdownAndBlock() will be called in TearDown(). | |
152 EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); | |
153 | |
154 // Create a client with the mock bus. | |
155 client_.reset(CupsClient::Create()); | |
156 client_->Init(mock_bus_.get()); | |
157 | |
158 actual_interface_ = ""; | |
159 actual_method_name_ = ""; | |
160 throw_error_ = false; | |
161 result_ = false; | |
162 argument_callback_ = base::Bind(&NopVerify); | |
163 } | |
164 | |
165 void TearDown() override { mock_bus_->ShutdownAndBlock(); } | |
166 | |
167 const std::string& actual_interface() { return actual_interface_; } | |
168 | |
169 const std::string& actual_method() { return actual_method_name_; } | |
170 | |
171 CupsClient* client() { return client_.get(); } | |
172 | |
173 // If |error| is true, the error callback will be triggered | |
174 // instead of the normal callback. | |
175 void ThrowError(bool error) { throw_error_ = error; } | |
176 | |
177 // Set the result for the response. | |
178 void SetResult(bool result) { result_ = result; } | |
179 | |
180 void SetArgumentCallback( | |
181 base::Callback<void(dbus::MessageReader* reader)> callback) { | |
182 argument_callback_ = callback; | |
183 } | |
184 | |
185 private: | |
186 void OnCallMethodWithErrorCallback( | |
187 dbus::MethodCall* method_call, | |
188 int timeout_ms, | |
189 const dbus::ObjectProxy::ResponseCallback& response_callback, | |
190 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
191 actual_interface_ = method_call->GetInterface(); | |
192 actual_method_name_ = method_call->GetMember(); | |
193 dbus::MessageReader reader(method_call); | |
194 argument_callback_.Run(&reader); | |
195 if (throw_error_) { | |
196 std::unique_ptr<dbus::ErrorResponse> response = | |
197 dbus::ErrorResponse::FromMethodCall(method_call, "", ""); | |
198 // this will be synchronous so response stays in scope. | |
199 error_callback.Run(response.get()); | |
200 return; | |
201 } | |
202 | |
203 std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
204 dbus::MessageWriter writer(response.get()); | |
205 writer.AppendBool(result_); | |
206 response_callback.Run(response.get()); | |
207 } | |
208 | |
209 // The interface of the called method. | |
210 std::string actual_interface_; | |
211 | |
212 // The name of the method which was called. | |
213 std::string actual_method_name_; | |
214 | |
215 // The client to be tested. | |
216 std::unique_ptr<CupsClient> client_; | |
217 | |
218 // The mock bus. | |
219 scoped_refptr<dbus::MockBus> mock_bus_; | |
220 | |
221 // The mock object proxy. | |
222 scoped_refptr<dbus::MockObjectProxy> mock_cups_proxy_; | |
223 | |
224 base::Callback<void(dbus::MessageReader*)> argument_callback_; | |
225 | |
226 bool throw_error_; | |
227 bool result_; | |
228 }; | |
229 | |
230 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
| |
231 CallbackHelper helper; | |
232 client()->AddPrinter("printer name", "ipp://1.1.1.1", "", true, | |
233 helper.MockAddCallback(), helper.MockErrorCallback()); | |
234 EXPECT_EQ("org.chromium.debugd", actual_interface()); | |
235 EXPECT_EQ("CupsAddPrinter", actual_method()); | |
236 } | |
237 | |
238 TEST_F(CupsClientTest, AddPrinterCallbackIsCalled) { | |
239 CallbackHelper helper; | |
240 ThrowError(false); | |
241 SetResult(true); | |
242 | |
243 client()->AddPrinter("printer name", "ipp://1.1.1.1", "", true, | |
244 helper.MockAddCallback(), helper.MockErrorCallback()); | |
245 EXPECT_TRUE(helper.callback_called()); | |
246 EXPECT_TRUE(helper.actual_result()); | |
247 } | |
248 | |
249 TEST_F(CupsClientTest, AddPrinterArgumentsPassed) { | |
250 CallbackHelper helper; | |
251 std::string printer_name = "added printer"; | |
252 std::string uri = "ipp://printer-p.com/"; | |
253 std::string ppd = "/manufacturer/model/filename.ppd"; | |
254 bool everywhere = false; | |
255 SetArgumentCallback( | |
256 base::Bind(&VerifyAddArgs, printer_name, uri, ppd, everywhere)); | |
257 | |
258 client()->AddPrinter(printer_name, uri, ppd, everywhere, | |
259 helper.MockRemoveCallback(), helper.MockErrorCallback()); | |
260 } | |
261 | |
262 TEST_F(CupsClientTest, AddCallsError) { | |
263 CallbackHelper helper; | |
264 ThrowError(true); | |
265 | |
266 client()->AddPrinter("printer name", "ipp://1.1.1.1", "", true, | |
267 helper.MockAddCallback(), helper.MockErrorCallback()); | |
268 | |
269 EXPECT_TRUE(helper.error_called()); | |
270 EXPECT_FALSE(helper.callback_called()); | |
271 } | |
272 | |
273 TEST_F(CupsClientTest, RemovePrinterCallsRemove) { | |
274 CallbackHelper helper; | |
275 client()->RemovePrinter("printer name", helper.MockRemoveCallback(), | |
276 helper.MockErrorCallback()); | |
277 EXPECT_EQ("org.chromium.debugd", actual_interface()); | |
278 EXPECT_EQ("CupsRemovePrinter", actual_method()); | |
279 } | |
280 | |
281 TEST_F(CupsClientTest, RemovePrinterCallbackIsCalled) { | |
282 CallbackHelper helper; | |
283 ThrowError(false); | |
284 SetResult(false); | |
285 | |
286 client()->RemovePrinter("printer", helper.MockRemoveCallback(), | |
287 helper.MockErrorCallback()); | |
288 EXPECT_TRUE(helper.callback_called()); | |
289 EXPECT_FALSE(helper.actual_result()); | |
290 } | |
291 | |
292 TEST_F(CupsClientTest, RemoveCallsError) { | |
293 CallbackHelper helper; | |
294 ThrowError(true); | |
295 | |
296 client()->RemovePrinter("Printer", helper.MockRemoveCallback(), | |
297 helper.MockErrorCallback()); | |
298 | |
299 EXPECT_TRUE(helper.error_called()); | |
300 EXPECT_FALSE(helper.callback_called()); | |
301 } | |
302 | |
303 TEST_F(CupsClientTest, RemovePrinterArgumentsPassed) { | |
304 CallbackHelper helper; | |
305 std::string printer_name = "deletable printer"; | |
306 SetArgumentCallback(base::Bind(&VerifyRemoveArgs, printer_name)); | |
307 | |
308 client()->RemovePrinter(printer_name, helper.MockRemoveCallback(), | |
309 helper.MockErrorCallback()); | |
310 } | |
311 | |
312 } // namespace chromeos | |
OLD | NEW |