summaryrefslogtreecommitdiffstats
path: root/chromeos/dbus/nfc_client_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos/dbus/nfc_client_unittest.cc')
-rw-r--r--chromeos/dbus/nfc_client_unittest.cc445
1 files changed, 411 insertions, 34 deletions
diff --git a/chromeos/dbus/nfc_client_unittest.cc b/chromeos/dbus/nfc_client_unittest.cc
index f62fc42..7327d9e 100644
--- a/chromeos/dbus/nfc_client_unittest.cc
+++ b/chromeos/dbus/nfc_client_unittest.cc
@@ -6,7 +6,9 @@
#include "base/message_loop/message_loop.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "chromeos/dbus/nfc_client_helpers.h"
+#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_manager_client.h"
+#include "chromeos/dbus/nfc_tag_client.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -29,6 +31,10 @@ const char kTestServiceName[] = "test.service.name";
const char kTestManagerPath[] = "/test/nfc/manager";
const char kTestAdapterPath0[] = "/test/nfc/adapter0";
const char kTestAdapterPath1[] = "/test/nfc/adapter1";
+const char kTestDevicePath0[] = "/test/nfc/device0";
+const char kTestDevicePath1[] = "/test/nfc/device1";
+const char kTestTagPath0[] = "/test/nfc/tag0";
+const char kTestTagPath1[] = "/test/nfc/tag1";
class MockNfcManagerObserver : public NfcManagerClient::Observer {
public:
@@ -45,6 +51,26 @@ class MockNfcAdapterObserver : public NfcAdapterClient::Observer {
const std::string&));
};
+class MockNfcDeviceObserver : public NfcDeviceClient::Observer {
+ public:
+ MOCK_METHOD2(DeviceFound, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(DeviceLost, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(DevicePropertyChanged, void(const dbus::ObjectPath&,
+ const std::string&));
+};
+
+class MockNfcTagObserver : public NfcTagClient::Observer {
+ public:
+ MOCK_METHOD2(TagFound, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(TagLost, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(TagPropertyChanged, void(const dbus::ObjectPath&,
+ const std::string&));
+};
+
} // namespace
class NfcClientTest : public testing::Test {
@@ -71,6 +97,22 @@ class NfcClientTest : public testing::Test {
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestAdapterPath1));
+ mock_device0_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestDevicePath0));
+ mock_device1_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestDevicePath1));
+ mock_tag0_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestTagPath0));
+ mock_tag1_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestTagPath1));
// Set expectations that use NfcClientTest::OnConnectToSignal when the
// client connect signals on the mock proxies.
@@ -95,6 +137,22 @@ class NfcClientTest : public testing::Test {
GetObjectProxy(nfc_adapter::kNfcAdapterServiceName,
dbus::ObjectPath(kTestAdapterPath1)))
.WillRepeatedly(Return(mock_adapter1_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_device::kNfcDeviceServiceName,
+ dbus::ObjectPath(kTestDevicePath0)))
+ .WillRepeatedly(Return(mock_device0_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_device::kNfcDeviceServiceName,
+ dbus::ObjectPath(kTestDevicePath1)))
+ .WillRepeatedly(Return(mock_device1_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_tag::kNfcTagServiceName,
+ dbus::ObjectPath(kTestTagPath0)))
+ .WillRepeatedly(Return(mock_tag0_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_tag::kNfcTagServiceName,
+ dbus::ObjectPath(kTestTagPath1)))
+ .WillRepeatedly(Return(mock_tag1_proxy_.get()));
// ShutdownAndBlock will be called in TearDown.
EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
@@ -105,21 +163,35 @@ class NfcClientTest : public testing::Test {
adapter_client_.reset(
NfcAdapterClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
manager_client_.get()));
+ device_client_.reset(
+ NfcDeviceClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
+ adapter_client_.get()));
+ tag_client_.reset(
+ NfcTagClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
+ adapter_client_.get()));
manager_client_->Init(mock_bus_.get());
adapter_client_->Init(mock_bus_.get());
+ device_client_->Init(mock_bus_.get());
+ tag_client_->Init(mock_bus_.get());
manager_client_->AddObserver(&mock_manager_observer_);
adapter_client_->AddObserver(&mock_adapter_observer_);
+ device_client_->AddObserver(&mock_device_observer_);
+ tag_client_->AddObserver(&mock_tag_observer_);
message_loop_.RunUntilIdle();
}
virtual void TearDown() OVERRIDE {
+ tag_client_->RemoveObserver(&mock_tag_observer_);
+ device_client_->RemoveObserver(&mock_device_observer_);
adapter_client_->RemoveObserver(&mock_adapter_observer_);
manager_client_->RemoveObserver(&mock_manager_observer_);
mock_bus_->ShutdownAndBlock();
}
- void SendManagerAdapterAddedSignal(const dbus::ObjectPath& object_path) {
+ void SimulateAdapterAdded(const dbus::ObjectPath& object_path) {
+ EXPECT_CALL(mock_manager_observer_, AdapterAdded(object_path));
+ EXPECT_CALL(mock_adapter_observer_, AdapterAdded(object_path));
dbus::Signal signal(nfc_manager::kNfcManagerInterface,
nfc_manager::kAdapterAddedSignal);
dbus::MessageWriter writer(&signal);
@@ -128,13 +200,64 @@ class NfcClientTest : public testing::Test {
manager_adapter_added_signal_callback_.Run(&signal);
}
- void SendManagerAdapterRemovedSignal(const dbus::ObjectPath& object_path) {
+ void SimulateAdapterRemoved(const dbus::ObjectPath& object_path) {
+ EXPECT_CALL(mock_manager_observer_, AdapterRemoved(object_path));
+ EXPECT_CALL(mock_adapter_observer_, AdapterRemoved(object_path));
dbus::Signal signal(nfc_manager::kNfcManagerInterface,
nfc_manager::kAdapterRemovedSignal);
dbus::MessageWriter writer(&signal);
writer.AppendObjectPath(object_path);
ASSERT_FALSE(manager_adapter_removed_signal_callback_.is_null());
manager_adapter_removed_signal_callback_.Run(&signal);
+ Mock::VerifyAndClearExpectations(&mock_manager_observer_);
+ Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
+ }
+
+ void SimulateTagsChanged(const std::vector<dbus::ObjectPath>& tag_paths,
+ const dbus::ObjectPath& adapter_path) {
+ NfcAdapterClient::Properties* properties =
+ adapter_client_->GetProperties(adapter_path);
+ ASSERT_TRUE(properties);
+ EXPECT_CALL(mock_adapter_observer_,
+ AdapterPropertyChanged(adapter_path,
+ nfc_adapter::kTagsProperty));
+ SendArrayPropertyChangedSignal(
+ properties,
+ nfc_adapter::kNfcAdapterInterface,
+ nfc_adapter::kTagsProperty,
+ tag_paths);
+ Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
+ }
+
+ void SimulateDevicesChanged(const std::vector<dbus::ObjectPath>& device_paths,
+ const dbus::ObjectPath& adapter_path) {
+ NfcAdapterClient::Properties* properties =
+ adapter_client_->GetProperties(adapter_path);
+ ASSERT_TRUE(properties);
+ EXPECT_CALL(mock_adapter_observer_,
+ AdapterPropertyChanged(adapter_path,
+ nfc_adapter::kDevicesProperty));
+ SendArrayPropertyChangedSignal(
+ properties,
+ nfc_adapter::kNfcAdapterInterface,
+ nfc_adapter::kDevicesProperty,
+ device_paths);
+ Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
+ }
+
+ void SendArrayPropertyChangedSignal(
+ dbus::PropertySet* properties,
+ const std::string& interface,
+ const std::string& property_name,
+ std::vector<dbus::ObjectPath> object_paths) {
+ dbus::Signal signal(interface, nfc_common::kPropertyChangedSignal);
+ dbus::MessageWriter writer(&signal);
+ writer.AppendString(property_name);
+ dbus::MessageWriter variant_writer(NULL);
+ writer.OpenVariant("ao", &variant_writer);
+ variant_writer.AppendArrayOfObjectPaths(object_paths);
+ writer.CloseContainer(&variant_writer);
+ properties->ChangedReceived(&signal);
}
MOCK_METHOD0(SuccessCallback, void(void));
@@ -142,6 +265,14 @@ class NfcClientTest : public testing::Test {
const std::string& error_message));
protected:
+ // The mock object proxies.
+ scoped_refptr<dbus::MockObjectProxy> mock_manager_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_adapter0_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_adapter1_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_device0_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_device1_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_tag0_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_tag1_proxy_;
// The mock bus.
scoped_refptr<dbus::MockBus> mock_bus_;
// A message loop to emulate asynchronous behavior.
@@ -151,13 +282,13 @@ class NfcClientTest : public testing::Test {
// The D-Bus client objects under test.
scoped_ptr<NfcManagerClient> manager_client_;
scoped_ptr<NfcAdapterClient> adapter_client_;
+ scoped_ptr<NfcDeviceClient> device_client_;
+ scoped_ptr<NfcTagClient> tag_client_;
// Mock observers.
MockNfcManagerObserver mock_manager_observer_;
MockNfcAdapterObserver mock_adapter_observer_;
- // The mock object proxies.
- scoped_refptr<dbus::MockObjectProxy> mock_manager_proxy_;
- scoped_refptr<dbus::MockObjectProxy> mock_adapter0_proxy_;
- scoped_refptr<dbus::MockObjectProxy> mock_adapter1_proxy_;
+ MockNfcDeviceObserver mock_device_observer_;
+ MockNfcTagObserver mock_tag_observer_;
// The signal callbacks used to simulate asychronous signals.
dbus::ObjectProxy::SignalCallback manager_adapter_added_signal_callback_;
dbus::ObjectProxy::SignalCallback manager_adapter_removed_signal_callback_;
@@ -197,12 +328,7 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
Mock::VerifyAndClearExpectations(this);
// Add adapter 0.
- EXPECT_CALL(mock_manager_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
- SendManagerAdapterAddedSignal(dbus::ObjectPath(kTestAdapterPath0));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath0));
// Invoking methods should succeed on adapter 0 but fail on adapter 1.
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
@@ -211,24 +337,21 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
- Mock::VerifyAndClearExpectations(this);
-
+ Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath1),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Add adapter 1.
- EXPECT_CALL(mock_manager_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath1)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath1)));
- SendManagerAdapterAddedSignal(dbus::ObjectPath(kTestAdapterPath1));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath1));
// Invoking methods should succeed on both adapters.
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
@@ -243,19 +366,17 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
- Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Remove adapter 0.
- EXPECT_CALL(mock_manager_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0)));
- SendManagerAdapterRemovedSignal(dbus::ObjectPath(kTestAdapterPath0));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterRemoved(dbus::ObjectPath(kTestAdapterPath0));
// Invoking methods should succeed on adapter 1 but fail on adapter 0.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
@@ -269,20 +390,20 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
- Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Remove adapter 1.
- EXPECT_CALL(mock_manager_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1)));
- SendManagerAdapterRemovedSignal(dbus::ObjectPath(kTestAdapterPath1));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterRemoved(dbus::ObjectPath(kTestAdapterPath1));
// Invoking methods should fail on both adapters.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
.Times(2);
+ EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);;
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
@@ -295,4 +416,260 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
}
+// Tests that when tags are added and removed through an adapter, all
+// observers are notified and the proxies are created and removed
+// accordingly.
+TEST_F(NfcClientTest, TagsAddedAndRemoved) {
+ // Invoking methods on tags that haven't been added should fail.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ NfcTagClient::RecordAttributes write_data;
+ write_data[nfc_record::kTypeProperty] = nfc_record::kTypeText;
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+
+ // Add adapter 0.
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath0));
+
+ // Add tag 0.
+ std::vector<dbus::ObjectPath> tag_paths;
+ tag_paths.push_back(dbus::ObjectPath(kTestTagPath0));
+ EXPECT_CALL(mock_tag_observer_,
+ TagFound(dbus::ObjectPath(kTestTagPath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should succeed on tag 0 but fail on tag 1.
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
+
+ // Add tag 1.
+ tag_paths.push_back(dbus::ObjectPath(kTestTagPath1));
+ EXPECT_CALL(mock_tag_observer_,
+ TagFound(dbus::ObjectPath(kTestTagPath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should succeed on both tags.
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
+
+ // Remove tag 0.
+ tag_paths.erase(tag_paths.begin());
+ EXPECT_CALL(mock_tag_observer_,
+ TagLost(dbus::ObjectPath(kTestTagPath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should succeed on tag 1 but fail on tag 0.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
+
+ // Remove tag 1.
+ tag_paths.clear();
+ EXPECT_CALL(mock_tag_observer_,
+ TagLost(dbus::ObjectPath(kTestTagPath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should fail on both tags.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
+ .Times(2);
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+}
+
+// Tests that when devices are added and removed through an adapter, all
+// observers are notified and the proxies are created and removed
+// accordingly.
+TEST_F(NfcClientTest, DevicesAddedAndRemoved) {
+ // Invoking methods on devices that haven't been added should fail.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ NfcDeviceClient::RecordAttributes write_data;
+ write_data[nfc_record::kTypeProperty] = nfc_record::kTypeText;
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+
+ // Add adapter 0.
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath0));
+
+ // Add device 0.
+ std::vector<dbus::ObjectPath> device_paths;
+ device_paths.push_back(dbus::ObjectPath(kTestDevicePath0));
+ EXPECT_CALL(mock_device_observer_,
+ DeviceFound(dbus::ObjectPath(kTestDevicePath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should succeed on device 0 but fail on device 1.
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
+
+ // Add device 1.
+ device_paths.push_back(dbus::ObjectPath(kTestDevicePath1));
+ EXPECT_CALL(mock_device_observer_,
+ DeviceFound(dbus::ObjectPath(kTestDevicePath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should succeed on both devices.
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
+
+ // Remove device 0.
+ device_paths.erase(device_paths.begin());
+ EXPECT_CALL(mock_device_observer_,
+ DeviceLost(dbus::ObjectPath(kTestDevicePath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should succeed on device 1 but fail on device 0.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
+
+ // Remove device 1.
+ device_paths.clear();
+ EXPECT_CALL(mock_device_observer_,
+ DeviceLost(dbus::ObjectPath(kTestDevicePath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should fail on both devices.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
+ .Times(2);
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+}
+
} // namespace chromeos