privet_url_fetcher_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 MockPrivetURLFetcherDelegate() : raw_mode_(false) { 29 } 30 31 virtual ~MockPrivetURLFetcherDelegate() { 32 } 33 34 virtual void OnError(PrivetURLFetcher* fetcher, 35 PrivetURLFetcher::ErrorType error) OVERRIDE { 36 OnErrorInternal(error); 37 } 38 39 MOCK_METHOD1(OnErrorInternal, void(PrivetURLFetcher::ErrorType error)); 40 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); 46 } 47 48 MOCK_METHOD1(OnParsedJsonInternal, void(bool has_error)); 49 50 virtual void OnNeedPrivetToken( 51 PrivetURLFetcher* fetcher, 52 const PrivetURLFetcher::TokenCallback& callback) { 53 } 54 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; 60 61 if (response_is_file) { 62 EXPECT_TRUE(response_file != base::FilePath()); 63 OnFileInternal(); 64 } else { 65 OnRawDataInternal(data); 66 } 67 68 return true; 69 } 70 71 MOCK_METHOD1(OnRawDataInternal, void(std::string data)); 72 73 MOCK_METHOD0(OnFileInternal, void()); 74 75 const base::DictionaryValue* saved_value() { return saved_value_.get(); } 76 77 void SetRawMode(bool raw_mode) { 78 raw_mode_ = raw_mode; 79 } 80 81 private: 82 scoped_ptr<base::DictionaryValue> saved_value_; 83 bool raw_mode_; 84}; 85 86class PrivetURLFetcherTest : public ::testing::Test { 87 public: 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(), 95 &delegate_)); 96 97 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL).GetOrigin().spec(), 98 kSamplePrivetToken); 99 } 100 virtual ~PrivetURLFetcherTest() { 101 } 102 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); 108 109 base::MessageLoop::current()->Run(); 110 callback.Cancel(); 111 } 112 113 void Stop() { 114 base::MessageLoop::current()->Quit(); 115 } 116 117 protected: 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_; 123}; 124 125TEST_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, 131 net::OK)); 132 fetcher->set_response_code(200); 133 134 EXPECT_CALL(delegate_, OnParsedJsonInternal(false)); 135 fetcher->delegate()->OnURLFetchComplete(fetcher); 136 137 const base::DictionaryValue* value = delegate_.saved_value(); 138 int hello_value; 139 ASSERT_TRUE(value != NULL); 140 ASSERT_TRUE(value->GetInteger("hello", &hello_value)); 141 EXPECT_EQ(2, hello_value); 142} 143 144TEST_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, 150 net::OK)); 151 fetcher->set_response_code(503); 152 153 fetcher->delegate()->OnURLFetchComplete(fetcher); 154 155 RunFor(base::TimeDelta::FromSeconds(7)); 156 fetcher = fetcher_factory_.GetFetcherByID(0); 157 158 ASSERT_TRUE(fetcher != NULL); 159 fetcher->SetResponseString(kSampleParsableJSON); 160 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 161 net::OK)); 162 fetcher->set_response_code(200); 163 164 EXPECT_CALL(delegate_, OnParsedJsonInternal(false)); 165 fetcher->delegate()->OnURLFetchComplete(fetcher); 166} 167 168TEST_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, 174 net::OK)); 175 fetcher->set_response_code(404); 176 177 EXPECT_CALL(delegate_, 178 OnErrorInternal(PrivetURLFetcher::RESPONSE_CODE_ERROR)); 179 fetcher->delegate()->OnURLFetchComplete(fetcher); 180} 181 182TEST_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, 188 net::OK)); 189 fetcher->set_response_code(200); 190 191 EXPECT_CALL(delegate_, 192 OnErrorInternal(PrivetURLFetcher::JSON_PARSE_ERROR)); 193 fetcher->delegate()->OnURLFetchComplete(fetcher); 194} 195 196TEST_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); 202 203 std::string header_token; 204 ASSERT_TRUE(headers.GetHeader("X-Privet-Token", &header_token)); 205 EXPECT_EQ(kSamplePrivetToken, header_token); 206} 207 208TEST_F(PrivetURLFetcherTest, Header2) { 209 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL).GetOrigin().spec(), 210 ""); 211 212 privet_urlfetcher_->SendEmptyPrivetToken(); 213 privet_urlfetcher_->Start(); 214 215 net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); 216 ASSERT_TRUE(fetcher != NULL); 217 net::HttpRequestHeaders headers; 218 fetcher->GetExtraRequestHeaders(&headers); 219 220 std::string header_token; 221 ASSERT_TRUE(headers.GetHeader("X-Privet-Token", &header_token)); 222 EXPECT_EQ(kEmptyPrivetToken, header_token); 223} 224 225TEST_F(PrivetURLFetcherTest, AlwaysSendEmpty) { 226 PrivetURLFetcher::SetTokenForHost(GURL(kSamplePrivetURL).GetOrigin().spec(), 227 "SampleToken"); 228 229 privet_urlfetcher_->SendEmptyPrivetToken(); 230 privet_urlfetcher_->Start(); 231 232 net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); 233 ASSERT_TRUE(fetcher != NULL); 234 net::HttpRequestHeaders headers; 235 fetcher->GetExtraRequestHeaders(&headers); 236 237 std::string header_token; 238 ASSERT_TRUE(headers.GetHeader("X-Privet-Token", &header_token)); 239 EXPECT_EQ(kEmptyPrivetToken, header_token); 240} 241 242TEST_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, 248 net::OK)); 249 fetcher->set_response_code(200); 250 251 EXPECT_CALL(delegate_, OnParsedJsonInternal(true)); 252 fetcher->delegate()->OnURLFetchComplete(fetcher); 253} 254 255TEST_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, 262 net::OK)); 263 fetcher->set_response_code(200); 264 265 EXPECT_CALL(delegate_, OnRawDataInternal(kSampleJSONWithError)); 266 fetcher->delegate()->OnURLFetchComplete(fetcher); 267} 268 269TEST_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); 277 278 std::string header_range; 279 ASSERT_TRUE(headers.GetHeader("Range", &header_range)); 280 EXPECT_EQ("bytes=200-300", header_range); 281} 282 283TEST_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, 292 net::OK)); 293 fetcher->set_response_code(200); 294 295 EXPECT_CALL(delegate_, OnFileInternal()); 296 fetcher->delegate()->OnURLFetchComplete(fetcher); 297} 298 299} // namespace 300 301} // namespace local_discovery 302