1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
9 #include "base/basictypes.h"
10 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 #define I18N_ADDRESSINPUT_UTIL_BASICTYPES_H_
15 #include "third_party/libaddressinput/chromium/preload_address_validator.h"
16 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
17 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h"
18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h"
19 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
20 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
21 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader.h"
22 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h"
23 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
24 #include "third_party/libaddressinput/src/cpp/src/region_data_constants.h"
25 #include "third_party/libaddressinput/src/cpp/test/fake_downloader.h"
29 using ::autofill::PreloadAddressValidator;
30 using ::i18n::addressinput::AddressData;
31 using ::i18n::addressinput::AddressField;
32 using ::i18n::addressinput::BuildCallback;
33 using ::i18n::addressinput::Downloader;
34 using ::i18n::addressinput::FakeDownloader;
35 using ::i18n::addressinput::FieldProblemMap;
36 using ::i18n::addressinput::NullStorage;
37 using ::i18n::addressinput::RegionDataConstants;
38 using ::i18n::addressinput::Storage;
40 using ::i18n::addressinput::COUNTRY;
41 using ::i18n::addressinput::ADMIN_AREA;
42 using ::i18n::addressinput::LOCALITY;
43 using ::i18n::addressinput::DEPENDENT_LOCALITY;
44 using ::i18n::addressinput::SORTING_CODE;
45 using ::i18n::addressinput::POSTAL_CODE;
46 using ::i18n::addressinput::STREET_ADDRESS;
47 using ::i18n::addressinput::RECIPIENT;
49 using ::i18n::addressinput::UNKNOWN_VALUE;
50 using ::i18n::addressinput::INVALID_FORMAT;
51 using ::i18n::addressinput::MISMATCHING_VALUE;
53 class PreloadAddressValidatorTest : public testing::Test {
55 PreloadAddressValidatorTest()
57 new PreloadAddressValidator(
58 FakeDownloader::kFakeAggregateDataUrl,
59 scoped_ptr<Downloader>(new FakeDownloader),
60 scoped_ptr<Storage>(new NullStorage))),
61 loaded_(BuildCallback(this, &PreloadAddressValidatorTest::Loaded)) {
62 validator_->LoadRules("US", *loaded_);
65 virtual ~PreloadAddressValidatorTest() {}
67 const scoped_ptr<PreloadAddressValidator> validator_;
68 const scoped_ptr<PreloadAddressValidator::Callback> loaded_;
71 void Loaded(bool success,
72 const std::string& region_code,
73 const int& rule_count) {
74 AddressData address_data;
75 address_data.region_code = region_code;
76 FieldProblemMap dummy;
77 PreloadAddressValidator::Status status =
78 validator_->Validate(address_data, NULL, &dummy);
79 ASSERT_EQ(success, status == PreloadAddressValidator::SUCCESS);
82 DISALLOW_COPY_AND_ASSIGN(PreloadAddressValidatorTest);
85 TEST_F(PreloadAddressValidatorTest, RegionHasRules) {
86 const std::vector<std::string>& region_codes =
87 RegionDataConstants::GetRegionCodes();
89 for (size_t i = 0; i < region_codes.size(); ++i) {
90 SCOPED_TRACE("For region: " + region_codes[i]);
91 validator_->LoadRules(region_codes[i], *loaded_);
92 address.region_code = region_codes[i];
93 FieldProblemMap dummy;
95 PreloadAddressValidator::SUCCESS,
96 validator_->Validate(address, NULL, &dummy));
100 TEST_F(PreloadAddressValidatorTest, EmptyAddressNoFatalFailure) {
102 address.region_code = "US";
104 FieldProblemMap dummy;
106 PreloadAddressValidator::SUCCESS,
107 validator_->Validate(address, NULL, &dummy));
110 TEST_F(PreloadAddressValidatorTest, USZipCode) {
112 address.address_line.push_back("340 Main St.");
113 address.locality = "Venice";
114 address.administrative_area = "CA";
115 address.region_code = "US";
117 // Valid Californian zip code.
118 address.postal_code = "90291";
119 FieldProblemMap problems;
121 PreloadAddressValidator::SUCCESS,
122 validator_->Validate(address, NULL, &problems));
123 EXPECT_TRUE(problems.empty());
127 // An extended, valid Californian zip code.
128 address.postal_code = "90210-1234";
130 PreloadAddressValidator::SUCCESS,
131 validator_->Validate(address, NULL, &problems));
132 EXPECT_TRUE(problems.empty());
136 // New York zip code (which is invalid for California).
137 address.postal_code = "12345";
139 PreloadAddressValidator::SUCCESS,
140 validator_->Validate(address, NULL, &problems));
141 EXPECT_EQ(1U, problems.size());
142 EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
143 EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE);
147 // A zip code with a "90" in the middle.
148 address.postal_code = "12903";
150 PreloadAddressValidator::SUCCESS,
151 validator_->Validate(address, NULL, &problems));
152 EXPECT_EQ(1U, problems.size());
153 EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
154 EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE);
158 // Invalid zip code (too many digits).
159 address.postal_code = "902911";
161 PreloadAddressValidator::SUCCESS,
162 validator_->Validate(address, NULL, &problems));
163 EXPECT_EQ(1U, problems.size());
164 EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
165 EXPECT_EQ(problems.begin()->second, INVALID_FORMAT);
169 // Invalid zip code (too few digits).
170 address.postal_code = "9029";
172 PreloadAddressValidator::SUCCESS,
173 validator_->Validate(address, NULL, &problems));
174 EXPECT_EQ(1U, problems.size());
175 EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
176 EXPECT_EQ(problems.begin()->second, INVALID_FORMAT);
179 // Test case disabled because libaddressinput address validation doesn't do
180 // those kinds of normalizations that this test case expects. TODO: Something.
181 TEST_F(PreloadAddressValidatorTest, DISABLED_BasicValidation) {
182 // US rules should always be available, even though this load call fails.
183 validator_->LoadRules("US", *loaded_);
185 address.region_code = "US";
186 address.language_code = "en";
187 address.administrative_area = "TX";
188 address.locality = "Paris";
189 address.postal_code = "75461";
190 address.address_line.push_back("123 Main St");
191 FieldProblemMap problems;
193 PreloadAddressValidator::SUCCESS,
194 validator_->Validate(address, NULL, &problems));
195 EXPECT_TRUE(problems.empty());
197 // The display name works as well as the key.
198 address.administrative_area = "Texas";
201 PreloadAddressValidator::SUCCESS,
202 validator_->Validate(address, NULL, &problems));
203 EXPECT_TRUE(problems.empty());
205 // Ignore capitalization.
206 address.administrative_area = "tx";
209 PreloadAddressValidator::SUCCESS,
210 validator_->Validate(address, NULL, &problems));
211 EXPECT_TRUE(problems.empty());
213 // Ignore capitalization.
214 address.administrative_area = "teXas";
217 PreloadAddressValidator::SUCCESS,
218 validator_->Validate(address, NULL, &problems));
219 EXPECT_TRUE(problems.empty());
221 // Ignore diacriticals.
222 address.administrative_area = "T\u00E9xas";
225 PreloadAddressValidator::SUCCESS,
226 validator_->Validate(address, NULL, &problems));
227 EXPECT_TRUE(problems.empty());
230 TEST_F(PreloadAddressValidatorTest, BasicValidationFailure) {
231 // US rules should always be available, even though this load call fails.
232 validator_->LoadRules("US", *loaded_);
234 address.region_code = "US";
235 address.language_code = "en";
236 address.administrative_area = "XT";
237 address.locality = "Paris";
238 address.postal_code = "75461";
239 address.address_line.push_back("123 Main St");
240 FieldProblemMap problems;
242 PreloadAddressValidator::SUCCESS,
243 validator_->Validate(address, NULL, &problems));
245 ASSERT_EQ(1U, problems.size());
246 EXPECT_EQ(UNKNOWN_VALUE, problems.begin()->second);
247 EXPECT_EQ(ADMIN_AREA, problems.begin()->first);
250 TEST_F(PreloadAddressValidatorTest, NoNullSuggestionsCrash) {
252 address.region_code = "US";
253 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
254 validator_->GetSuggestions(address, COUNTRY, 1, NULL));
257 TEST_F(PreloadAddressValidatorTest, SuggestAdminAreaForPostalCode) {
259 address.region_code = "US";
260 address.postal_code = "90291";
262 std::vector<AddressData> suggestions;
263 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
264 validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
265 ASSERT_EQ(1U, suggestions.size());
266 EXPECT_EQ("CA", suggestions[0].administrative_area);
267 EXPECT_EQ("90291", suggestions[0].postal_code);
270 TEST_F(PreloadAddressValidatorTest, SuggestLocalityForPostalCodeWithAdminArea) {
271 validator_->LoadRules("TW", *loaded_);
273 address.region_code = "TW";
274 address.postal_code = "515";
275 address.administrative_area = "Changhua";
277 std::vector<AddressData> suggestions;
278 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
279 validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
280 ASSERT_EQ(1U, suggestions.size());
281 EXPECT_EQ("Dacun Township", suggestions[0].locality);
282 EXPECT_EQ("Changhua County", suggestions[0].administrative_area);
283 EXPECT_EQ("515", suggestions[0].postal_code);
286 TEST_F(PreloadAddressValidatorTest, SuggestAdminAreaForPostalCodeWithLocality) {
287 validator_->LoadRules("TW", *loaded_);
289 address.region_code = "TW";
290 address.postal_code = "515";
291 address.locality = "Dacun";
293 std::vector<AddressData> suggestions;
294 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
295 validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
296 ASSERT_EQ(1U, suggestions.size());
297 EXPECT_EQ("Dacun Township", suggestions[0].locality);
298 EXPECT_EQ("Changhua County", suggestions[0].administrative_area);
299 EXPECT_EQ("515", suggestions[0].postal_code);
302 TEST_F(PreloadAddressValidatorTest, NoSuggestForPostalCodeWithWrongAdminArea) {
304 address.region_code = "US";
305 address.postal_code = "90066";
306 address.postal_code = "TX";
308 std::vector<AddressData> suggestions;
309 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
310 validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
311 EXPECT_TRUE(suggestions.empty());
314 TEST_F(PreloadAddressValidatorTest, SuggestForLocality) {
315 validator_->LoadRules("CN", *loaded_);
317 address.region_code = "CN";
318 address.locality = "Anqin";
320 std::vector<AddressData> suggestions;
321 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
322 validator_->GetSuggestions(address, LOCALITY, 10, &suggestions));
323 ASSERT_EQ(1U, suggestions.size());
324 EXPECT_EQ("Anqing Shi", suggestions[0].locality);
325 EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
328 TEST_F(PreloadAddressValidatorTest, SuggestForLocalityAndAdminArea) {
329 validator_->LoadRules("CN", *loaded_);
331 address.region_code = "CN";
332 address.locality = "Anqing";
333 address.administrative_area = "Anhui";
335 std::vector<AddressData> suggestions;
336 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
337 validator_->GetSuggestions(address, LOCALITY, 10, &suggestions));
338 ASSERT_EQ(1U, suggestions.size());
339 EXPECT_TRUE(suggestions[0].dependent_locality.empty());
340 EXPECT_EQ("Anqing Shi", suggestions[0].locality);
341 EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
344 TEST_F(PreloadAddressValidatorTest, SuggestForAdminAreaAndLocality) {
345 validator_->LoadRules("CN", *loaded_);
347 address.region_code = "CN";
348 address.locality = "Anqing";
349 address.administrative_area = "Anhui";
351 std::vector<AddressData> suggestions;
352 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
353 validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
354 ASSERT_EQ(1U, suggestions.size());
355 EXPECT_TRUE(suggestions[0].dependent_locality.empty());
356 EXPECT_TRUE(suggestions[0].locality.empty());
357 EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
360 TEST_F(PreloadAddressValidatorTest, SuggestForDependentLocality) {
361 validator_->LoadRules("CN", *loaded_);
363 address.region_code = "CN";
364 address.dependent_locality = "Zongyang";
366 std::vector<AddressData> suggestions;
367 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
368 validator_->GetSuggestions(
369 address, DEPENDENT_LOCALITY, 10, &suggestions));
370 ASSERT_EQ(1U, suggestions.size());
371 EXPECT_EQ("Zongyang Xian", suggestions[0].dependent_locality);
372 EXPECT_EQ("Anqing Shi", suggestions[0].locality);
373 EXPECT_EQ("ANHUI SHENG", suggestions[0].administrative_area);
376 TEST_F(PreloadAddressValidatorTest,
377 NoSuggestForDependentLocalityWithWrongAdminArea) {
378 validator_->LoadRules("CN", *loaded_);
380 address.region_code = "CN";
381 address.dependent_locality = "Zongyang";
382 address.administrative_area = "Sichuan Sheng";
384 std::vector<AddressData> suggestions;
385 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
386 validator_->GetSuggestions(
387 address, DEPENDENT_LOCALITY, 10, &suggestions));
388 EXPECT_TRUE(suggestions.empty());
391 TEST_F(PreloadAddressValidatorTest, EmptySuggestionsOverLimit) {
393 address.region_code = "US";
394 address.administrative_area = "A";
396 std::vector<AddressData> suggestions;
397 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
398 validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
399 EXPECT_TRUE(suggestions.empty());
402 TEST_F(PreloadAddressValidatorTest, PreferShortSuggestions) {
404 address.region_code = "US";
405 address.administrative_area = "CA";
407 std::vector<AddressData> suggestions;
408 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
409 validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
410 ASSERT_EQ(1U, suggestions.size());
411 EXPECT_EQ("CA", suggestions[0].administrative_area);
414 TEST_F(PreloadAddressValidatorTest, SuggestTheSingleMatchForFullMatchName) {
416 address.region_code = "US";
417 address.administrative_area = "Texas";
419 std::vector<AddressData> suggestions;
420 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
421 validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
422 ASSERT_EQ(1U, suggestions.size());
423 EXPECT_EQ("Texas", suggestions[0].administrative_area);
426 TEST_F(PreloadAddressValidatorTest, SuggestAdminArea) {
428 address.region_code = "US";
429 address.administrative_area = "Cali";
431 std::vector<AddressData> suggestions;
432 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
433 validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
434 ASSERT_EQ(1U, suggestions.size());
435 EXPECT_EQ("California", suggestions[0].administrative_area);
438 TEST_F(PreloadAddressValidatorTest, MultipleSuggestions) {
440 address.region_code = "US";
441 address.administrative_area = "MA";
443 std::vector<AddressData> suggestions;
444 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
445 validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
446 EXPECT_LT(1U, suggestions.size());
448 // Massachusetts should not be a suggestion, because it's already covered
450 std::set<std::string> expected_suggestions;
451 expected_suggestions.insert("MA");
452 expected_suggestions.insert("Maine");
453 expected_suggestions.insert("Marshall Islands");
454 expected_suggestions.insert("Maryland");
455 for (std::vector<AddressData>::const_iterator it = suggestions.begin();
456 it != suggestions.end(); ++it) {
457 expected_suggestions.erase(it->administrative_area);
459 EXPECT_TRUE(expected_suggestions.empty());
462 TEST_F(PreloadAddressValidatorTest, SuggestNonLatinKeyWhenLanguageMatches) {
463 validator_->LoadRules("KR", *loaded_);
465 address.language_code = "ko";
466 address.region_code = "KR";
467 address.postal_code = "210-210";
469 std::vector<AddressData> suggestions;
470 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
471 validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
472 ASSERT_EQ(1U, suggestions.size());
473 EXPECT_EQ("강원도", suggestions[0].administrative_area);
474 EXPECT_EQ("210-210", suggestions[0].postal_code);
477 TEST_F(PreloadAddressValidatorTest, SuggestNonLatinKeyWhenUserInputIsNotLatin) {
478 validator_->LoadRules("KR", *loaded_);
480 address.language_code = "en";
481 address.region_code = "KR";
482 address.administrative_area = "강원";
484 std::vector<AddressData> suggestions;
485 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
486 validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
487 ASSERT_EQ(1U, suggestions.size());
488 EXPECT_EQ("강원도", suggestions[0].administrative_area);
491 TEST_F(PreloadAddressValidatorTest,
492 SuggestLatinNameWhenLanguageDiffersAndLatinNameAvailable) {
493 validator_->LoadRules("KR", *loaded_);
495 address.language_code = "en";
496 address.region_code = "KR";
497 address.postal_code = "210-210";
499 std::vector<AddressData> suggestions;
500 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
501 validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
502 ASSERT_EQ(1U, suggestions.size());
503 EXPECT_EQ("Gangwon", suggestions[0].administrative_area);
504 EXPECT_EQ("210-210", suggestions[0].postal_code);
507 TEST_F(PreloadAddressValidatorTest, SuggestLatinNameWhenUserInputIsLatin) {
508 validator_->LoadRules("KR", *loaded_);
510 address.language_code = "ko";
511 address.region_code = "KR";
512 address.administrative_area = "Gang";
514 std::vector<AddressData> suggestions;
515 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
516 validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
517 ASSERT_EQ(1U, suggestions.size());
518 EXPECT_EQ("Gangwon", suggestions[0].administrative_area);
521 TEST_F(PreloadAddressValidatorTest, NoSuggestionsForEmptyAddress) {
523 address.region_code = "US";
525 std::vector<AddressData> suggestions;
527 PreloadAddressValidator::SUCCESS,
528 validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions));
529 EXPECT_TRUE(suggestions.empty());
532 TEST_F(PreloadAddressValidatorTest, SuggestionIncludesCountry) {
534 address.region_code = "US";
535 address.postal_code = "90291";
537 std::vector<AddressData> suggestions;
538 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
539 validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
540 ASSERT_EQ(1U, suggestions.size());
541 EXPECT_EQ("US", suggestions[0].region_code);
544 TEST_F(PreloadAddressValidatorTest,
545 SuggestOnlyForAdministrativeAreasAndPostalCode) {
547 address.region_code = "US";
548 address.administrative_area = "CA";
549 address.locality = "Los Angeles";
550 address.dependent_locality = "Venice";
551 address.postal_code = "90291";
552 address.sorting_code = "123";
553 address.address_line.push_back("123 Main St");
554 address.recipient = "Jon Smith";
556 // Fields that should not have suggestions in US.
557 static const AddressField kNoSugestFields[] = {
566 static const size_t kNumNoSuggestFields =
567 sizeof kNoSugestFields / sizeof (AddressField);
569 for (size_t i = 0; i < kNumNoSuggestFields; ++i) {
570 std::vector<AddressData> suggestions;
571 EXPECT_EQ(PreloadAddressValidator::SUCCESS,
572 validator_->GetSuggestions(
573 address, kNoSugestFields[i], 999, &suggestions));
574 EXPECT_TRUE(suggestions.empty());
578 TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaName) {
580 address.region_code = "US";
581 address.administrative_area = "cALIFORNIa";
582 EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
583 EXPECT_EQ("CA", address.administrative_area);
586 TEST_F(PreloadAddressValidatorTest, CanonicalizeUsAdminAreaKey) {
588 address.region_code = "US";
589 address.administrative_area = "CA";
590 EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
591 EXPECT_EQ("CA", address.administrative_area);
594 TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaKey) {
595 validator_->LoadRules("JP", *loaded_);
597 address.region_code = "JP";
598 address.administrative_area = "東京都";
599 EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
600 EXPECT_EQ("東京都", address.administrative_area);
603 TEST_F(PreloadAddressValidatorTest, CanonicalizeJpAdminAreaLatinName) {
604 validator_->LoadRules("JP", *loaded_);
606 address.region_code = "JP";
607 address.administrative_area = "tOKYo";
608 EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
609 EXPECT_EQ("TOKYO", address.administrative_area);