Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / nfc_client_unittest.cc
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.
4
5 #include "base/bind.h"
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"
18
19 using ::testing::_;
20 using ::testing::Invoke;
21 using ::testing::Mock;
22 using ::testing::Return;
23
24 using chromeos::nfc_client_helpers::ObjectPathVector;
25
26 namespace chromeos {
27
28 namespace {
29
30 // D-Bus service name used by the test.
31 const char kTestServiceName[] = "test.service.name";
32
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";
45
46 class MockNfcManagerObserver : public NfcManagerClient::Observer {
47  public:
48   MOCK_METHOD1(AdapterAdded, void(const dbus::ObjectPath&));
49   MOCK_METHOD1(AdapterRemoved, void(const dbus::ObjectPath&));
50   MOCK_METHOD1(ManagerPropertyChanged, void(const std::string&));
51 };
52
53 class MockNfcAdapterObserver : public NfcAdapterClient::Observer {
54  public:
55   MOCK_METHOD1(AdapterAdded, void(const dbus::ObjectPath&));
56   MOCK_METHOD1(AdapterRemoved, void(const dbus::ObjectPath&));
57   MOCK_METHOD2(AdapterPropertyChanged, void(const dbus::ObjectPath&,
58                                             const std::string&));
59 };
60
61 class MockNfcDeviceObserver : public NfcDeviceClient::Observer {
62  public:
63   MOCK_METHOD1(DeviceAdded, void(const dbus::ObjectPath&));
64   MOCK_METHOD1(DeviceRemoved, void(const dbus::ObjectPath&));
65   MOCK_METHOD2(DevicePropertyChanged, void(const dbus::ObjectPath&,
66                                            const std::string&));
67 };
68
69 class MockNfcRecordObserver : public NfcRecordClient::Observer {
70  public:
71   MOCK_METHOD1(RecordAdded, void(const dbus::ObjectPath&));
72   MOCK_METHOD1(RecordRemoved, void(const dbus::ObjectPath&));
73   MOCK_METHOD2(RecordPropertyChanged, void(const dbus::ObjectPath&,
74                                            const std::string&));
75   MOCK_METHOD1(RecordPropertiesReceived, void(const dbus::ObjectPath&));
76 };
77
78 class MockNfcTagObserver : public NfcTagClient::Observer {
79  public:
80   MOCK_METHOD1(TagAdded, void(const dbus::ObjectPath&));
81   MOCK_METHOD1(TagRemoved, void(const dbus::ObjectPath&));
82   MOCK_METHOD2(TagPropertyChanged, void(const dbus::ObjectPath&,
83                                         const std::string&));
84 };
85
86 }  // namespace
87
88 class NfcClientTest : public testing::Test {
89  public:
90   NfcClientTest() : response_(NULL) {}
91   virtual ~NfcClientTest() {}
92
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);
98
99     // Create the mock proxies.
100     mock_manager_proxy_ = new dbus::MockObjectProxy(
101         mock_bus_.get(),
102         kTestServiceName,
103         dbus::ObjectPath(kTestManagerPath));
104     mock_adapter0_proxy_ = new dbus::MockObjectProxy(
105         mock_bus_.get(),
106         kTestServiceName,
107         dbus::ObjectPath(kTestAdapterPath0));
108     mock_adapter1_proxy_ = new dbus::MockObjectProxy(
109         mock_bus_.get(),
110         kTestServiceName,
111         dbus::ObjectPath(kTestAdapterPath1));
112     mock_device0_proxy_ = new dbus::MockObjectProxy(
113         mock_bus_.get(),
114         kTestServiceName,
115         dbus::ObjectPath(kTestDevicePath0));
116     mock_device1_proxy_ = new dbus::MockObjectProxy(
117         mock_bus_.get(),
118         kTestServiceName,
119         dbus::ObjectPath(kTestDevicePath1));
120     mock_record0_proxy_ = new dbus::MockObjectProxy(
121         mock_bus_.get(),
122         kTestServiceName,
123         dbus::ObjectPath(kTestRecordPath0));
124     mock_record1_proxy_ = new dbus::MockObjectProxy(
125         mock_bus_.get(),
126         kTestServiceName,
127         dbus::ObjectPath(kTestRecordPath1));
128     mock_record2_proxy_ = new dbus::MockObjectProxy(
129         mock_bus_.get(),
130         kTestServiceName,
131         dbus::ObjectPath(kTestRecordPath2));
132     mock_record3_proxy_ = new dbus::MockObjectProxy(
133         mock_bus_.get(),
134         kTestServiceName,
135         dbus::ObjectPath(kTestRecordPath3));
136     mock_tag0_proxy_ = new dbus::MockObjectProxy(
137         mock_bus_.get(),
138         kTestServiceName,
139         dbus::ObjectPath(kTestTagPath0));
140     mock_tag1_proxy_ = new dbus::MockObjectProxy(
141         mock_bus_.get(),
142         kTestServiceName,
143         dbus::ObjectPath(kTestTagPath1));
144
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));
153
154     // Set expectations that return our mock proxies on demand.
155     EXPECT_CALL(
156         *mock_bus_.get(),
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()));
200
201     // ShutdownAndBlock will be called in TearDown.
202     EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
203
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_);
221
222     message_loop_.RunUntilIdle();
223   }
224
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();
231   }
232
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(
241         properties,
242         nfc_manager::kNfcManagerInterface,
243         nfc_manager::kAdaptersProperty,
244         adapter_paths);
245     Mock::VerifyAndClearExpectations(&mock_manager_observer_);
246   }
247
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(
257         properties,
258         nfc_adapter::kNfcAdapterInterface,
259         nfc_adapter::kTagsProperty,
260         tag_paths);
261     Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
262   }
263
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(
273         properties,
274         nfc_adapter::kNfcAdapterInterface,
275         nfc_adapter::kDevicesProperty,
276         device_paths);
277     Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
278   }
279
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(
290         properties,
291         nfc_device::kNfcDeviceInterface,
292         nfc_device::kRecordsProperty,
293         record_paths);
294     Mock::VerifyAndClearExpectations(&mock_device_observer_);
295   }
296
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(
307         properties,
308         nfc_tag::kNfcTagInterface,
309         nfc_tag::kRecordsProperty,
310         record_paths);
311     Mock::VerifyAndClearExpectations(&mock_tag_observer_);
312   }
313
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);
327   }
328
329   MOCK_METHOD0(SuccessCallback, void(void));
330   MOCK_METHOD2(ErrorCallback, void(const std::string& error_name,
331                                    const std::string& error_message));
332
333  protected:
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_;
346   // The mock bus.
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_;
358   // Mock observers.
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_;
367
368  private:
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;
380     }
381     message_loop_.PostTask(FROM_HERE, base::Bind(on_connected_callback,
382                                                  interface_name,
383                                                  signal_name,
384                                                  true));
385   }
386 };
387
388 // Tests that when adapters are added and removed through the manager, all
389 // observers are notified and the proxies are created and removed
390 // accordingly.
391 TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
392   // Invoking methods on adapters that haven't been added should fail.
393   EXPECT_CALL(*this,
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);
401
402   // Add adapter 0.
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);
408
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_);
417   EXPECT_CALL(*this,
418               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
419   EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
420       .Times(0);
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_);
428
429   // Add adapter 1.
430   adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath1));
431   EXPECT_CALL(mock_adapter_observer_,
432               AdapterAdded(dbus::ObjectPath(kTestAdapterPath1)));
433   SimulateAdaptersChanged(adapter_paths);
434
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_);
450
451   // Remove adapter 0.
452   adapter_paths.erase(adapter_paths.begin());
453   EXPECT_CALL(mock_adapter_observer_,
454               AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0)));
455   SimulateAdaptersChanged(adapter_paths);
456
457   // Invoking methods should succeed on adapter 1 but fail on adapter 0.
458   EXPECT_CALL(*this,
459               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
460   EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
461       .Times(0);
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);
468
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_);
477
478   // Remove adapter 1.
479   adapter_paths.clear();
480   EXPECT_CALL(mock_adapter_observer_,
481               AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1)));
482   SimulateAdaptersChanged(adapter_paths);
483
484   // Invoking methods should fail on both adapters.
485   EXPECT_CALL(*this,
486               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
487       .Times(2);
488   EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
489       .Times(0);
490   EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
491       .Times(0);
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)));
502 }
503
504 // Tests that when tags are added and removed through an adapter, all
505 // observers are notified and the proxies are created and removed
506 // accordingly.
507 TEST_F(NfcClientTest, TagsAddedAndRemoved) {
508   // Invoking methods on tags that haven't been added should fail.
509   EXPECT_CALL(*this,
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);
519
520   // Add adapter 0.
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_);
527
528   // Add tag 0.
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_);
535
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_);
544   EXPECT_CALL(*this,
545               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
546   EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
547       .Times(0);
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_);
555
556   // Add tag 1.
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_);
562
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_);
578
579   // Remove tag 0.
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_);
585
586   // Invoking methods should succeed on tag 1 but fail on tag 0.
587   EXPECT_CALL(*this,
588               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
589   EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
590       .Times(0);
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_);
605
606   // Remove tag 1.
607   tag_paths.clear();
608   EXPECT_CALL(mock_tag_observer_,
609               TagRemoved(dbus::ObjectPath(kTestTagPath1)));
610   SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
611   Mock::VerifyAndClearExpectations(&mock_tag_observer_);
612
613   // Invoking methods should fail on both tags.
614   EXPECT_CALL(*this,
615               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
616       .Times(2);
617   EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
618       .Times(0);
619   EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
620       .Times(0);
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)));
631 }
632
633 // Tests that when devices are added and removed through an adapter, all
634 // observers are notified and the proxies are created and removed
635 // accordingly.
636 TEST_F(NfcClientTest, DevicesAddedAndRemoved) {
637   // Invoking methods on devices that haven't been added should fail.
638   EXPECT_CALL(*this,
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);
648
649   // Add adapter 0.
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);
655
656   // Add device 0.
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_);
663
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_);
672   EXPECT_CALL(*this,
673               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
674   EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
675       .Times(0);
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_);
683
684   // Add device 1.
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_);
690
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_);
706
707   // Remove device 0.
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_);
713
714   // Invoking methods should succeed on device 1 but fail on device 0.
715   EXPECT_CALL(*this,
716               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
717   EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
718       .Times(0);
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_);
733
734   // Remove device 1.
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_);
740
741   // Invoking methods should fail on both devices.
742   EXPECT_CALL(*this,
743               ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
744       .Times(2);
745   EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
746       .Times(0);
747   EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
748       .Times(0);
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)));
759 }
760
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;
765
766   // Add adapters.
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_);
775
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_);
803
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_);
834
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]);
846
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_);
866
867   // Remove adapter 1.
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);
880 }
881
882 }  // namespace chromeos