1 // Copyright (c) 2012 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/compiler_specific.h"
6 #include "base/message_loop/message_loop.h"
7 #include "chrome/browser/extensions/api/dial/dial_device_data.h"
8 #include "chrome/browser/extensions/api/dial/dial_registry.h"
9 #include "chrome/browser/extensions/api/dial/dial_service.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "url/gurl.h"
14
15 using base::Time;
16 using base::TimeDelta;
17 using ::testing::A;
18 using ::testing::AtLeast;
19 using ::testing::Return;
20 using ::testing::InSequence;
21
22 namespace extensions {
23
24 class MockDialObserver : public DialRegistry::Observer {
25 public:
26 MOCK_METHOD1(OnDialDeviceEvent,
27 void(const DialRegistry::DeviceList& devices));
28 MOCK_METHOD1(OnDialError, void(DialRegistry::DialErrorCode type));
29 };
30
31 class MockDialService : public DialService {
32 public:
~MockDialService()33 virtual ~MockDialService() {}
34
35 MOCK_METHOD0(Discover, bool());
36 MOCK_METHOD1(AddObserver, void(DialService::Observer*));
37 MOCK_METHOD1(RemoveObserver, void(DialService::Observer*));
38 MOCK_METHOD1(HasObserver, bool(DialService::Observer*));
39 };
40
41 class MockDialRegistry : public DialRegistry {
42 public:
MockDialRegistry(Observer * dial_api,const base::TimeDelta & refresh_interval,const base::TimeDelta & expiration,const size_t max_devices)43 MockDialRegistry(Observer *dial_api,
44 const base::TimeDelta& refresh_interval,
45 const base::TimeDelta& expiration,
46 const size_t max_devices)
47 : DialRegistry(dial_api, refresh_interval, expiration, max_devices) {
48 time_ = Time::Now();
49 }
50
~MockDialRegistry()51 virtual ~MockDialRegistry() {
52 // Don't let the DialRegistry delete this.
53 DialService* tmp = dial_.release();
54 if (tmp != NULL)
55 CHECK_EQ(&mock_service_, tmp);
56 }
57
58 // Returns the mock Dial service.
mock_service()59 MockDialService& mock_service() {
60 return mock_service_;
61 }
62
63 // Set to mock out the current time.
64 Time time_;
65
66 protected:
Now() const67 virtual base::Time Now() const OVERRIDE {
68 return time_;
69 }
70
CreateDialService()71 virtual DialService* CreateDialService() OVERRIDE {
72 return &mock_service_;
73 }
74
ClearDialService()75 virtual void ClearDialService() OVERRIDE {
76 // Release the pointer but don't delete the object because the test owns it.
77 CHECK_EQ(&mock_service_, dial_.release());
78 }
79
80 private:
81 MockDialService mock_service_;
82 };
83
84 class DialRegistryTest : public testing::Test {
85 public:
DialRegistryTest()86 DialRegistryTest()
87 : first_device_("first", GURL("http://127.0.0.1/dd.xml"), Time::Now()),
88 second_device_("second", GURL("http://127.0.0.2/dd.xml"), Time::Now()),
89 third_device_("third", GURL("http://127.0.0.3/dd.xml"), Time::Now()) {
90 registry_.reset(new MockDialRegistry(&mock_observer_,
91 TimeDelta::FromSeconds(1000),
92 TimeDelta::FromSeconds(10),
93 10));
94 list_with_first_device_.push_back(first_device_);
95 list_with_second_device_.push_back(second_device_);
96 }
97
98 protected:
99 scoped_ptr<MockDialRegistry> registry_;
100 MockDialObserver mock_observer_;
101 const DialDeviceData first_device_;
102 const DialDeviceData second_device_;
103 const DialDeviceData third_device_;
104
105 const DialRegistry::DeviceList empty_list_;
106 DialRegistry::DeviceList list_with_first_device_;
107 DialRegistry::DeviceList list_with_second_device_;
108
109 // Must instantiate a MessageLoop for the thread, as the registry starts a
110 // RepeatingTimer when there are listeners.
111 base::MessageLoop message_loop_;
112
SetListenerExpectations()113 void SetListenerExpectations() {
114 EXPECT_CALL(registry_->mock_service(),
115 AddObserver(A<DialService::Observer*>()))
116 .Times(1);
117 EXPECT_CALL(registry_->mock_service(),
118 RemoveObserver(A<DialService::Observer*>()))
119 .Times(1);
120 }
121 };
122
TEST_F(DialRegistryTest,TestAddRemoveListeners)123 TEST_F(DialRegistryTest, TestAddRemoveListeners) {
124 SetListenerExpectations();
125 EXPECT_CALL(registry_->mock_service(), Discover())
126 .Times(1);
127
128 EXPECT_FALSE(registry_->repeating_timer_.IsRunning());
129 registry_->OnListenerAdded();
130 EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
131 registry_->OnListenerAdded();
132 EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
133 registry_->OnListenerRemoved();
134 EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
135 registry_->OnListenerRemoved();
136 EXPECT_FALSE(registry_->repeating_timer_.IsRunning());
137 }
138
TEST_F(DialRegistryTest,TestNoDevicesDiscovered)139 TEST_F(DialRegistryTest, TestNoDevicesDiscovered) {
140 SetListenerExpectations();
141 EXPECT_CALL(registry_->mock_service(), Discover())
142 .Times(1);
143 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
144 .Times(1);
145
146 registry_->OnListenerAdded();
147 registry_->OnDiscoveryRequest(NULL);
148 registry_->OnDiscoveryFinished(NULL);
149 registry_->OnListenerRemoved();
150 };
151
TEST_F(DialRegistryTest,TestDevicesDiscovered)152 TEST_F(DialRegistryTest, TestDevicesDiscovered) {
153 DialRegistry::DeviceList expected_list2;
154 expected_list2.push_back(first_device_);
155 expected_list2.push_back(second_device_);
156
157 SetListenerExpectations();
158 EXPECT_CALL(registry_->mock_service(), Discover())
159 .Times(2);
160 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
161 .Times(1);
162 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
163 .Times(2);
164 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list2))
165 .Times(1);
166
167 registry_->OnListenerAdded();
168 registry_->OnDiscoveryRequest(NULL);
169 registry_->OnDeviceDiscovered(NULL, first_device_);
170 registry_->OnDiscoveryFinished(NULL);
171
172 registry_->DoDiscovery();
173 registry_->OnDiscoveryRequest(NULL);
174 registry_->OnDeviceDiscovered(NULL, second_device_);
175 registry_->OnDiscoveryFinished(NULL);
176 registry_->OnListenerRemoved();
177 }
178
TEST_F(DialRegistryTest,TestDeviceExpires)179 TEST_F(DialRegistryTest, TestDeviceExpires) {
180 SetListenerExpectations();
181 EXPECT_CALL(registry_->mock_service(), Discover())
182 .Times(2);
183 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
184 .Times(2);
185 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
186 .Times(2);
187
188 registry_->OnListenerAdded();
189 registry_->OnDiscoveryRequest(NULL);
190 registry_->OnDeviceDiscovered(NULL, first_device_);
191 registry_->OnDiscoveryFinished(NULL);
192
193 registry_->time_ = Time::Now() + TimeDelta::FromSeconds(30);
194
195 registry_->DoDiscovery();
196 registry_->OnDiscoveryRequest(NULL);
197 registry_->OnDiscoveryFinished(NULL);
198 registry_->OnListenerRemoved();
199 }
200
TEST_F(DialRegistryTest,TestExpiredDeviceIsRediscovered)201 TEST_F(DialRegistryTest, TestExpiredDeviceIsRediscovered) {
202 std::vector<Time> discovery_times;
203 discovery_times.push_back(Time::Now());
204 discovery_times.push_back(discovery_times[0] + TimeDelta::FromSeconds(30));
205 discovery_times.push_back(discovery_times[1] + TimeDelta::FromSeconds(30));
206
207 DialDeviceData rediscovered_device("first",
208 GURL("http://127.0.0.1/dd.xml"),
209 discovery_times[2]);
210
211 SetListenerExpectations();
212
213 // TODO(mfoltz): Convert other tests to use InSequence to make expectations
214 // more obvious.
215 InSequence s;
216
217 EXPECT_CALL(registry_->mock_service(), Discover());
218 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
219 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
220
221 EXPECT_CALL(registry_->mock_service(), Discover());
222 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
223 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
224
225 EXPECT_CALL(registry_->mock_service(), Discover());
226 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
227 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
228
229 registry_->time_ = discovery_times[0];
230 registry_->OnListenerAdded();
231 registry_->OnDiscoveryRequest(NULL);
232 registry_->OnDeviceDiscovered(NULL, first_device_);
233 registry_->OnDiscoveryFinished(NULL);
234
235 // Will expire "first" device as it is not discovered this time.
236 registry_->time_ = discovery_times[1];
237 registry_->DoDiscovery();
238 registry_->OnDiscoveryRequest(NULL);
239 registry_->OnDiscoveryFinished(NULL);
240
241 // "first" device is rediscovered 30 seconds later. We pass a device object
242 // with a newer discovery time so it is not pruned immediately.
243 registry_->time_ = discovery_times[2];
244 registry_->DoDiscovery();
245 registry_->OnDiscoveryRequest(NULL);
246 registry_->OnDeviceDiscovered(NULL, rediscovered_device);
247 registry_->OnDiscoveryFinished(NULL);
248
249 registry_->OnListenerRemoved();
250 }
251
TEST_F(DialRegistryTest,TestRemovingListenerDoesNotClearList)252 TEST_F(DialRegistryTest, TestRemovingListenerDoesNotClearList) {
253 EXPECT_CALL(registry_->mock_service(),
254 AddObserver(A<DialService::Observer*>()))
255 .Times(2);
256 EXPECT_CALL(registry_->mock_service(),
257 RemoveObserver(A<DialService::Observer*>()))
258 .Times(2);
259
260 EXPECT_CALL(registry_->mock_service(), Discover())
261 .Times(2);
262
263 InSequence s;
264 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
265 .Times(1);
266 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
267 .Times(2);
268
269 registry_->OnListenerAdded();
270 registry_->OnDiscoveryRequest(NULL);
271 registry_->OnDeviceDiscovered(NULL, first_device_);
272 registry_->OnDiscoveryFinished(NULL);
273 registry_->OnListenerRemoved();
274
275 registry_->OnListenerAdded();
276 registry_->OnDiscoveryRequest(NULL);
277 registry_->OnDiscoveryFinished(NULL);
278 registry_->OnListenerRemoved();
279 }
280
TEST_F(DialRegistryTest,TestNetworkEventConnectionLost)281 TEST_F(DialRegistryTest, TestNetworkEventConnectionLost) {
282 SetListenerExpectations();
283
284 EXPECT_CALL(registry_->mock_service(), Discover())
285 .Times(1);
286
287 InSequence s;
288 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
289 .Times(1);
290 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
291 .Times(1);
292 EXPECT_CALL(mock_observer_, OnDialError(
293 DialRegistry::DIAL_NETWORK_DISCONNECTED)).Times(1);
294 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
295 .Times(1);
296
297 registry_->OnListenerAdded();
298 registry_->OnDiscoveryRequest(NULL);
299 registry_->OnDeviceDiscovered(NULL, first_device_);
300 registry_->OnDiscoveryFinished(NULL);
301
302 registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
303
304 registry_->OnDiscoveryRequest(NULL);
305 registry_->OnDiscoveryFinished(NULL);
306 registry_->OnListenerRemoved();
307 }
308
TEST_F(DialRegistryTest,TestNetworkEventConnectionRestored)309 TEST_F(DialRegistryTest, TestNetworkEventConnectionRestored) {
310 DialRegistry::DeviceList expected_list3;
311 expected_list3.push_back(second_device_);
312 expected_list3.push_back(third_device_);
313
314 // A disconnection should shutdown the DialService, so we expect the observer
315 // to be added twice.
316 EXPECT_CALL(registry_->mock_service(),
317 AddObserver(A<DialService::Observer*>()))
318 .Times(2);
319 EXPECT_CALL(registry_->mock_service(),
320 RemoveObserver(A<DialService::Observer*>()))
321 .Times(2);
322
323 EXPECT_CALL(registry_->mock_service(), Discover())
324 .Times(2);
325
326 InSequence s;
327 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
328 .Times(1);
329 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
330 .Times(1);
331 EXPECT_CALL(mock_observer_,
332 OnDialError(DialRegistry::DIAL_NETWORK_DISCONNECTED))
333 .Times(1);
334 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
335 .Times(2);
336 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_second_device_))
337 .Times(1);
338 EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list3))
339 .Times(1);
340
341 registry_->OnListenerAdded();
342 registry_->OnDiscoveryRequest(NULL);
343 registry_->OnDeviceDiscovered(NULL, first_device_);
344 registry_->OnDiscoveryFinished(NULL);
345
346 registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
347
348 registry_->OnDiscoveryRequest(NULL);
349 registry_->OnDiscoveryFinished(NULL);
350
351 registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_WIFI);
352
353 registry_->OnDiscoveryRequest(NULL);
354 registry_->OnDeviceDiscovered(NULL, second_device_);
355 registry_->OnDiscoveryFinished(NULL);
356
357 registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
358
359 registry_->OnDiscoveryRequest(NULL);
360 registry_->OnDeviceDiscovered(NULL, third_device_);
361 registry_->OnDiscoveryFinished(NULL);
362
363 registry_->OnListenerRemoved();
364 }
365
366 } // namespace extensions
367