1 // Copyright 2013 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 "chrome/browser/local_discovery/privet_http_asynchronous_factory.h"
6
7 #include "chrome/browser/local_discovery/privet_notifications.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 using testing::StrictMock;
12
13 using ::testing::_;
14 using ::testing::SaveArg;
15
16 namespace local_discovery {
17
18 namespace {
19
20 const char kExampleDeviceName[] = "test._privet._tcp.local";
21 const char kExampleDeviceHumanName[] = "Test device";
22 const char kExampleDeviceDescription[] = "Testing testing";
23 const char kExampleDeviceID[] = "__test__id";
24
25 class MockPrivetNotificationsListenerDeleagate
26 : public PrivetNotificationsListener::Delegate {
27 public:
28 MOCK_METHOD2(PrivetNotify, void(bool multiple, bool added));
29 MOCK_METHOD0(PrivetRemoveNotification, void());
30 };
31
32 // TODO(noamsml): Migrate this test to use a real privet info operation and a
33 // fake URL fetcher.
34 class MockPrivetInfoOperation : public PrivetInfoOperation {
35 public:
36 class DelegateForTests {
37 public:
~DelegateForTests()38 virtual ~DelegateForTests() {}
39 virtual void InfoOperationStarted(MockPrivetInfoOperation* operation) = 0;
40 };
41
MockPrivetInfoOperation(PrivetHTTPClient * client,DelegateForTests * delegate_for_tests,Delegate * delegate)42 MockPrivetInfoOperation(PrivetHTTPClient* client,
43 DelegateForTests* delegate_for_tests,
44 Delegate* delegate)
45 : client_(client),
46 delegate_for_tests_(delegate_for_tests),
47 delegate_(delegate) {
48 }
49
~MockPrivetInfoOperation()50 virtual ~MockPrivetInfoOperation() {
51 }
52
Start()53 virtual void Start() OVERRIDE {
54 delegate_for_tests_->InfoOperationStarted(this);
55 }
56
GetHTTPClient()57 virtual PrivetHTTPClient* GetHTTPClient() OVERRIDE {
58 return client_;
59 }
60
delegate()61 Delegate* delegate() { return delegate_; }
62
63 private:
64 PrivetHTTPClient* client_;
65 DelegateForTests* delegate_for_tests_;
66 Delegate* delegate_;
67 };
68
69 class MockPrivetHTTPClient : public PrivetHTTPClient {
70 public:
MockPrivetHTTPClient(MockPrivetInfoOperation::DelegateForTests * delegate_for_tests,const std::string & name)71 MockPrivetHTTPClient(
72 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests,
73 const std::string& name) : delegate_for_tests_(delegate_for_tests),
74 name_(name) {
75 }
76
CreateRegisterOperation(const std::string & user,PrivetRegisterOperation::Delegate * delegate)77 virtual scoped_ptr<PrivetRegisterOperation> CreateRegisterOperation(
78 const std::string& user,
79 PrivetRegisterOperation::Delegate* delegate) OVERRIDE {
80 return scoped_ptr<PrivetRegisterOperation>();
81 }
82
CreateInfoOperation(PrivetInfoOperation::Delegate * delegate)83 virtual scoped_ptr<PrivetInfoOperation> CreateInfoOperation(
84 PrivetInfoOperation::Delegate* delegate) OVERRIDE {
85 return scoped_ptr<PrivetInfoOperation>(new MockPrivetInfoOperation(
86 this, delegate_for_tests_, delegate));
87 }
88
CreateCapabilitiesOperation(PrivetCapabilitiesOperation::Delegate * delegate)89 virtual scoped_ptr<PrivetCapabilitiesOperation> CreateCapabilitiesOperation(
90 PrivetCapabilitiesOperation::Delegate* delegate) OVERRIDE {
91 NOTIMPLEMENTED();
92 return scoped_ptr<PrivetCapabilitiesOperation>();
93 }
94
CreateLocalPrintOperation(PrivetLocalPrintOperation::Delegate * delegate)95 virtual scoped_ptr<PrivetLocalPrintOperation> CreateLocalPrintOperation(
96 PrivetLocalPrintOperation::Delegate* delegate) OVERRIDE {
97 NOTIMPLEMENTED();
98 return scoped_ptr<PrivetLocalPrintOperation>();
99 }
100
GetName()101 virtual const std::string& GetName() OVERRIDE { return name_; }
102
GetCachedInfo() const103 virtual const base::DictionaryValue* GetCachedInfo() const OVERRIDE {
104 NOTIMPLEMENTED();
105 return NULL;
106 }
107
108 private:
109 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests_;
110 std::string name_;
111 };
112
113 class MockPrivetHttpFactory : public PrivetHTTPAsynchronousFactory {
114 public:
115 class MockResolution : public PrivetHTTPResolution {
116 public:
MockResolution(const std::string & name,MockPrivetInfoOperation::DelegateForTests * delegate_for_tests,const ResultCallback & callback)117 MockResolution(
118 const std::string& name,
119 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests,
120 const ResultCallback& callback)
121 : name_(name), delegate_for_tests_(delegate_for_tests),
122 callback_(callback) {
123 }
124
~MockResolution()125 virtual ~MockResolution() {
126 }
127
Start()128 virtual void Start() OVERRIDE {
129 callback_.Run(scoped_ptr<PrivetHTTPClient>(
130 new MockPrivetHTTPClient(delegate_for_tests_, name_)));
131 }
132
GetName()133 virtual const std::string& GetName() OVERRIDE {
134 return name_;
135 }
136
137 private:
138 std::string name_;
139 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests_;
140 ResultCallback callback_;
141 };
142
MockPrivetHttpFactory(MockPrivetInfoOperation::DelegateForTests * delegate_for_tests)143 MockPrivetHttpFactory(
144 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests)
145 : delegate_for_tests_(delegate_for_tests) {
146 }
147
CreatePrivetHTTP(const std::string & name,const net::HostPortPair & address,const ResultCallback & callback)148 virtual scoped_ptr<PrivetHTTPResolution> CreatePrivetHTTP(
149 const std::string& name,
150 const net::HostPortPair& address,
151 const ResultCallback& callback) OVERRIDE {
152 return scoped_ptr<PrivetHTTPResolution>(
153 new MockResolution(name, delegate_for_tests_, callback));
154 }
155
156 private:
157 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests_;
158 };
159
160 class MockDelegateForTests : public MockPrivetInfoOperation::DelegateForTests {
161 public:
162 MOCK_METHOD1(InfoOperationStarted, void(MockPrivetInfoOperation* operation));
163 };
164
165 class PrivetNotificationsListenerTest : public ::testing::Test {
166 public:
PrivetNotificationsListenerTest()167 PrivetNotificationsListenerTest() {
168 notification_listener_.reset(new PrivetNotificationsListener(
169 scoped_ptr<PrivetHTTPAsynchronousFactory>(
170 new MockPrivetHttpFactory(&mock_delegate_for_tests_)),
171 &mock_delegate_));
172
173 description_.name = kExampleDeviceHumanName;
174 description_.description = kExampleDeviceDescription;
175 }
176
~PrivetNotificationsListenerTest()177 virtual ~PrivetNotificationsListenerTest() {
178 }
179
ExpectInfoOperation()180 virtual void ExpectInfoOperation() {
181 EXPECT_CALL(mock_delegate_for_tests_, InfoOperationStarted(_))
182 .WillOnce(SaveArg<0>(&info_operation_));
183 }
184
185 protected:
186 StrictMock<MockPrivetNotificationsListenerDeleagate> mock_delegate_;
187 StrictMock<MockDelegateForTests> mock_delegate_for_tests_;
188 scoped_ptr<PrivetNotificationsListener> notification_listener_;
189 MockPrivetInfoOperation* info_operation_;
190 DeviceDescription description_;
191 };
192
TEST_F(PrivetNotificationsListenerTest,DisappearReappearTest)193 TEST_F(PrivetNotificationsListenerTest, DisappearReappearTest) {
194 ExpectInfoOperation();
195
196 EXPECT_CALL(mock_delegate_, PrivetNotify(
197 false,
198 true));
199
200 notification_listener_->DeviceChanged(
201 true,
202 kExampleDeviceName,
203 description_);
204
205 base::DictionaryValue value;
206
207 value.SetInteger("uptime", 20);
208
209 info_operation_->delegate()->OnPrivetInfoDone(info_operation_,
210 200, &value);
211
212 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification());
213
214 notification_listener_->DeviceRemoved(
215 kExampleDeviceName);
216
217 notification_listener_->DeviceChanged(
218 true,
219 kExampleDeviceName,
220 description_);
221
222 description_.id = kExampleDeviceID;
223
224 notification_listener_->DeviceChanged(
225 true,
226 kExampleDeviceName,
227 description_);
228 }
229
TEST_F(PrivetNotificationsListenerTest,RegisterTest)230 TEST_F(PrivetNotificationsListenerTest, RegisterTest) {
231 ExpectInfoOperation();
232
233 EXPECT_CALL(mock_delegate_, PrivetNotify(
234 false,
235 true));
236
237 notification_listener_->DeviceChanged(
238 true,
239 kExampleDeviceName,
240 description_);
241
242 base::DictionaryValue value;
243
244 value.SetInteger("uptime", 20);
245
246 info_operation_->delegate()->OnPrivetInfoDone(info_operation_,
247 200, &value);
248
249 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification());
250
251 description_.id = kExampleDeviceID;
252
253 notification_listener_->DeviceChanged(
254 true,
255 kExampleDeviceName,
256 description_);
257 }
258
TEST_F(PrivetNotificationsListenerTest,HighUptimeTest)259 TEST_F(PrivetNotificationsListenerTest, HighUptimeTest) {
260 ExpectInfoOperation();
261
262 notification_listener_->DeviceChanged(
263 true,
264 kExampleDeviceName,
265 description_);
266
267 base::DictionaryValue value;
268
269 value.SetInteger("uptime", 3600);
270
271 info_operation_->delegate()->OnPrivetInfoDone(info_operation_,
272 200, &value);
273
274 description_.id = kExampleDeviceID;
275
276 notification_listener_->DeviceChanged(
277 true,
278 kExampleDeviceName,
279 description_);
280 }
281
TEST_F(PrivetNotificationsListenerTest,HTTPErrorTest)282 TEST_F(PrivetNotificationsListenerTest, HTTPErrorTest) {
283 ExpectInfoOperation();
284
285 notification_listener_->DeviceChanged(
286 true,
287 kExampleDeviceName,
288 description_);
289
290 info_operation_->delegate()->OnPrivetInfoDone(info_operation_,
291 404, NULL);
292 }
293
TEST_F(PrivetNotificationsListenerTest,DictionaryErrorTest)294 TEST_F(PrivetNotificationsListenerTest, DictionaryErrorTest) {
295 ExpectInfoOperation();
296
297 notification_listener_->DeviceChanged(
298 true,
299 kExampleDeviceName,
300 description_);
301
302 base::DictionaryValue value;
303 value.SetString("error", "internal_error");
304
305 info_operation_->delegate()->OnPrivetInfoDone(info_operation_,
306 200, &value);
307 }
308
309 } // namespace
310
311 } // namespace local_discovery
312