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 "base/thread_task_runner_handle.h"
6 #include "chrome/browser/local_discovery/privet_url_fetcher.h"
7 #include "net/url_request/test_url_fetcher_factory.h"
8 #include "net/url_request/url_request_test_util.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using testing::StrictMock
;
14 namespace local_discovery
{
18 const char kSamplePrivetURL
[] =
19 "http://10.0.0.8:7676/privet/register?action=start";
20 const char kSamplePrivetToken
[] = "MyToken";
21 const char kEmptyPrivetToken
[] = "\"\"";
23 const char kSampleParsableJSON
[] = "{ \"hello\" : 2 }";
24 const char kSampleUnparsableJSON
[] = "{ \"hello\" : }";
25 const char kSampleJSONWithError
[] = "{ \"error\" : \"unittest_example\" }";
27 class MockPrivetURLFetcherDelegate
: public PrivetURLFetcher::Delegate
{
29 MockPrivetURLFetcherDelegate() : raw_mode_(false) {
32 ~MockPrivetURLFetcherDelegate() override
{
35 void OnError(PrivetURLFetcher
* fetcher
,
36 PrivetURLFetcher::ErrorType error
) override
{
37 OnErrorInternal(error
);
40 MOCK_METHOD1(OnErrorInternal
, void(PrivetURLFetcher::ErrorType error
));
42 void OnParsedJson(PrivetURLFetcher
* fetcher
,
43 const base::DictionaryValue
& value
,
44 bool has_error
) override
{
45 saved_value_
.reset(value
.DeepCopy());
46 OnParsedJsonInternal(has_error
);
49 MOCK_METHOD1(OnParsedJsonInternal
, void(bool has_error
));
51 virtual void OnNeedPrivetToken(
52 PrivetURLFetcher
* fetcher
,
53 const PrivetURLFetcher::TokenCallback
& callback
) {
56 bool OnRawData(PrivetURLFetcher
* fetcher
,
57 bool response_is_file
,
58 const std::string
& data
,
59 const base::FilePath
& response_file
) {
60 if (!raw_mode_
) return false;
62 if (response_is_file
) {
63 EXPECT_TRUE(response_file
!= base::FilePath());
66 OnRawDataInternal(data
);
72 MOCK_METHOD1(OnRawDataInternal
, void(std::string data
));
74 MOCK_METHOD0(OnFileInternal
, void());
76 const base::DictionaryValue
* saved_value() { return saved_value_
.get(); }
78 void SetRawMode(bool raw_mode
) {
82 std::string
GetAuthToken() { return "MyAuthToken"; }
85 scoped_ptr
<base::DictionaryValue
> saved_value_
;
89 class PrivetURLFetcherTest
: public ::testing::Test
{
91 PrivetURLFetcherTest() {
92 request_context_
= new net::TestURLRequestContextGetter(
93 base::ThreadTaskRunnerHandle::Get());
94 privet_urlfetcher_
.reset(new PrivetURLFetcher(
95 GURL(kSamplePrivetURL
),
96 net::URLFetcher::POST
,
97 request_context_
.get(),
100 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL
).GetOrigin().spec(),
103 virtual ~PrivetURLFetcherTest() {
106 void RunFor(base::TimeDelta time_period
) {
107 base::CancelableCallback
<void()> callback(base::Bind(
108 &PrivetURLFetcherTest::Stop
, base::Unretained(this)));
109 base::MessageLoop::current()->PostDelayedTask(
110 FROM_HERE
, callback
.callback(), time_period
);
112 base::MessageLoop::current()->Run();
117 base::MessageLoop::current()->Quit();
121 base::MessageLoop loop_
;
122 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_
;
123 net::TestURLFetcherFactory fetcher_factory_
;
124 scoped_ptr
<PrivetURLFetcher
> privet_urlfetcher_
;
125 StrictMock
<MockPrivetURLFetcherDelegate
> delegate_
;
128 TEST_F(PrivetURLFetcherTest
, FetchSuccess
) {
129 privet_urlfetcher_
->Start();
130 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
131 ASSERT_TRUE(fetcher
!= NULL
);
132 fetcher
->SetResponseString(kSampleParsableJSON
);
133 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
135 fetcher
->set_response_code(200);
137 EXPECT_CALL(delegate_
, OnParsedJsonInternal(false));
138 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
140 const base::DictionaryValue
* value
= delegate_
.saved_value();
142 ASSERT_TRUE(value
!= NULL
);
143 ASSERT_TRUE(value
->GetInteger("hello", &hello_value
));
144 EXPECT_EQ(2, hello_value
);
147 TEST_F(PrivetURLFetcherTest
, HTTP503Retry
) {
148 privet_urlfetcher_
->Start();
149 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
150 ASSERT_TRUE(fetcher
!= NULL
);
151 fetcher
->SetResponseString(kSampleParsableJSON
);
152 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
154 fetcher
->set_response_code(503);
156 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
158 RunFor(base::TimeDelta::FromSeconds(7));
159 fetcher
= fetcher_factory_
.GetFetcherByID(0);
161 ASSERT_TRUE(fetcher
!= NULL
);
162 fetcher
->SetResponseString(kSampleParsableJSON
);
163 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
165 fetcher
->set_response_code(200);
167 EXPECT_CALL(delegate_
, OnParsedJsonInternal(false));
168 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
171 TEST_F(PrivetURLFetcherTest
, ResponseCodeError
) {
172 privet_urlfetcher_
->Start();
173 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
174 ASSERT_TRUE(fetcher
!= NULL
);
175 fetcher
->SetResponseString(kSampleParsableJSON
);
176 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
178 fetcher
->set_response_code(404);
180 EXPECT_CALL(delegate_
,
181 OnErrorInternal(PrivetURLFetcher::RESPONSE_CODE_ERROR
));
182 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
185 TEST_F(PrivetURLFetcherTest
, JsonParseError
) {
186 privet_urlfetcher_
->Start();
187 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
188 ASSERT_TRUE(fetcher
!= NULL
);
189 fetcher
->SetResponseString(kSampleUnparsableJSON
);
190 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
192 fetcher
->set_response_code(200);
194 EXPECT_CALL(delegate_
,
195 OnErrorInternal(PrivetURLFetcher::JSON_PARSE_ERROR
));
196 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
199 TEST_F(PrivetURLFetcherTest
, Header
) {
200 privet_urlfetcher_
->Start();
201 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
202 ASSERT_TRUE(fetcher
!= NULL
);
203 net::HttpRequestHeaders headers
;
204 fetcher
->GetExtraRequestHeaders(&headers
);
206 std::string header_token
;
207 ASSERT_TRUE(headers
.GetHeader("X-Privet-Token", &header_token
));
208 EXPECT_EQ(kSamplePrivetToken
, header_token
);
211 TEST_F(PrivetURLFetcherTest
, Header2
) {
212 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL
).GetOrigin().spec(),
215 privet_urlfetcher_
->SendEmptyPrivetToken();
216 privet_urlfetcher_
->Start();
218 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
219 ASSERT_TRUE(fetcher
!= NULL
);
220 net::HttpRequestHeaders headers
;
221 fetcher
->GetExtraRequestHeaders(&headers
);
223 std::string header_token
;
224 ASSERT_TRUE(headers
.GetHeader("X-Privet-Token", &header_token
));
225 EXPECT_EQ(kEmptyPrivetToken
, header_token
);
228 TEST_F(PrivetURLFetcherTest
, AlwaysSendEmpty
) {
229 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL
).GetOrigin().spec(),
232 privet_urlfetcher_
->SendEmptyPrivetToken();
233 privet_urlfetcher_
->Start();
235 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
236 ASSERT_TRUE(fetcher
!= NULL
);
237 net::HttpRequestHeaders headers
;
238 fetcher
->GetExtraRequestHeaders(&headers
);
240 std::string header_token
;
241 ASSERT_TRUE(headers
.GetHeader("X-Privet-Token", &header_token
));
242 EXPECT_EQ(kEmptyPrivetToken
, header_token
);
245 TEST_F(PrivetURLFetcherTest
, FetchHasError
) {
246 privet_urlfetcher_
->Start();
247 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
248 ASSERT_TRUE(fetcher
!= NULL
);
249 fetcher
->SetResponseString(kSampleJSONWithError
);
250 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
252 fetcher
->set_response_code(200);
254 EXPECT_CALL(delegate_
, OnParsedJsonInternal(true));
255 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
258 TEST_F(PrivetURLFetcherTest
, FetcherRawData
) {
259 delegate_
.SetRawMode(true);
260 privet_urlfetcher_
->Start();
261 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
262 ASSERT_TRUE(fetcher
!= NULL
);
263 fetcher
->SetResponseString(kSampleJSONWithError
);
264 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
266 fetcher
->set_response_code(200);
268 EXPECT_CALL(delegate_
, OnRawDataInternal(kSampleJSONWithError
));
269 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
272 TEST_F(PrivetURLFetcherTest
, RangeRequest
) {
273 delegate_
.SetRawMode(true);
274 privet_urlfetcher_
->SetByteRange(200, 300);
275 privet_urlfetcher_
->Start();
276 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
277 ASSERT_TRUE(fetcher
!= NULL
);
278 net::HttpRequestHeaders headers
;
279 fetcher
->GetExtraRequestHeaders(&headers
);
281 std::string header_range
;
282 ASSERT_TRUE(headers
.GetHeader("Range", &header_range
));
283 EXPECT_EQ("bytes=200-300", header_range
);
286 TEST_F(PrivetURLFetcherTest
, FetcherToFile
) {
287 delegate_
.SetRawMode(true);
288 privet_urlfetcher_
->SaveResponseToFile();
289 privet_urlfetcher_
->Start();
290 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
291 ASSERT_TRUE(fetcher
!= NULL
);
292 fetcher
->SetResponseFilePath(
293 base::FilePath(FILE_PATH_LITERAL("sample/file")));
294 fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS
,
296 fetcher
->set_response_code(200);
298 EXPECT_CALL(delegate_
, OnFileInternal());
299 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
302 TEST_F(PrivetURLFetcherTest
, V3Mode
) {
303 delegate_
.SetRawMode(true);
304 privet_urlfetcher_
->V3Mode();
305 privet_urlfetcher_
->Start();
306 net::TestURLFetcher
* fetcher
= fetcher_factory_
.GetFetcherByID(0);
307 ASSERT_TRUE(fetcher
!= NULL
);
308 fetcher
->SetResponseFilePath(
309 base::FilePath(FILE_PATH_LITERAL("sample/file")));
310 net::HttpRequestHeaders headers
;
311 fetcher
->GetExtraRequestHeaders(&headers
);
313 std::string header_token
;
314 ASSERT_FALSE(headers
.GetHeader("X-Privet-Token", &header_token
));
315 ASSERT_FALSE(headers
.GetHeader("X-Privet-Auth", &header_token
));
316 ASSERT_TRUE(headers
.GetHeader("Authorization", &header_token
));
317 ASSERT_EQ("MyAuthToken", header_token
);
322 } // namespace local_discovery