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
13 using testing::_;
14 using testing::DoAll;
15 using testing::NiceMock;
16 using testing::Return;
17 using testing::SetArgPointee;
18 using testing::StrictMock;
19
20 namespace proximity_auth {
21 namespace {
22
23 class MockConnection : public Connection {
24 public:
MockConnection()25 MockConnection() : Connection(RemoteDevice()) {}
~MockConnection()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.
SendMessageImpl(scoped_ptr<WireMessage> message)38 virtual void SendMessageImpl(scoped_ptr<WireMessage> message) OVERRIDE {
39 SendMessageImplProxy(message.get());
40 }
41
DeserializeWireMessage(bool * is_incomplete_message)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
56 class MockConnectionObserver : public ConnectionObserver {
57 public:
MockConnectionObserver()58 MockConnectionObserver() {}
~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.
77 class TestWireMessage : public WireMessage {
78 public:
TestWireMessage()79 TestWireMessage() : WireMessage(std::string(), std::string()) {}
~TestWireMessage()80 virtual ~TestWireMessage() {}
81
82 private:
83 DISALLOW_COPY_AND_ASSIGN(TestWireMessage);
84 };
85
86 } // namespace
87
TEST(ProximityAuthConnectionTest,IsConnected)88 TEST(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
TEST(ProximityAuthConnectionTest,SendMessage_FailsWhenNotConnected)102 TEST(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
TEST(ProximityAuthConnectionTest,SendMessage_FailsWhenAnotherMessageSendIsInProgress)110 TEST(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
TEST(ProximityAuthConnectionTest,SendMessage_SucceedsWhenConnected)120 TEST(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
TEST(ProximityAuthConnectionTest,SendMessage_SucceedsAfterPreviousMessageSendCompletes)128 TEST(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
TEST(ProximityAuthConnectionTest,SetStatus_NotifiesObserversOfStatusChange)139 TEST(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
TEST(ProximityAuthConnectionTest,SetStatus_DoesntNotifyObserversIfStatusUnchanged)153 TEST(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
TEST(ProximityAuthConnectionTest,OnDidSendMessage_NotifiesObserversIfMessageSendInProgress)165 TEST(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
TEST(ProximityAuthConnectionTest,OnDidSendMessage_DoesntNotifyObserversIfNoMessageSendInProgress)178 TEST(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
TEST(ProximityAuthConnectionTest,OnBytesReceived_NotifiesObserversOnValidMessage)190 TEST(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
TEST(ProximityAuthConnectionTest,OnBytesReceived_DoesntNotifyObserversIfNotConnected)205 TEST(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
TEST(ProximityAuthConnectionTest,OnBytesReceived_DoesntNotifyObserversIfMessageIsIncomplete)217 TEST(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
TEST(ProximityAuthConnectionTest,OnBytesReceived_DoesntNotifyObserversIfMessageIsInvalid)232 TEST(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