Upstream version 5.34.104.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 scoped_ptr<std::string> Wrap(const std::string& data,
48                              const std::string& checksum,
49                              const std::string& timestamp) {
50   return make_scoped_ptr(new std::string(
51       data + "\n" + "checksum=" + checksum + "\n" + "timestamp=" + timestamp));
52 }
53
54 }  // namespace
55
56 // Tests for Retriever object.
57 class RetrieverTest : public testing::Test {
58  protected:
59   RetrieverTest()
60       : storage_(NULL),
61         retriever_(),
62         success_(false),
63         key_(),
64         data_() {
65     ResetRetriever(FakeDownloader::kFakeDataUrl);
66   }
67
68   virtual ~RetrieverTest() {}
69
70   scoped_ptr<Retriever::Callback> BuildCallback() {
71     return ::i18n::addressinput::BuildCallback(
72         this, &RetrieverTest::OnDataReady);
73   }
74
75   void ResetRetriever(const std::string& url) {
76     storage_ = new FakeStorage;
77     retriever_.reset(
78         new Retriever(url,
79                       scoped_ptr<Downloader>(new FakeDownloader),
80                       scoped_ptr<Storage>(storage_)));
81   }
82
83   std::string GetUrlForKey(const std::string& key) {
84     return retriever_->GetUrlForKey(key);
85   }
86
87   std::string GetKeyForUrl(const std::string& url) {
88     return retriever_->GetKeyForUrl(url);
89   }
90
91   Storage* storage_;  // Owned by |retriever_|.
92   scoped_ptr<Retriever> retriever_;
93   bool success_;
94   std::string key_;
95   std::string data_;
96
97  private:
98   void OnDataReady(bool success,
99                    const std::string& key,
100                    const std::string& data) {
101     success_ = success;
102     key_ = key;
103     data_ = data;
104   }
105 };
106
107 TEST_F(RetrieverTest, RetrieveData) {
108   retriever_->Retrieve(kKey, BuildCallback());
109
110   EXPECT_TRUE(success_);
111   EXPECT_EQ(kKey, key_);
112   EXPECT_FALSE(data_.empty());
113   EXPECT_NE(kEmptyData, data_);
114 }
115
116 TEST_F(RetrieverTest, ReadDataFromStorage) {
117   retriever_->Retrieve(kKey, BuildCallback());
118   retriever_->Retrieve(kKey, BuildCallback());
119
120   EXPECT_TRUE(success_);
121   EXPECT_EQ(kKey, key_);
122   EXPECT_FALSE(data_.empty());
123   EXPECT_NE(kEmptyData, data_);
124 }
125
126 TEST_F(RetrieverTest, MissingKeyReturnsEmptyData) {
127   static const char kMissingKey[] = "junk";
128
129   retriever_->Retrieve(kMissingKey, BuildCallback());
130
131   EXPECT_TRUE(success_);
132   EXPECT_EQ(kMissingKey, key_);
133   EXPECT_EQ(kEmptyData, data_);
134 }
135
136 // The downloader that always fails.
137 class FaultyDownloader : public Downloader {
138  public:
139   FaultyDownloader() {}
140   virtual ~FaultyDownloader() {}
141
142   // Downloader implementation.
143   virtual void Download(const std::string& url,
144                         scoped_ptr<Callback> downloaded) {
145     (*downloaded)(false, url, make_scoped_ptr(new std::string("garbage")));
146   }
147 };
148
149 TEST_F(RetrieverTest, FaultyDownloader) {
150   Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
151                           scoped_ptr<Downloader>(new FaultyDownloader),
152                           scoped_ptr<Storage>(new FakeStorage));
153   bad_retriever.Retrieve(kKey, BuildCallback());
154
155   EXPECT_FALSE(success_);
156   EXPECT_EQ(kKey, key_);
157   EXPECT_TRUE(data_.empty());
158 }
159
160 TEST_F(RetrieverTest, FaultyDownloaderFallback) {
161   Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
162                           scoped_ptr<Downloader>(new FaultyDownloader),
163                           scoped_ptr<Storage>(new FakeStorage));
164   const char kFallbackDataKey[] = "data/US";
165   bad_retriever.Retrieve(kFallbackDataKey, BuildCallback());
166
167   EXPECT_TRUE(success_);
168   EXPECT_EQ(kFallbackDataKey, key_);
169   EXPECT_FALSE(data_.empty());
170   EXPECT_NE(kEmptyData, data_);
171 }
172
173 TEST_F(RetrieverTest, NoChecksumAndTimestampWillRedownload) {
174   storage_->Put(kKey, make_scoped_ptr(new std::string(kEmptyData)));
175   retriever_->Retrieve(kKey, BuildCallback());
176   EXPECT_TRUE(success_);
177   EXPECT_EQ(kKey, key_);
178   EXPECT_FALSE(data_.empty());
179   EXPECT_NE(kEmptyData, data_);
180 }
181
182 TEST_F(RetrieverTest, ChecksumAndTimestampWillNotRedownload) {
183   storage_->Put(kKey,
184                 Wrap(kEmptyData, kEmptyDataChecksum, TimeToString(time(NULL))));
185   retriever_->Retrieve(kKey, BuildCallback());
186   EXPECT_TRUE(success_);
187   EXPECT_EQ(kKey, key_);
188   EXPECT_EQ(kEmptyData, data_);
189 }
190
191 TEST_F(RetrieverTest, OldTimestampWillRedownload) {
192   storage_->Put(kKey, Wrap(kEmptyData, kEmptyDataChecksum, "0"));
193   retriever_->Retrieve(kKey, BuildCallback());
194   EXPECT_TRUE(success_);
195   EXPECT_EQ(kKey, key_);
196   EXPECT_FALSE(data_.empty());
197   EXPECT_NE(kEmptyData, data_);
198 }
199
200 TEST_F(RetrieverTest, OldTimestampOkIfDownloadFails) {
201   storage_ = new FakeStorage;
202   Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
203                           scoped_ptr<Downloader>(new FaultyDownloader),
204                           scoped_ptr<Storage>(storage_));
205   storage_->Put(kKey, Wrap(kEmptyData, kEmptyDataChecksum, "0"));
206   bad_retriever.Retrieve(kKey, BuildCallback());
207   EXPECT_TRUE(success_);
208   EXPECT_EQ(kKey, key_);
209   EXPECT_EQ(kEmptyData, data_);
210 }
211
212 TEST_F(RetrieverTest, WrongChecksumWillRedownload) {
213   static const char kNonEmptyData[] = "{\"non-empty\": \"data\"}";
214   storage_->Put(
215       kKey,
216       Wrap(kNonEmptyData, kEmptyDataChecksum, TimeToString(time(NULL))));
217   retriever_->Retrieve(kKey, BuildCallback());
218   EXPECT_TRUE(success_);
219   EXPECT_EQ(kKey, key_);
220   EXPECT_FALSE(data_.empty());
221   EXPECT_NE(kNonEmptyData, data_);
222 }
223
224 // The downloader that doesn't get back to you.
225 class HangingDownloader : public Downloader {
226  public:
227   HangingDownloader() {}
228   virtual ~HangingDownloader() {}
229
230   // Downloader implementation.
231   virtual void Download(const std::string& url,
232                         scoped_ptr<Callback> downloaded) {}
233 };
234
235 TEST_F(RetrieverTest, RequestsDontStack) {
236   Retriever slow_retriever(FakeDownloader::kFakeDataUrl,
237                            scoped_ptr<Downloader>(new HangingDownloader),
238                            scoped_ptr<Storage>(new FakeStorage));
239
240   slow_retriever.Retrieve(kKey, BuildCallback());
241   EXPECT_FALSE(success_);
242   EXPECT_TRUE(key_.empty());
243
244   EXPECT_NO_FATAL_FAILURE(slow_retriever.Retrieve(kKey, BuildCallback()));
245 }
246
247 TEST_F(RetrieverTest, GetUrlForKey) {
248   ResetRetriever("test:///");
249   EXPECT_EQ("test:///", GetUrlForKey(""));
250   EXPECT_EQ("test:///data", GetUrlForKey("data"));
251   EXPECT_EQ("test:///data/US", GetUrlForKey("data/US"));
252   EXPECT_EQ("test:///data/CA--fr", GetUrlForKey("data/CA--fr"));
253 }
254
255 TEST_F(RetrieverTest, GetKeyForUrl) {
256   ResetRetriever("test:///");
257   EXPECT_EQ("", GetKeyForUrl("test://"));
258   EXPECT_EQ("", GetKeyForUrl("http://www.google.com/"));
259   EXPECT_EQ("", GetKeyForUrl(""));
260   EXPECT_EQ("", GetKeyForUrl("test:///"));
261   EXPECT_EQ("data", GetKeyForUrl("test:///data"));
262   EXPECT_EQ("data/US", GetKeyForUrl("test:///data/US"));
263   EXPECT_EQ("data/CA--fr", GetKeyForUrl("test:///data/CA--fr"));
264 }
265
266 TEST_F(RetrieverTest, NullCallbackNoCrash) {
267   ASSERT_NO_FATAL_FAILURE(
268       retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>()));
269   ASSERT_NO_FATAL_FAILURE(
270       retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>()));
271 }
272
273 }  // namespace addressinput
274 }  // namespace i18n