nfc_client_unittest.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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_tag_client.h" 12#include "dbus/mock_bus.h" 13#include "dbus/mock_object_proxy.h" 14#include "testing/gmock/include/gmock/gmock.h" 15#include "testing/gtest/include/gtest/gtest.h" 16#include "third_party/cros_system_api/dbus/service_constants.h" 17 18using ::testing::_; 19using ::testing::Invoke; 20using ::testing::Mock; 21using ::testing::Return; 22 23namespace chromeos { 24 25namespace { 26 27// D-Bus service name used by the test. 28const char kTestServiceName[] = "test.service.name"; 29 30// Object paths that are used for testing. 31const char kTestManagerPath[] = "/test/nfc/manager"; 32const char kTestAdapterPath0[] = "/test/nfc/adapter0"; 33const char kTestAdapterPath1[] = "/test/nfc/adapter1"; 34const char kTestDevicePath0[] = "/test/nfc/device0"; 35const char kTestDevicePath1[] = "/test/nfc/device1"; 36const char kTestTagPath0[] = "/test/nfc/tag0"; 37const char kTestTagPath1[] = "/test/nfc/tag1"; 38 39class MockNfcManagerObserver : public NfcManagerClient::Observer { 40 public: 41 MOCK_METHOD1(AdapterAdded, void(const dbus::ObjectPath&)); 42 MOCK_METHOD1(AdapterRemoved, void(const dbus::ObjectPath&)); 43 MOCK_METHOD1(ManagerPropertyChanged, void(const std::string&)); 44}; 45 46class MockNfcAdapterObserver : public NfcAdapterClient::Observer { 47 public: 48 MOCK_METHOD1(AdapterAdded, void(const dbus::ObjectPath&)); 49 MOCK_METHOD1(AdapterRemoved, void(const dbus::ObjectPath&)); 50 MOCK_METHOD2(AdapterPropertyChanged, void(const dbus::ObjectPath&, 51 const std::string&)); 52}; 53 54class MockNfcDeviceObserver : public NfcDeviceClient::Observer { 55 public: 56 MOCK_METHOD1(DeviceFound, void(const dbus::ObjectPath&)); 57 MOCK_METHOD1(DeviceLost, void(const dbus::ObjectPath&)); 58 MOCK_METHOD2(DevicePropertyChanged, void(const dbus::ObjectPath&, 59 const std::string&)); 60}; 61 62class MockNfcTagObserver : public NfcTagClient::Observer { 63 public: 64 MOCK_METHOD1(TagFound, void(const dbus::ObjectPath&)); 65 MOCK_METHOD1(TagLost, void(const dbus::ObjectPath&)); 66 MOCK_METHOD2(TagPropertyChanged, void(const dbus::ObjectPath&, 67 const std::string&)); 68}; 69 70} // namespace 71 72class NfcClientTest : public testing::Test { 73 public: 74 NfcClientTest() : response_(NULL) {} 75 virtual ~NfcClientTest() {} 76 77 virtual void SetUp() OVERRIDE { 78 // Create the mock bus. 79 dbus::Bus::Options options; 80 options.bus_type = dbus::Bus::SYSTEM; 81 mock_bus_ = new dbus::MockBus(options); 82 83 // Create the mock proxies. 84 mock_manager_proxy_ = new dbus::MockObjectProxy( 85 mock_bus_.get(), 86 kTestServiceName, 87 dbus::ObjectPath(kTestManagerPath)); 88 mock_adapter0_proxy_ = new dbus::MockObjectProxy( 89 mock_bus_.get(), 90 kTestServiceName, 91 dbus::ObjectPath(kTestAdapterPath0)); 92 mock_adapter1_proxy_ = new dbus::MockObjectProxy( 93 mock_bus_.get(), 94 kTestServiceName, 95 dbus::ObjectPath(kTestAdapterPath1)); 96 mock_device0_proxy_ = new dbus::MockObjectProxy( 97 mock_bus_.get(), 98 kTestServiceName, 99 dbus::ObjectPath(kTestDevicePath0)); 100 mock_device1_proxy_ = new dbus::MockObjectProxy( 101 mock_bus_.get(), 102 kTestServiceName, 103 dbus::ObjectPath(kTestDevicePath1)); 104 mock_tag0_proxy_ = new dbus::MockObjectProxy( 105 mock_bus_.get(), 106 kTestServiceName, 107 dbus::ObjectPath(kTestTagPath0)); 108 mock_tag1_proxy_ = new dbus::MockObjectProxy( 109 mock_bus_.get(), 110 kTestServiceName, 111 dbus::ObjectPath(kTestTagPath1)); 112 113 // Set expectations that use NfcClientTest::OnConnectToSignal when the 114 // client connect signals on the mock proxies. 115 EXPECT_CALL(*mock_manager_proxy_.get(), ConnectToSignal(_, _, _, _)) 116 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal)); 117 EXPECT_CALL(*mock_adapter0_proxy_.get(), ConnectToSignal(_, _, _, _)) 118 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal)); 119 EXPECT_CALL(*mock_adapter1_proxy_.get(), ConnectToSignal(_, _, _, _)) 120 .WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal)); 121 122 // Set expectations that return our mock proxies on demand. 123 EXPECT_CALL( 124 *mock_bus_.get(), 125 GetObjectProxy(nfc_manager::kNfcManagerServiceName, 126 dbus::ObjectPath(nfc_manager::kNfcManagerServicePath))) 127 .WillRepeatedly(Return(mock_manager_proxy_.get())); 128 EXPECT_CALL(*mock_bus_.get(), 129 GetObjectProxy(nfc_adapter::kNfcAdapterServiceName, 130 dbus::ObjectPath(kTestAdapterPath0))) 131 .WillRepeatedly(Return(mock_adapter0_proxy_.get())); 132 EXPECT_CALL(*mock_bus_.get(), 133 GetObjectProxy(nfc_adapter::kNfcAdapterServiceName, 134 dbus::ObjectPath(kTestAdapterPath1))) 135 .WillRepeatedly(Return(mock_adapter1_proxy_.get())); 136 EXPECT_CALL(*mock_bus_.get(), 137 GetObjectProxy(nfc_device::kNfcDeviceServiceName, 138 dbus::ObjectPath(kTestDevicePath0))) 139 .WillRepeatedly(Return(mock_device0_proxy_.get())); 140 EXPECT_CALL(*mock_bus_.get(), 141 GetObjectProxy(nfc_device::kNfcDeviceServiceName, 142 dbus::ObjectPath(kTestDevicePath1))) 143 .WillRepeatedly(Return(mock_device1_proxy_.get())); 144 EXPECT_CALL(*mock_bus_.get(), 145 GetObjectProxy(nfc_tag::kNfcTagServiceName, 146 dbus::ObjectPath(kTestTagPath0))) 147 .WillRepeatedly(Return(mock_tag0_proxy_.get())); 148 EXPECT_CALL(*mock_bus_.get(), 149 GetObjectProxy(nfc_tag::kNfcTagServiceName, 150 dbus::ObjectPath(kTestTagPath1))) 151 .WillRepeatedly(Return(mock_tag1_proxy_.get())); 152 153 // ShutdownAndBlock will be called in TearDown. 154 EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); 155 156 // Create the clients. 157 manager_client_.reset( 158 NfcManagerClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION)); 159 adapter_client_.reset( 160 NfcAdapterClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION, 161 manager_client_.get())); 162 device_client_.reset( 163 NfcDeviceClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION, 164 adapter_client_.get())); 165 tag_client_.reset( 166 NfcTagClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION, 167 adapter_client_.get())); 168 manager_client_->Init(mock_bus_.get()); 169 adapter_client_->Init(mock_bus_.get()); 170 device_client_->Init(mock_bus_.get()); 171 tag_client_->Init(mock_bus_.get()); 172 manager_client_->AddObserver(&mock_manager_observer_); 173 adapter_client_->AddObserver(&mock_adapter_observer_); 174 device_client_->AddObserver(&mock_device_observer_); 175 tag_client_->AddObserver(&mock_tag_observer_); 176 177 message_loop_.RunUntilIdle(); 178 } 179 180 virtual void TearDown() OVERRIDE { 181 tag_client_->RemoveObserver(&mock_tag_observer_); 182 device_client_->RemoveObserver(&mock_device_observer_); 183 adapter_client_->RemoveObserver(&mock_adapter_observer_); 184 manager_client_->RemoveObserver(&mock_manager_observer_); 185 mock_bus_->ShutdownAndBlock(); 186 } 187 188 void SimulateAdaptersChanged( 189 const std::vector<dbus::ObjectPath>& adapter_paths) { 190 NfcManagerClient::Properties* properties = 191 manager_client_->GetProperties(); 192 ASSERT_TRUE(properties); 193 EXPECT_CALL(mock_manager_observer_, 194 ManagerPropertyChanged(nfc_manager::kAdaptersProperty)); 195 SendArrayPropertyChangedSignal( 196 properties, 197 nfc_manager::kNfcManagerInterface, 198 nfc_manager::kAdaptersProperty, 199 adapter_paths); 200 Mock::VerifyAndClearExpectations(&mock_manager_observer_); 201 } 202 203 void SimulateTagsChanged(const std::vector<dbus::ObjectPath>& tag_paths, 204 const dbus::ObjectPath& adapter_path) { 205 NfcAdapterClient::Properties* properties = 206 adapter_client_->GetProperties(adapter_path); 207 ASSERT_TRUE(properties); 208 EXPECT_CALL(mock_adapter_observer_, 209 AdapterPropertyChanged(adapter_path, 210 nfc_adapter::kTagsProperty)); 211 SendArrayPropertyChangedSignal( 212 properties, 213 nfc_adapter::kNfcAdapterInterface, 214 nfc_adapter::kTagsProperty, 215 tag_paths); 216 Mock::VerifyAndClearExpectations(&mock_adapter_observer_); 217 } 218 219 void SimulateDevicesChanged(const std::vector<dbus::ObjectPath>& device_paths, 220 const dbus::ObjectPath& adapter_path) { 221 NfcAdapterClient::Properties* properties = 222 adapter_client_->GetProperties(adapter_path); 223 ASSERT_TRUE(properties); 224 EXPECT_CALL(mock_adapter_observer_, 225 AdapterPropertyChanged(adapter_path, 226 nfc_adapter::kDevicesProperty)); 227 SendArrayPropertyChangedSignal( 228 properties, 229 nfc_adapter::kNfcAdapterInterface, 230 nfc_adapter::kDevicesProperty, 231 device_paths); 232 Mock::VerifyAndClearExpectations(&mock_adapter_observer_); 233 } 234 235 void SendArrayPropertyChangedSignal( 236 dbus::PropertySet* properties, 237 const std::string& interface, 238 const std::string& property_name, 239 std::vector<dbus::ObjectPath> object_paths) { 240 dbus::Signal signal(interface, nfc_common::kPropertyChangedSignal); 241 dbus::MessageWriter writer(&signal); 242 writer.AppendString(property_name); 243 dbus::MessageWriter variant_writer(NULL); 244 writer.OpenVariant("ao", &variant_writer); 245 variant_writer.AppendArrayOfObjectPaths(object_paths); 246 writer.CloseContainer(&variant_writer); 247 properties->ChangedReceived(&signal); 248 } 249 250 MOCK_METHOD0(SuccessCallback, void(void)); 251 MOCK_METHOD2(ErrorCallback, void(const std::string& error_name, 252 const std::string& error_message)); 253 254 protected: 255 // The mock object proxies. 256 scoped_refptr<dbus::MockObjectProxy> mock_manager_proxy_; 257 scoped_refptr<dbus::MockObjectProxy> mock_adapter0_proxy_; 258 scoped_refptr<dbus::MockObjectProxy> mock_adapter1_proxy_; 259 scoped_refptr<dbus::MockObjectProxy> mock_device0_proxy_; 260 scoped_refptr<dbus::MockObjectProxy> mock_device1_proxy_; 261 scoped_refptr<dbus::MockObjectProxy> mock_tag0_proxy_; 262 scoped_refptr<dbus::MockObjectProxy> mock_tag1_proxy_; 263 // The mock bus. 264 scoped_refptr<dbus::MockBus> mock_bus_; 265 // A message loop to emulate asynchronous behavior. 266 base::MessageLoop message_loop_; 267 // Response returned by mock methods. 268 dbus::Response* response_; 269 // The D-Bus client objects under test. 270 scoped_ptr<NfcManagerClient> manager_client_; 271 scoped_ptr<NfcAdapterClient> adapter_client_; 272 scoped_ptr<NfcDeviceClient> device_client_; 273 scoped_ptr<NfcTagClient> tag_client_; 274 // Mock observers. 275 MockNfcManagerObserver mock_manager_observer_; 276 MockNfcAdapterObserver mock_adapter_observer_; 277 MockNfcDeviceObserver mock_device_observer_; 278 MockNfcTagObserver mock_tag_observer_; 279 // The signal callbacks used to simulate asychronous signals. 280 dbus::ObjectProxy::SignalCallback manager_adapter_added_signal_callback_; 281 dbus::ObjectProxy::SignalCallback manager_adapter_removed_signal_callback_; 282 283 private: 284 // Used to implement the mock proxy. 285 void OnConnectToSignal( 286 const std::string& interface_name, 287 const std::string& signal_name, 288 const dbus::ObjectProxy::SignalCallback& signal_callback, 289 const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback) { 290 if (interface_name == nfc_manager::kNfcManagerInterface) { 291 if (signal_name == nfc_manager::kAdapterAddedSignal) 292 manager_adapter_added_signal_callback_ = signal_callback; 293 else if (signal_name == nfc_manager::kAdapterRemovedSignal) 294 manager_adapter_removed_signal_callback_ = signal_callback; 295 } 296 message_loop_.PostTask(FROM_HERE, base::Bind(on_connected_callback, 297 interface_name, 298 signal_name, 299 true)); 300 } 301}; 302 303// Tests that when adapters are added and removed through the manager, all 304// observers are notified and the proxies are created and removed 305// accordingly. 306TEST_F(NfcClientTest, AdaptersAddedAndRemoved) { 307 // Invoking methods on adapters that haven't been added should fail. 308 EXPECT_CALL(*this, 309 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 310 adapter_client_->StartPollLoop( 311 dbus::ObjectPath(kTestAdapterPath0), 312 nfc_adapter::kModeInitiator, 313 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 314 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 315 Mock::VerifyAndClearExpectations(this); 316 317 // Add adapter 0. 318 std::vector<dbus::ObjectPath> adapter_paths; 319 adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath0)); 320 EXPECT_CALL(mock_adapter_observer_, 321 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0))); 322 SimulateAdaptersChanged(adapter_paths); 323 324 // Invoking methods should succeed on adapter 0 but fail on adapter 1. 325 EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 326 adapter_client_->StartPollLoop( 327 dbus::ObjectPath(kTestAdapterPath0), 328 nfc_adapter::kModeInitiator, 329 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 330 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 331 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_); 332 EXPECT_CALL(*this, 333 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 334 EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 335 .Times(0); 336 adapter_client_->StartPollLoop( 337 dbus::ObjectPath(kTestAdapterPath1), 338 nfc_adapter::kModeInitiator, 339 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 340 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 341 Mock::VerifyAndClearExpectations(this); 342 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_); 343 344 // Add adapter 1. 345 adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath1)); 346 EXPECT_CALL(mock_adapter_observer_, 347 AdapterAdded(dbus::ObjectPath(kTestAdapterPath1))); 348 SimulateAdaptersChanged(adapter_paths); 349 350 // Invoking methods should succeed on both adapters. 351 EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 352 EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 353 adapter_client_->StartPollLoop( 354 dbus::ObjectPath(kTestAdapterPath0), 355 nfc_adapter::kModeInitiator, 356 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 357 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 358 adapter_client_->StartPollLoop( 359 dbus::ObjectPath(kTestAdapterPath1), 360 nfc_adapter::kModeInitiator, 361 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 362 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 363 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_); 364 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_); 365 366 // Remove adapter 0. 367 adapter_paths.erase(adapter_paths.begin()); 368 EXPECT_CALL(mock_adapter_observer_, 369 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0))); 370 SimulateAdaptersChanged(adapter_paths); 371 372 // Invoking methods should succeed on adapter 1 but fail on adapter 0. 373 EXPECT_CALL(*this, 374 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 375 EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 376 .Times(0); 377 adapter_client_->StartPollLoop( 378 dbus::ObjectPath(kTestAdapterPath0), 379 nfc_adapter::kModeInitiator, 380 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 381 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 382 Mock::VerifyAndClearExpectations(this); 383 384 EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 385 adapter_client_->StartPollLoop( 386 dbus::ObjectPath(kTestAdapterPath1), 387 nfc_adapter::kModeInitiator, 388 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 389 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 390 Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_); 391 Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_); 392 393 // Remove adapter 1. 394 adapter_paths.clear(); 395 EXPECT_CALL(mock_adapter_observer_, 396 AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1))); 397 SimulateAdaptersChanged(adapter_paths); 398 399 // Invoking methods should fail on both adapters. 400 EXPECT_CALL(*this, 401 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)) 402 .Times(2); 403 EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 404 .Times(0); 405 EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 406 .Times(0);; 407 adapter_client_->StartPollLoop( 408 dbus::ObjectPath(kTestAdapterPath0), 409 nfc_adapter::kModeInitiator, 410 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 411 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 412 adapter_client_->StartPollLoop( 413 dbus::ObjectPath(kTestAdapterPath1), 414 nfc_adapter::kModeInitiator, 415 base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)), 416 base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this))); 417} 418 419// Tests that when tags are added and removed through an adapter, all 420// observers are notified and the proxies are created and removed 421// accordingly. 422TEST_F(NfcClientTest, TagsAddedAndRemoved) { 423 // Invoking methods on tags that haven't been added should fail. 424 EXPECT_CALL(*this, 425 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 426 NfcTagClient::RecordAttributes write_data; 427 write_data[nfc_record::kTypeProperty] = nfc_record::kTypeText; 428 tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data, 429 base::Bind(&NfcClientTest::SuccessCallback, 430 base::Unretained(this)), 431 base::Bind(&NfcClientTest::ErrorCallback, 432 base::Unretained(this))); 433 Mock::VerifyAndClearExpectations(this); 434 435 // Add adapter 0. 436 std::vector<dbus::ObjectPath> adapter_paths; 437 adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath0)); 438 EXPECT_CALL(mock_adapter_observer_, 439 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0))); 440 SimulateAdaptersChanged(adapter_paths); 441 442 // Add tag 0. 443 std::vector<dbus::ObjectPath> tag_paths; 444 tag_paths.push_back(dbus::ObjectPath(kTestTagPath0)); 445 EXPECT_CALL(mock_tag_observer_, 446 TagFound(dbus::ObjectPath(kTestTagPath0))); 447 SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0)); 448 Mock::VerifyAndClearExpectations(&mock_tag_observer_); 449 450 // Invoking methods should succeed on tag 0 but fail on tag 1. 451 EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 452 tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data, 453 base::Bind(&NfcClientTest::SuccessCallback, 454 base::Unretained(this)), 455 base::Bind(&NfcClientTest::ErrorCallback, 456 base::Unretained(this))); 457 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_); 458 EXPECT_CALL(*this, 459 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 460 EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 461 .Times(0); 462 tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data, 463 base::Bind(&NfcClientTest::SuccessCallback, 464 base::Unretained(this)), 465 base::Bind(&NfcClientTest::ErrorCallback, 466 base::Unretained(this))); 467 Mock::VerifyAndClearExpectations(this); 468 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_); 469 470 // Add tag 1. 471 tag_paths.push_back(dbus::ObjectPath(kTestTagPath1)); 472 EXPECT_CALL(mock_tag_observer_, 473 TagFound(dbus::ObjectPath(kTestTagPath1))); 474 SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0)); 475 Mock::VerifyAndClearExpectations(&mock_tag_observer_); 476 477 // Invoking methods should succeed on both tags. 478 EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 479 EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 480 tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data, 481 base::Bind(&NfcClientTest::SuccessCallback, 482 base::Unretained(this)), 483 base::Bind(&NfcClientTest::ErrorCallback, 484 base::Unretained(this))); 485 tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data, 486 base::Bind(&NfcClientTest::SuccessCallback, 487 base::Unretained(this)), 488 base::Bind(&NfcClientTest::ErrorCallback, 489 base::Unretained(this))); 490 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_); 491 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_); 492 493 // Remove tag 0. 494 tag_paths.erase(tag_paths.begin()); 495 EXPECT_CALL(mock_tag_observer_, 496 TagLost(dbus::ObjectPath(kTestTagPath0))); 497 SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0)); 498 Mock::VerifyAndClearExpectations(&mock_tag_observer_); 499 500 // Invoking methods should succeed on tag 1 but fail on tag 0. 501 EXPECT_CALL(*this, 502 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 503 EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 504 .Times(0); 505 tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data, 506 base::Bind(&NfcClientTest::SuccessCallback, 507 base::Unretained(this)), 508 base::Bind(&NfcClientTest::ErrorCallback, 509 base::Unretained(this))); 510 Mock::VerifyAndClearExpectations(this); 511 Mock::VerifyAndClearExpectations(&mock_tag0_proxy_); 512 EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 513 tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data, 514 base::Bind(&NfcClientTest::SuccessCallback, 515 base::Unretained(this)), 516 base::Bind(&NfcClientTest::ErrorCallback, 517 base::Unretained(this))); 518 Mock::VerifyAndClearExpectations(&mock_tag1_proxy_); 519 520 // Remove tag 1. 521 tag_paths.clear(); 522 EXPECT_CALL(mock_tag_observer_, 523 TagLost(dbus::ObjectPath(kTestTagPath1))); 524 SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0)); 525 Mock::VerifyAndClearExpectations(&mock_tag_observer_); 526 527 // Invoking methods should fail on both tags. 528 EXPECT_CALL(*this, 529 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)) 530 .Times(2); 531 EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 532 .Times(0); 533 EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 534 .Times(0); 535 tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data, 536 base::Bind(&NfcClientTest::SuccessCallback, 537 base::Unretained(this)), 538 base::Bind(&NfcClientTest::ErrorCallback, 539 base::Unretained(this))); 540 tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data, 541 base::Bind(&NfcClientTest::SuccessCallback, 542 base::Unretained(this)), 543 base::Bind(&NfcClientTest::ErrorCallback, 544 base::Unretained(this))); 545} 546 547// Tests that when devices are added and removed through an adapter, all 548// observers are notified and the proxies are created and removed 549// accordingly. 550TEST_F(NfcClientTest, DevicesAddedAndRemoved) { 551 // Invoking methods on devices that haven't been added should fail. 552 EXPECT_CALL(*this, 553 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 554 NfcDeviceClient::RecordAttributes write_data; 555 write_data[nfc_record::kTypeProperty] = nfc_record::kTypeText; 556 device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data, 557 base::Bind(&NfcClientTest::SuccessCallback, 558 base::Unretained(this)), 559 base::Bind(&NfcClientTest::ErrorCallback, 560 base::Unretained(this))); 561 Mock::VerifyAndClearExpectations(this); 562 563 // Add adapter 0. 564 std::vector<dbus::ObjectPath> adapter_paths; 565 adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath0)); 566 EXPECT_CALL(mock_adapter_observer_, 567 AdapterAdded(dbus::ObjectPath(kTestAdapterPath0))); 568 SimulateAdaptersChanged(adapter_paths); 569 570 // Add device 0. 571 std::vector<dbus::ObjectPath> device_paths; 572 device_paths.push_back(dbus::ObjectPath(kTestDevicePath0)); 573 EXPECT_CALL(mock_device_observer_, 574 DeviceFound(dbus::ObjectPath(kTestDevicePath0))); 575 SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0)); 576 Mock::VerifyAndClearExpectations(&mock_device_observer_); 577 578 // Invoking methods should succeed on device 0 but fail on device 1. 579 EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 580 device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data, 581 base::Bind(&NfcClientTest::SuccessCallback, 582 base::Unretained(this)), 583 base::Bind(&NfcClientTest::ErrorCallback, 584 base::Unretained(this))); 585 Mock::VerifyAndClearExpectations(&mock_device0_proxy_); 586 EXPECT_CALL(*this, 587 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 588 EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 589 .Times(0); 590 device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data, 591 base::Bind(&NfcClientTest::SuccessCallback, 592 base::Unretained(this)), 593 base::Bind(&NfcClientTest::ErrorCallback, 594 base::Unretained(this))); 595 Mock::VerifyAndClearExpectations(this); 596 Mock::VerifyAndClearExpectations(&mock_device1_proxy_); 597 598 // Add device 1. 599 device_paths.push_back(dbus::ObjectPath(kTestDevicePath1)); 600 EXPECT_CALL(mock_device_observer_, 601 DeviceFound(dbus::ObjectPath(kTestDevicePath1))); 602 SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0)); 603 Mock::VerifyAndClearExpectations(&mock_device_observer_); 604 605 // Invoking methods should succeed on both devices. 606 EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 607 EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 608 device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data, 609 base::Bind(&NfcClientTest::SuccessCallback, 610 base::Unretained(this)), 611 base::Bind(&NfcClientTest::ErrorCallback, 612 base::Unretained(this))); 613 device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data, 614 base::Bind(&NfcClientTest::SuccessCallback, 615 base::Unretained(this)), 616 base::Bind(&NfcClientTest::ErrorCallback, 617 base::Unretained(this))); 618 Mock::VerifyAndClearExpectations(&mock_device0_proxy_); 619 Mock::VerifyAndClearExpectations(&mock_device1_proxy_); 620 621 // Remove device 0. 622 device_paths.erase(device_paths.begin()); 623 EXPECT_CALL(mock_device_observer_, 624 DeviceLost(dbus::ObjectPath(kTestDevicePath0))); 625 SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0)); 626 Mock::VerifyAndClearExpectations(&mock_device_observer_); 627 628 // Invoking methods should succeed on device 1 but fail on device 0. 629 EXPECT_CALL(*this, 630 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)); 631 EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 632 .Times(0); 633 device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data, 634 base::Bind(&NfcClientTest::SuccessCallback, 635 base::Unretained(this)), 636 base::Bind(&NfcClientTest::ErrorCallback, 637 base::Unretained(this))); 638 Mock::VerifyAndClearExpectations(this); 639 Mock::VerifyAndClearExpectations(&mock_device0_proxy_); 640 EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _)); 641 device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data, 642 base::Bind(&NfcClientTest::SuccessCallback, 643 base::Unretained(this)), 644 base::Bind(&NfcClientTest::ErrorCallback, 645 base::Unretained(this))); 646 Mock::VerifyAndClearExpectations(&mock_device1_proxy_); 647 648 // Remove device 1. 649 device_paths.clear(); 650 EXPECT_CALL(mock_device_observer_, 651 DeviceLost(dbus::ObjectPath(kTestDevicePath1))); 652 SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0)); 653 Mock::VerifyAndClearExpectations(&mock_device_observer_); 654 655 // Invoking methods should fail on both devices. 656 EXPECT_CALL(*this, 657 ErrorCallback(nfc_client_helpers::kUnknownObjectError, _)) 658 .Times(2); 659 EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 660 .Times(0); 661 EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 662 .Times(0); 663 device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data, 664 base::Bind(&NfcClientTest::SuccessCallback, 665 base::Unretained(this)), 666 base::Bind(&NfcClientTest::ErrorCallback, 667 base::Unretained(this))); 668 device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data, 669 base::Bind(&NfcClientTest::SuccessCallback, 670 base::Unretained(this)), 671 base::Bind(&NfcClientTest::ErrorCallback, 672 base::Unretained(this))); 673} 674 675} // namespace chromeos 676