1// Copyright 2014 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 "components/proximity_auth/connection.h" 6 7#include "components/proximity_auth/connection_observer.h" 8#include "components/proximity_auth/remote_device.h" 9#include "components/proximity_auth/wire_message.h" 10#include "testing/gmock/include/gmock/gmock.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13using testing::_; 14using testing::DoAll; 15using testing::NiceMock; 16using testing::Return; 17using testing::SetArgPointee; 18using testing::StrictMock; 19 20namespace proximity_auth { 21namespace { 22 23class MockConnection : public Connection { 24 public: 25 MockConnection() : Connection(RemoteDevice()) {} 26 ~MockConnection() {} 27 28 MOCK_METHOD1(SetPaused, void(bool paused)); 29 MOCK_METHOD0(Connect, void()); 30 MOCK_METHOD0(Disconnect, void()); 31 MOCK_METHOD0(CancelConnectionAttempt, void()); 32 MOCK_METHOD1(SendMessageImplProxy, void(WireMessage* message)); 33 MOCK_METHOD1(DeserializeWireMessageProxy, 34 WireMessage*(bool* is_incomplete_message)); 35 36 // Gmock only supports copyable types, so create simple wrapper methods for 37 // ease of mocking. 38 virtual void SendMessageImpl(scoped_ptr<WireMessage> message) OVERRIDE { 39 SendMessageImplProxy(message.get()); 40 } 41 42 virtual scoped_ptr<WireMessage> DeserializeWireMessage( 43 bool* is_incomplete_message) OVERRIDE { 44 return make_scoped_ptr(DeserializeWireMessageProxy(is_incomplete_message)); 45 } 46 47 using Connection::status; 48 using Connection::SetStatus; 49 using Connection::OnDidSendMessage; 50 using Connection::OnBytesReceived; 51 52 private: 53 DISALLOW_COPY_AND_ASSIGN(MockConnection); 54}; 55 56class MockConnectionObserver : public ConnectionObserver { 57 public: 58 MockConnectionObserver() {} 59 virtual ~MockConnectionObserver() {} 60 61 MOCK_METHOD3(OnConnectionStatusChanged, 62 void(const Connection& connection, 63 Connection::Status old_status, 64 Connection::Status new_status)); 65 MOCK_METHOD2(OnMessageReceived, 66 void(const Connection& connection, const WireMessage& message)); 67 MOCK_METHOD3(OnSendCompleted, 68 void(const Connection& connection, 69 const WireMessage& message, 70 bool success)); 71 72 private: 73 DISALLOW_COPY_AND_ASSIGN(MockConnectionObserver); 74}; 75 76// Unlike WireMessage, offers a public constructor. 77class TestWireMessage : public WireMessage { 78 public: 79 TestWireMessage() : WireMessage(std::string(), std::string()) {} 80 virtual ~TestWireMessage() {} 81 82 private: 83 DISALLOW_COPY_AND_ASSIGN(TestWireMessage); 84}; 85 86} // namespace 87 88TEST(ProximityAuthConnectionTest, IsConnected) { 89 StrictMock<MockConnection> connection; 90 EXPECT_FALSE(connection.IsConnected()); 91 92 connection.SetStatus(Connection::CONNECTED); 93 EXPECT_TRUE(connection.IsConnected()); 94 95 connection.SetStatus(Connection::DISCONNECTED); 96 EXPECT_FALSE(connection.IsConnected()); 97 98 connection.SetStatus(Connection::IN_PROGRESS); 99 EXPECT_FALSE(connection.IsConnected()); 100} 101 102TEST(ProximityAuthConnectionTest, SendMessage_FailsWhenNotConnected) { 103 StrictMock<MockConnection> connection; 104 connection.SetStatus(Connection::IN_PROGRESS); 105 106 EXPECT_CALL(connection, SendMessageImplProxy(_)).Times(0); 107 connection.SendMessage(scoped_ptr<WireMessage>()); 108} 109 110TEST(ProximityAuthConnectionTest, 111 SendMessage_FailsWhenAnotherMessageSendIsInProgress) { 112 NiceMock<MockConnection> connection; 113 connection.SetStatus(Connection::CONNECTED); 114 connection.SendMessage(scoped_ptr<WireMessage>()); 115 116 EXPECT_CALL(connection, SendMessageImplProxy(_)).Times(0); 117 connection.SendMessage(scoped_ptr<WireMessage>()); 118} 119 120TEST(ProximityAuthConnectionTest, SendMessage_SucceedsWhenConnected) { 121 StrictMock<MockConnection> connection; 122 connection.SetStatus(Connection::CONNECTED); 123 124 EXPECT_CALL(connection, SendMessageImplProxy(_)); 125 connection.SendMessage(scoped_ptr<WireMessage>()); 126} 127 128TEST(ProximityAuthConnectionTest, 129 SendMessage_SucceedsAfterPreviousMessageSendCompletes) { 130 NiceMock<MockConnection> connection; 131 connection.SetStatus(Connection::CONNECTED); 132 connection.SendMessage(scoped_ptr<WireMessage>()); 133 connection.OnDidSendMessage(TestWireMessage(), true /* success */); 134 135 EXPECT_CALL(connection, SendMessageImplProxy(_)); 136 connection.SendMessage(scoped_ptr<WireMessage>()); 137} 138 139TEST(ProximityAuthConnectionTest, SetStatus_NotifiesObserversOfStatusChange) { 140 StrictMock<MockConnection> connection; 141 EXPECT_EQ(Connection::DISCONNECTED, connection.status()); 142 143 StrictMock<MockConnectionObserver> observer; 144 connection.AddObserver(&observer); 145 146 EXPECT_CALL( 147 observer, 148 OnConnectionStatusChanged( 149 Ref(connection), Connection::DISCONNECTED, Connection::CONNECTED)); 150 connection.SetStatus(Connection::CONNECTED); 151} 152 153TEST(ProximityAuthConnectionTest, 154 SetStatus_DoesntNotifyObserversIfStatusUnchanged) { 155 StrictMock<MockConnection> connection; 156 EXPECT_EQ(Connection::DISCONNECTED, connection.status()); 157 158 StrictMock<MockConnectionObserver> observer; 159 connection.AddObserver(&observer); 160 161 EXPECT_CALL(observer, OnConnectionStatusChanged(_, _, _)).Times(0); 162 connection.SetStatus(Connection::DISCONNECTED); 163} 164 165TEST(ProximityAuthConnectionTest, 166 OnDidSendMessage_NotifiesObserversIfMessageSendInProgress) { 167 NiceMock<MockConnection> connection; 168 connection.SetStatus(Connection::CONNECTED); 169 connection.SendMessage(scoped_ptr<WireMessage>()); 170 171 StrictMock<MockConnectionObserver> observer; 172 connection.AddObserver(&observer); 173 174 EXPECT_CALL(observer, OnSendCompleted(Ref(connection), _, true)); 175 connection.OnDidSendMessage(TestWireMessage(), true /* success */); 176} 177 178TEST(ProximityAuthConnectionTest, 179 OnDidSendMessage_DoesntNotifyObserversIfNoMessageSendInProgress) { 180 NiceMock<MockConnection> connection; 181 connection.SetStatus(Connection::CONNECTED); 182 183 StrictMock<MockConnectionObserver> observer; 184 connection.AddObserver(&observer); 185 186 EXPECT_CALL(observer, OnSendCompleted(_, _, _)).Times(0); 187 connection.OnDidSendMessage(TestWireMessage(), true /* success */); 188} 189 190TEST(ProximityAuthConnectionTest, 191 OnBytesReceived_NotifiesObserversOnValidMessage) { 192 NiceMock<MockConnection> connection; 193 connection.SetStatus(Connection::CONNECTED); 194 195 StrictMock<MockConnectionObserver> observer; 196 connection.AddObserver(&observer); 197 198 ON_CALL(connection, DeserializeWireMessageProxy(_)) 199 .WillByDefault( 200 DoAll(SetArgPointee<0>(false), Return(new TestWireMessage))); 201 EXPECT_CALL(observer, OnMessageReceived(Ref(connection), _)); 202 connection.OnBytesReceived(std::string()); 203} 204 205TEST(ProximityAuthConnectionTest, 206 OnBytesReceived_DoesntNotifyObserversIfNotConnected) { 207 StrictMock<MockConnection> connection; 208 connection.SetStatus(Connection::IN_PROGRESS); 209 210 StrictMock<MockConnectionObserver> observer; 211 connection.AddObserver(&observer); 212 213 EXPECT_CALL(observer, OnMessageReceived(_, _)).Times(0); 214 connection.OnBytesReceived(std::string()); 215} 216 217TEST(ProximityAuthConnectionTest, 218 OnBytesReceived_DoesntNotifyObserversIfMessageIsIncomplete) { 219 NiceMock<MockConnection> connection; 220 connection.SetStatus(Connection::CONNECTED); 221 222 StrictMock<MockConnectionObserver> observer; 223 connection.AddObserver(&observer); 224 225 ON_CALL(connection, DeserializeWireMessageProxy(_)) 226 .WillByDefault(DoAll(SetArgPointee<0>(true), 227 Return(static_cast<WireMessage*>(NULL)))); 228 EXPECT_CALL(observer, OnMessageReceived(_, _)).Times(0); 229 connection.OnBytesReceived(std::string()); 230} 231 232TEST(ProximityAuthConnectionTest, 233 OnBytesReceived_DoesntNotifyObserversIfMessageIsInvalid) { 234 NiceMock<MockConnection> connection; 235 connection.SetStatus(Connection::CONNECTED); 236 237 StrictMock<MockConnectionObserver> observer; 238 connection.AddObserver(&observer); 239 240 ON_CALL(connection, DeserializeWireMessageProxy(_)) 241 .WillByDefault(DoAll(SetArgPointee<0>(false), 242 Return(static_cast<WireMessage*>(NULL)))); 243 EXPECT_CALL(observer, OnMessageReceived(_, _)).Times(0); 244 connection.OnBytesReceived(std::string()); 245} 246 247} // namespace proximity_auth 248