1 // Copyright (C) 2014 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 "ondemand_supply_task.h" 16 17 #include <libaddressinput/callback.h> 18 #include <libaddressinput/null_storage.h> 19 #include <libaddressinput/supplier.h> 20 #include <libaddressinput/util/basictypes.h> 21 #include <libaddressinput/util/scoped_ptr.h> 22 23 #include <cstddef> 24 #include <cstring> 25 #include <map> 26 #include <string> 27 #include <utility> 28 29 #include <gtest/gtest.h> 30 31 #include "lookup_key.h" 32 #include "mock_downloader.h" 33 #include "retriever.h" 34 #include "rule.h" 35 36 namespace { 37 38 using i18n::addressinput::BuildCallback; 39 using i18n::addressinput::LookupKey; 40 using i18n::addressinput::MockDownloader; 41 using i18n::addressinput::NullStorage; 42 using i18n::addressinput::OndemandSupplyTask; 43 using i18n::addressinput::Retriever; 44 using i18n::addressinput::Rule; 45 using i18n::addressinput::scoped_ptr; 46 using i18n::addressinput::Supplier; 47 48 class OndemandSupplyTaskTest : public testing::Test { 49 protected: 50 OndemandSupplyTaskTest() 51 : success_(true), 52 lookup_key_(), 53 rule_(), 54 called_(false), 55 downloader_(new MockDownloader), 56 rule_cache_(), 57 retriever_( 58 new Retriever( 59 MockDownloader::kMockDataUrl, downloader_, new NullStorage)), 60 supplied_(BuildCallback(this, &OndemandSupplyTaskTest::Supplied)), 61 task_(new OndemandSupplyTask(lookup_key_, &rule_cache_, *supplied_)) {} 62 63 virtual ~OndemandSupplyTaskTest() { 64 for (std::map<std::string, const Rule*>::const_iterator 65 it = rule_cache_.begin(); it != rule_cache_.end(); ++it) { 66 delete it->second; 67 } 68 } 69 70 void Queue(const std::string& key) { 71 task_->Queue(key); 72 } 73 74 void Retrieve() { 75 task_->Retrieve(*retriever_); 76 } 77 78 bool success_; // Expected status from MockDownloader. 79 LookupKey lookup_key_; // Stub. 80 const Rule* rule_[arraysize(LookupKey::kHierarchy)]; 81 bool called_; 82 MockDownloader* const downloader_; 83 84 private: 85 void Supplied(bool success, 86 const LookupKey& lookup_key, 87 const Supplier::RuleHierarchy& hierarchy) { 88 ASSERT_EQ(success_, success); 89 ASSERT_EQ(&lookup_key_, &lookup_key); 90 ASSERT_EQ(&task_->hierarchy_, &hierarchy); 91 std::memcpy(rule_, hierarchy.rule, sizeof rule_); 92 called_ = true; 93 } 94 95 std::map<std::string, const Rule*> rule_cache_; 96 const scoped_ptr<Retriever> retriever_; 97 const scoped_ptr<const Supplier::Callback> supplied_; 98 OndemandSupplyTask* const task_; 99 100 DISALLOW_COPY_AND_ASSIGN(OndemandSupplyTaskTest); 101 }; 102 103 TEST_F(OndemandSupplyTaskTest, Empty) { 104 ASSERT_NO_FATAL_FAILURE(Retrieve()); 105 ASSERT_TRUE(called_); 106 EXPECT_TRUE(rule_[0] == NULL); 107 EXPECT_TRUE(rule_[1] == NULL); 108 EXPECT_TRUE(rule_[2] == NULL); 109 EXPECT_TRUE(rule_[3] == NULL); 110 } 111 112 TEST_F(OndemandSupplyTaskTest, Invalid) { 113 Queue("data/XA"); 114 115 success_ = false; 116 117 ASSERT_NO_FATAL_FAILURE(Retrieve()); 118 ASSERT_TRUE(called_); 119 } 120 121 TEST_F(OndemandSupplyTaskTest, Valid) { 122 downloader_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 123 124 Queue("data/XA"); 125 126 ASSERT_NO_FATAL_FAILURE(Retrieve()); 127 ASSERT_TRUE(called_); 128 EXPECT_TRUE(rule_[0] != NULL); 129 EXPECT_TRUE(rule_[1] == NULL); 130 EXPECT_TRUE(rule_[2] == NULL); 131 EXPECT_TRUE(rule_[3] == NULL); 132 133 EXPECT_EQ("data/XA", rule_[0]->GetId()); 134 135 // All rules on the COUNTRY level inherit from the default rule. 136 EXPECT_FALSE(rule_[0]->GetFormat().empty()); 137 EXPECT_FALSE(rule_[0]->GetRequired().empty()); 138 EXPECT_TRUE(rule_[0]->GetPostalCodeMatcher() == NULL); 139 } 140 141 TEST_F(OndemandSupplyTaskTest, ValidHierarchy) { 142 downloader_->data_.insert( 143 std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 144 downloader_->data_.insert( 145 std::make_pair("data/XA/aa", "{\"id\":\"data/XA/aa\"}")); 146 downloader_->data_.insert( 147 std::make_pair("data/XA/aa/bb", "{\"id\":\"data/XA/aa/bb\"}")); 148 downloader_->data_.insert( 149 std::make_pair("data/XA/aa/bb/cc", "{\"id\":\"data/XA/aa/bb/cc\"}")); 150 151 Queue("data/XA"); 152 Queue("data/XA/aa"); 153 Queue("data/XA/aa/bb"); 154 Queue("data/XA/aa/bb/cc"); 155 156 ASSERT_NO_FATAL_FAILURE(Retrieve()); 157 ASSERT_TRUE(called_); 158 EXPECT_TRUE(rule_[0] != NULL); 159 EXPECT_TRUE(rule_[1] != NULL); 160 EXPECT_TRUE(rule_[2] != NULL); 161 EXPECT_TRUE(rule_[3] != NULL); 162 163 EXPECT_EQ("data/XA", rule_[0]->GetId()); 164 EXPECT_EQ("data/XA/aa", rule_[1]->GetId()); 165 EXPECT_EQ("data/XA/aa/bb", rule_[2]->GetId()); 166 EXPECT_EQ("data/XA/aa/bb/cc", rule_[3]->GetId()); 167 168 // All rules on the COUNTRY level inherit from the default rule. 169 EXPECT_FALSE(rule_[0]->GetFormat().empty()); 170 EXPECT_FALSE(rule_[0]->GetRequired().empty()); 171 172 // Only rules on the COUNTRY level inherit from the default rule. 173 EXPECT_TRUE(rule_[1]->GetFormat().empty()); 174 EXPECT_TRUE(rule_[1]->GetRequired().empty()); 175 EXPECT_TRUE(rule_[2]->GetFormat().empty()); 176 EXPECT_TRUE(rule_[2]->GetRequired().empty()); 177 EXPECT_TRUE(rule_[3]->GetFormat().empty()); 178 EXPECT_TRUE(rule_[3]->GetRequired().empty()); 179 } 180 181 TEST_F(OndemandSupplyTaskTest, InvalidJson1) { 182 downloader_->data_.insert(std::make_pair("data/XA", ":")); 183 184 success_ = false; 185 186 Queue("data/XA"); 187 188 ASSERT_NO_FATAL_FAILURE(Retrieve()); 189 ASSERT_TRUE(called_); 190 } 191 192 TEST_F(OndemandSupplyTaskTest, InvalidJson2) { 193 downloader_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 194 downloader_->data_.insert(std::make_pair("data/XA/aa", ":")); 195 196 success_ = false; 197 198 Queue("data/XA"); 199 Queue("data/XA/aa"); 200 201 ASSERT_NO_FATAL_FAILURE(Retrieve()); 202 ASSERT_TRUE(called_); 203 } 204 205 TEST_F(OndemandSupplyTaskTest, EmptyJsonJustMeansServerKnowsNothingAboutKey) { 206 downloader_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 207 downloader_->data_.insert(std::make_pair("data/XA/aa", "{}")); 208 209 Queue("data/XA"); 210 Queue("data/XA/aa"); 211 212 ASSERT_NO_FATAL_FAILURE(Retrieve()); 213 ASSERT_TRUE(called_); 214 EXPECT_TRUE(rule_[0] != NULL); 215 EXPECT_TRUE(rule_[1] == NULL); 216 EXPECT_TRUE(rule_[2] == NULL); 217 EXPECT_TRUE(rule_[3] == NULL); 218 219 EXPECT_EQ("data/XA", rule_[0]->GetId()); 220 } 221 222 TEST_F(OndemandSupplyTaskTest, IfCountryFailsAllFails) { 223 downloader_->data_.insert( 224 std::make_pair("data/XA/aa", "{\"id\":\"data/XA/aa\"}")); 225 226 success_ = false; 227 228 Queue("data/XA"); 229 Queue("data/XA/aa"); 230 231 ASSERT_NO_FATAL_FAILURE(Retrieve()); 232 ASSERT_TRUE(called_); 233 } 234 235 } // namespace 236