1 // Copyright 2013 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.
6 #include "base/location.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/single_thread_task_runner.h"
9 #include "chromeos/dbus/nfc_adapter_client.h"
10 #include "chromeos/dbus/nfc_client_helpers.h"
11 #include "chromeos/dbus/nfc_device_client.h"
12 #include "chromeos/dbus/nfc_manager_client.h"
13 #include "chromeos/dbus/nfc_record_client.h"
14 #include "chromeos/dbus/nfc_tag_client.h"
15 #include "dbus/mock_bus.h"
16 #include "dbus/mock_object_proxy.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
22 using ::testing::Invoke
;
23 using ::testing::Mock
;
24 using ::testing::Return
;
26 using chromeos::nfc_client_helpers::ObjectPathVector
;
32 // D-Bus service name used by the test.
33 const char kTestServiceName
[] = "test.service.name";
35 // Object paths that are used for testing.
36 const char kTestManagerPath
[] = "/test/nfc/manager";
37 const char kTestAdapterPath0
[] = "/test/nfc/adapter0";
38 const char kTestAdapterPath1
[] = "/test/nfc/adapter1";
39 const char kTestDevicePath0
[] = "/test/nfc/device0";
40 const char kTestDevicePath1
[] = "/test/nfc/device1";
41 const char kTestRecordPath0
[] = "/test/nfc/record0";
42 const char kTestRecordPath1
[] = "/test/nfc/record1";
43 const char kTestRecordPath2
[] = "/test/nfc/record2";
44 const char kTestRecordPath3
[] = "/test/nfc/record3";
45 const char kTestTagPath0
[] = "/test/nfc/tag0";
46 const char kTestTagPath1
[] = "/test/nfc/tag1";
48 class MockNfcManagerObserver
: public NfcManagerClient::Observer
{
50 MOCK_METHOD1(AdapterAdded
, void(const dbus::ObjectPath
&));
51 MOCK_METHOD1(AdapterRemoved
, void(const dbus::ObjectPath
&));
52 MOCK_METHOD1(ManagerPropertyChanged
, void(const std::string
&));
55 class MockNfcAdapterObserver
: public NfcAdapterClient::Observer
{
57 MOCK_METHOD1(AdapterAdded
, void(const dbus::ObjectPath
&));
58 MOCK_METHOD1(AdapterRemoved
, void(const dbus::ObjectPath
&));
59 MOCK_METHOD2(AdapterPropertyChanged
, void(const dbus::ObjectPath
&,
63 class MockNfcDeviceObserver
: public NfcDeviceClient::Observer
{
65 MOCK_METHOD1(DeviceAdded
, void(const dbus::ObjectPath
&));
66 MOCK_METHOD1(DeviceRemoved
, void(const dbus::ObjectPath
&));
67 MOCK_METHOD2(DevicePropertyChanged
, void(const dbus::ObjectPath
&,
71 class MockNfcRecordObserver
: public NfcRecordClient::Observer
{
73 MOCK_METHOD1(RecordAdded
, void(const dbus::ObjectPath
&));
74 MOCK_METHOD1(RecordRemoved
, void(const dbus::ObjectPath
&));
75 MOCK_METHOD2(RecordPropertyChanged
, void(const dbus::ObjectPath
&,
77 MOCK_METHOD1(RecordPropertiesReceived
, void(const dbus::ObjectPath
&));
80 class MockNfcTagObserver
: public NfcTagClient::Observer
{
82 MOCK_METHOD1(TagAdded
, void(const dbus::ObjectPath
&));
83 MOCK_METHOD1(TagRemoved
, void(const dbus::ObjectPath
&));
84 MOCK_METHOD2(TagPropertyChanged
, void(const dbus::ObjectPath
&,
90 class NfcClientTest
: public testing::Test
{
92 NfcClientTest() : response_(NULL
) {}
93 ~NfcClientTest() override
{}
95 void SetUp() override
{
96 // Create the mock bus.
97 dbus::Bus::Options options
;
98 options
.bus_type
= dbus::Bus::SYSTEM
;
99 mock_bus_
= new dbus::MockBus(options
);
101 // Create the mock proxies.
102 mock_manager_proxy_
= new dbus::MockObjectProxy(
105 dbus::ObjectPath(kTestManagerPath
));
106 mock_adapter0_proxy_
= new dbus::MockObjectProxy(
109 dbus::ObjectPath(kTestAdapterPath0
));
110 mock_adapter1_proxy_
= new dbus::MockObjectProxy(
113 dbus::ObjectPath(kTestAdapterPath1
));
114 mock_device0_proxy_
= new dbus::MockObjectProxy(
117 dbus::ObjectPath(kTestDevicePath0
));
118 mock_device1_proxy_
= new dbus::MockObjectProxy(
121 dbus::ObjectPath(kTestDevicePath1
));
122 mock_record0_proxy_
= new dbus::MockObjectProxy(
125 dbus::ObjectPath(kTestRecordPath0
));
126 mock_record1_proxy_
= new dbus::MockObjectProxy(
129 dbus::ObjectPath(kTestRecordPath1
));
130 mock_record2_proxy_
= new dbus::MockObjectProxy(
133 dbus::ObjectPath(kTestRecordPath2
));
134 mock_record3_proxy_
= new dbus::MockObjectProxy(
137 dbus::ObjectPath(kTestRecordPath3
));
138 mock_tag0_proxy_
= new dbus::MockObjectProxy(
141 dbus::ObjectPath(kTestTagPath0
));
142 mock_tag1_proxy_
= new dbus::MockObjectProxy(
145 dbus::ObjectPath(kTestTagPath1
));
147 // Set expectations that use NfcClientTest::OnConnectToSignal when the
148 // client connect signals on the mock proxies.
149 EXPECT_CALL(*mock_manager_proxy_
.get(), ConnectToSignal(_
, _
, _
, _
))
150 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal
));
151 EXPECT_CALL(*mock_adapter0_proxy_
.get(), ConnectToSignal(_
, _
, _
, _
))
152 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal
));
153 EXPECT_CALL(*mock_adapter1_proxy_
.get(), ConnectToSignal(_
, _
, _
, _
))
154 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal
));
156 // Set expectations that return our mock proxies on demand.
159 GetObjectProxy(nfc_manager::kNfcManagerServiceName
,
160 dbus::ObjectPath(nfc_manager::kNfcManagerServicePath
)))
161 .WillRepeatedly(Return(mock_manager_proxy_
.get()));
162 EXPECT_CALL(*mock_bus_
.get(),
163 GetObjectProxy(nfc_adapter::kNfcAdapterServiceName
,
164 dbus::ObjectPath(kTestAdapterPath0
)))
165 .WillRepeatedly(Return(mock_adapter0_proxy_
.get()));
166 EXPECT_CALL(*mock_bus_
.get(),
167 GetObjectProxy(nfc_adapter::kNfcAdapterServiceName
,
168 dbus::ObjectPath(kTestAdapterPath1
)))
169 .WillRepeatedly(Return(mock_adapter1_proxy_
.get()));
170 EXPECT_CALL(*mock_bus_
.get(),
171 GetObjectProxy(nfc_device::kNfcDeviceServiceName
,
172 dbus::ObjectPath(kTestDevicePath0
)))
173 .WillRepeatedly(Return(mock_device0_proxy_
.get()));
174 EXPECT_CALL(*mock_bus_
.get(),
175 GetObjectProxy(nfc_device::kNfcDeviceServiceName
,
176 dbus::ObjectPath(kTestDevicePath1
)))
177 .WillRepeatedly(Return(mock_device1_proxy_
.get()));
178 EXPECT_CALL(*mock_bus_
.get(),
179 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
180 dbus::ObjectPath(kTestRecordPath0
)))
181 .WillRepeatedly(Return(mock_record0_proxy_
.get()));
182 EXPECT_CALL(*mock_bus_
.get(),
183 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
184 dbus::ObjectPath(kTestRecordPath1
)))
185 .WillRepeatedly(Return(mock_record1_proxy_
.get()));
186 EXPECT_CALL(*mock_bus_
.get(),
187 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
188 dbus::ObjectPath(kTestRecordPath2
)))
189 .WillRepeatedly(Return(mock_record2_proxy_
.get()));
190 EXPECT_CALL(*mock_bus_
.get(),
191 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
192 dbus::ObjectPath(kTestRecordPath3
)))
193 .WillRepeatedly(Return(mock_record3_proxy_
.get()));
194 EXPECT_CALL(*mock_bus_
.get(),
195 GetObjectProxy(nfc_tag::kNfcTagServiceName
,
196 dbus::ObjectPath(kTestTagPath0
)))
197 .WillRepeatedly(Return(mock_tag0_proxy_
.get()));
198 EXPECT_CALL(*mock_bus_
.get(),
199 GetObjectProxy(nfc_tag::kNfcTagServiceName
,
200 dbus::ObjectPath(kTestTagPath1
)))
201 .WillRepeatedly(Return(mock_tag1_proxy_
.get()));
203 // ShutdownAndBlock will be called in TearDown.
204 EXPECT_CALL(*mock_bus_
.get(), ShutdownAndBlock()).WillOnce(Return());
206 // Create the clients.
207 manager_client_
.reset(NfcManagerClient::Create());
208 adapter_client_
.reset(NfcAdapterClient::Create(manager_client_
.get()));
209 device_client_
.reset(NfcDeviceClient::Create(adapter_client_
.get()));
210 tag_client_
.reset(NfcTagClient::Create(adapter_client_
.get()));
211 record_client_
.reset(
212 NfcRecordClient::Create(device_client_
.get(), tag_client_
.get()));
213 manager_client_
->Init(mock_bus_
.get());
214 adapter_client_
->Init(mock_bus_
.get());
215 device_client_
->Init(mock_bus_
.get());
216 tag_client_
->Init(mock_bus_
.get());
217 record_client_
->Init(mock_bus_
.get());
218 manager_client_
->AddObserver(&mock_manager_observer_
);
219 adapter_client_
->AddObserver(&mock_adapter_observer_
);
220 device_client_
->AddObserver(&mock_device_observer_
);
221 tag_client_
->AddObserver(&mock_tag_observer_
);
222 record_client_
->AddObserver(&mock_record_observer_
);
224 message_loop_
.RunUntilIdle();
227 void TearDown() override
{
228 tag_client_
->RemoveObserver(&mock_tag_observer_
);
229 device_client_
->RemoveObserver(&mock_device_observer_
);
230 adapter_client_
->RemoveObserver(&mock_adapter_observer_
);
231 manager_client_
->RemoveObserver(&mock_manager_observer_
);
232 mock_bus_
->ShutdownAndBlock();
235 void SimulateAdaptersChanged(
236 const ObjectPathVector
& adapter_paths
) {
237 NfcManagerClient::Properties
* properties
=
238 manager_client_
->GetProperties();
239 ASSERT_TRUE(properties
);
240 EXPECT_CALL(mock_manager_observer_
,
241 ManagerPropertyChanged(nfc_manager::kAdaptersProperty
));
242 SendArrayPropertyChangedSignal(
244 nfc_manager::kNfcManagerInterface
,
245 nfc_manager::kAdaptersProperty
,
247 Mock::VerifyAndClearExpectations(&mock_manager_observer_
);
250 void SimulateTagsChanged(const ObjectPathVector
& tag_paths
,
251 const dbus::ObjectPath
& adapter_path
) {
252 NfcAdapterClient::Properties
* properties
=
253 adapter_client_
->GetProperties(adapter_path
);
254 ASSERT_TRUE(properties
);
255 EXPECT_CALL(mock_adapter_observer_
,
256 AdapterPropertyChanged(adapter_path
,
257 nfc_adapter::kTagsProperty
));
258 SendArrayPropertyChangedSignal(
260 nfc_adapter::kNfcAdapterInterface
,
261 nfc_adapter::kTagsProperty
,
263 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
266 void SimulateDevicesChanged(const ObjectPathVector
& device_paths
,
267 const dbus::ObjectPath
& adapter_path
) {
268 NfcAdapterClient::Properties
* properties
=
269 adapter_client_
->GetProperties(adapter_path
);
270 ASSERT_TRUE(properties
);
271 EXPECT_CALL(mock_adapter_observer_
,
272 AdapterPropertyChanged(adapter_path
,
273 nfc_adapter::kDevicesProperty
));
274 SendArrayPropertyChangedSignal(
276 nfc_adapter::kNfcAdapterInterface
,
277 nfc_adapter::kDevicesProperty
,
279 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
282 void SimulateDeviceRecordsChanged(
283 const ObjectPathVector
& record_paths
,
284 const dbus::ObjectPath
& device_path
) {
285 NfcDeviceClient::Properties
* properties
=
286 device_client_
->GetProperties(device_path
);
287 ASSERT_TRUE(properties
);
288 EXPECT_CALL(mock_device_observer_
,
289 DevicePropertyChanged(device_path
,
290 nfc_device::kRecordsProperty
));
291 SendArrayPropertyChangedSignal(
293 nfc_device::kNfcDeviceInterface
,
294 nfc_device::kRecordsProperty
,
296 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
299 void SimulateTagRecordsChanged(
300 const ObjectPathVector
& record_paths
,
301 const dbus::ObjectPath
& tag_path
) {
302 NfcTagClient::Properties
* properties
=
303 tag_client_
->GetProperties(tag_path
);
304 ASSERT_TRUE(properties
);
305 EXPECT_CALL(mock_tag_observer_
,
306 TagPropertyChanged(tag_path
,
307 nfc_tag::kRecordsProperty
));
308 SendArrayPropertyChangedSignal(
310 nfc_tag::kNfcTagInterface
,
311 nfc_tag::kRecordsProperty
,
313 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
316 void SendArrayPropertyChangedSignal(
317 dbus::PropertySet
* properties
,
318 const std::string
& interface
,
319 const std::string
& property_name
,
320 ObjectPathVector object_paths
) {
321 dbus::Signal
signal(interface
, nfc_common::kPropertyChangedSignal
);
322 dbus::MessageWriter
writer(&signal
);
323 writer
.AppendString(property_name
);
324 dbus::MessageWriter
variant_writer(NULL
);
325 writer
.OpenVariant("ao", &variant_writer
);
326 variant_writer
.AppendArrayOfObjectPaths(object_paths
);
327 writer
.CloseContainer(&variant_writer
);
328 properties
->ChangedReceived(&signal
);
331 MOCK_METHOD0(SuccessCallback
, void(void));
332 MOCK_METHOD2(ErrorCallback
, void(const std::string
& error_name
,
333 const std::string
& error_message
));
336 // The mock object proxies.
337 scoped_refptr
<dbus::MockObjectProxy
> mock_manager_proxy_
;
338 scoped_refptr
<dbus::MockObjectProxy
> mock_adapter0_proxy_
;
339 scoped_refptr
<dbus::MockObjectProxy
> mock_adapter1_proxy_
;
340 scoped_refptr
<dbus::MockObjectProxy
> mock_device0_proxy_
;
341 scoped_refptr
<dbus::MockObjectProxy
> mock_device1_proxy_
;
342 scoped_refptr
<dbus::MockObjectProxy
> mock_record0_proxy_
;
343 scoped_refptr
<dbus::MockObjectProxy
> mock_record1_proxy_
;
344 scoped_refptr
<dbus::MockObjectProxy
> mock_record2_proxy_
;
345 scoped_refptr
<dbus::MockObjectProxy
> mock_record3_proxy_
;
346 scoped_refptr
<dbus::MockObjectProxy
> mock_tag0_proxy_
;
347 scoped_refptr
<dbus::MockObjectProxy
> mock_tag1_proxy_
;
349 scoped_refptr
<dbus::MockBus
> mock_bus_
;
350 // A message loop to emulate asynchronous behavior.
351 base::MessageLoop message_loop_
;
352 // Response returned by mock methods.
353 dbus::Response
* response_
;
354 // The D-Bus client objects under test.
355 scoped_ptr
<NfcManagerClient
> manager_client_
;
356 scoped_ptr
<NfcAdapterClient
> adapter_client_
;
357 scoped_ptr
<NfcDeviceClient
> device_client_
;
358 scoped_ptr
<NfcTagClient
> tag_client_
;
359 scoped_ptr
<NfcRecordClient
> record_client_
;
361 MockNfcManagerObserver mock_manager_observer_
;
362 MockNfcAdapterObserver mock_adapter_observer_
;
363 MockNfcDeviceObserver mock_device_observer_
;
364 MockNfcTagObserver mock_tag_observer_
;
365 MockNfcRecordObserver mock_record_observer_
;
366 // The signal callbacks used to simulate asychronous signals.
367 dbus::ObjectProxy::SignalCallback manager_adapter_added_signal_callback_
;
368 dbus::ObjectProxy::SignalCallback manager_adapter_removed_signal_callback_
;
371 // Used to implement the mock proxy.
372 void OnConnectToSignal(
373 const std::string
& interface_name
,
374 const std::string
& signal_name
,
375 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
376 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
377 if (interface_name
== nfc_manager::kNfcManagerInterface
) {
378 if (signal_name
== nfc_manager::kAdapterAddedSignal
)
379 manager_adapter_added_signal_callback_
= signal_callback
;
380 else if (signal_name
== nfc_manager::kAdapterRemovedSignal
)
381 manager_adapter_removed_signal_callback_
= signal_callback
;
383 message_loop_
.task_runner()->PostTask(
385 base::Bind(on_connected_callback
, interface_name
, signal_name
, true));
389 // Tests that when adapters are added and removed through the manager, all
390 // observers are notified and the proxies are created and removed
392 TEST_F(NfcClientTest
, AdaptersAddedAndRemoved
) {
393 // Invoking methods on adapters that haven't been added should fail.
395 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
396 adapter_client_
->StartPollLoop(
397 dbus::ObjectPath(kTestAdapterPath0
),
398 nfc_adapter::kModeInitiator
,
399 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
400 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
401 Mock::VerifyAndClearExpectations(this);
404 ObjectPathVector adapter_paths
;
405 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
406 EXPECT_CALL(mock_adapter_observer_
,
407 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
408 SimulateAdaptersChanged(adapter_paths
);
410 // Invoking methods should succeed on adapter 0 but fail on adapter 1.
411 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
412 adapter_client_
->StartPollLoop(
413 dbus::ObjectPath(kTestAdapterPath0
),
414 nfc_adapter::kModeInitiator
,
415 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
416 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
417 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_
);
419 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
420 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
422 adapter_client_
->StartPollLoop(
423 dbus::ObjectPath(kTestAdapterPath1
),
424 nfc_adapter::kModeInitiator
,
425 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
426 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
427 Mock::VerifyAndClearExpectations(this);
428 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_
);
431 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath1
));
432 EXPECT_CALL(mock_adapter_observer_
,
433 AdapterAdded(dbus::ObjectPath(kTestAdapterPath1
)));
434 SimulateAdaptersChanged(adapter_paths
);
436 // Invoking methods should succeed on both adapters.
437 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
438 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
439 adapter_client_
->StartPollLoop(
440 dbus::ObjectPath(kTestAdapterPath0
),
441 nfc_adapter::kModeInitiator
,
442 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
443 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
444 adapter_client_
->StartPollLoop(
445 dbus::ObjectPath(kTestAdapterPath1
),
446 nfc_adapter::kModeInitiator
,
447 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
448 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
449 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_
);
450 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_
);
453 adapter_paths
.erase(adapter_paths
.begin());
454 EXPECT_CALL(mock_adapter_observer_
,
455 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0
)));
456 SimulateAdaptersChanged(adapter_paths
);
458 // Invoking methods should succeed on adapter 1 but fail on adapter 0.
460 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
461 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
463 adapter_client_
->StartPollLoop(
464 dbus::ObjectPath(kTestAdapterPath0
),
465 nfc_adapter::kModeInitiator
,
466 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
467 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
468 Mock::VerifyAndClearExpectations(this);
470 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
471 adapter_client_
->StartPollLoop(
472 dbus::ObjectPath(kTestAdapterPath1
),
473 nfc_adapter::kModeInitiator
,
474 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
475 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
476 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_
);
477 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_
);
480 adapter_paths
.clear();
481 EXPECT_CALL(mock_adapter_observer_
,
482 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1
)));
483 SimulateAdaptersChanged(adapter_paths
);
485 // Invoking methods should fail on both adapters.
487 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
))
489 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
491 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
493 adapter_client_
->StartPollLoop(
494 dbus::ObjectPath(kTestAdapterPath0
),
495 nfc_adapter::kModeInitiator
,
496 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
497 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
498 adapter_client_
->StartPollLoop(
499 dbus::ObjectPath(kTestAdapterPath1
),
500 nfc_adapter::kModeInitiator
,
501 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
502 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
505 // Tests that when tags are added and removed through an adapter, all
506 // observers are notified and the proxies are created and removed
508 TEST_F(NfcClientTest
, TagsAddedAndRemoved
) {
509 // Invoking methods on tags that haven't been added should fail.
511 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
512 base::DictionaryValue write_data
;
513 write_data
.SetString(nfc_record::kTypeProperty
, nfc_record::kTypeText
);
514 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
515 base::Bind(&NfcClientTest::SuccessCallback
,
516 base::Unretained(this)),
517 base::Bind(&NfcClientTest::ErrorCallback
,
518 base::Unretained(this)));
519 Mock::VerifyAndClearExpectations(this);
522 ObjectPathVector adapter_paths
;
523 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
524 EXPECT_CALL(mock_adapter_observer_
,
525 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
526 SimulateAdaptersChanged(adapter_paths
);
527 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
530 ObjectPathVector tag_paths
;
531 tag_paths
.push_back(dbus::ObjectPath(kTestTagPath0
));
532 EXPECT_CALL(mock_tag_observer_
,
533 TagAdded(dbus::ObjectPath(kTestTagPath0
)));
534 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
535 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
537 // Invoking methods should succeed on tag 0 but fail on tag 1.
538 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
539 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
540 base::Bind(&NfcClientTest::SuccessCallback
,
541 base::Unretained(this)),
542 base::Bind(&NfcClientTest::ErrorCallback
,
543 base::Unretained(this)));
544 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_
);
546 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
547 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
549 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
550 base::Bind(&NfcClientTest::SuccessCallback
,
551 base::Unretained(this)),
552 base::Bind(&NfcClientTest::ErrorCallback
,
553 base::Unretained(this)));
554 Mock::VerifyAndClearExpectations(this);
555 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_
);
558 tag_paths
.push_back(dbus::ObjectPath(kTestTagPath1
));
559 EXPECT_CALL(mock_tag_observer_
,
560 TagAdded(dbus::ObjectPath(kTestTagPath1
)));
561 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
562 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
564 // Invoking methods should succeed on both tags.
565 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
566 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
567 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
568 base::Bind(&NfcClientTest::SuccessCallback
,
569 base::Unretained(this)),
570 base::Bind(&NfcClientTest::ErrorCallback
,
571 base::Unretained(this)));
572 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
573 base::Bind(&NfcClientTest::SuccessCallback
,
574 base::Unretained(this)),
575 base::Bind(&NfcClientTest::ErrorCallback
,
576 base::Unretained(this)));
577 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_
);
578 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_
);
581 tag_paths
.erase(tag_paths
.begin());
582 EXPECT_CALL(mock_tag_observer_
,
583 TagRemoved(dbus::ObjectPath(kTestTagPath0
)));
584 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
585 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
587 // Invoking methods should succeed on tag 1 but fail on tag 0.
589 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
590 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
592 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
593 base::Bind(&NfcClientTest::SuccessCallback
,
594 base::Unretained(this)),
595 base::Bind(&NfcClientTest::ErrorCallback
,
596 base::Unretained(this)));
597 Mock::VerifyAndClearExpectations(this);
598 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_
);
599 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
600 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
601 base::Bind(&NfcClientTest::SuccessCallback
,
602 base::Unretained(this)),
603 base::Bind(&NfcClientTest::ErrorCallback
,
604 base::Unretained(this)));
605 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_
);
609 EXPECT_CALL(mock_tag_observer_
,
610 TagRemoved(dbus::ObjectPath(kTestTagPath1
)));
611 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
612 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
614 // Invoking methods should fail on both tags.
616 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
))
618 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
620 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
622 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
623 base::Bind(&NfcClientTest::SuccessCallback
,
624 base::Unretained(this)),
625 base::Bind(&NfcClientTest::ErrorCallback
,
626 base::Unretained(this)));
627 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
628 base::Bind(&NfcClientTest::SuccessCallback
,
629 base::Unretained(this)),
630 base::Bind(&NfcClientTest::ErrorCallback
,
631 base::Unretained(this)));
634 // Tests that when devices are added and removed through an adapter, all
635 // observers are notified and the proxies are created and removed
637 TEST_F(NfcClientTest
, DevicesAddedAndRemoved
) {
638 // Invoking methods on devices that haven't been added should fail.
640 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
641 base::DictionaryValue write_data
;
642 write_data
.SetString(nfc_record::kTypeProperty
, nfc_record::kTypeText
);
643 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
644 base::Bind(&NfcClientTest::SuccessCallback
,
645 base::Unretained(this)),
646 base::Bind(&NfcClientTest::ErrorCallback
,
647 base::Unretained(this)));
648 Mock::VerifyAndClearExpectations(this);
651 ObjectPathVector adapter_paths
;
652 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
653 EXPECT_CALL(mock_adapter_observer_
,
654 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
655 SimulateAdaptersChanged(adapter_paths
);
658 ObjectPathVector device_paths
;
659 device_paths
.push_back(dbus::ObjectPath(kTestDevicePath0
));
660 EXPECT_CALL(mock_device_observer_
,
661 DeviceAdded(dbus::ObjectPath(kTestDevicePath0
)));
662 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
663 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
665 // Invoking methods should succeed on device 0 but fail on device 1.
666 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
667 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
668 base::Bind(&NfcClientTest::SuccessCallback
,
669 base::Unretained(this)),
670 base::Bind(&NfcClientTest::ErrorCallback
,
671 base::Unretained(this)));
672 Mock::VerifyAndClearExpectations(&mock_device0_proxy_
);
674 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
675 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
677 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
678 base::Bind(&NfcClientTest::SuccessCallback
,
679 base::Unretained(this)),
680 base::Bind(&NfcClientTest::ErrorCallback
,
681 base::Unretained(this)));
682 Mock::VerifyAndClearExpectations(this);
683 Mock::VerifyAndClearExpectations(&mock_device1_proxy_
);
686 device_paths
.push_back(dbus::ObjectPath(kTestDevicePath1
));
687 EXPECT_CALL(mock_device_observer_
,
688 DeviceAdded(dbus::ObjectPath(kTestDevicePath1
)));
689 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
690 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
692 // Invoking methods should succeed on both devices.
693 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
694 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
695 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
696 base::Bind(&NfcClientTest::SuccessCallback
,
697 base::Unretained(this)),
698 base::Bind(&NfcClientTest::ErrorCallback
,
699 base::Unretained(this)));
700 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
701 base::Bind(&NfcClientTest::SuccessCallback
,
702 base::Unretained(this)),
703 base::Bind(&NfcClientTest::ErrorCallback
,
704 base::Unretained(this)));
705 Mock::VerifyAndClearExpectations(&mock_device0_proxy_
);
706 Mock::VerifyAndClearExpectations(&mock_device1_proxy_
);
709 device_paths
.erase(device_paths
.begin());
710 EXPECT_CALL(mock_device_observer_
,
711 DeviceRemoved(dbus::ObjectPath(kTestDevicePath0
)));
712 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
713 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
715 // Invoking methods should succeed on device 1 but fail on device 0.
717 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
718 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
720 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
721 base::Bind(&NfcClientTest::SuccessCallback
,
722 base::Unretained(this)),
723 base::Bind(&NfcClientTest::ErrorCallback
,
724 base::Unretained(this)));
725 Mock::VerifyAndClearExpectations(this);
726 Mock::VerifyAndClearExpectations(&mock_device0_proxy_
);
727 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
728 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
729 base::Bind(&NfcClientTest::SuccessCallback
,
730 base::Unretained(this)),
731 base::Bind(&NfcClientTest::ErrorCallback
,
732 base::Unretained(this)));
733 Mock::VerifyAndClearExpectations(&mock_device1_proxy_
);
736 device_paths
.clear();
737 EXPECT_CALL(mock_device_observer_
,
738 DeviceRemoved(dbus::ObjectPath(kTestDevicePath1
)));
739 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
740 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
742 // Invoking methods should fail on both devices.
744 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
))
746 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
748 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
750 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
751 base::Bind(&NfcClientTest::SuccessCallback
,
752 base::Unretained(this)),
753 base::Bind(&NfcClientTest::ErrorCallback
,
754 base::Unretained(this)));
755 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
756 base::Bind(&NfcClientTest::SuccessCallback
,
757 base::Unretained(this)),
758 base::Bind(&NfcClientTest::ErrorCallback
,
759 base::Unretained(this)));
762 TEST_F(NfcClientTest
, ObjectCleanup
) {
763 // Tests that when an adapter gets removed, proxies that belong to the
764 // adapter, device, tag, and record hierarchy get cleaned up properly.
765 ObjectPathVector object_paths
;
768 EXPECT_CALL(mock_adapter_observer_
,
769 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
770 EXPECT_CALL(mock_adapter_observer_
,
771 AdapterAdded(dbus::ObjectPath(kTestAdapterPath1
)));
772 object_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
773 object_paths
.push_back(dbus::ObjectPath(kTestAdapterPath1
));
774 SimulateAdaptersChanged(object_paths
);
775 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
777 // Add devices and a tags. Assign them like the following:
778 // - device 0 -> adapter 0
779 // - tag 0 -> adapter 0
780 // - device 1 -> adapter 1
781 // - tag 1 -> adapter 1
782 EXPECT_CALL(mock_device_observer_
,
783 DeviceAdded(dbus::ObjectPath(kTestDevicePath0
)));
784 EXPECT_CALL(mock_device_observer_
,
785 DeviceAdded(dbus::ObjectPath(kTestDevicePath1
)));
786 EXPECT_CALL(mock_tag_observer_
,
787 TagAdded(dbus::ObjectPath(kTestTagPath0
)));
788 EXPECT_CALL(mock_tag_observer_
,
789 TagAdded(dbus::ObjectPath(kTestTagPath1
)));
790 object_paths
.clear();
791 object_paths
.push_back(dbus::ObjectPath(kTestDevicePath0
));
792 SimulateDevicesChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath0
));
793 object_paths
.clear();
794 object_paths
.push_back(dbus::ObjectPath(kTestTagPath0
));
795 SimulateTagsChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath0
));
796 object_paths
.clear();
797 object_paths
.push_back(dbus::ObjectPath(kTestDevicePath1
));
798 SimulateDevicesChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath1
));
799 object_paths
.clear();
800 object_paths
.push_back(dbus::ObjectPath(kTestTagPath1
));
801 SimulateTagsChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath1
));
802 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
803 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
805 // Add records. Assign them like the following:
806 // - record 0 -> device 0
807 // - record 1 -> tag 0
808 // - record 2 -> device 1
809 // - record 3 -> tag 1
810 EXPECT_CALL(mock_record_observer_
,
811 RecordAdded(dbus::ObjectPath(kTestRecordPath0
)));
812 EXPECT_CALL(mock_record_observer_
,
813 RecordAdded(dbus::ObjectPath(kTestRecordPath1
)));
814 EXPECT_CALL(mock_record_observer_
,
815 RecordAdded(dbus::ObjectPath(kTestRecordPath2
)));
816 EXPECT_CALL(mock_record_observer_
,
817 RecordAdded(dbus::ObjectPath(kTestRecordPath3
)));
818 object_paths
.clear();
819 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath0
));
820 SimulateDeviceRecordsChanged(object_paths
,
821 dbus::ObjectPath(kTestDevicePath0
));
822 object_paths
.clear();
823 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath1
));
824 SimulateTagRecordsChanged(object_paths
,
825 dbus::ObjectPath(kTestTagPath0
));
826 object_paths
.clear();
827 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath2
));
828 SimulateDeviceRecordsChanged(object_paths
,
829 dbus::ObjectPath(kTestDevicePath1
));
830 object_paths
.clear();
831 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath3
));
832 SimulateTagRecordsChanged(object_paths
,
833 dbus::ObjectPath(kTestTagPath1
));
834 Mock::VerifyAndClearExpectations(&mock_record_observer_
);
836 // Check that the records have been assigned to the correct device or tag.
837 NfcTagClient::Properties
* tag_properties
=
838 tag_client_
->GetProperties(dbus::ObjectPath(kTestTagPath0
));
839 EXPECT_EQ((size_t)1, tag_properties
->records
.value().size());
840 EXPECT_EQ(dbus::ObjectPath(kTestRecordPath1
),
841 tag_properties
->records
.value()[0]);
842 NfcDeviceClient::Properties
* device_properties
=
843 device_client_
->GetProperties(dbus::ObjectPath(kTestDevicePath0
));
844 EXPECT_EQ((size_t)1, device_properties
->records
.value().size());
845 EXPECT_EQ(dbus::ObjectPath(kTestRecordPath0
),
846 device_properties
->records
.value()[0]);
848 // Remove adapter 0. Make sure that all of the tag, device, and records that
849 // are in the adapter 0 hierarchy are removed.
850 object_paths
.clear();
851 object_paths
.push_back(dbus::ObjectPath(kTestAdapterPath1
));
852 EXPECT_CALL(mock_adapter_observer_
,
853 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0
)));
854 EXPECT_CALL(mock_device_observer_
,
855 DeviceRemoved(dbus::ObjectPath(kTestDevicePath0
)));
856 EXPECT_CALL(mock_tag_observer_
,
857 TagRemoved(dbus::ObjectPath(kTestTagPath0
)));
858 EXPECT_CALL(mock_record_observer_
,
859 RecordRemoved(dbus::ObjectPath(kTestRecordPath0
)));
860 EXPECT_CALL(mock_record_observer_
,
861 RecordRemoved(dbus::ObjectPath(kTestRecordPath1
)));
862 SimulateAdaptersChanged(object_paths
);
863 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
864 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
865 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
866 Mock::VerifyAndClearExpectations(&mock_record_observer_
);
869 object_paths
.clear();
870 EXPECT_CALL(mock_adapter_observer_
,
871 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1
)));
872 EXPECT_CALL(mock_device_observer_
,
873 DeviceRemoved(dbus::ObjectPath(kTestDevicePath1
)));
874 EXPECT_CALL(mock_tag_observer_
,
875 TagRemoved(dbus::ObjectPath(kTestTagPath1
)));
876 EXPECT_CALL(mock_record_observer_
,
877 RecordRemoved(dbus::ObjectPath(kTestRecordPath2
)));
878 EXPECT_CALL(mock_record_observer_
,
879 RecordRemoved(dbus::ObjectPath(kTestRecordPath3
)));
880 SimulateAdaptersChanged(object_paths
);
883 } // namespace chromeos