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 34namespace i18n { 35namespace addressinput { 36 37class 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 133namespace { 134 135TEST_F(ValidationTaskTest, FailureCountryRuleNull) { 136 success_ = false; 137 138 ASSERT_NO_FATAL_FAILURE(Validate()); 139 ASSERT_TRUE(called_); 140 EXPECT_EQ(expected_, problems_); 141} 142 143TEST_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 152TEST_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 160TEST_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 170TEST_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 180TEST_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 190TEST_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 209TEST_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 231TEST_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 245TEST_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 259TEST_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 272TEST_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 284TEST_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 297TEST_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 310TEST_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 321TEST_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 335TEST_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 350TEST_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 366TEST_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 380TEST_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 394TEST_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 411TEST_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 426TEST_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 441TEST_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 454TEST_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