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