1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/run_loop.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/geolocation/geoposition.h"
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/timezone/timezone_provider.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_response_headers.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_status_code.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_fetcher_impl.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request_status.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kRequestRetryIntervalMilliSeconds = 200;
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This should be different from default to prevent TimeZoneRequest
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// from modifying it.
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kTestTimeZoneProviderUrl[] =
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "https://localhost/maps/api/timezone/json?";
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kSimpleResponseBody[] =
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "{\n"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    \"dstOffset\" : 0.0,\n"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    \"rawOffset\" : -28800.0,\n"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    \"status\" : \"OK\",\n"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    \"timeZoneId\" : \"America/Los_Angeles\",\n"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    \"timeZoneName\" : \"Pacific Standard Time\"\n"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "}";
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct SimpleRequest {
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SimpleRequest()
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : url("https://localhost/maps/api/timezone/"
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "json?location=39.603481,-119.682251&timestamp=1331161200&sensor="
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "false"),
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        http_response(kSimpleResponseBody) {
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    position.latitude = 39.6034810;
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    position.longitude = -119.6822510;
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    position.accuracy = 1;
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    position.error_code = 0;
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    position.timestamp = base::Time::FromTimeT(1331161200);
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    position.status = chromeos::Geoposition::STATUS_NONE;
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "latitude=39.603481, longitude=-119.682251, accuracy=1.000000, "
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "error_code=0, error_message='', status=0 (NONE)",
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        position.ToString());
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone.dstOffset = 0;
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone.rawOffset = -28800;
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone.timeZoneId = "America/Los_Angeles";
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone.timeZoneName = "Pacific Standard Time";
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone.error_message.erase();
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone.status = chromeos::TimeZoneResponseData::OK;
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "dstOffset=0.000000, rawOffset=-28800.000000, "
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "timeZoneId='America/Los_Angeles', timeZoneName='Pacific Standard "
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "Time', error_message='', status=0 (OK)",
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        timezone.ToStringForDebug());
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL url;
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos::Geoposition position;
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string http_response;
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos::TimeZoneResponseData timezone;
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // anonymous namespace
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chromeos {
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This is helper class for net::FakeURLFetcherFactory.
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class TestTimeZoneAPIURLFetcherCallback {
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestTimeZoneAPIURLFetcherCallback(const GURL& url,
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    const size_t require_retries,
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    const std::string& response,
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    TimeZoneProvider* provider)
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : url_(url),
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        require_retries_(require_retries),
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        response_(response),
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        factory_(NULL),
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        attempts_(0),
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        provider_(provider) {}
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& url,
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLFetcherDelegate* delegate,
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const std::string& response_data,
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::HttpStatusCode response_code,
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::Status status) {
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(provider_->requests_.size(), 1U);
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    TimeZoneRequest* timezone_request = provider_->requests_[0];
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::TimeDelta base_retry_interval =
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(kRequestRetryIntervalMilliSeconds);
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone_request->set_retry_sleep_on_server_error_for_testing(
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base_retry_interval);
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone_request->set_retry_sleep_on_bad_response_for_testing(
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base_retry_interval);
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++attempts_;
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (attempts_ > require_retries_) {
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      response_code = net::HTTP_OK;
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      status = net::URLRequestStatus::SUCCESS;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      factory_->SetFakeResponse(url, response_, response_code, status);
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher(
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        url, delegate, response_, response_code, status));
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> download_headers =
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new net::HttpResponseHeaders(std::string());
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    download_headers->AddHeader("Content-Type: application/json");
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    fetcher->set_response_headers(download_headers);
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return fetcher.Pass();
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void Initialize(net::FakeURLFetcherFactory* factory) {
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    factory_ = factory;
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    factory_->SetFakeResponse(url_,
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              std::string(),
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              net::HTTP_INTERNAL_SERVER_ERROR,
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              net::URLRequestStatus::FAILED);
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t attempts() const { return attempts_; }
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const GURL url_;
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Respond with OK on required retry attempt.
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const size_t require_retries_;
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string response_;
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::FakeURLFetcherFactory* factory_;
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t attempts_;
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneProvider* provider_;
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestTimeZoneAPIURLFetcherCallback);
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This implements fake TimeZone API remote endpoint.
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Response data is served to TimeZoneProvider via
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// net::FakeURLFetcher.
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class TimeZoneAPIFetcherFactory {
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneAPIFetcherFactory(const GURL& url,
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            const std::string& response,
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            const size_t require_retries,
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            TimeZoneProvider* provider) {
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    url_callback_.reset(new TestTimeZoneAPIURLFetcherCallback(
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        url, require_retries, response, provider));
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLFetcherImpl::set_factory(NULL);
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    fetcher_factory_.reset(new net::FakeURLFetcherFactory(
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NULL,
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(&TestTimeZoneAPIURLFetcherCallback::CreateURLFetcher,
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   base::Unretained(url_callback_.get()))));
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    url_callback_->Initialize(fetcher_factory_.get());
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t attempts() const { return url_callback_->attempts(); }
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<TestTimeZoneAPIURLFetcherCallback> url_callback_;
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<net::FakeURLFetcherFactory> fetcher_factory_;
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TimeZoneAPIFetcherFactory);
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class TimeZoneReceiver {
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneReceiver() : server_error_(false) {}
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void OnRequestDone(scoped_ptr<TimeZoneResponseData> timezone,
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     bool server_error) {
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    timezone_ = timezone.Pass();
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    server_error_ = server_error;
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_runner_->Quit();
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void WaitUntilRequestDone() {
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_runner_.reset(new base::RunLoop);
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_runner_->Run();
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const TimeZoneResponseData* timezone() const { return timezone_.get(); }
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool server_error() const { return server_error_; }
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<TimeZoneResponseData> timezone_;
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool server_error_;
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::RunLoop> message_loop_runner_;
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class TimeZoneTest : public testing::Test {
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(TimeZoneTest, ResponseOK) {
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneProvider provider(NULL, GURL(kTestTimeZoneProviderUrl));
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const SimpleRequest simple_request;
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneAPIFetcherFactory url_factory(simple_request.url,
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        simple_request.http_response,
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        0 /* require_retries */,
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        &provider);
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneReceiver receiver;
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  provider.RequestTimezone(simple_request.position,
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           false,
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           base::TimeDelta::FromSeconds(1),
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           base::Bind(&TimeZoneReceiver::OnRequestDone,
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      base::Unretained(&receiver)));
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  receiver.WaitUntilRequestDone();
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(simple_request.timezone.ToStringForDebug(),
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            receiver.timezone()->ToStringForDebug());
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(receiver.server_error());
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1U, url_factory.attempts());
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(TimeZoneTest, ResponseOKWithRetries) {
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneProvider provider(NULL, GURL(kTestTimeZoneProviderUrl));
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const SimpleRequest simple_request;
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneAPIFetcherFactory url_factory(simple_request.url,
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        simple_request.http_response,
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        3 /* require_retries */,
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        &provider);
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneReceiver receiver;
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  provider.RequestTimezone(simple_request.position,
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           false,
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           base::TimeDelta::FromSeconds(1),
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           base::Bind(&TimeZoneReceiver::OnRequestDone,
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      base::Unretained(&receiver)));
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  receiver.WaitUntilRequestDone();
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(simple_request.timezone.ToStringForDebug(),
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            receiver.timezone()->ToStringForDebug());
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(receiver.server_error());
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(4U, url_factory.attempts());
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(TimeZoneTest, InvalidResponse) {
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneProvider provider(NULL, GURL(kTestTimeZoneProviderUrl));
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const SimpleRequest simple_request;
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneAPIFetcherFactory url_factory(simple_request.url,
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        "invalid JSON string",
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        0 /* require_retries */,
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        &provider);
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TimeZoneReceiver receiver;
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int timeout_seconds = 1;
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t expected_retries = static_cast<size_t>(
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      timeout_seconds * 1000 / kRequestRetryIntervalMilliSeconds);
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_GE(expected_retries, 2U);
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  provider.RequestTimezone(simple_request.position,
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           false,
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           base::TimeDelta::FromSeconds(timeout_seconds),
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           base::Bind(&TimeZoneReceiver::OnRequestDone,
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      base::Unretained(&receiver)));
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  receiver.WaitUntilRequestDone();
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "dstOffset=0.000000, rawOffset=0.000000, timeZoneId='', timeZoneName='', "
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "error_message='TimeZone provider at 'https://localhost/' : JSONReader "
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "failed: Line: 1, column: 1, Unexpected token..', status=6 "
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "(REQUEST_ERROR)",
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      receiver.timezone()->ToStringForDebug());
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(receiver.server_error());
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_GE(url_factory.attempts(), 2U);
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (url_factory.attempts() > expected_retries + 1) {
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(WARNING) << "TimeZoneTest::InvalidResponse: Too many attempts ("
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 << url_factory.attempts() << "), no more then "
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 << expected_retries + 1 << " expected.";
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (url_factory.attempts() < expected_retries - 1) {
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(WARNING) << "TimeZoneTest::InvalidResponse: Too less attempts ("
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 << url_factory.attempts() << "), greater then "
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 << expected_retries - 1 << " expected.";
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace chromeos
291