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.
5 #include "chrome/browser/local_discovery/privet_url_fetcher.h"
6 #include "net/url_request/test_url_fetcher_factory.h"
7 #include "net/url_request/url_request_test_util.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using testing::StrictMock
;
13 namespace local_discovery
{
17 const char kSamplePrivetURL
[] =
18 "http://10.0.0.8:7676/privet/register?action=start";
19 const char kSamplePrivetToken
[] = "MyToken";
20 const char kEmptyPrivetToken
[] = "\"\"";
22 const char kSampleParsableJSON
[] = "{ \"hello\" : 2 }";
23 const char kSampleUnparsableJSON
[] = "{ \"hello\" : }";
24 const char kSampleJSONWithError
[] = "{ \"error\" : \"unittest_example\" }";
26 class MockPrivetURLFetcherDelegate
: public PrivetURLFetcher::Delegate
{
28 MockPrivetURLFetcherDelegate() : raw_mode_(false) {
31 virtual ~MockPrivetURLFetcherDelegate() {
34 virtual void OnError(PrivetURLFetcher
* fetcher
,
35 PrivetURLFetcher::ErrorType error
) OVERRIDE
{
36 OnErrorInternal(error
);
39 MOCK_METHOD1(OnErrorInternal
, void(PrivetURLFetcher::ErrorType error
));
41 virtual void OnParsedJson(PrivetURLFetcher
* fetcher
,
42 const base::DictionaryValue
* value
,
43 bool has_error
) OVERRIDE
{
44 saved_value_
.reset(value
->DeepCopy());
45 OnParsedJsonInternal(has_error
);
48 MOCK_METHOD1(OnParsedJsonInternal
, void(bool has_error
));
50 virtual void OnNeedPrivetToken(
51 PrivetURLFetcher
* fetcher
,
52 const PrivetURLFetcher::TokenCallback
& callback
) {
55 bool OnRawData(PrivetURLFetcher
* fetcher
,
56 bool response_is_file
,
57 const std::string
& data
,
58 const base::FilePath
& response_file
) {
59 if (!raw_mode_
) return false;
61 if (response_is_file
) {
62 EXPECT_TRUE(response_file
!= base::FilePath());
65 OnRawDataInternal(data
);
71 MOCK_METHOD1(OnRawDataInternal
, void(std::string data
));
73 MOCK_METHOD0(OnFileInternal
, void());
75 const base::DictionaryValue
* saved_value() { return saved_value_
.get(); }
77 void SetRawMode(bool raw_mode
) {
82 scoped_ptr
<base::DictionaryValue
> saved_value_
;
86 class PrivetURLFetcherTest
: public ::testing::Test
{
88 PrivetURLFetcherTest() {
89 request_context_
= new net::TestURLRequestContextGetter(
90 base::MessageLoopProxy::current());
91 privet_urlfetcher_
.reset(new PrivetURLFetcher(
92 GURL(kSamplePrivetURL
),
93 net::URLFetcher::POST
,
94 request_context_
.get(),
97 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL
).GetOrigin().spec(),
100 virtual ~PrivetURLFetcherTest() {
103 void RunFor(base::TimeDelta time_period
) {
104 base::CancelableCallback
<void()> callback(base::Bind(
105 &PrivetURLFetcherTest::Stop
, base::Unretained(this)));
106 base::MessageLoop::current()->PostDelayedTask(
107 FROM_HERE
, callback
.callback(), time_period
);
109 base::MessageLoop::current()->Run();
114 base::MessageLoop::current()->Quit();
118 base::MessageLoop loop_
;
119 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_
;
120 net::TestURLFetcherFactory fetcher_factory_
;
121 scoped_ptr
<PrivetURLFetcher
> privet_urlfetcher_
;
122 StrictMock
<MockPrivetURLFetcherDelegate
> delegate_
;
125 TEST_F(PrivetURLFetcherTest
, FetchSuccess
) {
126 privet_urlfetcher_
->Start();
127 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
128 ASSERT_TRUE(fetcher
!= NULL
);
129 fetcher
->SetResponseString(kSampleParsableJSON
);
130 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
132 fetcher
->set_response_code(200);
134 EXPECT_CALL(delegate_
, OnParsedJsonInternal(false));
135 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
137 const base::DictionaryValue
* value
= delegate_
.saved_value();
139 ASSERT_TRUE(value
!= NULL
);
140 ASSERT_TRUE(value
->GetInteger("hello", &hello_value
));
141 EXPECT_EQ(2, hello_value
);
144 TEST_F(PrivetURLFetcherTest
, HTTP503Retry
) {
145 privet_urlfetcher_
->Start();
146 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
147 ASSERT_TRUE(fetcher
!= NULL
);
148 fetcher
->SetResponseString(kSampleParsableJSON
);
149 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
151 fetcher
->set_response_code(503);
153 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
155 RunFor(base::TimeDelta::FromSeconds(7));
156 fetcher
= fetcher_factory_
.GetFetcherByID(0);
158 ASSERT_TRUE(fetcher
!= NULL
);
159 fetcher
->SetResponseString(kSampleParsableJSON
);
160 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
162 fetcher
->set_response_code(200);
164 EXPECT_CALL(delegate_
, OnParsedJsonInternal(false));
165 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
168 TEST_F(PrivetURLFetcherTest
, ResponseCodeError
) {
169 privet_urlfetcher_
->Start();
170 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
171 ASSERT_TRUE(fetcher
!= NULL
);
172 fetcher
->SetResponseString(kSampleParsableJSON
);
173 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
175 fetcher
->set_response_code(404);
177 EXPECT_CALL(delegate_
,
178 OnErrorInternal(PrivetURLFetcher::RESPONSE_CODE_ERROR
));
179 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
182 TEST_F(PrivetURLFetcherTest
, JsonParseError
) {
183 privet_urlfetcher_
->Start();
184 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
185 ASSERT_TRUE(fetcher
!= NULL
);
186 fetcher
->SetResponseString(kSampleUnparsableJSON
);
187 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
189 fetcher
->set_response_code(200);
191 EXPECT_CALL(delegate_
,
192 OnErrorInternal(PrivetURLFetcher::JSON_PARSE_ERROR
));
193 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
196 TEST_F(PrivetURLFetcherTest
, Header
) {
197 privet_urlfetcher_
->Start();
198 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
199 ASSERT_TRUE(fetcher
!= NULL
);
200 net::HttpRequestHeaders headers
;
201 fetcher
->GetExtraRequestHeaders(&headers
);
203 std::string header_token
;
204 ASSERT_TRUE(headers
.GetHeader("X-Privet-Token", &header_token
));
205 EXPECT_EQ(kSamplePrivetToken
, header_token
);
208 TEST_F(PrivetURLFetcherTest
, Header2
) {
209 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL
).GetOrigin().spec(),
212 privet_urlfetcher_
->SendEmptyPrivetToken();
213 privet_urlfetcher_
->Start();
215 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
216 ASSERT_TRUE(fetcher
!= NULL
);
217 net::HttpRequestHeaders headers
;
218 fetcher
->GetExtraRequestHeaders(&headers
);
220 std::string header_token
;
221 ASSERT_TRUE(headers
.GetHeader("X-Privet-Token", &header_token
));
222 EXPECT_EQ(kEmptyPrivetToken
, header_token
);
225 TEST_F(PrivetURLFetcherTest
, AlwaysSendEmpty
) {
226 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL
).GetOrigin().spec(),
229 privet_urlfetcher_
->SendEmptyPrivetToken();
230 privet_urlfetcher_
->Start();
232 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
233 ASSERT_TRUE(fetcher
!= NULL
);
234 net::HttpRequestHeaders headers
;
235 fetcher
->GetExtraRequestHeaders(&headers
);
237 std::string header_token
;
238 ASSERT_TRUE(headers
.GetHeader("X-Privet-Token", &header_token
));
239 EXPECT_EQ(kEmptyPrivetToken
, header_token
);
242 TEST_F(PrivetURLFetcherTest
, FetchHasError
) {
243 privet_urlfetcher_
->Start();
244 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
245 ASSERT_TRUE(fetcher
!= NULL
);
246 fetcher
->SetResponseString(kSampleJSONWithError
);
247 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
249 fetcher
->set_response_code(200);
251 EXPECT_CALL(delegate_
, OnParsedJsonInternal(true));
252 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
255 TEST_F(PrivetURLFetcherTest
, FetcherRawData
) {
256 delegate_
.SetRawMode(true);
257 privet_urlfetcher_
->Start();
258 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
259 ASSERT_TRUE(fetcher
!= NULL
);
260 fetcher
->SetResponseString(kSampleJSONWithError
);
261 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
263 fetcher
->set_response_code(200);
265 EXPECT_CALL(delegate_
, OnRawDataInternal(kSampleJSONWithError
));
266 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
269 TEST_F(PrivetURLFetcherTest
, RangeRequest
) {
270 delegate_
.SetRawMode(true);
271 privet_urlfetcher_
->SetByteRange(200, 300);
272 privet_urlfetcher_
->Start();
273 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
274 ASSERT_TRUE(fetcher
!= NULL
);
275 net::HttpRequestHeaders headers
;
276 fetcher
->GetExtraRequestHeaders(&headers
);
278 std::string header_range
;
279 ASSERT_TRUE(headers
.GetHeader("Range", &header_range
));
280 EXPECT_EQ("bytes=200-300", header_range
);
283 TEST_F(PrivetURLFetcherTest
, FetcherToFile
) {
284 delegate_
.SetRawMode(true);
285 privet_urlfetcher_
->SaveResponseToFile();
286 privet_urlfetcher_
->Start();
287 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
288 ASSERT_TRUE(fetcher
!= NULL
);
289 fetcher
->SetResponseFilePath(
290 base::FilePath(FILE_PATH_LITERAL("sample/file")));
291 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
293 fetcher
->set_response_code(200);
295 EXPECT_CALL(delegate_
, OnFileInternal());
296 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
301 } // namespace local_discovery