aboutsummaryrefslogtreecommitdiff
path: root/cpp/test/address_input_helper_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/test/address_input_helper_test.cc')
-rw-r--r--cpp/test/address_input_helper_test.cc359
1 files changed, 359 insertions, 0 deletions
diff --git a/cpp/test/address_input_helper_test.cc b/cpp/test/address_input_helper_test.cc
new file mode 100644
index 0000000..84a2286
--- /dev/null
+++ b/cpp/test/address_input_helper_test.cc
@@ -0,0 +1,359 @@
+// Copyright (C) 2013 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <libaddressinput/address_input_helper.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/callback.h>
+#include <libaddressinput/null_storage.h>
+#include <libaddressinput/preload_supplier.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+#include <utility>
+
+#include <gtest/gtest.h>
+
+#include "fake_downloader.h"
+#include "mock_downloader.h"
+
+namespace {
+
+using i18n::addressinput::AddressData;
+using i18n::addressinput::AddressInputHelper;
+using i18n::addressinput::BuildCallback;
+using i18n::addressinput::Callback;
+using i18n::addressinput::FakeDownloader;
+using i18n::addressinput::MockDownloader;
+using i18n::addressinput::NullStorage;
+using i18n::addressinput::PreloadSupplier;
+using i18n::addressinput::scoped_ptr;
+
+class AddressInputHelperTest : public testing::Test {
+ protected:
+ AddressInputHelperTest()
+ // Our PreloadSupplier loads all data for a country at a time.
+ : supplier_(FakeDownloader::kFakeAggregateDataUrl,
+ new FakeDownloader,
+ new NullStorage),
+ address_input_helper_(&supplier_),
+ loaded_(BuildCallback(this, &AddressInputHelperTest::Loaded)) {}
+
+ ~AddressInputHelperTest() {}
+
+ // Helper method to test FillAddress that ensures the PreloadSupplier has the
+ // necessary data preloaded.
+ void FillAddress(AddressData* address) {
+ const std::string& region_code = address->region_code;
+ if (!region_code.empty()) {
+ supplier_.LoadRules(region_code, *loaded_);
+ }
+ address_input_helper_.FillAddress(address);
+ }
+
+ private:
+ // Used to preload data that we need.
+ void Loaded(bool success, const std::string&, int) {
+ ASSERT_TRUE(success);
+ }
+
+ PreloadSupplier supplier_;
+ const AddressInputHelper address_input_helper_;
+ const scoped_ptr<const PreloadSupplier::Callback> loaded_;
+ DISALLOW_COPY_AND_ASSIGN(AddressInputHelperTest);
+};
+
+TEST_F(AddressInputHelperTest, AddressWithMissingPostalCode) {
+ AddressData address;
+ address.region_code = "CX";
+ address.administrative_area = "WA";
+
+ // There is only one postal code for Christmas Island
+ AddressData expected = address;
+ expected.postal_code = "6798";
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingAdmin) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "58098";
+ // Other data should be left alone.
+ address.address_line.push_back("10 High St");
+
+ // North Dakota has post codes starting with 58.
+ AddressData expected = address;
+ expected.administrative_area = "ND";
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+
+ address.administrative_area = "CA"; // Override the admin area.
+ // Now, since the admin area was already filled in, we don't fix it, even
+ // though it was correct.
+ expected.administrative_area = "CA";
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingLowerLevel) {
+ AddressData address;
+ address.region_code = "TW";
+ address.postal_code = "53012";
+
+ /* This matches 二水鄉 - Ershuei Township. */
+ AddressData expected = address;
+ /* This locality is in 彰化縣 - Changhua County. */
+ expected.administrative_area = "\xE5\xBD\xB0\xE5\x8C\x96\xE7\xB8\xA3";
+ expected.locality = "\xE4\xBA\x8C\xE6\xB0\xB4\xE9\x84\x89";
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+
+ // Override the admin area.
+ address.administrative_area = "Already filled in";
+ expected.administrative_area = "Already filled in";
+ address.locality = "";
+ // However, the locality will still be filled in.
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingLowerLevelLatin) {
+ AddressData address;
+ address.region_code = "TW";
+ address.postal_code = "53012";
+ address.language_code = "zh-Latn";
+
+ /* This matches 二水鄉 - Ershuei Township. */
+ AddressData expected = address;
+ /* This locality is in 彰化縣 - Changhua County. */
+ expected.locality = "Ershuei Township";
+ expected.administrative_area = "Changhua County";
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+
+ // Override the admin area.
+ address.administrative_area = "Already filled in";
+ expected.administrative_area = "Already filled in";
+ address.locality = "";
+ // However, the locality will still be filled in.
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingDependentLocality) {
+ AddressData address;
+ address.region_code = "KR";
+ // This matches Danwon-gu district.
+ address.postal_code = "425-111";
+
+ AddressData expected = address;
+ /* The province is Gyeonggi - 경기도. */
+ expected.administrative_area = "\xEA\xB2\xBD\xEA\xB8\xB0\xEB\x8F\x84";
+ /* The city is Ansan-si - 안산시. */
+ expected.locality = "\xEC\x95\x88\xEC\x82\xB0\xEC\x8B\x9C";
+ /* The district is Danwon-gu - 단원구 */
+ expected.dependent_locality = "\xEB\x8B\xA8\xEC\x9B\x90\xEA\xB5\xAC";
+
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+
+ AddressData address_ko_latn;
+ address_ko_latn.region_code = "KR";
+ address_ko_latn.postal_code = "425-111";
+ address_ko_latn.language_code = "ko-latn";
+
+ expected = address_ko_latn;
+ /* The province is Gyeonggi - 경기도. */
+ expected.administrative_area = "Gyeonggi";
+ /* The city is Ansan-si - 안산시. */
+ expected.locality = "Ansan-si";
+ /* The district is Danwon-gu - 단원구 */
+ expected.dependent_locality = "Danwon-gu";
+
+ FillAddress(&address_ko_latn);
+ EXPECT_EQ(expected, address_ko_latn);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithPostalCodeMatchingMultipleValues) {
+ AddressData address;
+ address.region_code = "KR";
+ // This matches Wando-gun and Ganjin-gun, both in Jeonnam province.
+ address.postal_code = "527-111";
+
+ AddressData expected = address;
+ /* The province, Jeonnam - 전라남도 - is known, but we have several locality
+ * matches so none of them are populated. */
+ expected.administrative_area =
+ "\xEC\xA0\x84\xEB\x9D\xBC\xEB\x82\xA8\xEB\x8F\x84";
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithInvalidPostalCode) {
+ AddressData address;
+ address.postal_code = "970";
+ address.region_code = "US";
+
+ // We don't expect any changes, since the postal code couldn't be determined
+ // as valid.
+ AddressData expected = address;
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithNoPostalCodeValidation) {
+ AddressData address;
+ address.postal_code = "123";
+ address.region_code = "GA";
+
+ // We don't expect any changes, since the postal code couldn't be determined
+ // as valid - we have no information about postal codes in Gabon (or even that
+ // they are in use).
+ AddressData expected = address;
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperTest, AddressWithInvalidOrMissingRegionCode) {
+ AddressData address;
+ address.postal_code = "XXX";
+ address.administrative_area = "YYY";
+
+ // We don't expect any changes, since there was no region code.
+ AddressData expected = address;
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+
+ address.region_code = "XXXX";
+ expected.region_code = "XXXX";
+ // Again, nothing should change.
+ FillAddress(&address);
+ EXPECT_EQ(expected, address);
+}
+
+class AddressInputHelperMockDataTest : public testing::Test {
+ protected:
+ AddressInputHelperMockDataTest()
+ : downloader_(new MockDownloader),
+ // Our PreloadSupplier loads all data for a country at a time.
+ supplier_(MockDownloader::kMockDataUrl,
+ downloader_,
+ new NullStorage),
+ address_input_helper_(&supplier_),
+ loaded_(BuildCallback(this, &AddressInputHelperMockDataTest::Loaded)) {}
+
+ ~AddressInputHelperMockDataTest() {}
+
+ // Helper method to test FillAddress that ensures the PreloadSupplier has the
+ // necessary data preloaded.
+ void FillAddress(AddressData* address) {
+ const std::string& region_code = address->region_code;
+ if (!region_code.empty()) {
+ supplier_.LoadRules(region_code, *loaded_);
+ }
+ address_input_helper_.FillAddress(address);
+ }
+
+ MockDownloader* const downloader_;
+
+ private:
+ // Our mock downloader we assume will always succeed.
+ void Loaded(bool success, const std::string&, int) {
+ ASSERT_TRUE(success);
+ }
+
+ PreloadSupplier supplier_;
+ const AddressInputHelper address_input_helper_;
+ const scoped_ptr<const PreloadSupplier::Callback> loaded_;
+ DISALLOW_COPY_AND_ASSIGN(AddressInputHelperMockDataTest);
+};
+
+TEST_F(AddressInputHelperMockDataTest,
+ PostalCodeSharedAcrossDifferentHierarchies) {
+ // Note that this data is in the format of data that would be returned from
+ // the aggregate server.
+ downloader_->data_.insert(std::make_pair(
+ // We use KR since we need a country where we format all fields down to
+ // dependent locality, or the hierarchy won't be loaded.
+ "data/KR",
+ "{\"data/KR\": "
+ // The top-level ZIP expression must be present for sub-key matches to be
+ // evaluated.
+ "{\"id\":\"data/KR\", \"sub_keys\":\"A~B\", \"zip\":\"\\\\d{5}\"}, "
+ "\"data/KR/A\": "
+ "{\"id\":\"data/KR/A\", \"sub_keys\":\"A1\"}, "
+ "\"data/KR/A/A1\": "
+ "{\"id\":\"data/KR/A/A1\", \"zip\":\"1\"}, "
+ "\"data/KR/B\": "
+ "{\"id\":\"data/KR/B\", \"sub_keys\":\"B1\"}, "
+ "\"data/KR/B/B1\": "
+ "{\"id\":\"data/KR/B/B1\", \"zip\":\"12\"}}"));
+
+ AddressData address;
+ address.region_code = "KR";
+ address.postal_code = "12345";
+ address.administrative_area = "";
+
+ AddressData expected = address;
+ FillAddress(&address);
+ // Nothing should have changed, since the ZIP code matches both of the cities,
+ // and they aren't even in the same state.
+ EXPECT_EQ(expected, address);
+}
+
+TEST_F(AddressInputHelperMockDataTest,
+ PostalCodeSharedAcrossDifferentHierarchiesSameState) {
+ // Create data where one state matches the ZIP code, but the other doesn't:
+ // within the state which does, multiple cities and sub-cities match. The only
+ // thing we can be certain of is therefore the state.
+ downloader_->data_.insert(std::make_pair(
+ // We use KR since we need a country where we format all fields down to
+ // dependent locality, or the hierarchy won't be loaded.
+ "data/KR",
+ "{\"data/KR\": "
+ // The top-level ZIP expression must be present for sub-key matches to be
+ // evaluated.
+ "{\"id\":\"data/KR\", \"sub_keys\":\"A~B\", \"zip\":\"\\\\d\{5}\"}, "
+ "\"data/KR/A\": "
+ "{\"id\":\"data/KR/A\", \"sub_keys\":\"A1~A2\"}, "
+ "\"data/KR/A/A1\": "
+ "{\"id\":\"data/KR/A/A1\", \"sub_keys\":\"A1a\", \"zip\":\"1\"}, "
+ // This key matches the ZIP code.
+ "\"data/KR/A/A1/A1a\": "
+ "{\"id\":\"data/KR/A/A1/A1a\", \"zip\":\"12\"}, "
+ "\"data/KR/A/A2\": "
+ "{\"id\":\"data/KR/A/A2\", \"sub_keys\":\"A2a\", \"zip\":\"1\"}, "
+ // This key, also in state A, but in city A2, matches the ZIP code.
+ "\"data/KR/A/A2/A2a\": "
+ "{\"id\":\"data/KR/A/A2/A2a\", \"zip\":\"123\"}, "
+ // This key, in state B, does not match the ZIP code.
+ "\"data/KR/B\": "
+ "{\"id\":\"data/KR/B\", \"zip\":\"2\"}}"));
+
+ AddressData address;
+ address.region_code = "KR";
+ address.postal_code = "12345";
+ address.administrative_area = "";
+
+ AddressData expected = address;
+ expected.administrative_area = "A";
+ FillAddress(&address);
+ // The ZIP code matches multiple city districts and cities; but only one
+ // state, so we fill this in.
+ EXPECT_EQ(expected, address);
+}
+
+} // namespace