Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: third_party/libaddressinput/chromium/cpp/test/retriever_test.cc

Issue 389863002: Remove Chrome's own version of libaddressinput in favor of the upstream. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "util/string_util.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 reject_empty_data_(false) {
66 ResetRetriever(FakeDownloader::kFakeDataUrl);
67 }
68
69 virtual ~RetrieverTest() {}
70
71 scoped_ptr<Retriever::Callback> BuildCallback() {
72 return ::i18n::addressinput::BuildCallback(
73 this, &RetrieverTest::OnDataReady);
74 }
75
76 void ResetRetriever(const std::string& url) {
77 storage_ = new FakeStorage;
78 retriever_.reset(
79 new Retriever(url,
80 scoped_ptr<Downloader>(new FakeDownloader),
81 scoped_ptr<Storage>(storage_)));
82 }
83
84 std::string GetUrlForKey(const std::string& key) {
85 return retriever_->GetUrlForKey(key);
86 }
87
88 std::string GetKeyForUrl(const std::string& url) {
89 return retriever_->GetKeyForUrl(url);
90 }
91
92 FakeStorage* storage_; // Owned by |retriever_|.
93 scoped_ptr<Retriever> retriever_;
94 bool success_;
95 std::string key_;
96 std::string data_;
97 bool reject_empty_data_;
98
99 private:
100 bool OnDataReady(bool success,
101 const std::string& key,
102 const std::string& data) {
103 success_ = success;
104 key_ = key;
105 data_ = data;
106 return !reject_empty_data_ || data_ != kEmptyData;
107 }
108 };
109
110 TEST_F(RetrieverTest, RegionHasData) {
111 const std::vector<std::string>& region_codes =
112 RegionDataConstants::GetRegionCodes();
113 for (size_t i = 0; i < region_codes.size(); ++i) {
114 std::string key = "data/" + region_codes[i];
115 SCOPED_TRACE("For key: " + key);
116
117 retriever_->Retrieve(key, BuildCallback());
118 EXPECT_TRUE(success_);
119 EXPECT_EQ(key, key_);
120 EXPECT_FALSE(data_.empty());
121 EXPECT_NE(kEmptyData, data_);
122 }
123 }
124
125 TEST_F(RetrieverTest, RetrieveData) {
126 retriever_->Retrieve(kKey, BuildCallback());
127
128 EXPECT_TRUE(success_);
129 EXPECT_EQ(kKey, key_);
130 EXPECT_FALSE(data_.empty());
131 EXPECT_NE(kEmptyData, data_);
132 }
133
134 TEST_F(RetrieverTest, ReadDataFromStorage) {
135 retriever_->Retrieve(kKey, BuildCallback());
136 retriever_->Retrieve(kKey, BuildCallback());
137
138 EXPECT_TRUE(success_);
139 EXPECT_EQ(kKey, key_);
140 EXPECT_FALSE(data_.empty());
141 EXPECT_NE(kEmptyData, data_);
142 }
143
144 TEST_F(RetrieverTest, MissingKeyReturnsEmptyData) {
145 static const char kMissingKey[] = "junk";
146
147 retriever_->Retrieve(kMissingKey, BuildCallback());
148
149 EXPECT_TRUE(success_);
150 EXPECT_EQ(kMissingKey, key_);
151 EXPECT_EQ(kEmptyData, data_);
152 }
153
154 // The downloader that always fails.
155 class FaultyDownloader : public Downloader {
156 public:
157 FaultyDownloader() {}
158 virtual ~FaultyDownloader() {}
159
160 // Downloader implementation.
161 virtual void Download(const std::string& url,
162 scoped_ptr<Callback> downloaded) {
163 (*downloaded)(false, url, make_scoped_ptr(new std::string("garbage")));
164 }
165 };
166
167 TEST_F(RetrieverTest, FaultyDownloader) {
168 Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
169 scoped_ptr<Downloader>(new FaultyDownloader),
170 scoped_ptr<Storage>(new FakeStorage));
171 bad_retriever.Retrieve(kKey, BuildCallback());
172
173 EXPECT_FALSE(success_);
174 EXPECT_EQ(kKey, key_);
175 EXPECT_TRUE(data_.empty());
176 }
177
178 TEST_F(RetrieverTest, FaultyDownloaderFallback) {
179 Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
180 scoped_ptr<Downloader>(new FaultyDownloader),
181 scoped_ptr<Storage>(new FakeStorage));
182 const char kFallbackDataKey[] = "data/US";
183 bad_retriever.Retrieve(kFallbackDataKey, BuildCallback());
184
185 EXPECT_TRUE(success_);
186 EXPECT_EQ(kFallbackDataKey, key_);
187 EXPECT_FALSE(data_.empty());
188 EXPECT_NE(kEmptyData, data_);
189 }
190
191 TEST_F(RetrieverTest, NoChecksumAndTimestampWillRedownload) {
192 storage_->Put(kKey, make_scoped_ptr(new std::string(kEmptyData)));
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, ChecksumAndTimestampWillNotRedownload) {
201 storage_->Put(kKey,
202 Wrap(kEmptyData, kEmptyDataChecksum, TimeToString(time(NULL))));
203 retriever_->Retrieve(kKey, BuildCallback());
204 EXPECT_TRUE(success_);
205 EXPECT_EQ(kKey, key_);
206 EXPECT_EQ(kEmptyData, data_);
207 }
208
209 TEST_F(RetrieverTest, OldTimestampWillRedownload) {
210 storage_->Put(kKey, Wrap(kEmptyData, kEmptyDataChecksum, "0"));
211 retriever_->Retrieve(kKey, BuildCallback());
212 EXPECT_TRUE(success_);
213 EXPECT_EQ(kKey, key_);
214 EXPECT_FALSE(data_.empty());
215 EXPECT_NE(kEmptyData, data_);
216 }
217
218 TEST_F(RetrieverTest, JunkDataRedownloads) {
219 ResetRetriever(std::string(FakeDownloader::kFakeDataUrl));
220 storage_->Put(kKey,
221 Wrap(kEmptyData, kEmptyDataChecksum, TimeToString(time(NULL))));
222 reject_empty_data_ = true;
223 retriever_->Retrieve(kKey, BuildCallback());
224 EXPECT_TRUE(success_);
225 EXPECT_EQ(kKey, key_);
226 EXPECT_FALSE(data_.empty());
227 EXPECT_NE(kEmptyData, data_);
228
229 // After verifying it's correct, it's saved in storage.
230 EXPECT_EQ(data_, storage_->SynchronousGet(kKey).substr(0, data_.size()));
231 }
232
233 TEST_F(RetrieverTest, JunkDataIsntStored) {
234 // Data the retriever accepts is stored in |storage_|.
235 ResetRetriever("test:///");
236 const std::string not_a_key("foobar");
237 retriever_->Retrieve(not_a_key, BuildCallback());
238 EXPECT_TRUE(success_);
239 EXPECT_EQ(not_a_key, key_);
240 EXPECT_FALSE(data_.empty());
241 EXPECT_EQ(kEmptyData, data_);
242 EXPECT_EQ(
243 kEmptyData,
244 storage_->SynchronousGet(not_a_key).substr(0, sizeof kEmptyData - 1));
245
246 // Try again, but this time reject the data.
247 reject_empty_data_ = true;
248 ResetRetriever("test:///");
249 EXPECT_EQ("", storage_->SynchronousGet(not_a_key));
250 retriever_->Retrieve(not_a_key, BuildCallback());
251
252 // Falls back to the fallback, which doesn't have data for Canada.
253 EXPECT_FALSE(success_);
254 EXPECT_EQ(not_a_key, key_);
255 EXPECT_TRUE(data_.empty());
256
257 // Since the retriever is rejecting empty data, it shouldn't be stored.
258 EXPECT_EQ("", storage_->SynchronousGet(not_a_key));
259 }
260
261 TEST_F(RetrieverTest, OldTimestampOkIfDownloadFails) {
262 storage_ = new FakeStorage;
263 Retriever bad_retriever(FakeDownloader::kFakeDataUrl,
264 scoped_ptr<Downloader>(new FaultyDownloader),
265 scoped_ptr<Storage>(storage_));
266 storage_->Put(kKey, Wrap(kEmptyData, kEmptyDataChecksum, "0"));
267 bad_retriever.Retrieve(kKey, BuildCallback());
268 EXPECT_TRUE(success_);
269 EXPECT_EQ(kKey, key_);
270 EXPECT_EQ(kEmptyData, data_);
271 }
272
273 TEST_F(RetrieverTest, WrongChecksumWillRedownload) {
274 static const char kNonEmptyData[] = "{\"non-empty\": \"data\"}";
275 storage_->Put(
276 kKey,
277 Wrap(kNonEmptyData, kEmptyDataChecksum, TimeToString(time(NULL))));
278 retriever_->Retrieve(kKey, BuildCallback());
279 EXPECT_TRUE(success_);
280 EXPECT_EQ(kKey, key_);
281 EXPECT_FALSE(data_.empty());
282 EXPECT_NE(kNonEmptyData, data_);
283 }
284
285 // The downloader that doesn't get back to you.
286 class HangingDownloader : public Downloader {
287 public:
288 HangingDownloader() {}
289 virtual ~HangingDownloader() {}
290
291 // Downloader implementation.
292 virtual void Download(const std::string& url,
293 scoped_ptr<Callback> downloaded) {}
294 };
295
296 TEST_F(RetrieverTest, RequestsDontStack) {
297 Retriever slow_retriever(FakeDownloader::kFakeDataUrl,
298 scoped_ptr<Downloader>(new HangingDownloader),
299 scoped_ptr<Storage>(new FakeStorage));
300
301 slow_retriever.Retrieve(kKey, BuildCallback());
302 EXPECT_FALSE(success_);
303 EXPECT_TRUE(key_.empty());
304
305 EXPECT_NO_FATAL_FAILURE(slow_retriever.Retrieve(kKey, BuildCallback()));
306 }
307
308 TEST_F(RetrieverTest, GetUrlForKey) {
309 ResetRetriever("test:///");
310 EXPECT_EQ("test:///", GetUrlForKey(""));
311 EXPECT_EQ("test:///data", GetUrlForKey("data"));
312 EXPECT_EQ("test:///data/US", GetUrlForKey("data/US"));
313 EXPECT_EQ("test:///data/CA--fr", GetUrlForKey("data/CA--fr"));
314 }
315
316 TEST_F(RetrieverTest, GetKeyForUrl) {
317 ResetRetriever("test:///");
318 EXPECT_EQ("", GetKeyForUrl("test://"));
319 EXPECT_EQ("", GetKeyForUrl("http://www.google.com/"));
320 EXPECT_EQ("", GetKeyForUrl(""));
321 EXPECT_EQ("", GetKeyForUrl("test:///"));
322 EXPECT_EQ("data", GetKeyForUrl("test:///data"));
323 EXPECT_EQ("data/US", GetKeyForUrl("test:///data/US"));
324 EXPECT_EQ("data/CA--fr", GetKeyForUrl("test:///data/CA--fr"));
325 }
326
327 TEST_F(RetrieverTest, NullCallbackNoCrash) {
328 ASSERT_NO_FATAL_FAILURE(
329 retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>()));
330 ASSERT_NO_FATAL_FAILURE(
331 retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>()));
332 }
333
334 } // namespace addressinput
335 } // namespace i18n
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698