Chromium Code Reviews| Index: components/proximity_auth/bluetooth_connection_unittest.cc |
| diff --git a/components/proximity_auth/bluetooth_connection_unittest.cc b/components/proximity_auth/bluetooth_connection_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a4dea4d880fbf588a8de7119f923c34edd7494eb |
| --- /dev/null |
| +++ b/components/proximity_auth/bluetooth_connection_unittest.cc |
| @@ -0,0 +1,487 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/proximity_auth/bluetooth_connection.h" |
| + |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/numerics/safe_conversions.h" |
| +#include "base/run_loop.h" |
| +#include "components/proximity_auth/remote_device.h" |
| +#include "components/proximity_auth/wire_message.h" |
| +#include "device/bluetooth/bluetooth_adapter_factory.h" |
| +#include "device/bluetooth/bluetooth_uuid.h" |
| +#include "device/bluetooth/test/mock_bluetooth_adapter.h" |
| +#include "device/bluetooth/test/mock_bluetooth_device.h" |
| +#include "device/bluetooth/test/mock_bluetooth_socket.h" |
| +#include "net/base/io_buffer.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +using testing::_; |
| +using testing::NiceMock; |
| +using testing::Ref; |
| +using testing::Return; |
| +using testing::SaveArg; |
| +using testing::StrictMock; |
| + |
| +namespace proximity_auth { |
| +namespace { |
| + |
| +const char kDeviceName[] = "Device name"; |
| +const char kOtherDeviceName[] = "Other device name"; |
| + |
| +const char kBluetoothAddress[] = "11:22:33:44:55:66"; |
| +const char kOtherBluetoothAddress[] = "AA:BB:CC:DD:EE:FF"; |
| + |
| +const char kSerializedMessage[] = "Yarrr, this be a serialized message. Yarr!"; |
| +const int kSerializedMessageLength = strlen(kSerializedMessage); |
| + |
| +const char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF"; |
| + |
| +const RemoteDevice kRemoteDevice = {kDeviceName, kBluetoothAddress}; |
| + |
| +const int kReceiveBufferSize = 6; |
| +const char kReceiveBufferContents[] = "bytes"; |
| + |
| +// Create a buffer for testing received data. |
| +scoped_refptr<net::IOBuffer> CreateReceiveBuffer() { |
| + scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kReceiveBufferSize); |
| + memcpy(buffer->data(), kReceiveBufferContents, kReceiveBufferSize); |
| + return buffer; |
| +} |
| + |
| +class MockBluetoothConnection : public BluetoothConnection { |
| + public: |
| + MockBluetoothConnection() |
| + : BluetoothConnection(kRemoteDevice, device::BluetoothUUID(kUuid)) {} |
| + |
| + // Bluetooth dependencies. |
| + typedef device::BluetoothDevice::ConnectToServiceCallback |
| + ConnectToServiceCallback; |
| + typedef device::BluetoothDevice::ConnectToServiceErrorCallback |
| + ConnectToServiceErrorCallback; |
| + MOCK_METHOD4(ConnectToService, |
| + void(device::BluetoothDevice* device, |
| + const device::BluetoothUUID& uuid, |
| + const ConnectToServiceCallback& callback, |
| + const ConnectToServiceErrorCallback& error_callback)); |
| + |
| + // Calls back into the parent Connection class. |
| + MOCK_METHOD1(SetStatusProxy, void(Status status)); |
| + MOCK_METHOD1(OnBytesReceived, void(const std::string& bytes)); |
| + MOCK_METHOD2(OnDidSendMessage, |
| + void(const WireMessage& message, bool success)); |
| + |
| + virtual void SetStatus(Status status) OVERRIDE { |
| + SetStatusProxy(status); |
| + BluetoothConnection::SetStatus(status); |
| + } |
| + |
| + using BluetoothConnection::Connect; |
| + using BluetoothConnection::DeviceRemoved; |
| + using BluetoothConnection::Disconnect; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnection); |
| +}; |
| + |
| +class TestWireMessage : public WireMessage { |
| + public: |
| + TestWireMessage() : WireMessage("permit id", "payload") {} |
| + virtual ~TestWireMessage() {} |
| + |
| + virtual std::string Serialize() const OVERRIDE { return kSerializedMessage; } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(TestWireMessage); |
| +}; |
| + |
| +} // namespace |
| + |
| +class ProximityAuthBluetoothConnectionTest : public testing::Test { |
| + public: |
| + ProximityAuthBluetoothConnectionTest() |
| + : adapter_(new StrictMock<device::MockBluetoothAdapter>), |
| + device_(adapter_.get(), 0, kDeviceName, kBluetoothAddress, true, true), |
| + socket_(new StrictMock<device::MockBluetoothSocket>), |
| + uuid_(kUuid) { |
| + device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); |
| + } |
| + |
| + // Transition the connection into an in-progress state. |
| + void BeginConnecting(MockBluetoothConnection* connection) { |
|
Tim Song
2014/09/22 23:30:38
check STATUS == DISCONNECTED
Ilya Sherman
2014/09/23 05:24:22
Done.
|
| + EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
|
Tim Song
2014/09/22 23:30:39
use ON_CALL instead.
Ilya Sherman
2014/09/23 05:24:22
Done.
|
| + EXPECT_CALL(*adapter_, AddObserver(connection)); |
| + EXPECT_CALL(*connection, ConnectToService(&device_, uuid_, _, _)); |
| + connection->Connect(); |
|
Tim Song
2014/09/22 23:30:38
check status == CONNECTING
Ilya Sherman
2014/09/23 05:24:22
Done.
|
| + } |
| + |
| + // Transition the connection into a connected state. |
| + void Connect(MockBluetoothConnection* connection) { |
| + device::BluetoothDevice::ConnectToServiceCallback callback; |
| + EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
|
Tim Song
2014/09/22 23:30:39
use ON_CALL
Ilya Sherman
2014/09/23 05:24:22
Done.
|
| + EXPECT_CALL(*adapter_, AddObserver(connection)); |
| + EXPECT_CALL(*connection, ConnectToService(_, _, _, _)) |
| + .WillOnce(SaveArg<2>(&callback)); |
| + connection->Connect(); |
| + ASSERT_FALSE(callback.is_null()); |
| + |
| + EXPECT_CALL(*connection, SetStatusProxy(Connection::CONNECTED)); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)); |
| + callback.Run(socket_); |
|
Tim Song
2014/09/22 23:30:39
Check status == CONNECTED
Ilya Sherman
2014/09/23 05:24:22
Done.
|
| + } |
| + |
| + protected: |
| + // Mocks used for verifying interactions with the Bluetooth subsystem. |
| + scoped_refptr<StrictMock<device::MockBluetoothAdapter> > adapter_; |
| + NiceMock<device::MockBluetoothDevice> device_; |
| + scoped_refptr<StrictMock<device::MockBluetoothSocket> > socket_; |
| + |
| + device::BluetoothUUID uuid_; |
| + |
| + private: |
| + base::MessageLoop message_loop_; |
| +}; |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasInProgress) { |
| + // Create an in-progress connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + BeginConnecting(&connection); |
| + |
| + // A second call to Connect() should be ignored. |
| + EXPECT_CALL(connection, SetStatusProxy(_)).Times(0); |
| + connection.Connect(); |
| + |
| + // The connection cleans up after itself upon destruction. |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasConnected) { |
| + // Create a connected connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + Connect(&connection); |
| + |
| + // A second call to Connect() should be ignored. |
| + EXPECT_CALL(connection, SetStatusProxy(_)).Times(0); |
| + connection.Connect(); |
| + |
| + // The connection disconnects and unregisters as an observer upon destruction. |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, Connect_NoBluetoothAdapter) { |
| + // Some platforms do not support Bluetooth. This test is only meaningful on |
| + // those platforms. |
| + adapter_ = NULL; |
| + if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) |
| + return; |
| + |
| + StrictMock<MockBluetoothConnection> connection; |
| + EXPECT_CALL(connection, SetStatusProxy(_)).Times(0); |
| + connection.Connect(); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, Connect_DeviceMissing) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)) |
| + .WillOnce(Return(static_cast<device::BluetoothDevice*>(NULL))); |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + connection.Connect(); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Connect_DeviceRemovedWhileConnecting) { |
| + // Create an in-progress connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + BeginConnecting(&connection); |
| + |
| + // Remove the device while the connection is in-progress. This should cause |
| + // the connection to disconnect. |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| + connection.DeviceRemoved(adapter_.get(), &device_); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Connect_OtherDeviceRemovedWhileConnecting) { |
| + // Create an in-progress connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + BeginConnecting(&connection); |
| + |
| + // Remove a device other than the one that is being connected to. This should |
| + // not have any effect on the connection. |
| + NiceMock<device::MockBluetoothDevice> other_device( |
| + adapter_.get(), 0, kOtherDeviceName, kOtherBluetoothAddress, true, true); |
| + EXPECT_CALL(connection, SetStatusProxy(_)).Times(0); |
| + connection.DeviceRemoved(adapter_.get(), &other_device); |
| + |
| + // The connection removes itself as an observer when it is destroyed. |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionFails) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + |
| + device::BluetoothDevice::ConnectToServiceErrorCallback error_callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
| + EXPECT_CALL(*adapter_, AddObserver(&connection)); |
| + EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _)) |
| + .WillOnce(SaveArg<3>(&error_callback)); |
| + connection.Connect(); |
| + ASSERT_FALSE(error_callback.is_null()); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| + error_callback.Run("super descriptive error message"); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionSucceeds) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + |
| + device::BluetoothDevice::ConnectToServiceCallback callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
| + EXPECT_CALL(*adapter_, AddObserver(&connection)); |
| + EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _)) |
| + .WillOnce(SaveArg<2>(&callback)); |
| + connection.Connect(); |
|
Tim Song
2014/09/22 23:30:38
Why not just use the ProximityAuthBluetoothConnect
Ilya Sherman
2014/09/23 05:24:22
Because we need to save a reference to the callbac
Tim Song
2014/09/23 21:22:12
I don't understand. This function is almost line-b
Ilya Sherman
2014/09/23 22:07:07
Hmm, I suppose you're right. Okay, I've updated t
|
| + ASSERT_FALSE(callback.is_null()); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::CONNECTED)); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)); |
| + callback.Run(socket_); |
| + |
| + // The connection disconnects and unregisters as an observer upon destruction. |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Connect_ConnectionSucceeds_ThenDeviceRemoved) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + |
| + device::BluetoothDevice::ConnectToServiceCallback callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
| + EXPECT_CALL(*adapter_, AddObserver(&connection)); |
| + EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _)) |
| + .WillOnce(SaveArg<2>(&callback)); |
| + connection.Connect(); |
| + ASSERT_FALSE(callback.is_null()); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::CONNECTED)); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)); |
| + callback.Run(socket_); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| + connection.DeviceRemoved(adapter_.get(), &device_); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Connect_ConnectionSucceeds_ReceiveData) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + |
| + // Connect. |
| + device::BluetoothDevice::ConnectToServiceCallback callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
| + EXPECT_CALL(*adapter_, AddObserver(&connection)); |
| + EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _)) |
| + .WillOnce(SaveArg<2>(&callback)); |
| + connection.Connect(); |
| + ASSERT_FALSE(callback.is_null()); |
| + |
| + device::BluetoothSocket::ReceiveCompletionCallback receive_callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::CONNECTED)); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)) |
| + .WillOnce(SaveArg<1>(&receive_callback)); |
| + callback.Run(socket_); |
| + ASSERT_FALSE(receive_callback.is_null()); |
| + |
| + // Receive some data. Once complete, the connection should re-register to be |
| + // ready receive more data. |
| + scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer(); |
| + EXPECT_CALL( |
| + connection, |
| + OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize))); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)); |
| + receive_callback.Run(kReceiveBufferSize, buffer); |
| + base::RunLoop run_loop; |
| + run_loop.RunUntilIdle(); |
| + |
| + // The connection disconnects and unregisters as an observer upon destruction. |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Connect_ConnectionSucceeds_ReceiveDataAfterReceiveError) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + |
| + // Connect. |
| + device::BluetoothDevice::ConnectToServiceCallback callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
| + EXPECT_CALL(*adapter_, AddObserver(&connection)); |
| + EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _)) |
| + .WillOnce(SaveArg<2>(&callback)); |
| + connection.Connect(); |
| + ASSERT_FALSE(callback.is_null()); |
| + |
| + device::BluetoothSocket::ReceiveErrorCompletionCallback |
| + receive_error_callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::CONNECTED)); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)) |
| + .WillOnce(SaveArg<2>(&receive_error_callback)); |
| + callback.Run(socket_); |
| + ASSERT_FALSE(receive_error_callback.is_null()); |
| + |
| + // Simulate an error while receiving data. The connection should re-register |
| + // to be ready receive more data despite the error. |
| + device::BluetoothSocket::ReceiveCompletionCallback receive_callback; |
| + EXPECT_CALL(*socket_, Receive(_, _, _)) |
| + .WillOnce(SaveArg<1>(&receive_callback)); |
| + receive_error_callback.Run(device::BluetoothSocket::kSystemError, |
| + "The system is down. They're taking over!"); |
| + base::RunLoop run_loop; |
| + run_loop.RunUntilIdle(); |
| + |
| + // Receive some data. |
| + scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer(); |
| + EXPECT_CALL( |
| + connection, |
| + OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize))); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)); |
| + receive_callback.Run(kReceiveBufferSize, buffer); |
| + base::RunLoop run_loop2; |
| + run_loop2.RunUntilIdle(); |
| + |
| + // The connection disconnects and unregisters as an observer upon destruction. |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Disconnect_ConnectionWasAlreadyDisconnected) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + EXPECT_CALL(connection, SetStatusProxy(_)).Times(0); |
| + connection.Disconnect(); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Disconnect_ConnectionWasInProgress) { |
| + // Create an in-progress connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + BeginConnecting(&connection); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| + connection.Disconnect(); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Disconnect_ConnectionWasConnected) { |
| + // Create a connected connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + Connect(&connection); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| + connection.Disconnect(); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + Connect_ThenDisconnectWhileInProgress_ThenBackingConnectionSucceeds) { |
| + StrictMock<MockBluetoothConnection> connection; |
| + device::BluetoothDevice::ConnectToServiceCallback callback; |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS)); |
| + EXPECT_CALL(*adapter_, GetDevice(_)).WillOnce(Return(&device_)); |
| + EXPECT_CALL(*adapter_, AddObserver(&connection)); |
| + EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _)) |
| + .WillOnce(SaveArg<2>(&callback)); |
| + connection.Connect(); |
|
Tim Song
2014/09/22 23:30:38
Why not use BeginConnection?
Ilya Sherman
2014/09/23 05:24:22
Same as before: We need to save a reference to the
|
| + ASSERT_FALSE(callback.is_null()); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| + connection.Disconnect(); |
| + |
| + EXPECT_CALL(connection, SetStatusProxy(_)).Times(0); |
| + EXPECT_CALL(*socket_, Receive(_, _, _)).Times(0); |
| + callback.Run(socket_); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, |
| + SendMessage_SendsExpectedDataOverTheWire) { |
| + // Create a connected connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + Connect(&connection); |
| + |
| + scoped_refptr<net::IOBuffer> buffer; |
| + scoped_ptr<TestWireMessage> wire_message(new TestWireMessage); |
| + EXPECT_CALL(*socket_, Send(_, kSerializedMessageLength, _, _)) |
| + .WillOnce(SaveArg<0>(&buffer)); |
| + connection.SendMessage(wire_message.PassAs<WireMessage>()); |
| + ASSERT_TRUE(buffer.get()); |
| + EXPECT_EQ(kSerializedMessage, |
| + std::string(buffer->data(), kSerializedMessageLength)); |
| + |
| + // The connection disconnects and unregisters as an observer upon destruction. |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Success) { |
| + // Create a connected connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + Connect(&connection); |
| + |
| + scoped_ptr<TestWireMessage> wire_message(new TestWireMessage); |
| + // Ownership will be transfered below, so grab a reference here. |
| + TestWireMessage* expected_wire_message = wire_message.get(); |
| + |
| + device::BluetoothSocket::SendCompletionCallback callback; |
| + EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<2>(&callback)); |
| + connection.SendMessage(wire_message.PassAs<WireMessage>()); |
| + ASSERT_FALSE(callback.is_null()); |
| + |
| + EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), true)); |
| + callback.Run(kSerializedMessageLength); |
| + |
| + // The connection disconnects and unregisters as an observer upon destruction. |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| +} |
| + |
| +TEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Failure) { |
| + // Create a connected connection. |
| + StrictMock<MockBluetoothConnection> connection; |
| + Connect(&connection); |
| + |
| + scoped_ptr<TestWireMessage> wire_message(new TestWireMessage); |
| + // Ownership will be transfered below, so grab a reference here. |
| + TestWireMessage* expected_wire_message = wire_message.get(); |
| + |
| + device::BluetoothSocket::ErrorCompletionCallback error_callback; |
| + EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<3>(&error_callback)); |
| + connection.SendMessage(wire_message.PassAs<WireMessage>()); |
| + |
| + ASSERT_FALSE(error_callback.is_null()); |
| + EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), false)); |
| + EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED)); |
| + EXPECT_CALL(*socket_, Disconnect(_)); |
| + EXPECT_CALL(*adapter_, RemoveObserver(&connection)); |
| + error_callback.Run("The most helpful of error messages"); |
| +} |
| + |
| +} // namespace proximity_auth |