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_source.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::MockSource; 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 source_(new MockSource), 56 rule_cache_(), 57 retriever_(new Retriever(source_, new NullStorage)), 58 supplied_(BuildCallback(this, &OndemandSupplyTaskTest::Supplied)), 59 task_(new OndemandSupplyTask(lookup_key_, &rule_cache_, *supplied_)) {} 60 61 virtual ~OndemandSupplyTaskTest() { 62 for (std::map<std::string, const Rule*>::const_iterator 63 it = rule_cache_.begin(); it != rule_cache_.end(); ++it) { 64 delete it->second; 65 } 66 } 67 68 void Queue(const std::string& key) { task_->Queue(key); } 69 70 void Retrieve() { task_->Retrieve(*retriever_); } 71 72 bool success_; // Expected status from MockSource. 73 LookupKey lookup_key_; // Stub. 74 const Rule* rule_[arraysize(LookupKey::kHierarchy)]; 75 bool called_; 76 MockSource* const source_; 77 78 private: 79 void Supplied(bool success, 80 const LookupKey& lookup_key, 81 const Supplier::RuleHierarchy& hierarchy) { 82 ASSERT_EQ(success_, success); 83 ASSERT_EQ(&lookup_key_, &lookup_key); 84 ASSERT_EQ(&task_->hierarchy_, &hierarchy); 85 std::memcpy(rule_, hierarchy.rule, sizeof rule_); 86 called_ = true; 87 } 88 89 std::map<std::string, const Rule*> rule_cache_; 90 const scoped_ptr<Retriever> retriever_; 91 const scoped_ptr<const Supplier::Callback> supplied_; 92 OndemandSupplyTask* const task_; 93 94 DISALLOW_COPY_AND_ASSIGN(OndemandSupplyTaskTest); 95 }; 96 97 TEST_F(OndemandSupplyTaskTest, Empty) { 98 ASSERT_NO_FATAL_FAILURE(Retrieve()); 99 ASSERT_TRUE(called_); 100 EXPECT_TRUE(rule_[0] == NULL); 101 EXPECT_TRUE(rule_[1] == NULL); 102 EXPECT_TRUE(rule_[2] == NULL); 103 EXPECT_TRUE(rule_[3] == NULL); 104 } 105 106 TEST_F(OndemandSupplyTaskTest, Invalid) { 107 Queue("data/XA"); 108 109 success_ = false; 110 111 ASSERT_NO_FATAL_FAILURE(Retrieve()); 112 ASSERT_TRUE(called_); 113 } 114 115 TEST_F(OndemandSupplyTaskTest, Valid) { 116 source_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 117 118 Queue("data/XA"); 119 120 ASSERT_NO_FATAL_FAILURE(Retrieve()); 121 ASSERT_TRUE(called_); 122 EXPECT_TRUE(rule_[0] != NULL); 123 EXPECT_TRUE(rule_[1] == NULL); 124 EXPECT_TRUE(rule_[2] == NULL); 125 EXPECT_TRUE(rule_[3] == NULL); 126 127 EXPECT_EQ("data/XA", rule_[0]->GetId()); 128 129 // All rules on the COUNTRY level inherit from the default rule. 130 EXPECT_FALSE(rule_[0]->GetFormat().empty()); 131 EXPECT_FALSE(rule_[0]->GetRequired().empty()); 132 EXPECT_TRUE(rule_[0]->GetPostalCodeMatcher() == NULL); 133 } 134 135 TEST_F(OndemandSupplyTaskTest, ValidHierarchy) { 136 source_->data_.insert( 137 std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 138 source_->data_.insert( 139 std::make_pair("data/XA/aa", "{\"id\":\"data/XA/aa\"}")); 140 source_->data_.insert( 141 std::make_pair("data/XA/aa/bb", "{\"id\":\"data/XA/aa/bb\"}")); 142 source_->data_.insert( 143 std::make_pair("data/XA/aa/bb/cc", "{\"id\":\"data/XA/aa/bb/cc\"}")); 144 145 Queue("data/XA"); 146 Queue("data/XA/aa"); 147 Queue("data/XA/aa/bb"); 148 Queue("data/XA/aa/bb/cc"); 149 150 ASSERT_NO_FATAL_FAILURE(Retrieve()); 151 ASSERT_TRUE(called_); 152 EXPECT_TRUE(rule_[0] != NULL); 153 EXPECT_TRUE(rule_[1] != NULL); 154 EXPECT_TRUE(rule_[2] != NULL); 155 EXPECT_TRUE(rule_[3] != NULL); 156 157 EXPECT_EQ("data/XA", rule_[0]->GetId()); 158 EXPECT_EQ("data/XA/aa", rule_[1]->GetId()); 159 EXPECT_EQ("data/XA/aa/bb", rule_[2]->GetId()); 160 EXPECT_EQ("data/XA/aa/bb/cc", rule_[3]->GetId()); 161 162 // All rules on the COUNTRY level inherit from the default rule. 163 EXPECT_FALSE(rule_[0]->GetFormat().empty()); 164 EXPECT_FALSE(rule_[0]->GetRequired().empty()); 165 166 // Only rules on the COUNTRY level inherit from the default rule. 167 EXPECT_TRUE(rule_[1]->GetFormat().empty()); 168 EXPECT_TRUE(rule_[1]->GetRequired().empty()); 169 EXPECT_TRUE(rule_[2]->GetFormat().empty()); 170 EXPECT_TRUE(rule_[2]->GetRequired().empty()); 171 EXPECT_TRUE(rule_[3]->GetFormat().empty()); 172 EXPECT_TRUE(rule_[3]->GetRequired().empty()); 173 } 174 175 TEST_F(OndemandSupplyTaskTest, InvalidJson1) { 176 source_->data_.insert(std::make_pair("data/XA", ":")); 177 178 success_ = false; 179 180 Queue("data/XA"); 181 182 ASSERT_NO_FATAL_FAILURE(Retrieve()); 183 ASSERT_TRUE(called_); 184 } 185 186 TEST_F(OndemandSupplyTaskTest, InvalidJson2) { 187 source_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 188 source_->data_.insert(std::make_pair("data/XA/aa", ":")); 189 190 success_ = false; 191 192 Queue("data/XA"); 193 Queue("data/XA/aa"); 194 195 ASSERT_NO_FATAL_FAILURE(Retrieve()); 196 ASSERT_TRUE(called_); 197 } 198 199 TEST_F(OndemandSupplyTaskTest, EmptyJsonJustMeansServerKnowsNothingAboutKey) { 200 source_->data_.insert(std::make_pair("data/XA", "{\"id\":\"data/XA\"}")); 201 source_->data_.insert(std::make_pair("data/XA/aa", "{}")); 202 203 Queue("data/XA"); 204 Queue("data/XA/aa"); 205 206 ASSERT_NO_FATAL_FAILURE(Retrieve()); 207 ASSERT_TRUE(called_); 208 EXPECT_TRUE(rule_[0] != NULL); 209 EXPECT_TRUE(rule_[1] == NULL); 210 EXPECT_TRUE(rule_[2] == NULL); 211 EXPECT_TRUE(rule_[3] == NULL); 212 213 EXPECT_EQ("data/XA", rule_[0]->GetId()); 214 } 215 216 TEST_F(OndemandSupplyTaskTest, IfCountryFailsAllFails) { 217 source_->data_.insert( 218 std::make_pair("data/XA/aa", "{\"id\":\"data/XA/aa\"}")); 219 220 success_ = false; 221 222 Queue("data/XA"); 223 Queue("data/XA/aa"); 224 225 ASSERT_NO_FATAL_FAILURE(Retrieve()); 226 ASSERT_TRUE(called_); 227 } 228 229 } // namespace 230