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