| OLD | NEW |
| 1 // Copyright (C) 2013 Google Inc. | 1 // Copyright (C) 2013 Google Inc. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "retriever.h" | 15 #include "retriever.h" |
| 16 | 16 |
| 17 #include <libaddressinput/callback.h> | 17 #include <libaddressinput/callback.h> |
| 18 #include <libaddressinput/downloader.h> | 18 #include <libaddressinput/downloader.h> |
| 19 #include <libaddressinput/storage.h> |
| 19 #include <libaddressinput/util/scoped_ptr.h> | 20 #include <libaddressinput/util/scoped_ptr.h> |
| 20 | 21 |
| 22 #include <cstddef> |
| 23 #include <ctime> |
| 21 #include <string> | 24 #include <string> |
| 22 | 25 |
| 23 #include <gtest/gtest.h> | 26 #include <gtest/gtest.h> |
| 24 | 27 |
| 25 #include "fake_downloader.h" | 28 #include "fake_downloader.h" |
| 26 #include "fake_storage.h" | 29 #include "fake_storage.h" |
| 27 #include "region_data_constants.h" | 30 #include "region_data_constants.h" |
| 31 #include "time_to_string.h" |
| 28 | 32 |
| 29 namespace i18n { | 33 namespace i18n { |
| 30 namespace addressinput { | 34 namespace addressinput { |
| 31 | 35 |
| 36 namespace { |
| 37 |
| 32 const char kKey[] = "data/CA"; | 38 const char kKey[] = "data/CA"; |
| 33 | 39 |
| 34 // Empty data that the downloader can return. | 40 // Empty data that the downloader can return. |
| 35 const char kEmptyData[] = "{}"; | 41 const char kEmptyData[] = "{}"; |
| 36 | 42 |
| 43 // The MD5 checksum for kEmptyData. Retriever uses MD5 to validate data |
| 44 // integrity. |
| 45 const char kEmptyDataChecksum[] = "99914b932bd37a50b983c5e7c90ae93b"; |
| 46 |
| 47 } // namespace |
| 48 |
| 37 // Tests for Retriever object. | 49 // Tests for Retriever object. |
| 38 class RetrieverTest : public testing::Test { | 50 class RetrieverTest : public testing::Test { |
| 39 protected: | 51 protected: |
| 40 RetrieverTest() | 52 RetrieverTest() |
| 41 : success_(false), | 53 : storage_(NULL), |
| 54 retriever_(), |
| 55 success_(false), |
| 42 key_(), | 56 key_(), |
| 43 data_() { | 57 data_() { |
| 44 ResetRetriever(FakeDownloader::kFakeDataUrl); | 58 ResetRetriever(FakeDownloader::kFakeDataUrl); |
| 45 } | 59 } |
| 46 | 60 |
| 47 virtual ~RetrieverTest() {} | 61 virtual ~RetrieverTest() {} |
| 48 | 62 |
| 49 scoped_ptr<Retriever::Callback> BuildCallback() { | 63 scoped_ptr<Retriever::Callback> BuildCallback() { |
| 50 return ::i18n::addressinput::BuildCallback( | 64 return ::i18n::addressinput::BuildCallback( |
| 51 this, &RetrieverTest::OnDataReady); | 65 this, &RetrieverTest::OnDataReady); |
| 52 } | 66 } |
| 53 | 67 |
| 54 void ResetRetriever(const std::string& url) { | 68 void ResetRetriever(const std::string& url) { |
| 69 storage_ = new FakeStorage; |
| 55 retriever_.reset( | 70 retriever_.reset( |
| 56 new Retriever(url, | 71 new Retriever(url, |
| 57 scoped_ptr<Downloader>(new FakeDownloader), | 72 scoped_ptr<Downloader>(new FakeDownloader), |
| 58 scoped_ptr<Storage>(new FakeStorage))); | 73 scoped_ptr<Storage>(storage_))); |
| 59 } | 74 } |
| 60 | 75 |
| 61 std::string GetUrlForKey(const std::string& key) { | 76 std::string GetUrlForKey(const std::string& key) { |
| 62 return retriever_->GetUrlForKey(key); | 77 return retriever_->GetUrlForKey(key); |
| 63 } | 78 } |
| 64 | 79 |
| 65 std::string GetKeyForUrl(const std::string& url) { | 80 std::string GetKeyForUrl(const std::string& url) { |
| 66 return retriever_->GetKeyForUrl(url); | 81 return retriever_->GetKeyForUrl(url); |
| 67 } | 82 } |
| 68 | 83 |
| 84 Storage* storage_; // Owned by |retriever_|. |
| 69 scoped_ptr<Retriever> retriever_; | 85 scoped_ptr<Retriever> retriever_; |
| 70 bool success_; | 86 bool success_; |
| 71 std::string key_; | 87 std::string key_; |
| 72 std::string data_; | 88 std::string data_; |
| 73 | 89 |
| 74 private: | 90 private: |
| 75 void OnDataReady(bool success, | 91 void OnDataReady(bool success, |
| 76 const std::string& key, | 92 const std::string& key, |
| 77 const std::string& data) { | 93 const std::string& data) { |
| 78 success_ = success; | 94 success_ = success; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 scoped_ptr<Storage>(new FakeStorage)); | 156 scoped_ptr<Storage>(new FakeStorage)); |
| 141 const char kFallbackDataKey[] = "data/US"; | 157 const char kFallbackDataKey[] = "data/US"; |
| 142 bad_retriever.Retrieve(kFallbackDataKey, BuildCallback()); | 158 bad_retriever.Retrieve(kFallbackDataKey, BuildCallback()); |
| 143 | 159 |
| 144 EXPECT_TRUE(success_); | 160 EXPECT_TRUE(success_); |
| 145 EXPECT_EQ(kFallbackDataKey, key_); | 161 EXPECT_EQ(kFallbackDataKey, key_); |
| 146 EXPECT_FALSE(data_.empty()); | 162 EXPECT_FALSE(data_.empty()); |
| 147 EXPECT_NE(kEmptyData, data_); | 163 EXPECT_NE(kEmptyData, data_); |
| 148 } | 164 } |
| 149 | 165 |
| 166 TEST_F(RetrieverTest, NoChecksumAndTimestampWillRedownload) { |
| 167 storage_->Put(kKey, kEmptyData); |
| 168 retriever_->Retrieve(kKey, BuildCallback()); |
| 169 EXPECT_TRUE(success_); |
| 170 EXPECT_EQ(kKey, key_); |
| 171 EXPECT_FALSE(data_.empty()); |
| 172 EXPECT_NE(kEmptyData, data_); |
| 173 } |
| 174 |
| 175 TEST_F(RetrieverTest, ChecksumAndTimestampWillNotRedownload) { |
| 176 storage_->Put(kKey, |
| 177 "timestamp=" + TimeToString(time(NULL)) + "\n" + |
| 178 "checksum=" + kEmptyDataChecksum + "\n" + |
| 179 kEmptyData); |
| 180 retriever_->Retrieve(kKey, BuildCallback()); |
| 181 EXPECT_TRUE(success_); |
| 182 EXPECT_EQ(kKey, key_); |
| 183 EXPECT_EQ(kEmptyData, data_); |
| 184 } |
| 185 |
| 186 TEST_F(RetrieverTest, OldTimestampWillRedownload) { |
| 187 storage_->Put(kKey, |
| 188 std::string("timestamp=0\n") + |
| 189 "checksum=" + kEmptyDataChecksum + "\n" + |
| 190 kEmptyData); |
| 191 retriever_->Retrieve(kKey, BuildCallback()); |
| 192 EXPECT_TRUE(success_); |
| 193 EXPECT_EQ(kKey, key_); |
| 194 EXPECT_FALSE(data_.empty()); |
| 195 EXPECT_NE(kEmptyData, data_); |
| 196 } |
| 197 |
| 198 TEST_F(RetrieverTest, OldTimestampOkIfDownloadFails) { |
| 199 storage_ = new FakeStorage; |
| 200 Retriever bad_retriever(FakeDownloader::kFakeDataUrl, |
| 201 scoped_ptr<Downloader>(new FaultyDownloader), |
| 202 scoped_ptr<Storage>(storage_)); |
| 203 storage_->Put(kKey, |
| 204 std::string("timestamp=0\n") + |
| 205 "checksum=" + kEmptyDataChecksum + "\n" + |
| 206 kEmptyData); |
| 207 bad_retriever.Retrieve(kKey, BuildCallback()); |
| 208 EXPECT_TRUE(success_); |
| 209 EXPECT_EQ(kKey, key_); |
| 210 EXPECT_EQ(kEmptyData, data_); |
| 211 } |
| 212 |
| 213 TEST_F(RetrieverTest, WrongChecksumWillRedownload) { |
| 214 static const char kNonEmptyData[] = "{\"non-empty\": \"data\"}"; |
| 215 storage_->Put(kKey, |
| 216 "timestamp=" + TimeToString(time(NULL)) + "\n" + |
| 217 "checksum=" + kEmptyDataChecksum + "\n" + |
| 218 kNonEmptyData); |
| 219 retriever_->Retrieve(kKey, BuildCallback()); |
| 220 EXPECT_TRUE(success_); |
| 221 EXPECT_EQ(kKey, key_); |
| 222 EXPECT_FALSE(data_.empty()); |
| 223 EXPECT_NE(kNonEmptyData, data_); |
| 224 } |
| 225 |
| 150 // The downloader that doesn't get back to you. | 226 // The downloader that doesn't get back to you. |
| 151 class HangingDownloader : public Downloader { | 227 class HangingDownloader : public Downloader { |
| 152 public: | 228 public: |
| 153 HangingDownloader() {} | 229 HangingDownloader() {} |
| 154 virtual ~HangingDownloader() {} | 230 virtual ~HangingDownloader() {} |
| 155 | 231 |
| 156 // Downloader implementation. | 232 // Downloader implementation. |
| 157 virtual void Download(const std::string& url, | 233 virtual void Download(const std::string& url, |
| 158 scoped_ptr<Callback> downloaded) {} | 234 scoped_ptr<Callback> downloaded) {} |
| 159 }; | 235 }; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 182 ResetRetriever("test:///"); | 258 ResetRetriever("test:///"); |
| 183 EXPECT_EQ("", GetKeyForUrl("test://")); | 259 EXPECT_EQ("", GetKeyForUrl("test://")); |
| 184 EXPECT_EQ("", GetKeyForUrl("http://www.google.com/")); | 260 EXPECT_EQ("", GetKeyForUrl("http://www.google.com/")); |
| 185 EXPECT_EQ("", GetKeyForUrl("")); | 261 EXPECT_EQ("", GetKeyForUrl("")); |
| 186 EXPECT_EQ("", GetKeyForUrl("test:///")); | 262 EXPECT_EQ("", GetKeyForUrl("test:///")); |
| 187 EXPECT_EQ("data", GetKeyForUrl("test:///data")); | 263 EXPECT_EQ("data", GetKeyForUrl("test:///data")); |
| 188 EXPECT_EQ("data/US", GetKeyForUrl("test:///data/US")); | 264 EXPECT_EQ("data/US", GetKeyForUrl("test:///data/US")); |
| 189 EXPECT_EQ("data/CA--fr", GetKeyForUrl("test:///data/CA--fr")); | 265 EXPECT_EQ("data/CA--fr", GetKeyForUrl("test:///data/CA--fr")); |
| 190 } | 266 } |
| 191 | 267 |
| 268 TEST_F(RetrieverTest, NullCallbackNoCrash) { |
| 269 ASSERT_NO_FATAL_FAILURE( |
| 270 retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>())); |
| 271 ASSERT_NO_FATAL_FAILURE( |
| 272 retriever_->Retrieve(kKey, scoped_ptr<Retriever::Callback>())); |
| 273 } |
| 274 |
| 192 } // namespace addressinput | 275 } // namespace addressinput |
| 193 } // namespace i18n | 276 } // namespace i18n |
| OLD | NEW |