Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / libaddressinput / chromium / cpp / test / retriever_test.cc
1 // Copyright (C) 2013 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "retriever.h"
16
17 #include <libaddressinput/callback.h>
18 #include <libaddressinput/downloader.h>
19 #include <libaddressinput/storage.h>
20 #include <libaddressinput/util/scoped_ptr.h>
21
22 #include <cstddef>
23 #include <ctime>
24 #include <string>
25
26 #include <gtest/gtest.h>
27
28 #include "fake_downloader.h"
29 #include "fake_storage.h"
30 #include "region_data_constants.h"
31 #include "time_to_string.h"
32
33 namespace i18n {
34 namespace addressinput {
35
36 namespace {
37
38 const char kKey[] = "data/CA";
39
40 // Empty data that the downloader can return.
41 const char kEmptyData[] = "{}";
42
43 // The MD5 checksum for kEmptyData. Retriever uses MD5 to validate data
44 // integrity.
45 const char kEmptyDataChecksum[] = "99914b932bd37a50b983c5e7c90ae93b";
46
47 std::string Wrap(const std::string& data,
48                  const std::string& checksum,
49                  const std::string& timestamp) {
50   return data + "\n" + "checksum=" + checksum + "\n" + "timestamp=" + timestamp;
51 }
52
53 }  // namespace
54
55 // Tests for Retriever object.
56 class RetrieverTest : public testing::Test {
57  protected:
58   RetrieverTest()
59       : storage_(NULL),
60         retriever_(),
61         success_(false),
62         key_(),
63         data_() {
64     ResetRetriever(FakeDownloader::kFakeDataUrl);
65   }
66
67   virtual ~RetrieverTest() {}
68
69   scoped_ptr<Retriever::Callback> BuildCallback() {
70     return ::i18n::addressinput::BuildCallback(
71         this, &RetrieverTest::OnDataReady);
72   }
73
74   void ResetRetriever(const std::string& url) {
75     storage_ = new FakeStorage;
76     retriever_.reset(
77         new Retriever(url,
78                       scoped_ptr<Downloader>(new FakeDownloader),
79                       scoped_ptr<Storage>(storage_)));
80   }
81
82   std::string GetUrlForKey(const std::string& key) {
83     return retriever_->GetUrlForKey(key);
84   }
85
86   std::string GetKeyForUrl(const std::string& url) {
87     return retriever_->GetKeyForUrl(url);
88   }
89
90   Storage* storage_;  // Owned by |retriever_|.
91   scoped_ptr<Retriever> retriever_;
92   bool success_;
93   std::string key_;
94   std::string data_;
95
96  private:
97   void OnDataReady(bool success,
98                    const std::string& key,
99                    const std::string& data) {
100     success_ = success;
101     key_ = key;
102     data_ = data;
103   }
104 };
105
106 TEST_F(RetrieverTest, RetrieveData) {
107   retriever_->Retrieve(kKey, BuildCallback());
108
109   EXPECT_TRUE(success_);
110   EXPECT_EQ(kKey, key_);
111   EXPECT_FALSE(data_.empty());
112   EXPECT_NE(kEmptyData, data_);
113 }
114
115 TEST_F(RetrieverTest, ReadDataFromStorage) {
116   retriever_->Retrieve(kKey, BuildCallback());
117   retriever_->Retrieve(kKey, BuildCallback());
118
119   EXPECT_TRUE(success_);
120   EXPECT_EQ(kKey, key_);
121   EXPECT_FALSE(data_.empty());
122   EXPECT_NE(kEmptyData, data_);
123 }
124
125 TEST_F(RetrieverTest, MissingKeyReturnsEmptyData) {
126   static const char kMissingKey[] = "junk";
127
128   retriever_->Retrieve(kMissingKey, BuildCallback());
129
130   EXPECT_TRUE(success_);
131   EXPECT_EQ(kMissingKey, key_);
132   EXPECT_EQ(kEmptyData, data_);
133 }
134
135 // The downloader that always fails.
136 class FaultyDownloader : public Downloader {
137  public:
138   FaultyDownloader() {}
139   virtual ~FaultyDownloader() {}
140
141   // Downloader implementation.
142   virtual void Download(const std::string& url,
143                         scoped_ptr<Callback> downloaded) {
144     (*downloaded)(false, url, make_scoped_ptr(new std::string("garbage")));
145   }
146 };
147
148 TEST_F(RetrieverTest, FaultyDownloader) {
149   Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
150                           scoped_ptr<Downloader>(new FaultyDownloader),
151                           scoped_ptr<Storage>(new FakeStorage));
152   bad_retriever.Retrieve(kKey, BuildCallback());
153
154   EXPECT_FALSE(success_);
155   EXPECT_EQ(kKey, key_);
156   EXPECT_TRUE(data_.empty());
157 }
158
159 TEST_F(RetrieverTest, FaultyDownloaderFallback) {
160   Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
161                           scoped_ptr<Downloader>(new FaultyDownloader),
162                           scoped_ptr<Storage>(new FakeStorage));
163   const char kFallbackDataKey[] = "data/US";
164   bad_retriever.Retrieve(kFallbackDataKey, BuildCallback());
165
166   EXPECT_TRUE(success_);
167   EXPECT_EQ(kFallbackDataKey, key_);
168   EXPECT_FALSE(data_.empty());
169   EXPECT_NE(kEmptyData, data_);
170 }
171
172 TEST_F(RetrieverTest, NoChecksumAndTimestampWillRedownload) {
173   storage_->Put(kKey, kEmptyData);
174   retriever_->Retrieve(kKey, BuildCallback());
175   EXPECT_TRUE(success_);
176   EXPECT_EQ(kKey, key_);
177   EXPECT_FALSE(data_.empty());
178   EXPECT_NE(kEmptyData, data_);
179 }
180
181 TEST_F(RetrieverTest, ChecksumAndTimestampWillNotRedownload) {
182   storage_->Put(kKey,
183                 Wrap(kEmptyData, kEmptyDataChecksum, TimeToString(time(NULL))));
184   retriever_->Retrieve(kKey, BuildCallback());
185   EXPECT_TRUE(success_);
186   EXPECT_EQ(kKey, key_);
187   EXPECT_EQ(kEmptyData, data_);
188 }
189
190 TEST_F(RetrieverTest, OldTimestampWillRedownload) {
191   storage_->Put(kKey, Wrap(kEmptyData, kEmptyDataChecksum, "0"));
192   retriever_->Retrieve(kKey, BuildCallback());
193   EXPECT_TRUE(success_);
194   EXPECT_EQ(kKey, key_);
195   EXPECT_FALSE(data_.empty());
196   EXPECT_NE(kEmptyData, data_);
197 }
198
199 TEST_F(RetrieverTest, OldTimestampOkIfDownloadFails) {
200   storage_ = new FakeStorage;
201   Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
202                           scoped_ptr<Downloader>(new FaultyDownloader),
203                           scoped_ptr<Storage>(storage_));
204   storage_->Put(kKey, Wrap(kEmptyData, kEmptyDataChecksum, "0"));
205   bad_retriever.Retrieve(kKey, BuildCallback());
206   EXPECT_TRUE(success_);
207   EXPECT_EQ(kKey, key_);
208   EXPECT_EQ(kEmptyData, data_);
209 }
210
211 TEST_F(RetrieverTest, WrongChecksumWillRedownload) {
212   static const char kNonEmptyData[] = "{\"non-empty\": \"data\"}";
213   storage_->Put(
214       kKey,
215       Wrap(kNonEmptyData, kEmptyDataChecksum, TimeToString(time(NULL))));
216   retriever_->Retrieve(kKey, BuildCallback());
217   EXPECT_TRUE(success_);
218   EXPECT_EQ(kKey, key_);
219   EXPECT_FALSE(data_.empty());
220   EXPECT_NE(kNonEmptyData, data_);
221 }
222
223 // The downloader that doesn't get back to you.
224 class HangingDownloader : public Downloader {
225  public:
226   HangingDownloader() {}
227   virtual ~HangingDownloader() {}
228
229   // Downloader implementation.
230   virtual void Download(const std::string& url,
231                         scoped_ptr<Callback> downloaded) {}
232 };
233
234 TEST_F(RetrieverTest, RequestsDontStack) {
235   Retriever slow_retriever(FakeDownloader::kFakeDataUrl,
236                            scoped_ptr<Downloader>(new HangingDownloader),
237                            scoped_ptr<Storage>(new FakeStorage));
238
239   slow_retriever.Retrieve(kKey, BuildCallback());
240   EXPECT_FALSE(success_);
241   EXPECT_TRUE(key_.empty());
242
243   EXPECT_NO_FATAL_FAILURE(slow_retriever.Retrieve(kKey, BuildCallback()));
244 }
245
246 TEST_F(RetrieverTest, GetUrlForKey) {
247   ResetRetriever("test:///");
248   EXPECT_EQ("test:///", GetUrlForKey(""));
249   EXPECT_EQ("test:///data", GetUrlForKey("data"));
250   EXPECT_EQ("test:///data/US", GetUrlForKey("data/US"));
251   EXPECT_EQ("test:///data/CA--fr", GetUrlForKey("data/CA--fr"));
252 }
253
254 TEST_F(RetrieverTest, GetKeyForUrl) {
255   ResetRetriever("test:///");
256   EXPECT_EQ("", GetKeyForUrl("test://"));
257   EXPECT_EQ("", GetKeyForUrl("http://www.google.com/"));
258   EXPECT_EQ("", GetKeyForUrl(""));
259   EXPECT_EQ("", GetKeyForUrl("test:///"));
260   EXPECT_EQ("data", GetKeyForUrl("test:///data"));
261   EXPECT_EQ("data/US", GetKeyForUrl("test:///data/US"));
262   EXPECT_EQ("data/CA--fr", GetKeyForUrl("test:///data/CA--fr"));
263 }
264
265 TEST_F(RetrieverTest, NullCallbackNoCrash) {
266   ASSERT_NO_FATAL_FAILURE(
267       retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>()));
268   ASSERT_NO_FATAL_FAILURE(
269       retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>()));
270 }
271
272 }  // namespace addressinput
273 }  // namespace i18n