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_http_impl.h"
8 #include "chrome/browser/local_discovery/privet_notifications.h"
9 #include "net/url_request/test_url_fetcher_factory.h"
10 #include "net/url_request/url_request_test_util.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 using testing::StrictMock;
15
16 using ::testing::_;
17 using ::testing::SaveArg;
18
19 namespace local_discovery {
20
21 namespace {
22
23 const char kExampleDeviceName[] = "test._privet._tcp.local";
24 const char kExampleDeviceHumanName[] = "Test device";
25 const char kExampleDeviceDescription[] = "Testing testing";
26 const char kExampleDeviceID[] = "__test__id";
27 const char kDeviceInfoURL[] = "http://1.2.3.4:8080/privet/info";
28
29 const char kInfoResponseUptime20[] = "{\"uptime\": 20}";
30 const char kInfoResponseUptime3600[] = "{\"uptime\": 3600}";
31 const char kInfoResponseNoUptime[] = "{}";
32
33 class MockPrivetNotificationsListenerDeleagate
34 : public PrivetNotificationsListener::Delegate {
35 public:
36 MOCK_METHOD2(PrivetNotify, void(bool multiple, bool added));
37 MOCK_METHOD0(PrivetRemoveNotification, void());
38 };
39
40 class MockPrivetHttpFactory : public PrivetHTTPAsynchronousFactory {
41 public:
42 class MockResolution : public PrivetHTTPResolution {
43 public:
MockResolution(const std::string & name,net::URLRequestContextGetter * request_context,const ResultCallback & callback)44 MockResolution(
45 const std::string& name,
46 net::URLRequestContextGetter* request_context,
47 const ResultCallback& callback)
48 : name_(name), request_context_(request_context), callback_(callback) {
49 }
50
~MockResolution()51 virtual ~MockResolution() {
52 }
53
Start()54 virtual void Start() OVERRIDE {
55 callback_.Run(scoped_ptr<PrivetHTTPClient>(
56 new PrivetHTTPClientImpl(
57 name_,
58 net::HostPortPair("1.2.3.4", 8080),
59 request_context_)));
60 }
61
GetName()62 virtual const std::string& GetName() OVERRIDE {
63 return name_;
64 }
65
66 private:
67 std::string name_;
68 scoped_refptr<net::URLRequestContextGetter> request_context_;
69 ResultCallback callback_;
70 };
71
MockPrivetHttpFactory(net::URLRequestContextGetter * request_context)72 explicit MockPrivetHttpFactory(net::URLRequestContextGetter* request_context)
73 : request_context_(request_context) {
74 }
75
CreatePrivetHTTP(const std::string & name,const net::HostPortPair & address,const ResultCallback & callback)76 virtual scoped_ptr<PrivetHTTPResolution> CreatePrivetHTTP(
77 const std::string& name,
78 const net::HostPortPair& address,
79 const ResultCallback& callback) OVERRIDE {
80 return scoped_ptr<PrivetHTTPResolution>(
81 new MockResolution(name, request_context_, callback));
82 }
83
84 private:
85 scoped_refptr<net::URLRequestContextGetter> request_context_;
86 };
87
88 class PrivetNotificationsListenerTest : public ::testing::Test {
89 public:
PrivetNotificationsListenerTest()90 PrivetNotificationsListenerTest() : request_context_(
91 new net::TestURLRequestContextGetter(base::MessageLoopProxy::current())) {
92 notification_listener_.reset(new PrivetNotificationsListener(
93 scoped_ptr<PrivetHTTPAsynchronousFactory>(
94 new MockPrivetHttpFactory(request_context_.get())),
95 &mock_delegate_));
96
97 description_.name = kExampleDeviceHumanName;
98 description_.description = kExampleDeviceDescription;
99 }
100
~PrivetNotificationsListenerTest()101 virtual ~PrivetNotificationsListenerTest() {
102 }
103
SuccessfulResponseToInfo(const std::string & response)104 bool SuccessfulResponseToInfo(const std::string& response) {
105 net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
106 EXPECT_TRUE(fetcher);
107 EXPECT_EQ(GURL(kDeviceInfoURL), fetcher->GetOriginalURL());
108
109 if (!fetcher || GURL(kDeviceInfoURL) != fetcher->GetOriginalURL())
110 return false;
111
112 fetcher->SetResponseString(response);
113 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
114 net::OK));
115 fetcher->set_response_code(200);
116 fetcher->delegate()->OnURLFetchComplete(fetcher);
117 return true;
118 }
119
120 protected:
121 StrictMock<MockPrivetNotificationsListenerDeleagate> mock_delegate_;
122 scoped_ptr<PrivetNotificationsListener> notification_listener_;
123 base::MessageLoop message_loop_;
124 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
125 net::TestURLFetcherFactory fetcher_factory_;
126 DeviceDescription description_;
127 };
128
TEST_F(PrivetNotificationsListenerTest,DisappearReappearTest)129 TEST_F(PrivetNotificationsListenerTest, DisappearReappearTest) {
130
131 EXPECT_CALL(mock_delegate_, PrivetNotify(
132 false,
133 true));
134
135 notification_listener_->DeviceChanged(
136 true,
137 kExampleDeviceName,
138 description_);
139
140 SuccessfulResponseToInfo(kInfoResponseUptime20);
141
142 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification());
143
144 notification_listener_->DeviceRemoved(
145 kExampleDeviceName);
146
147 notification_listener_->DeviceChanged(
148 true,
149 kExampleDeviceName,
150 description_);
151
152 description_.id = kExampleDeviceID;
153
154 notification_listener_->DeviceChanged(
155 true,
156 kExampleDeviceName,
157 description_);
158 }
159
TEST_F(PrivetNotificationsListenerTest,RegisterTest)160 TEST_F(PrivetNotificationsListenerTest, RegisterTest) {
161 EXPECT_CALL(mock_delegate_, PrivetNotify(
162 false,
163 true));
164
165 notification_listener_->DeviceChanged(
166 true,
167 kExampleDeviceName,
168 description_);
169
170 SuccessfulResponseToInfo(kInfoResponseUptime20);
171
172 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification());
173
174 description_.id = kExampleDeviceID;
175
176 notification_listener_->DeviceChanged(
177 true,
178 kExampleDeviceName,
179 description_);
180 }
181
TEST_F(PrivetNotificationsListenerTest,HighUptimeTest)182 TEST_F(PrivetNotificationsListenerTest, HighUptimeTest) {
183 notification_listener_->DeviceChanged(
184 true,
185 kExampleDeviceName,
186 description_);
187
188 SuccessfulResponseToInfo(kInfoResponseUptime3600);
189
190 description_.id = kExampleDeviceID;
191
192 notification_listener_->DeviceChanged(
193 true,
194 kExampleDeviceName,
195 description_);
196 }
197
TEST_F(PrivetNotificationsListenerTest,HTTPErrorTest)198 TEST_F(PrivetNotificationsListenerTest, HTTPErrorTest) {
199 notification_listener_->DeviceChanged(
200 true,
201 kExampleDeviceName,
202 description_);
203
204 net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
205
206 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
207 net::OK));
208 fetcher->set_response_code(200);
209 fetcher->delegate()->OnURLFetchComplete(fetcher);
210 }
211
TEST_F(PrivetNotificationsListenerTest,DictionaryErrorTest)212 TEST_F(PrivetNotificationsListenerTest, DictionaryErrorTest) {
213 notification_listener_->DeviceChanged(
214 true,
215 kExampleDeviceName,
216 description_);
217
218 SuccessfulResponseToInfo(kInfoResponseNoUptime);
219 }
220
221 } // namespace
222
223 } // namespace local_discovery
224