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/message_loop/message_loop.h"
7 #include "chromeos/dbus/nfc_adapter_client.h"
8 #include "chromeos/dbus/nfc_client_helpers.h"
9 #include "chromeos/dbus/nfc_device_client.h"
10 #include "chromeos/dbus/nfc_manager_client.h"
11 #include "chromeos/dbus/nfc_record_client.h"
12 #include "chromeos/dbus/nfc_tag_client.h"
13 #include "dbus/mock_bus.h"
14 #include "dbus/mock_object_proxy.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/cros_system_api/dbus/service_constants.h"
20 using ::testing::Invoke
;
21 using ::testing::Mock
;
22 using ::testing::Return
;
24 using chromeos::nfc_client_helpers::ObjectPathVector
;
30 // D-Bus service name used by the test.
31 const char kTestServiceName
[] = "test.service.name";
33 // Object paths that are used for testing.
34 const char kTestManagerPath
[] = "/test/nfc/manager";
35 const char kTestAdapterPath0
[] = "/test/nfc/adapter0";
36 const char kTestAdapterPath1
[] = "/test/nfc/adapter1";
37 const char kTestDevicePath0
[] = "/test/nfc/device0";
38 const char kTestDevicePath1
[] = "/test/nfc/device1";
39 const char kTestRecordPath0
[] = "/test/nfc/record0";
40 const char kTestRecordPath1
[] = "/test/nfc/record1";
41 const char kTestRecordPath2
[] = "/test/nfc/record2";
42 const char kTestRecordPath3
[] = "/test/nfc/record3";
43 const char kTestTagPath0
[] = "/test/nfc/tag0";
44 const char kTestTagPath1
[] = "/test/nfc/tag1";
46 class MockNfcManagerObserver
: public NfcManagerClient::Observer
{
48 MOCK_METHOD1(AdapterAdded
, void(const dbus::ObjectPath
&));
49 MOCK_METHOD1(AdapterRemoved
, void(const dbus::ObjectPath
&));
50 MOCK_METHOD1(ManagerPropertyChanged
, void(const std::string
&));
53 class MockNfcAdapterObserver
: public NfcAdapterClient::Observer
{
55 MOCK_METHOD1(AdapterAdded
, void(const dbus::ObjectPath
&));
56 MOCK_METHOD1(AdapterRemoved
, void(const dbus::ObjectPath
&));
57 MOCK_METHOD2(AdapterPropertyChanged
, void(const dbus::ObjectPath
&,
61 class MockNfcDeviceObserver
: public NfcDeviceClient::Observer
{
63 MOCK_METHOD1(DeviceAdded
, void(const dbus::ObjectPath
&));
64 MOCK_METHOD1(DeviceRemoved
, void(const dbus::ObjectPath
&));
65 MOCK_METHOD2(DevicePropertyChanged
, void(const dbus::ObjectPath
&,
69 class MockNfcRecordObserver
: public NfcRecordClient::Observer
{
71 MOCK_METHOD1(RecordAdded
, void(const dbus::ObjectPath
&));
72 MOCK_METHOD1(RecordRemoved
, void(const dbus::ObjectPath
&));
73 MOCK_METHOD2(RecordPropertyChanged
, void(const dbus::ObjectPath
&,
75 MOCK_METHOD1(RecordPropertiesReceived
, void(const dbus::ObjectPath
&));
78 class MockNfcTagObserver
: public NfcTagClient::Observer
{
80 MOCK_METHOD1(TagAdded
, void(const dbus::ObjectPath
&));
81 MOCK_METHOD1(TagRemoved
, void(const dbus::ObjectPath
&));
82 MOCK_METHOD2(TagPropertyChanged
, void(const dbus::ObjectPath
&,
88 class NfcClientTest
: public testing::Test
{
90 NfcClientTest() : response_(NULL
) {}
91 virtual ~NfcClientTest() {}
93 virtual void SetUp() OVERRIDE
{
94 // Create the mock bus.
95 dbus::Bus::Options options
;
96 options
.bus_type
= dbus::Bus::SYSTEM
;
97 mock_bus_
= new dbus::MockBus(options
);
99 // Create the mock proxies.
100 mock_manager_proxy_
= new dbus::MockObjectProxy(
103 dbus::ObjectPath(kTestManagerPath
));
104 mock_adapter0_proxy_
= new dbus::MockObjectProxy(
107 dbus::ObjectPath(kTestAdapterPath0
));
108 mock_adapter1_proxy_
= new dbus::MockObjectProxy(
111 dbus::ObjectPath(kTestAdapterPath1
));
112 mock_device0_proxy_
= new dbus::MockObjectProxy(
115 dbus::ObjectPath(kTestDevicePath0
));
116 mock_device1_proxy_
= new dbus::MockObjectProxy(
119 dbus::ObjectPath(kTestDevicePath1
));
120 mock_record0_proxy_
= new dbus::MockObjectProxy(
123 dbus::ObjectPath(kTestRecordPath0
));
124 mock_record1_proxy_
= new dbus::MockObjectProxy(
127 dbus::ObjectPath(kTestRecordPath1
));
128 mock_record2_proxy_
= new dbus::MockObjectProxy(
131 dbus::ObjectPath(kTestRecordPath2
));
132 mock_record3_proxy_
= new dbus::MockObjectProxy(
135 dbus::ObjectPath(kTestRecordPath3
));
136 mock_tag0_proxy_
= new dbus::MockObjectProxy(
139 dbus::ObjectPath(kTestTagPath0
));
140 mock_tag1_proxy_
= new dbus::MockObjectProxy(
143 dbus::ObjectPath(kTestTagPath1
));
145 // Set expectations that use NfcClientTest::OnConnectToSignal when the
146 // client connect signals on the mock proxies.
147 EXPECT_CALL(*mock_manager_proxy_
.get(), ConnectToSignal(_
, _
, _
, _
))
148 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal
));
149 EXPECT_CALL(*mock_adapter0_proxy_
.get(), ConnectToSignal(_
, _
, _
, _
))
150 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal
));
151 EXPECT_CALL(*mock_adapter1_proxy_
.get(), ConnectToSignal(_
, _
, _
, _
))
152 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal
));
154 // Set expectations that return our mock proxies on demand.
157 GetObjectProxy(nfc_manager::kNfcManagerServiceName
,
158 dbus::ObjectPath(nfc_manager::kNfcManagerServicePath
)))
159 .WillRepeatedly(Return(mock_manager_proxy_
.get()));
160 EXPECT_CALL(*mock_bus_
.get(),
161 GetObjectProxy(nfc_adapter::kNfcAdapterServiceName
,
162 dbus::ObjectPath(kTestAdapterPath0
)))
163 .WillRepeatedly(Return(mock_adapter0_proxy_
.get()));
164 EXPECT_CALL(*mock_bus_
.get(),
165 GetObjectProxy(nfc_adapter::kNfcAdapterServiceName
,
166 dbus::ObjectPath(kTestAdapterPath1
)))
167 .WillRepeatedly(Return(mock_adapter1_proxy_
.get()));
168 EXPECT_CALL(*mock_bus_
.get(),
169 GetObjectProxy(nfc_device::kNfcDeviceServiceName
,
170 dbus::ObjectPath(kTestDevicePath0
)))
171 .WillRepeatedly(Return(mock_device0_proxy_
.get()));
172 EXPECT_CALL(*mock_bus_
.get(),
173 GetObjectProxy(nfc_device::kNfcDeviceServiceName
,
174 dbus::ObjectPath(kTestDevicePath1
)))
175 .WillRepeatedly(Return(mock_device1_proxy_
.get()));
176 EXPECT_CALL(*mock_bus_
.get(),
177 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
178 dbus::ObjectPath(kTestRecordPath0
)))
179 .WillRepeatedly(Return(mock_record0_proxy_
.get()));
180 EXPECT_CALL(*mock_bus_
.get(),
181 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
182 dbus::ObjectPath(kTestRecordPath1
)))
183 .WillRepeatedly(Return(mock_record1_proxy_
.get()));
184 EXPECT_CALL(*mock_bus_
.get(),
185 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
186 dbus::ObjectPath(kTestRecordPath2
)))
187 .WillRepeatedly(Return(mock_record2_proxy_
.get()));
188 EXPECT_CALL(*mock_bus_
.get(),
189 GetObjectProxy(nfc_record::kNfcRecordServiceName
,
190 dbus::ObjectPath(kTestRecordPath3
)))
191 .WillRepeatedly(Return(mock_record3_proxy_
.get()));
192 EXPECT_CALL(*mock_bus_
.get(),
193 GetObjectProxy(nfc_tag::kNfcTagServiceName
,
194 dbus::ObjectPath(kTestTagPath0
)))
195 .WillRepeatedly(Return(mock_tag0_proxy_
.get()));
196 EXPECT_CALL(*mock_bus_
.get(),
197 GetObjectProxy(nfc_tag::kNfcTagServiceName
,
198 dbus::ObjectPath(kTestTagPath1
)))
199 .WillRepeatedly(Return(mock_tag1_proxy_
.get()));
201 // ShutdownAndBlock will be called in TearDown.
202 EXPECT_CALL(*mock_bus_
.get(), ShutdownAndBlock()).WillOnce(Return());
204 // Create the clients.
205 manager_client_
.reset(NfcManagerClient::Create());
206 adapter_client_
.reset(NfcAdapterClient::Create(manager_client_
.get()));
207 device_client_
.reset(NfcDeviceClient::Create(adapter_client_
.get()));
208 tag_client_
.reset(NfcTagClient::Create(adapter_client_
.get()));
209 record_client_
.reset(
210 NfcRecordClient::Create(device_client_
.get(), tag_client_
.get()));
211 manager_client_
->Init(mock_bus_
.get());
212 adapter_client_
->Init(mock_bus_
.get());
213 device_client_
->Init(mock_bus_
.get());
214 tag_client_
->Init(mock_bus_
.get());
215 record_client_
->Init(mock_bus_
.get());
216 manager_client_
->AddObserver(&mock_manager_observer_
);
217 adapter_client_
->AddObserver(&mock_adapter_observer_
);
218 device_client_
->AddObserver(&mock_device_observer_
);
219 tag_client_
->AddObserver(&mock_tag_observer_
);
220 record_client_
->AddObserver(&mock_record_observer_
);
222 message_loop_
.RunUntilIdle();
225 virtual void TearDown() OVERRIDE
{
226 tag_client_
->RemoveObserver(&mock_tag_observer_
);
227 device_client_
->RemoveObserver(&mock_device_observer_
);
228 adapter_client_
->RemoveObserver(&mock_adapter_observer_
);
229 manager_client_
->RemoveObserver(&mock_manager_observer_
);
230 mock_bus_
->ShutdownAndBlock();
233 void SimulateAdaptersChanged(
234 const ObjectPathVector
& adapter_paths
) {
235 NfcManagerClient::Properties
* properties
=
236 manager_client_
->GetProperties();
237 ASSERT_TRUE(properties
);
238 EXPECT_CALL(mock_manager_observer_
,
239 ManagerPropertyChanged(nfc_manager::kAdaptersProperty
));
240 SendArrayPropertyChangedSignal(
242 nfc_manager::kNfcManagerInterface
,
243 nfc_manager::kAdaptersProperty
,
245 Mock::VerifyAndClearExpectations(&mock_manager_observer_
);
248 void SimulateTagsChanged(const ObjectPathVector
& tag_paths
,
249 const dbus::ObjectPath
& adapter_path
) {
250 NfcAdapterClient::Properties
* properties
=
251 adapter_client_
->GetProperties(adapter_path
);
252 ASSERT_TRUE(properties
);
253 EXPECT_CALL(mock_adapter_observer_
,
254 AdapterPropertyChanged(adapter_path
,
255 nfc_adapter::kTagsProperty
));
256 SendArrayPropertyChangedSignal(
258 nfc_adapter::kNfcAdapterInterface
,
259 nfc_adapter::kTagsProperty
,
261 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
264 void SimulateDevicesChanged(const ObjectPathVector
& device_paths
,
265 const dbus::ObjectPath
& adapter_path
) {
266 NfcAdapterClient::Properties
* properties
=
267 adapter_client_
->GetProperties(adapter_path
);
268 ASSERT_TRUE(properties
);
269 EXPECT_CALL(mock_adapter_observer_
,
270 AdapterPropertyChanged(adapter_path
,
271 nfc_adapter::kDevicesProperty
));
272 SendArrayPropertyChangedSignal(
274 nfc_adapter::kNfcAdapterInterface
,
275 nfc_adapter::kDevicesProperty
,
277 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
280 void SimulateDeviceRecordsChanged(
281 const ObjectPathVector
& record_paths
,
282 const dbus::ObjectPath
& device_path
) {
283 NfcDeviceClient::Properties
* properties
=
284 device_client_
->GetProperties(device_path
);
285 ASSERT_TRUE(properties
);
286 EXPECT_CALL(mock_device_observer_
,
287 DevicePropertyChanged(device_path
,
288 nfc_device::kRecordsProperty
));
289 SendArrayPropertyChangedSignal(
291 nfc_device::kNfcDeviceInterface
,
292 nfc_device::kRecordsProperty
,
294 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
297 void SimulateTagRecordsChanged(
298 const ObjectPathVector
& record_paths
,
299 const dbus::ObjectPath
& tag_path
) {
300 NfcTagClient::Properties
* properties
=
301 tag_client_
->GetProperties(tag_path
);
302 ASSERT_TRUE(properties
);
303 EXPECT_CALL(mock_tag_observer_
,
304 TagPropertyChanged(tag_path
,
305 nfc_tag::kRecordsProperty
));
306 SendArrayPropertyChangedSignal(
308 nfc_tag::kNfcTagInterface
,
309 nfc_tag::kRecordsProperty
,
311 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
314 void SendArrayPropertyChangedSignal(
315 dbus::PropertySet
* properties
,
316 const std::string
& interface
,
317 const std::string
& property_name
,
318 ObjectPathVector object_paths
) {
319 dbus::Signal
signal(interface
, nfc_common::kPropertyChangedSignal
);
320 dbus::MessageWriter
writer(&signal
);
321 writer
.AppendString(property_name
);
322 dbus::MessageWriter
variant_writer(NULL
);
323 writer
.OpenVariant("ao", &variant_writer
);
324 variant_writer
.AppendArrayOfObjectPaths(object_paths
);
325 writer
.CloseContainer(&variant_writer
);
326 properties
->ChangedReceived(&signal
);
329 MOCK_METHOD0(SuccessCallback
, void(void));
330 MOCK_METHOD2(ErrorCallback
, void(const std::string
& error_name
,
331 const std::string
& error_message
));
334 // The mock object proxies.
335 scoped_refptr
<dbus::MockObjectProxy
> mock_manager_proxy_
;
336 scoped_refptr
<dbus::MockObjectProxy
> mock_adapter0_proxy_
;
337 scoped_refptr
<dbus::MockObjectProxy
> mock_adapter1_proxy_
;
338 scoped_refptr
<dbus::MockObjectProxy
> mock_device0_proxy_
;
339 scoped_refptr
<dbus::MockObjectProxy
> mock_device1_proxy_
;
340 scoped_refptr
<dbus::MockObjectProxy
> mock_record0_proxy_
;
341 scoped_refptr
<dbus::MockObjectProxy
> mock_record1_proxy_
;
342 scoped_refptr
<dbus::MockObjectProxy
> mock_record2_proxy_
;
343 scoped_refptr
<dbus::MockObjectProxy
> mock_record3_proxy_
;
344 scoped_refptr
<dbus::MockObjectProxy
> mock_tag0_proxy_
;
345 scoped_refptr
<dbus::MockObjectProxy
> mock_tag1_proxy_
;
347 scoped_refptr
<dbus::MockBus
> mock_bus_
;
348 // A message loop to emulate asynchronous behavior.
349 base::MessageLoop message_loop_
;
350 // Response returned by mock methods.
351 dbus::Response
* response_
;
352 // The D-Bus client objects under test.
353 scoped_ptr
<NfcManagerClient
> manager_client_
;
354 scoped_ptr
<NfcAdapterClient
> adapter_client_
;
355 scoped_ptr
<NfcDeviceClient
> device_client_
;
356 scoped_ptr
<NfcTagClient
> tag_client_
;
357 scoped_ptr
<NfcRecordClient
> record_client_
;
359 MockNfcManagerObserver mock_manager_observer_
;
360 MockNfcAdapterObserver mock_adapter_observer_
;
361 MockNfcDeviceObserver mock_device_observer_
;
362 MockNfcTagObserver mock_tag_observer_
;
363 MockNfcRecordObserver mock_record_observer_
;
364 // The signal callbacks used to simulate asychronous signals.
365 dbus::ObjectProxy::SignalCallback manager_adapter_added_signal_callback_
;
366 dbus::ObjectProxy::SignalCallback manager_adapter_removed_signal_callback_
;
369 // Used to implement the mock proxy.
370 void OnConnectToSignal(
371 const std::string
& interface_name
,
372 const std::string
& signal_name
,
373 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
374 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
375 if (interface_name
== nfc_manager::kNfcManagerInterface
) {
376 if (signal_name
== nfc_manager::kAdapterAddedSignal
)
377 manager_adapter_added_signal_callback_
= signal_callback
;
378 else if (signal_name
== nfc_manager::kAdapterRemovedSignal
)
379 manager_adapter_removed_signal_callback_
= signal_callback
;
381 message_loop_
.PostTask(FROM_HERE
, base::Bind(on_connected_callback
,
388 // Tests that when adapters are added and removed through the manager, all
389 // observers are notified and the proxies are created and removed
391 TEST_F(NfcClientTest
, AdaptersAddedAndRemoved
) {
392 // Invoking methods on adapters that haven't been added should fail.
394 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
395 adapter_client_
->StartPollLoop(
396 dbus::ObjectPath(kTestAdapterPath0
),
397 nfc_adapter::kModeInitiator
,
398 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
399 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
400 Mock::VerifyAndClearExpectations(this);
403 ObjectPathVector adapter_paths
;
404 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
405 EXPECT_CALL(mock_adapter_observer_
,
406 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
407 SimulateAdaptersChanged(adapter_paths
);
409 // Invoking methods should succeed on adapter 0 but fail on adapter 1.
410 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
411 adapter_client_
->StartPollLoop(
412 dbus::ObjectPath(kTestAdapterPath0
),
413 nfc_adapter::kModeInitiator
,
414 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
415 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
416 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_
);
418 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
419 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
421 adapter_client_
->StartPollLoop(
422 dbus::ObjectPath(kTestAdapterPath1
),
423 nfc_adapter::kModeInitiator
,
424 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
425 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
426 Mock::VerifyAndClearExpectations(this);
427 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_
);
430 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath1
));
431 EXPECT_CALL(mock_adapter_observer_
,
432 AdapterAdded(dbus::ObjectPath(kTestAdapterPath1
)));
433 SimulateAdaptersChanged(adapter_paths
);
435 // Invoking methods should succeed on both adapters.
436 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
437 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
438 adapter_client_
->StartPollLoop(
439 dbus::ObjectPath(kTestAdapterPath0
),
440 nfc_adapter::kModeInitiator
,
441 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
442 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
443 adapter_client_
->StartPollLoop(
444 dbus::ObjectPath(kTestAdapterPath1
),
445 nfc_adapter::kModeInitiator
,
446 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
447 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
448 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_
);
449 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_
);
452 adapter_paths
.erase(adapter_paths
.begin());
453 EXPECT_CALL(mock_adapter_observer_
,
454 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0
)));
455 SimulateAdaptersChanged(adapter_paths
);
457 // Invoking methods should succeed on adapter 1 but fail on adapter 0.
459 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
460 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
462 adapter_client_
->StartPollLoop(
463 dbus::ObjectPath(kTestAdapterPath0
),
464 nfc_adapter::kModeInitiator
,
465 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
466 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
467 Mock::VerifyAndClearExpectations(this);
469 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
470 adapter_client_
->StartPollLoop(
471 dbus::ObjectPath(kTestAdapterPath1
),
472 nfc_adapter::kModeInitiator
,
473 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
474 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
475 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_
);
476 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_
);
479 adapter_paths
.clear();
480 EXPECT_CALL(mock_adapter_observer_
,
481 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1
)));
482 SimulateAdaptersChanged(adapter_paths
);
484 // Invoking methods should fail on both adapters.
486 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
))
488 EXPECT_CALL(*mock_adapter0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
490 EXPECT_CALL(*mock_adapter1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
492 adapter_client_
->StartPollLoop(
493 dbus::ObjectPath(kTestAdapterPath0
),
494 nfc_adapter::kModeInitiator
,
495 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
496 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
497 adapter_client_
->StartPollLoop(
498 dbus::ObjectPath(kTestAdapterPath1
),
499 nfc_adapter::kModeInitiator
,
500 base::Bind(&NfcClientTest::SuccessCallback
, base::Unretained(this)),
501 base::Bind(&NfcClientTest::ErrorCallback
, base::Unretained(this)));
504 // Tests that when tags are added and removed through an adapter, all
505 // observers are notified and the proxies are created and removed
507 TEST_F(NfcClientTest
, TagsAddedAndRemoved
) {
508 // Invoking methods on tags that haven't been added should fail.
510 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
511 base::DictionaryValue write_data
;
512 write_data
.SetString(nfc_record::kTypeProperty
, nfc_record::kTypeText
);
513 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
514 base::Bind(&NfcClientTest::SuccessCallback
,
515 base::Unretained(this)),
516 base::Bind(&NfcClientTest::ErrorCallback
,
517 base::Unretained(this)));
518 Mock::VerifyAndClearExpectations(this);
521 ObjectPathVector adapter_paths
;
522 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
523 EXPECT_CALL(mock_adapter_observer_
,
524 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
525 SimulateAdaptersChanged(adapter_paths
);
526 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
529 ObjectPathVector tag_paths
;
530 tag_paths
.push_back(dbus::ObjectPath(kTestTagPath0
));
531 EXPECT_CALL(mock_tag_observer_
,
532 TagAdded(dbus::ObjectPath(kTestTagPath0
)));
533 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
534 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
536 // Invoking methods should succeed on tag 0 but fail on tag 1.
537 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
538 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
539 base::Bind(&NfcClientTest::SuccessCallback
,
540 base::Unretained(this)),
541 base::Bind(&NfcClientTest::ErrorCallback
,
542 base::Unretained(this)));
543 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_
);
545 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
546 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
548 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
549 base::Bind(&NfcClientTest::SuccessCallback
,
550 base::Unretained(this)),
551 base::Bind(&NfcClientTest::ErrorCallback
,
552 base::Unretained(this)));
553 Mock::VerifyAndClearExpectations(this);
554 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_
);
557 tag_paths
.push_back(dbus::ObjectPath(kTestTagPath1
));
558 EXPECT_CALL(mock_tag_observer_
,
559 TagAdded(dbus::ObjectPath(kTestTagPath1
)));
560 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
561 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
563 // Invoking methods should succeed on both tags.
564 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
565 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
566 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
567 base::Bind(&NfcClientTest::SuccessCallback
,
568 base::Unretained(this)),
569 base::Bind(&NfcClientTest::ErrorCallback
,
570 base::Unretained(this)));
571 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
572 base::Bind(&NfcClientTest::SuccessCallback
,
573 base::Unretained(this)),
574 base::Bind(&NfcClientTest::ErrorCallback
,
575 base::Unretained(this)));
576 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_
);
577 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_
);
580 tag_paths
.erase(tag_paths
.begin());
581 EXPECT_CALL(mock_tag_observer_
,
582 TagRemoved(dbus::ObjectPath(kTestTagPath0
)));
583 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
584 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
586 // Invoking methods should succeed on tag 1 but fail on tag 0.
588 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
589 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
591 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
592 base::Bind(&NfcClientTest::SuccessCallback
,
593 base::Unretained(this)),
594 base::Bind(&NfcClientTest::ErrorCallback
,
595 base::Unretained(this)));
596 Mock::VerifyAndClearExpectations(this);
597 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_
);
598 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
599 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
600 base::Bind(&NfcClientTest::SuccessCallback
,
601 base::Unretained(this)),
602 base::Bind(&NfcClientTest::ErrorCallback
,
603 base::Unretained(this)));
604 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_
);
608 EXPECT_CALL(mock_tag_observer_
,
609 TagRemoved(dbus::ObjectPath(kTestTagPath1
)));
610 SimulateTagsChanged(tag_paths
, dbus::ObjectPath(kTestAdapterPath0
));
611 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
613 // Invoking methods should fail on both tags.
615 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
))
617 EXPECT_CALL(*mock_tag0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
619 EXPECT_CALL(*mock_tag1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
621 tag_client_
->Write(dbus::ObjectPath(kTestTagPath0
), write_data
,
622 base::Bind(&NfcClientTest::SuccessCallback
,
623 base::Unretained(this)),
624 base::Bind(&NfcClientTest::ErrorCallback
,
625 base::Unretained(this)));
626 tag_client_
->Write(dbus::ObjectPath(kTestTagPath1
), write_data
,
627 base::Bind(&NfcClientTest::SuccessCallback
,
628 base::Unretained(this)),
629 base::Bind(&NfcClientTest::ErrorCallback
,
630 base::Unretained(this)));
633 // Tests that when devices are added and removed through an adapter, all
634 // observers are notified and the proxies are created and removed
636 TEST_F(NfcClientTest
, DevicesAddedAndRemoved
) {
637 // Invoking methods on devices that haven't been added should fail.
639 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
640 base::DictionaryValue write_data
;
641 write_data
.SetString(nfc_record::kTypeProperty
, nfc_record::kTypeText
);
642 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
643 base::Bind(&NfcClientTest::SuccessCallback
,
644 base::Unretained(this)),
645 base::Bind(&NfcClientTest::ErrorCallback
,
646 base::Unretained(this)));
647 Mock::VerifyAndClearExpectations(this);
650 ObjectPathVector adapter_paths
;
651 adapter_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
652 EXPECT_CALL(mock_adapter_observer_
,
653 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
654 SimulateAdaptersChanged(adapter_paths
);
657 ObjectPathVector device_paths
;
658 device_paths
.push_back(dbus::ObjectPath(kTestDevicePath0
));
659 EXPECT_CALL(mock_device_observer_
,
660 DeviceAdded(dbus::ObjectPath(kTestDevicePath0
)));
661 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
662 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
664 // Invoking methods should succeed on device 0 but fail on device 1.
665 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
666 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
667 base::Bind(&NfcClientTest::SuccessCallback
,
668 base::Unretained(this)),
669 base::Bind(&NfcClientTest::ErrorCallback
,
670 base::Unretained(this)));
671 Mock::VerifyAndClearExpectations(&mock_device0_proxy_
);
673 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
674 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
676 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
677 base::Bind(&NfcClientTest::SuccessCallback
,
678 base::Unretained(this)),
679 base::Bind(&NfcClientTest::ErrorCallback
,
680 base::Unretained(this)));
681 Mock::VerifyAndClearExpectations(this);
682 Mock::VerifyAndClearExpectations(&mock_device1_proxy_
);
685 device_paths
.push_back(dbus::ObjectPath(kTestDevicePath1
));
686 EXPECT_CALL(mock_device_observer_
,
687 DeviceAdded(dbus::ObjectPath(kTestDevicePath1
)));
688 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
689 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
691 // Invoking methods should succeed on both devices.
692 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
693 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
694 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
695 base::Bind(&NfcClientTest::SuccessCallback
,
696 base::Unretained(this)),
697 base::Bind(&NfcClientTest::ErrorCallback
,
698 base::Unretained(this)));
699 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
700 base::Bind(&NfcClientTest::SuccessCallback
,
701 base::Unretained(this)),
702 base::Bind(&NfcClientTest::ErrorCallback
,
703 base::Unretained(this)));
704 Mock::VerifyAndClearExpectations(&mock_device0_proxy_
);
705 Mock::VerifyAndClearExpectations(&mock_device1_proxy_
);
708 device_paths
.erase(device_paths
.begin());
709 EXPECT_CALL(mock_device_observer_
,
710 DeviceRemoved(dbus::ObjectPath(kTestDevicePath0
)));
711 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
712 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
714 // Invoking methods should succeed on device 1 but fail on device 0.
716 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
));
717 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
719 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
720 base::Bind(&NfcClientTest::SuccessCallback
,
721 base::Unretained(this)),
722 base::Bind(&NfcClientTest::ErrorCallback
,
723 base::Unretained(this)));
724 Mock::VerifyAndClearExpectations(this);
725 Mock::VerifyAndClearExpectations(&mock_device0_proxy_
);
726 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
));
727 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
728 base::Bind(&NfcClientTest::SuccessCallback
,
729 base::Unretained(this)),
730 base::Bind(&NfcClientTest::ErrorCallback
,
731 base::Unretained(this)));
732 Mock::VerifyAndClearExpectations(&mock_device1_proxy_
);
735 device_paths
.clear();
736 EXPECT_CALL(mock_device_observer_
,
737 DeviceRemoved(dbus::ObjectPath(kTestDevicePath1
)));
738 SimulateDevicesChanged(device_paths
, dbus::ObjectPath(kTestAdapterPath0
));
739 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
741 // Invoking methods should fail on both devices.
743 ErrorCallback(nfc_client_helpers::kUnknownObjectError
, _
))
745 EXPECT_CALL(*mock_device0_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
747 EXPECT_CALL(*mock_device1_proxy_
, CallMethodWithErrorCallback(_
, _
, _
, _
))
749 device_client_
->Push(dbus::ObjectPath(kTestDevicePath0
), write_data
,
750 base::Bind(&NfcClientTest::SuccessCallback
,
751 base::Unretained(this)),
752 base::Bind(&NfcClientTest::ErrorCallback
,
753 base::Unretained(this)));
754 device_client_
->Push(dbus::ObjectPath(kTestDevicePath1
), write_data
,
755 base::Bind(&NfcClientTest::SuccessCallback
,
756 base::Unretained(this)),
757 base::Bind(&NfcClientTest::ErrorCallback
,
758 base::Unretained(this)));
761 TEST_F(NfcClientTest
, ObjectCleanup
) {
762 // Tests that when an adapter gets removed, proxies that belong to the
763 // adapter, device, tag, and record hierarchy get cleaned up properly.
764 ObjectPathVector object_paths
;
767 EXPECT_CALL(mock_adapter_observer_
,
768 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0
)));
769 EXPECT_CALL(mock_adapter_observer_
,
770 AdapterAdded(dbus::ObjectPath(kTestAdapterPath1
)));
771 object_paths
.push_back(dbus::ObjectPath(kTestAdapterPath0
));
772 object_paths
.push_back(dbus::ObjectPath(kTestAdapterPath1
));
773 SimulateAdaptersChanged(object_paths
);
774 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
776 // Add devices and a tags. Assign them like the following:
777 // - device 0 -> adapter 0
778 // - tag 0 -> adapter 0
779 // - device 1 -> adapter 1
780 // - tag 1 -> adapter 1
781 EXPECT_CALL(mock_device_observer_
,
782 DeviceAdded(dbus::ObjectPath(kTestDevicePath0
)));
783 EXPECT_CALL(mock_device_observer_
,
784 DeviceAdded(dbus::ObjectPath(kTestDevicePath1
)));
785 EXPECT_CALL(mock_tag_observer_
,
786 TagAdded(dbus::ObjectPath(kTestTagPath0
)));
787 EXPECT_CALL(mock_tag_observer_
,
788 TagAdded(dbus::ObjectPath(kTestTagPath1
)));
789 object_paths
.clear();
790 object_paths
.push_back(dbus::ObjectPath(kTestDevicePath0
));
791 SimulateDevicesChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath0
));
792 object_paths
.clear();
793 object_paths
.push_back(dbus::ObjectPath(kTestTagPath0
));
794 SimulateTagsChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath0
));
795 object_paths
.clear();
796 object_paths
.push_back(dbus::ObjectPath(kTestDevicePath1
));
797 SimulateDevicesChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath1
));
798 object_paths
.clear();
799 object_paths
.push_back(dbus::ObjectPath(kTestTagPath1
));
800 SimulateTagsChanged(object_paths
, dbus::ObjectPath(kTestAdapterPath1
));
801 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
802 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
804 // Add records. Assign them like the following:
805 // - record 0 -> device 0
806 // - record 1 -> tag 0
807 // - record 2 -> device 1
808 // - record 3 -> tag 1
809 EXPECT_CALL(mock_record_observer_
,
810 RecordAdded(dbus::ObjectPath(kTestRecordPath0
)));
811 EXPECT_CALL(mock_record_observer_
,
812 RecordAdded(dbus::ObjectPath(kTestRecordPath1
)));
813 EXPECT_CALL(mock_record_observer_
,
814 RecordAdded(dbus::ObjectPath(kTestRecordPath2
)));
815 EXPECT_CALL(mock_record_observer_
,
816 RecordAdded(dbus::ObjectPath(kTestRecordPath3
)));
817 object_paths
.clear();
818 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath0
));
819 SimulateDeviceRecordsChanged(object_paths
,
820 dbus::ObjectPath(kTestDevicePath0
));
821 object_paths
.clear();
822 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath1
));
823 SimulateTagRecordsChanged(object_paths
,
824 dbus::ObjectPath(kTestTagPath0
));
825 object_paths
.clear();
826 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath2
));
827 SimulateDeviceRecordsChanged(object_paths
,
828 dbus::ObjectPath(kTestDevicePath1
));
829 object_paths
.clear();
830 object_paths
.push_back(dbus::ObjectPath(kTestRecordPath3
));
831 SimulateTagRecordsChanged(object_paths
,
832 dbus::ObjectPath(kTestTagPath1
));
833 Mock::VerifyAndClearExpectations(&mock_record_observer_
);
835 // Check that the records have been assigned to the correct device or tag.
836 NfcTagClient::Properties
* tag_properties
=
837 tag_client_
->GetProperties(dbus::ObjectPath(kTestTagPath0
));
838 EXPECT_EQ((size_t)1, tag_properties
->records
.value().size());
839 EXPECT_EQ(dbus::ObjectPath(kTestRecordPath1
),
840 tag_properties
->records
.value()[0]);
841 NfcDeviceClient::Properties
* device_properties
=
842 device_client_
->GetProperties(dbus::ObjectPath(kTestDevicePath0
));
843 EXPECT_EQ((size_t)1, device_properties
->records
.value().size());
844 EXPECT_EQ(dbus::ObjectPath(kTestRecordPath0
),
845 device_properties
->records
.value()[0]);
847 // Remove adapter 0. Make sure that all of the tag, device, and records that
848 // are in the adapter 0 hierarchy are removed.
849 object_paths
.clear();
850 object_paths
.push_back(dbus::ObjectPath(kTestAdapterPath1
));
851 EXPECT_CALL(mock_adapter_observer_
,
852 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0
)));
853 EXPECT_CALL(mock_device_observer_
,
854 DeviceRemoved(dbus::ObjectPath(kTestDevicePath0
)));
855 EXPECT_CALL(mock_tag_observer_
,
856 TagRemoved(dbus::ObjectPath(kTestTagPath0
)));
857 EXPECT_CALL(mock_record_observer_
,
858 RecordRemoved(dbus::ObjectPath(kTestRecordPath0
)));
859 EXPECT_CALL(mock_record_observer_
,
860 RecordRemoved(dbus::ObjectPath(kTestRecordPath1
)));
861 SimulateAdaptersChanged(object_paths
);
862 Mock::VerifyAndClearExpectations(&mock_adapter_observer_
);
863 Mock::VerifyAndClearExpectations(&mock_device_observer_
);
864 Mock::VerifyAndClearExpectations(&mock_tag_observer_
);
865 Mock::VerifyAndClearExpectations(&mock_record_observer_
);
868 object_paths
.clear();
869 EXPECT_CALL(mock_adapter_observer_
,
870 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1
)));
871 EXPECT_CALL(mock_device_observer_
,
872 DeviceRemoved(dbus::ObjectPath(kTestDevicePath1
)));
873 EXPECT_CALL(mock_tag_observer_
,
874 TagRemoved(dbus::ObjectPath(kTestTagPath1
)));
875 EXPECT_CALL(mock_record_observer_
,
876 RecordRemoved(dbus::ObjectPath(kTestRecordPath2
)));
877 EXPECT_CALL(mock_record_observer_
,
878 RecordRemoved(dbus::ObjectPath(kTestRecordPath3
)));
879 SimulateAdaptersChanged(object_paths
);
882 } // namespace chromeos