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