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 <libaddressinput/address_validator.h> 16 17 #include <libaddressinput/address_data.h> 18 #include <libaddressinput/address_problem.h> 19 #include <libaddressinput/callback.h> 20 #include <libaddressinput/null_storage.h> 21 #include <libaddressinput/ondemand_supplier.h> 22 #include <libaddressinput/preload_supplier.h> 23 #include <libaddressinput/util/basictypes.h> 24 #include <libaddressinput/util/scoped_ptr.h> 25 26 #include <utility> 27 28 #include <gtest/gtest.h> 29 30 #include "fake_downloader.h" 31 32 namespace { 33 34 using i18n::addressinput::AddressData; 35 using i18n::addressinput::AddressValidator; 36 using i18n::addressinput::BuildCallback; 37 using i18n::addressinput::FakeDownloader; 38 using i18n::addressinput::FieldProblemMap; 39 using i18n::addressinput::NullStorage; 40 using i18n::addressinput::OndemandSupplier; 41 using i18n::addressinput::PreloadSupplier; 42 using i18n::addressinput::scoped_ptr; 43 44 using i18n::addressinput::COUNTRY; 45 using i18n::addressinput::ADMIN_AREA; 46 using i18n::addressinput::LOCALITY; 47 using i18n::addressinput::DEPENDENT_LOCALITY; 48 using i18n::addressinput::POSTAL_CODE; 49 using i18n::addressinput::STREET_ADDRESS; 50 51 using i18n::addressinput::UNEXPECTED_FIELD; 52 using i18n::addressinput::MISSING_REQUIRED_FIELD; 53 using i18n::addressinput::UNKNOWN_VALUE; 54 using i18n::addressinput::INVALID_FORMAT; 55 using i18n::addressinput::MISMATCHING_VALUE; 56 57 class ValidatorWrapper { 58 public: 59 virtual ~ValidatorWrapper() {} 60 virtual void Validate(const AddressData& address, 61 bool allow_postal, 62 bool require_name, 63 const FieldProblemMap* filter, 64 FieldProblemMap* problems, 65 const AddressValidator::Callback& validated) = 0; 66 }; 67 68 class OndemandValidatorWrapper : public ValidatorWrapper { 69 public: 70 static ValidatorWrapper* Build() { return new OndemandValidatorWrapper; } 71 72 virtual ~OndemandValidatorWrapper() {} 73 74 virtual void Validate(const AddressData& address, 75 bool allow_postal, 76 bool require_name, 77 const FieldProblemMap* filter, 78 FieldProblemMap* problems, 79 const AddressValidator::Callback& validated) { 80 validator_.Validate( 81 address, 82 allow_postal, 83 require_name, 84 filter, 85 problems, 86 validated); 87 } 88 89 private: 90 OndemandValidatorWrapper() 91 : supplier_(FakeDownloader::kFakeDataUrl, 92 new FakeDownloader, 93 new NullStorage), 94 validator_(&supplier_) {} 95 96 OndemandSupplier supplier_; 97 const AddressValidator validator_; 98 DISALLOW_COPY_AND_ASSIGN(OndemandValidatorWrapper); 99 }; 100 101 class PreloadValidatorWrapper : public ValidatorWrapper { 102 public: 103 static ValidatorWrapper* Build() { return new PreloadValidatorWrapper; } 104 105 virtual ~PreloadValidatorWrapper() {} 106 107 virtual void Validate(const AddressData& address, 108 bool allow_postal, 109 bool require_name, 110 const FieldProblemMap* filter, 111 FieldProblemMap* problems, 112 const AddressValidator::Callback& validated) { 113 const std::string& region_code = address.region_code; 114 if (!region_code.empty() && !supplier_.IsLoaded(region_code)) { 115 supplier_.LoadRules(region_code, *loaded_); 116 } 117 validator_.Validate( 118 address, 119 allow_postal, 120 require_name, 121 filter, 122 problems, 123 validated); 124 } 125 126 private: 127 PreloadValidatorWrapper() 128 : supplier_(FakeDownloader::kFakeAggregateDataUrl, 129 new FakeDownloader, 130 new NullStorage), 131 validator_(&supplier_), 132 loaded_(BuildCallback(this, &PreloadValidatorWrapper::Loaded)) {} 133 134 void Loaded(bool success, const std::string&, int) { 135 ASSERT_TRUE(success); 136 } 137 138 PreloadSupplier supplier_; 139 const AddressValidator validator_; 140 const scoped_ptr<const PreloadSupplier::Callback> loaded_; 141 DISALLOW_COPY_AND_ASSIGN(PreloadValidatorWrapper); 142 }; 143 144 class AddressValidatorTest 145 : public testing::TestWithParam<ValidatorWrapper* (*)()> { 146 protected: 147 AddressValidatorTest() 148 : address_(), 149 allow_postal_(false), 150 require_name_(false), 151 filter_(), 152 problems_(), 153 expected_(), 154 called_(false), 155 validator_wrapper_((*GetParam())()), 156 validated_(BuildCallback(this, &AddressValidatorTest::Validated)) {} 157 158 virtual ~AddressValidatorTest() {} 159 160 void Validate() { 161 validator_wrapper_->Validate( 162 address_, 163 allow_postal_, 164 require_name_, 165 &filter_, 166 &problems_, 167 *validated_); 168 } 169 170 AddressData address_; 171 bool allow_postal_; 172 bool require_name_; 173 FieldProblemMap filter_; 174 FieldProblemMap problems_; 175 FieldProblemMap expected_; 176 bool called_; 177 178 private: 179 void Validated(bool success, 180 const AddressData& address, 181 const FieldProblemMap& problems) { 182 ASSERT_TRUE(success); 183 ASSERT_EQ(&address_, &address); 184 ASSERT_EQ(&problems_, &problems); 185 called_ = true; 186 } 187 188 const scoped_ptr<ValidatorWrapper> validator_wrapper_; 189 const scoped_ptr<const AddressValidator::Callback> validated_; 190 191 DISALLOW_COPY_AND_ASSIGN(AddressValidatorTest); 192 }; 193 194 INSTANTIATE_TEST_CASE_P(OndemandSupplier, 195 AddressValidatorTest, 196 testing::Values(&OndemandValidatorWrapper::Build)); 197 198 INSTANTIATE_TEST_CASE_P(PreloadSupplier, 199 AddressValidatorTest, 200 testing::Values(&PreloadValidatorWrapper::Build)); 201 202 TEST_P(AddressValidatorTest, EmptyAddress) { 203 expected_.insert(std::make_pair(COUNTRY, MISSING_REQUIRED_FIELD)); 204 205 ASSERT_NO_FATAL_FAILURE(Validate()); 206 ASSERT_TRUE(called_); 207 EXPECT_EQ(expected_, problems_); 208 } 209 210 TEST_P(AddressValidatorTest, InvalidCountry) { 211 address_.region_code = "QZ"; 212 213 expected_.insert(std::make_pair(COUNTRY, UNKNOWN_VALUE)); 214 215 ASSERT_NO_FATAL_FAILURE(Validate()); 216 ASSERT_TRUE(called_); 217 EXPECT_EQ(expected_, problems_); 218 } 219 220 TEST_P(AddressValidatorTest, ValidAddressUS) { 221 address_.region_code = "US"; 222 address_.administrative_area = "CA"; // California 223 address_.locality = "Mountain View"; 224 address_.postal_code = "94043"; 225 address_.address_line.push_back("1600 Amphitheatre Parkway"); 226 address_.language_code = "en"; 227 228 ASSERT_NO_FATAL_FAILURE(Validate()); 229 ASSERT_TRUE(called_); 230 EXPECT_EQ(expected_, problems_); 231 } 232 233 TEST_P(AddressValidatorTest, InvalidAddressUS) { 234 address_.region_code = "US"; 235 address_.postal_code = "123"; 236 237 expected_.insert(std::make_pair(ADMIN_AREA, MISSING_REQUIRED_FIELD)); 238 expected_.insert(std::make_pair(LOCALITY, MISSING_REQUIRED_FIELD)); 239 expected_.insert(std::make_pair(STREET_ADDRESS, MISSING_REQUIRED_FIELD)); 240 expected_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 241 242 ASSERT_NO_FATAL_FAILURE(Validate()); 243 ASSERT_TRUE(called_); 244 EXPECT_EQ(expected_, problems_); 245 } 246 247 TEST_P(AddressValidatorTest, ValidAddressCH) { 248 address_.region_code = "CH"; 249 address_.locality = "ZH"; /* Zrich */ 250 address_.postal_code = "8002"; 251 address_.address_line.push_back("Brandschenkestrasse 110"); 252 address_.language_code = "de"; 253 254 ASSERT_NO_FATAL_FAILURE(Validate()); 255 ASSERT_TRUE(called_); 256 EXPECT_EQ(expected_, problems_); 257 } 258 259 TEST_P(AddressValidatorTest, InvalidAddressCH) { 260 address_.region_code = "CH"; 261 address_.postal_code = "123"; 262 263 expected_.insert(std::make_pair(STREET_ADDRESS, MISSING_REQUIRED_FIELD)); 264 expected_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 265 expected_.insert(std::make_pair(LOCALITY, MISSING_REQUIRED_FIELD)); 266 267 ASSERT_NO_FATAL_FAILURE(Validate()); 268 ASSERT_TRUE(called_); 269 EXPECT_EQ(expected_, problems_); 270 } 271 272 TEST_P(AddressValidatorTest, ValidPostalCodeMX) { 273 address_.region_code = "MX"; 274 address_.locality = "Villahermosa"; 275 address_.administrative_area = "TAB"; // Tabasco 276 address_.postal_code = "86070"; 277 address_.address_line.push_back( 278 /* Av Gregorio Mndez Magaa 1400 */ 279 "Av Gregorio M\xC3\xA9ndez Maga\xC3\xB1""a 1400"); 280 address_.language_code = "es"; 281 282 ASSERT_NO_FATAL_FAILURE(Validate()); 283 ASSERT_TRUE(called_); 284 EXPECT_EQ(expected_, problems_); 285 } 286 287 TEST_P(AddressValidatorTest, MismatchingPostalCodeMX) { 288 address_.region_code = "MX"; 289 address_.locality = "Villahermosa"; 290 address_.administrative_area = "TAB"; // Tabasco 291 address_.postal_code = "80000"; 292 address_.address_line.push_back( 293 /* Av Gregorio Mndez Magaa 1400 */ 294 "Av Gregorio M\xC3\xA9ndez Maga\xC3\xB1""a 1400"); 295 address_.language_code = "es"; 296 297 expected_.insert(std::make_pair(POSTAL_CODE, MISMATCHING_VALUE)); 298 299 ASSERT_NO_FATAL_FAILURE(Validate()); 300 ASSERT_TRUE(called_); 301 EXPECT_EQ(expected_, problems_); 302 } 303 304 TEST_P(AddressValidatorTest, ValidateFilter) { 305 address_.region_code = "CH"; 306 address_.postal_code = "123"; 307 308 filter_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 309 310 expected_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 311 312 ASSERT_NO_FATAL_FAILURE(Validate()); 313 ASSERT_TRUE(called_); 314 EXPECT_EQ(expected_, problems_); 315 } 316 317 TEST_P(AddressValidatorTest, ValidateClearsProblems) { 318 address_.region_code = "CH"; 319 address_.locality = "ZH"; /* Zrich */ 320 address_.postal_code = "123"; 321 address_.address_line.push_back("Brandschenkestrasse 110"); 322 address_.language_code = "de"; 323 324 problems_.insert(std::make_pair(LOCALITY, UNEXPECTED_FIELD)); 325 problems_.insert(std::make_pair(LOCALITY, MISSING_REQUIRED_FIELD)); 326 problems_.insert(std::make_pair(STREET_ADDRESS, MISSING_REQUIRED_FIELD)); 327 328 expected_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 329 330 ASSERT_NO_FATAL_FAILURE(Validate()); 331 ASSERT_TRUE(called_); 332 EXPECT_EQ(expected_, problems_); 333 } 334 335 TEST_P(AddressValidatorTest, ValidKanjiAddressJP) { 336 address_.region_code = "JP"; 337 address_.administrative_area = 338 "\xE5\xBE\xB3\xE5\xB3\xB6\xE7\x9C\x8C"; /* */ 339 address_.locality = 340 "\xE5\xBE\xB3\xE5\xB3\xB6\xE5\xB8\x82"; /* */ 341 address_.postal_code = "770-0847"; 342 address_.address_line.push_back("..."); 343 address_.language_code = "ja"; 344 345 ASSERT_NO_FATAL_FAILURE(Validate()); 346 ASSERT_TRUE(called_); 347 EXPECT_EQ(expected_, problems_); 348 } 349 350 TEST_P(AddressValidatorTest, ValidLatinAddressJP) { 351 // Skip this test case when using the OndemandSupplier, which depends on the 352 // address metadata server to map Latin script names to local script names. 353 if (GetParam() == &OndemandValidatorWrapper::Build) return; 354 355 address_.region_code = "JP"; 356 address_.administrative_area = "Tokushima"; 357 address_.locality = "Tokushima"; 358 address_.postal_code = "770-0847"; 359 address_.address_line.push_back("..."); 360 address_.language_code = "ja-Latn"; 361 362 ASSERT_NO_FATAL_FAILURE(Validate()); 363 ASSERT_TRUE(called_); 364 EXPECT_EQ(expected_, problems_); 365 } 366 367 TEST_P(AddressValidatorTest, ValidAddressBR) { 368 // Skip this test case when using the OndemandSupplier, which depends on the 369 // address metadata server to map natural language names to metadata IDs. 370 if (GetParam() == &OndemandValidatorWrapper::Build) return; 371 372 address_.region_code = "BR"; 373 address_.administrative_area = "S\xC3\xA3o Paulo"; /* So Paulo */ 374 address_.locality = "Presidente Prudente"; 375 address_.postal_code = "19063-008"; 376 address_.address_line.push_back("Rodovia Raposo Tavares, 6388-6682"); 377 address_.language_code = "pt"; 378 379 ASSERT_NO_FATAL_FAILURE(Validate()); 380 ASSERT_TRUE(called_); 381 EXPECT_EQ(expected_, problems_); 382 } 383 384 TEST_P(AddressValidatorTest, ValidAddressCA_en) { 385 // Skip this test case when using the OndemandSupplier, which depends on the 386 // address metadata server to map natural language names to metadata IDs. 387 if (GetParam() == &OndemandValidatorWrapper::Build) return; 388 389 address_.region_code = "CA"; 390 address_.administrative_area = "New Brunswick"; 391 address_.locality = "Saint John County"; 392 address_.postal_code = "E2L 4Z6"; 393 address_.address_line.push_back("..."); 394 address_.language_code = "en"; 395 396 ASSERT_NO_FATAL_FAILURE(Validate()); 397 ASSERT_TRUE(called_); 398 EXPECT_EQ(expected_, problems_); 399 } 400 401 TEST_P(AddressValidatorTest, ValidAddressCA_fr) { 402 // Skip this test case when using the OndemandSupplier, which depends on the 403 // address metadata server to map natural language names to metadata IDs. 404 if (GetParam() == &OndemandValidatorWrapper::Build) return; 405 406 address_.region_code = "CA"; 407 address_.administrative_area = "Nouveau-Brunswick"; 408 address_.locality = "Comt\xC3\xA9 de Saint-Jean"; /* Comt de Saint-Jean */ 409 address_.postal_code = "E2L 4Z6"; 410 address_.address_line.push_back("..."); 411 address_.language_code = "fr"; 412 413 ASSERT_NO_FATAL_FAILURE(Validate()); 414 ASSERT_TRUE(called_); 415 EXPECT_EQ(expected_, problems_); 416 } 417 418 } // namespace 419