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
15using base::Time;
16using base::TimeDelta;
17using ::testing::A;
18using ::testing::AtLeast;
19using ::testing::Return;
20using ::testing::InSequence;
21
22namespace extensions {
23
24class 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
31class MockDialService : public DialService {
32 public:
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
41class MockDialRegistry : public DialRegistry {
42 public:
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
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.
59  MockDialService& mock_service() {
60    return mock_service_;
61  }
62
63  // Set to mock out the current time.
64  Time time_;
65
66 protected:
67  virtual base::Time Now() const OVERRIDE {
68    return time_;
69  }
70
71  virtual DialService* CreateDialService() OVERRIDE {
72    return &mock_service_;
73  }
74
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
84class DialRegistryTest : public testing::Test {
85 public:
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
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
123TEST_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
139TEST_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
152TEST_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
179TEST_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
201TEST_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
252TEST_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
281TEST_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
309TEST_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