privet_url_fetcher_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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_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"
10
11using testing::StrictMock;
12
13namespace local_discovery {
14
15namespace {
16
17const char kSamplePrivetURL[] =
18    "http://10.0.0.8:7676/privet/register?action=start";
19const char kSamplePrivetToken[] = "MyToken";
20const char kEmptyPrivetToken[] = "\"\"";
21
22const char kSampleParsableJSON[] = "{ \"hello\" : 2 }";
23const char kSampleUnparsableJSON[] = "{ \"hello\" : }";
24const char kSampleJSONWithError[] = "{ \"error\" : \"unittest_example\" }";
25
26class MockPrivetURLFetcherDelegate : public PrivetURLFetcher::Delegate {
27 public:
28  virtual void OnError(PrivetURLFetcher* fetcher,
29                       PrivetURLFetcher::ErrorType error) OVERRIDE {
30    OnErrorInternal(error);
31  }
32
33  MOCK_METHOD1(OnErrorInternal, void(PrivetURLFetcher::ErrorType error));
34
35  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
36                            const base::DictionaryValue* value,
37                            bool has_error) OVERRIDE {
38    saved_value_.reset(value->DeepCopy());
39    OnParsedJsonInternal(has_error);
40  }
41
42  MOCK_METHOD1(OnParsedJsonInternal, void(bool has_error));
43
44  virtual void OnNeedPrivetToken(
45      PrivetURLFetcher* fetcher,
46      const PrivetURLFetcher::TokenCallback& callback) {
47  }
48
49  const DictionaryValue* saved_value() { return saved_value_.get(); }
50
51 private:
52  scoped_ptr<DictionaryValue> saved_value_;
53};
54
55class PrivetURLFetcherTest : public ::testing::Test {
56 public:
57  PrivetURLFetcherTest() {
58    request_context_= new net::TestURLRequestContextGetter(
59        base::MessageLoopProxy::current());
60    privet_urlfetcher_.reset(new PrivetURLFetcher(
61        kSamplePrivetToken,
62        GURL(kSamplePrivetURL),
63        net::URLFetcher::POST,
64        request_context_.get(),
65        &delegate_));
66  }
67  virtual ~PrivetURLFetcherTest() {
68  }
69
70  void RunFor(base::TimeDelta time_period) {
71    base::CancelableCallback<void()> callback(base::Bind(
72        &PrivetURLFetcherTest::Stop, base::Unretained(this)));
73    base::MessageLoop::current()->PostDelayedTask(
74        FROM_HERE, callback.callback(), time_period);
75
76    base::MessageLoop::current()->Run();
77    callback.Cancel();
78  }
79
80  void Stop() {
81    base::MessageLoop::current()->Quit();
82  }
83
84 protected:
85  base::MessageLoop loop_;
86  scoped_refptr<net::TestURLRequestContextGetter> request_context_;
87  net::TestURLFetcherFactory fetcher_factory_;
88  scoped_ptr<PrivetURLFetcher> privet_urlfetcher_;
89  StrictMock<MockPrivetURLFetcherDelegate> delegate_;
90};
91
92TEST_F(PrivetURLFetcherTest, FetchSuccess) {
93  privet_urlfetcher_->Start();
94  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
95  ASSERT_TRUE(fetcher != NULL);
96  fetcher->SetResponseString(kSampleParsableJSON);
97  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
98                                            net::OK));
99  fetcher->set_response_code(200);
100
101  EXPECT_CALL(delegate_, OnParsedJsonInternal(false));
102  fetcher->delegate()->OnURLFetchComplete(fetcher);
103
104  const base::DictionaryValue* value = delegate_.saved_value();
105  int hello_value;
106  ASSERT_TRUE(value != NULL);
107  ASSERT_TRUE(value->GetInteger("hello", &hello_value));
108  EXPECT_EQ(2, hello_value);
109}
110
111TEST_F(PrivetURLFetcherTest, URLFetcherErrorRetry) {
112  privet_urlfetcher_->Start();
113  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
114  ASSERT_TRUE(fetcher != NULL);
115  fetcher->SetResponseString(kSampleParsableJSON);
116  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
117                                            net::ERR_TIMED_OUT));
118  fetcher->set_response_code(-1);
119
120  fetcher->delegate()->OnURLFetchComplete(fetcher);
121
122  RunFor(base::TimeDelta::FromSeconds(7));
123  fetcher = fetcher_factory_.GetFetcherByID(0);
124
125  ASSERT_TRUE(fetcher != NULL);
126  fetcher->SetResponseString(kSampleParsableJSON);
127  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
128                                            net::OK));
129  fetcher->set_response_code(200);
130
131  EXPECT_CALL(delegate_, OnParsedJsonInternal(false));
132  fetcher->delegate()->OnURLFetchComplete(fetcher);
133}
134
135TEST_F(PrivetURLFetcherTest, HTTP503Retry) {
136  privet_urlfetcher_->Start();
137  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
138  ASSERT_TRUE(fetcher != NULL);
139  fetcher->SetResponseString(kSampleParsableJSON);
140  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
141                                            net::OK));
142  fetcher->set_response_code(503);
143
144  fetcher->delegate()->OnURLFetchComplete(fetcher);
145
146  RunFor(base::TimeDelta::FromSeconds(7));
147  fetcher = fetcher_factory_.GetFetcherByID(0);
148
149  ASSERT_TRUE(fetcher != NULL);
150  fetcher->SetResponseString(kSampleParsableJSON);
151  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
152                                            net::OK));
153  fetcher->set_response_code(200);
154
155  EXPECT_CALL(delegate_, OnParsedJsonInternal(false));
156  fetcher->delegate()->OnURLFetchComplete(fetcher);
157}
158
159TEST_F(PrivetURLFetcherTest, ResponseCodeError) {
160  privet_urlfetcher_->Start();
161  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
162  ASSERT_TRUE(fetcher != NULL);
163  fetcher->SetResponseString(kSampleParsableJSON);
164  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
165                                            net::OK));
166  fetcher->set_response_code(404);
167
168  EXPECT_CALL(delegate_,
169              OnErrorInternal(PrivetURLFetcher::RESPONSE_CODE_ERROR));
170  fetcher->delegate()->OnURLFetchComplete(fetcher);
171}
172
173TEST_F(PrivetURLFetcherTest, JsonParseError) {
174  privet_urlfetcher_->Start();
175  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
176  ASSERT_TRUE(fetcher != NULL);
177  fetcher->SetResponseString(kSampleUnparsableJSON);
178  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
179                                            net::OK));
180  fetcher->set_response_code(200);
181
182  EXPECT_CALL(delegate_,
183              OnErrorInternal(PrivetURLFetcher::JSON_PARSE_ERROR));
184  fetcher->delegate()->OnURLFetchComplete(fetcher);
185}
186
187TEST_F(PrivetURLFetcherTest, Header) {
188  privet_urlfetcher_->Start();
189  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
190  ASSERT_TRUE(fetcher != NULL);
191  net::HttpRequestHeaders headers;
192  fetcher->GetExtraRequestHeaders(&headers);
193
194  std::string header_token;
195  ASSERT_TRUE(headers.GetHeader("X-Privet-Token", &header_token));
196  EXPECT_EQ(kSamplePrivetToken, header_token);
197}
198
199TEST_F(PrivetURLFetcherTest, Header2) {
200  privet_urlfetcher_.reset(new PrivetURLFetcher(
201      "",
202      GURL(kSamplePrivetURL),
203      net::URLFetcher::POST,
204      request_context_.get(),
205      &delegate_));
206
207  privet_urlfetcher_->AllowEmptyPrivetToken();
208  privet_urlfetcher_->Start();
209
210  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
211  ASSERT_TRUE(fetcher != NULL);
212  net::HttpRequestHeaders headers;
213  fetcher->GetExtraRequestHeaders(&headers);
214
215  std::string header_token;
216  ASSERT_TRUE(headers.GetHeader("X-Privet-Token", &header_token));
217  EXPECT_EQ(kEmptyPrivetToken, header_token);
218}
219
220TEST_F(PrivetURLFetcherTest, FetchHasError) {
221  privet_urlfetcher_->Start();
222  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
223  ASSERT_TRUE(fetcher != NULL);
224  fetcher->SetResponseString(kSampleJSONWithError);
225  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
226                                            net::OK));
227  fetcher->set_response_code(200);
228
229  EXPECT_CALL(delegate_, OnParsedJsonInternal(true));
230  fetcher->delegate()->OnURLFetchComplete(fetcher);
231}
232
233}  // namespace
234
235}  // namespace local_discovery
236