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