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 "validation_task.h" 16 17 #include <libaddressinput/address_data.h> 18 #include <libaddressinput/address_field.h> 19 #include <libaddressinput/address_problem.h> 20 #include <libaddressinput/address_validator.h> 21 #include <libaddressinput/callback.h> 22 #include <libaddressinput/supplier.h> 23 #include <libaddressinput/util/basictypes.h> 24 #include <libaddressinput/util/scoped_ptr.h> 25 26 #include <cstddef> 27 #include <utility> 28 29 #include <gtest/gtest.h> 30 31 #include "lookup_key.h" 32 #include "rule.h" 33 34 namespace i18n { 35 namespace addressinput { 36 37 class LookupKey; 38 39 class ValidationTaskTest : public testing::Test { 40 protected: 41 ValidationTaskTest() 42 : json_(), 43 success_(true), 44 address_(), 45 allow_postal_(false), 46 require_name_(false), 47 filter_(), 48 problems_(), 49 expected_(), 50 called_(false), 51 validated_(BuildCallback(this, &ValidationTaskTest::Validated)) { 52 // Add all problems to the filter except those affected by the metadata 53 // in region_data_constants.cc. 54 static const AddressField kFields[] = { 55 COUNTRY, 56 ADMIN_AREA, 57 LOCALITY, 58 DEPENDENT_LOCALITY, 59 SORTING_CODE, 60 POSTAL_CODE, 61 STREET_ADDRESS, 62 RECIPIENT 63 }; 64 65 static const AddressProblem kProblems[] = { 66 // UNEXPECTED_FIELD is validated using IsFieldUsed(). 67 // MISSING_REQUIRED_FIELD is validated using IsFieldRequired(). 68 UNKNOWN_VALUE, 69 INVALID_FORMAT, 70 MISMATCHING_VALUE, 71 USES_P_O_BOX 72 }; 73 74 for (size_t i = 0; i < arraysize(kFields); ++i) { 75 AddressField field = kFields[i]; 76 for (size_t j = 0; j < arraysize(kProblems); ++j) { 77 AddressProblem problem = kProblems[j]; 78 filter_.insert(std::make_pair(field, problem)); 79 } 80 } 81 82 filter_.insert(std::make_pair(COUNTRY, UNEXPECTED_FIELD)); 83 filter_.insert(std::make_pair(COUNTRY, MISSING_REQUIRED_FIELD)); 84 filter_.insert(std::make_pair(RECIPIENT, UNEXPECTED_FIELD)); 85 filter_.insert(std::make_pair(RECIPIENT, MISSING_REQUIRED_FIELD)); 86 } 87 88 virtual ~ValidationTaskTest() {} 89 90 void Validate() { 91 Rule rule[arraysize(json_)]; 92 93 ValidationTask* task = new ValidationTask( 94 address_, 95 allow_postal_, 96 require_name_, 97 &filter_, 98 &problems_, 99 *validated_); 100 101 Supplier::RuleHierarchy hierarchy; 102 103 for (size_t i = 0; i < arraysize(json_) && json_[i] != NULL; ++i) { 104 ASSERT_TRUE(rule[i].ParseSerializedRule(json_[i])); 105 hierarchy.rule[i] = &rule[i]; 106 } 107 108 (*task->supplied_)(success_, *task->lookup_key_, hierarchy); 109 } 110 111 const char* json_[arraysize(LookupKey::kHierarchy)]; 112 bool success_; 113 AddressData address_; 114 bool allow_postal_; 115 bool require_name_; 116 FieldProblemMap filter_; 117 FieldProblemMap problems_; 118 FieldProblemMap expected_; 119 bool called_; 120 121 private: 122 void Validated(bool success, 123 const AddressData& address, 124 const FieldProblemMap& problems) { 125 ASSERT_EQ(success_, success); 126 ASSERT_EQ(&address_, &address); 127 ASSERT_EQ(&problems_, &problems); 128 called_ = true; 129 } 130 131 const scoped_ptr<const AddressValidator::Callback> validated_; 132 133 DISALLOW_COPY_AND_ASSIGN(ValidationTaskTest); 134 }; 135 136 namespace { 137 138 TEST_F(ValidationTaskTest, FailureCountryRuleNull) { 139 success_ = false; 140 141 ASSERT_NO_FATAL_FAILURE(Validate()); 142 ASSERT_TRUE(called_); 143 EXPECT_EQ(expected_, problems_); 144 } 145 146 TEST_F(ValidationTaskTest, FailureCountryRuleEmpty) { 147 json_[0] = "{}"; 148 success_ = false; 149 150 ASSERT_NO_FATAL_FAILURE(Validate()); 151 ASSERT_TRUE(called_); 152 EXPECT_EQ(expected_, problems_); 153 } 154 155 TEST_F(ValidationTaskTest, SuccessCountryRuleNullNameEmpty) { 156 expected_.insert(std::make_pair(COUNTRY, MISSING_REQUIRED_FIELD)); 157 158 ASSERT_NO_FATAL_FAILURE(Validate()); 159 ASSERT_TRUE(called_); 160 EXPECT_EQ(expected_, problems_); 161 } 162 163 TEST_F(ValidationTaskTest, SuccessCountryRuleNullNameNotEmpty) { 164 address_.region_code = "rrr"; 165 166 expected_.insert(std::make_pair(COUNTRY, UNKNOWN_VALUE)); 167 168 ASSERT_NO_FATAL_FAILURE(Validate()); 169 ASSERT_TRUE(called_); 170 EXPECT_EQ(expected_, problems_); 171 } 172 173 TEST_F(ValidationTaskTest, SuccessCountryRuleEmptyNameEmpty) { 174 json_[0] = "{}"; 175 176 expected_.insert(std::make_pair(COUNTRY, MISSING_REQUIRED_FIELD)); 177 178 ASSERT_NO_FATAL_FAILURE(Validate()); 179 ASSERT_TRUE(called_); 180 EXPECT_EQ(expected_, problems_); 181 } 182 183 TEST_F(ValidationTaskTest, SuccessCountryRuleEmptyNameNotEmpty) { 184 json_[0] = "{}"; 185 186 address_.region_code = "rrr"; 187 188 ASSERT_NO_FATAL_FAILURE(Validate()); 189 ASSERT_TRUE(called_); 190 EXPECT_EQ(expected_, problems_); 191 } 192 193 TEST_F(ValidationTaskTest, MissingRequiredFieldsUS) { 194 json_[0] = "{}"; 195 196 address_.region_code = "US"; 197 198 filter_.insert(std::make_pair(ADMIN_AREA, MISSING_REQUIRED_FIELD)); 199 filter_.insert(std::make_pair(LOCALITY, MISSING_REQUIRED_FIELD)); 200 filter_.insert(std::make_pair(POSTAL_CODE, MISSING_REQUIRED_FIELD)); 201 filter_.insert(std::make_pair(STREET_ADDRESS, MISSING_REQUIRED_FIELD)); 202 expected_.insert(std::make_pair(ADMIN_AREA, MISSING_REQUIRED_FIELD)); 203 expected_.insert(std::make_pair(LOCALITY, MISSING_REQUIRED_FIELD)); 204 expected_.insert(std::make_pair(POSTAL_CODE, MISSING_REQUIRED_FIELD)); 205 expected_.insert(std::make_pair(STREET_ADDRESS, MISSING_REQUIRED_FIELD)); 206 207 ASSERT_NO_FATAL_FAILURE(Validate()); 208 ASSERT_TRUE(called_); 209 EXPECT_EQ(expected_, problems_); 210 } 211 212 TEST_F(ValidationTaskTest, MissingNoRequiredFieldsUS) { 213 json_[0] = "{}"; 214 215 address_.region_code = "US"; 216 address_.administrative_area = "sss"; 217 address_.locality = "ccc"; 218 address_.postal_code = "zzz"; 219 address_.address_line.push_back("aaa"); 220 address_.recipient = "nnn"; 221 222 filter_.insert(std::make_pair(ADMIN_AREA, MISSING_REQUIRED_FIELD)); 223 filter_.insert(std::make_pair(LOCALITY, MISSING_REQUIRED_FIELD)); 224 filter_.insert(std::make_pair(POSTAL_CODE, MISSING_REQUIRED_FIELD)); 225 filter_.insert(std::make_pair(STREET_ADDRESS, MISSING_REQUIRED_FIELD)); 226 227 ASSERT_NO_FATAL_FAILURE(Validate()); 228 ASSERT_TRUE(called_); 229 EXPECT_EQ(expected_, problems_); 230 } 231 232 TEST_F(ValidationTaskTest, UnexpectedFieldUS) { 233 json_[0] = "{}"; 234 235 address_.region_code = "US"; 236 address_.dependent_locality = "ddd"; 237 238 filter_.insert(std::make_pair(DEPENDENT_LOCALITY, UNEXPECTED_FIELD)); 239 expected_.insert(std::make_pair(DEPENDENT_LOCALITY, UNEXPECTED_FIELD)); 240 241 ASSERT_NO_FATAL_FAILURE(Validate()); 242 ASSERT_TRUE(called_); 243 EXPECT_EQ(expected_, problems_); 244 } 245 246 TEST_F(ValidationTaskTest, MissingRequiredFieldRequireName) { 247 json_[0] = "{}"; 248 249 address_.region_code = "rrr"; 250 251 require_name_ = true; 252 253 expected_.insert(std::make_pair(RECIPIENT, MISSING_REQUIRED_FIELD)); 254 255 ASSERT_NO_FATAL_FAILURE(Validate()); 256 ASSERT_TRUE(called_); 257 EXPECT_EQ(expected_, problems_); 258 } 259 260 TEST_F(ValidationTaskTest, UnknownValueRuleNull) { 261 json_[0] = "{\"fmt\":\"%R%S\",\"require\":\"RS\",\"sub_keys\":\"aa~bb\"}"; 262 263 address_.region_code = "rrr"; 264 address_.administrative_area = "sss"; 265 266 expected_.insert(std::make_pair(ADMIN_AREA, UNKNOWN_VALUE)); 267 268 ASSERT_NO_FATAL_FAILURE(Validate()); 269 ASSERT_TRUE(called_); 270 EXPECT_EQ(expected_, problems_); 271 } 272 273 TEST_F(ValidationTaskTest, NoUnknownValueRuleNotNull) { 274 json_[0] = "{\"fmt\":\"%R%S\",\"require\":\"RS\",\"sub_keys\":\"aa~bb\"}"; 275 json_[1] = "{}"; 276 277 address_.region_code = "rrr"; 278 address_.administrative_area = "sss"; 279 280 ASSERT_NO_FATAL_FAILURE(Validate()); 281 ASSERT_TRUE(called_); 282 EXPECT_EQ(expected_, problems_); 283 } 284 285 TEST_F(ValidationTaskTest, PostalCodeUnrecognizedFormatTooShort) { 286 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{3}\"}"; 287 288 address_.region_code = "rrr"; 289 address_.postal_code = "12"; 290 291 expected_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 292 293 ASSERT_NO_FATAL_FAILURE(Validate()); 294 ASSERT_TRUE(called_); 295 EXPECT_EQ(expected_, problems_); 296 } 297 298 TEST_F(ValidationTaskTest, PostalCodeUnrecognizedFormatTooLong) { 299 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{3}\"}"; 300 301 address_.region_code = "rrr"; 302 address_.postal_code = "1234"; 303 304 expected_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 305 306 ASSERT_NO_FATAL_FAILURE(Validate()); 307 ASSERT_TRUE(called_); 308 EXPECT_EQ(expected_, problems_); 309 } 310 311 TEST_F(ValidationTaskTest, PostalCodeRecognizedFormat) { 312 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{3}\"}"; 313 314 address_.region_code = "rrr"; 315 address_.postal_code = "123"; 316 317 ASSERT_NO_FATAL_FAILURE(Validate()); 318 ASSERT_TRUE(called_); 319 EXPECT_EQ(expected_, problems_); 320 } 321 322 TEST_F(ValidationTaskTest, PostalCodeMismatchingValue1) { 323 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{3}\"}"; 324 json_[1] = "{\"zip\":\"1\"}"; 325 326 address_.region_code = "rrr"; 327 address_.postal_code = "000"; 328 329 expected_.insert(std::make_pair(POSTAL_CODE, MISMATCHING_VALUE)); 330 331 ASSERT_NO_FATAL_FAILURE(Validate()); 332 ASSERT_TRUE(called_); 333 EXPECT_EQ(expected_, problems_); 334 } 335 336 TEST_F(ValidationTaskTest, PostalCodeMismatchingValue2) { 337 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{3}\"}"; 338 json_[1] = "{\"zip\":\"1\"}"; 339 json_[2] = "{\"zip\":\"12\"}"; 340 341 address_.region_code = "rrr"; 342 address_.postal_code = "100"; 343 344 expected_.insert(std::make_pair(POSTAL_CODE, MISMATCHING_VALUE)); 345 346 ASSERT_NO_FATAL_FAILURE(Validate()); 347 ASSERT_TRUE(called_); 348 EXPECT_EQ(expected_, problems_); 349 } 350 351 TEST_F(ValidationTaskTest, PostalCodeMismatchingValue3) { 352 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{3}\"}"; 353 json_[1] = "{\"zip\":\"1\"}"; 354 json_[2] = "{\"zip\":\"12\"}"; 355 json_[3] = "{\"zip\":\"123\"}"; 356 357 address_.region_code = "rrr"; 358 address_.postal_code = "120"; 359 360 expected_.insert(std::make_pair(POSTAL_CODE, MISMATCHING_VALUE)); 361 362 ASSERT_NO_FATAL_FAILURE(Validate()); 363 ASSERT_TRUE(called_); 364 EXPECT_EQ(expected_, problems_); 365 } 366 367 TEST_F(ValidationTaskTest, PostalCodeMatchingValue) { 368 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{3}\"}"; 369 json_[1] = "{\"zip\":\"1\"}"; 370 json_[2] = "{\"zip\":\"12\"}"; 371 json_[3] = "{\"zip\":\"123\"}"; 372 373 address_.region_code = "rrr"; 374 address_.postal_code = "123"; 375 376 ASSERT_NO_FATAL_FAILURE(Validate()); 377 ASSERT_TRUE(called_); 378 EXPECT_EQ(expected_, problems_); 379 } 380 381 TEST_F(ValidationTaskTest, PostalCodePrefixMismatchingValue) { 382 json_[0] = "{\"fmt\":\"%Z\",\"zip\":\"\\\\d{5}\"}"; 383 json_[1] = "{\"zip\":\"9[0-5]|96[01]\"}"; 384 385 address_.region_code = "rrr"; 386 address_.postal_code = "10960"; 387 388 expected_.insert(std::make_pair(POSTAL_CODE, MISMATCHING_VALUE)); 389 390 ASSERT_NO_FATAL_FAILURE(Validate()); 391 ASSERT_TRUE(called_); 392 EXPECT_EQ(expected_, problems_); 393 } 394 395 TEST_F(ValidationTaskTest, PostalCodeFilterIgnoresMismatching) { 396 json_[0] = "{\"zip\":\"\\\\d{3}\"}"; 397 json_[1] = "{\"zip\":\"1\"}"; 398 399 address_.region_code = "rrr"; 400 address_.postal_code = "000"; 401 402 filter_.erase(POSTAL_CODE); 403 filter_.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT)); 404 405 // (POSTAL_CODE, MISMATCHING_VALUE) should not be reported. 406 407 ASSERT_NO_FATAL_FAILURE(Validate()); 408 ASSERT_TRUE(called_); 409 EXPECT_EQ(expected_, problems_); 410 } 411 412 TEST_F(ValidationTaskTest, UsesPoBoxLanguageUnd) { 413 json_[0] = "{\"fmt\":\"%A\"}"; 414 415 address_.region_code = "rrr"; 416 address_.address_line.push_back("aaa"); 417 address_.address_line.push_back("P.O. Box"); 418 address_.address_line.push_back("aaa"); 419 420 expected_.insert(std::make_pair(STREET_ADDRESS, USES_P_O_BOX)); 421 422 ASSERT_NO_FATAL_FAILURE(Validate()); 423 ASSERT_TRUE(called_); 424 EXPECT_EQ(expected_, problems_); 425 } 426 427 TEST_F(ValidationTaskTest, UsesPoBoxLanguageDa) { 428 json_[0] = "{\"fmt\":\"%A\",\"languages\":\"da\"}"; 429 430 address_.region_code = "rrr"; 431 address_.address_line.push_back("aaa"); 432 address_.address_line.push_back("Postboks"); 433 address_.address_line.push_back("aaa"); 434 435 expected_.insert(std::make_pair(STREET_ADDRESS, USES_P_O_BOX)); 436 437 ASSERT_NO_FATAL_FAILURE(Validate()); 438 ASSERT_TRUE(called_); 439 EXPECT_EQ(expected_, problems_); 440 } 441 442 TEST_F(ValidationTaskTest, UsesPoBoxLanguageDaNotMatchDe) { 443 json_[0] = "{\"fmt\":\"%A\",\"languages\":\"da\"}"; 444 445 address_.region_code = "rrr"; 446 address_.address_line.push_back("aaa"); 447 address_.address_line.push_back("Postfach"); 448 address_.address_line.push_back("aaa"); 449 450 ASSERT_NO_FATAL_FAILURE(Validate()); 451 ASSERT_TRUE(called_); 452 EXPECT_EQ(expected_, problems_); 453 } 454 455 TEST_F(ValidationTaskTest, UsesPoBoxAllowPostal) { 456 json_[0] = "{\"fmt\":\"%A\"}"; 457 458 address_.region_code = "rrr"; 459 address_.address_line.push_back("aaa"); 460 address_.address_line.push_back("P.O. Box"); 461 address_.address_line.push_back("aaa"); 462 463 allow_postal_ = true; 464 465 ASSERT_NO_FATAL_FAILURE(Validate()); 466 ASSERT_TRUE(called_); 467 EXPECT_EQ(expected_, problems_); 468 } 469 470 } // namespace 471 } // namespace addressinput 472 } // namespace i18n 473