1// Copyright (C) 2013 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 "rule.h"
16
17#include <libaddressinput/address_field.h>
18#include <libaddressinput/localization.h>
19#include <libaddressinput/util/basictypes.h>
20
21#include <cstddef>
22#include <string>
23#include <utility>
24#include <vector>
25
26#include <gtest/gtest.h>
27
28#include "format_element.h"
29#include "grit.h"
30#include "messages.h"
31#include "region_data_constants.h"
32#include "util/json.h"
33
34namespace {
35
36using i18n::addressinput::AddressField;
37using i18n::addressinput::ADMIN_AREA;
38using i18n::addressinput::FormatElement;
39using i18n::addressinput::INVALID_MESSAGE_ID;
40using i18n::addressinput::Json;
41using i18n::addressinput::LOCALITY;
42using i18n::addressinput::Localization;
43using i18n::addressinput::RegionDataConstants;
44using i18n::addressinput::Rule;
45using i18n::addressinput::STREET_ADDRESS;
46
47TEST(RuleTest, CopyOverwritesRule) {
48  Rule rule;
49  ASSERT_TRUE(rule.ParseSerializedRule("{"
50                                       "\"fmt\":\"%S%Z\","
51                                       "\"lfmt\":\"%Z%S\","
52                                       "\"id\":\"data/XA\","
53                                       "\"name\":\"Le Test\","
54                                       "\"lname\":\"Testistan\","
55                                       "\"require\":\"AC\","
56                                       "\"sub_keys\":\"aa~bb~cc\","
57                                       "\"languages\":\"en~fr\","
58                                       "\"zip\":\"\\\\d{3}\","
59                                       "\"state_name_type\":\"area\","
60                                       "\"zip_name_type\":\"postal\","
61                                       "\"zipex\":\"1234\","
62                                       "\"posturl\":\"http://www.testpost.com\""
63                                       "}"));
64
65  Rule copy;
66  EXPECT_NE(rule.GetFormat(), copy.GetFormat());
67  EXPECT_NE(rule.GetLatinFormat(), copy.GetLatinFormat());
68  EXPECT_NE(rule.GetId(), copy.GetId());
69  EXPECT_NE(rule.GetRequired(), copy.GetRequired());
70  EXPECT_NE(rule.GetSubKeys(), copy.GetSubKeys());
71  EXPECT_NE(rule.GetLanguages(), copy.GetLanguages());
72  EXPECT_NE(rule.GetAdminAreaNameMessageId(),
73            copy.GetAdminAreaNameMessageId());
74  EXPECT_NE(rule.GetPostalCodeNameMessageId(),
75            copy.GetPostalCodeNameMessageId());
76  EXPECT_NE(rule.GetName(), copy.GetName());
77  EXPECT_NE(rule.GetLatinName(), copy.GetLatinName());
78  EXPECT_NE(rule.GetPostalCodeExample(), copy.GetPostalCodeExample());
79  EXPECT_NE(rule.GetPostServiceUrl(), copy.GetPostServiceUrl());
80
81  EXPECT_TRUE(rule.GetPostalCodeMatcher() != NULL);
82  EXPECT_TRUE(copy.GetPostalCodeMatcher() == NULL);
83
84  copy.CopyFrom(rule);
85  EXPECT_EQ(rule.GetFormat(), copy.GetFormat());
86  EXPECT_EQ(rule.GetLatinFormat(), copy.GetLatinFormat());
87  EXPECT_EQ(rule.GetId(), copy.GetId());
88  EXPECT_EQ(rule.GetRequired(), copy.GetRequired());
89  EXPECT_EQ(rule.GetSubKeys(), copy.GetSubKeys());
90  EXPECT_EQ(rule.GetLanguages(), copy.GetLanguages());
91  EXPECT_EQ(rule.GetAdminAreaNameMessageId(),
92            copy.GetAdminAreaNameMessageId());
93  EXPECT_EQ(rule.GetPostalCodeNameMessageId(),
94            copy.GetPostalCodeNameMessageId());
95  EXPECT_EQ(rule.GetName(), copy.GetName());
96  EXPECT_EQ(rule.GetLatinName(), copy.GetLatinName());
97  EXPECT_EQ(rule.GetPostalCodeExample(), copy.GetPostalCodeExample());
98  EXPECT_EQ(rule.GetPostServiceUrl(), copy.GetPostServiceUrl());
99
100  EXPECT_TRUE(copy.GetPostalCodeMatcher() != NULL);
101}
102
103TEST(RuleTest, ParseOverwritesRule) {
104  Rule rule;
105  ASSERT_TRUE(rule.ParseSerializedRule("{"
106                                       "\"fmt\":\"%S%Z\","
107                                       "\"state_name_type\":\"area\","
108                                       "\"zip\":\"1234\","
109                                       "\"zip_name_type\":\"postal\","
110                                       "\"zipex\":\"1234\","
111                                       "\"posturl\":\"http://www.testpost.com\""
112                                       "}"));
113  EXPECT_FALSE(rule.GetFormat().empty());
114  EXPECT_EQ(IDS_LIBADDRESSINPUT_AREA,
115            rule.GetAdminAreaNameMessageId());
116  EXPECT_EQ(IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL,
117            rule.GetPostalCodeNameMessageId());
118  EXPECT_EQ("1234", rule.GetSolePostalCode());
119  EXPECT_EQ("1234", rule.GetPostalCodeExample());
120  EXPECT_EQ("http://www.testpost.com", rule.GetPostServiceUrl());
121
122  ASSERT_TRUE(rule.ParseSerializedRule("{"
123                                       "\"fmt\":\"\","
124                                       "\"state_name_type\":\"do_si\","
125                                       "\"zip_name_type\":\"zip\","
126                                       "\"zipex\":\"5678\","
127                                       "\"posturl\":\"http://www.fakepost.com\""
128                                       "}"));
129  EXPECT_TRUE(rule.GetFormat().empty());
130  EXPECT_EQ(IDS_LIBADDRESSINPUT_DO_SI,
131            rule.GetAdminAreaNameMessageId());
132  EXPECT_EQ(IDS_LIBADDRESSINPUT_ZIP_CODE_LABEL,
133            rule.GetPostalCodeNameMessageId());
134  EXPECT_TRUE(rule.GetSolePostalCode().empty());
135  EXPECT_EQ("5678", rule.GetPostalCodeExample());
136  EXPECT_EQ("http://www.fakepost.com", rule.GetPostServiceUrl());
137}
138
139TEST(RuleTest, ParsesFormatCorrectly) {
140  std::vector<FormatElement> expected;
141  expected.push_back(FormatElement(ADMIN_AREA));
142  expected.push_back(FormatElement(LOCALITY));
143  Rule rule;
144  ASSERT_TRUE(rule.ParseSerializedRule("{\"fmt\":\"%S%C\"}"));
145  EXPECT_EQ(expected, rule.GetFormat());
146}
147
148TEST(RuleTest, ParsesNameCorrectly) {
149  Rule rule;
150  ASSERT_TRUE(rule.ParseSerializedRule("{\"name\":\"Le Test\"}"));
151  EXPECT_EQ("Le Test", rule.GetName());
152}
153
154TEST(RuleTest, ParsesLatinNameCorrectly) {
155  Rule rule;
156  ASSERT_TRUE(rule.ParseSerializedRule("{\"lname\":\"Testistan\"}"));
157  EXPECT_EQ("Testistan", rule.GetLatinName());
158}
159
160TEST(RuleTest, ParsesLatinFormatCorrectly) {
161  std::vector<FormatElement> expected;
162  expected.push_back(FormatElement(LOCALITY));
163  expected.push_back(FormatElement(ADMIN_AREA));
164  Rule rule;
165  ASSERT_TRUE(rule.ParseSerializedRule("{\"lfmt\":\"%C%S\"}"));
166  EXPECT_EQ(expected, rule.GetLatinFormat());
167}
168
169TEST(RuleTest, ParsesRequiredCorrectly) {
170  std::vector<AddressField> expected;
171  expected.push_back(STREET_ADDRESS);
172  expected.push_back(LOCALITY);
173  Rule rule;
174  ASSERT_TRUE(rule.ParseSerializedRule("{\"require\":\"AC\"}"));
175  EXPECT_EQ(expected, rule.GetRequired());
176}
177
178TEST(RuleTest, ParsesSubKeysCorrectly) {
179  std::vector<std::string> expected;
180  expected.push_back("aa");
181  expected.push_back("bb");
182  expected.push_back("cc");
183  Rule rule;
184  ASSERT_TRUE(rule.ParseSerializedRule("{\"sub_keys\":\"aa~bb~cc\"}"));
185  EXPECT_EQ(expected, rule.GetSubKeys());
186}
187
188TEST(RuleTest, ParsesLanguagesCorrectly) {
189  std::vector<std::string> expected;
190  expected.push_back("de");
191  expected.push_back("fr");
192  expected.push_back("it");
193  Rule rule;
194  ASSERT_TRUE(rule.ParseSerializedRule("{\"languages\":\"de~fr~it\"}"));
195  EXPECT_EQ(expected, rule.GetLanguages());
196}
197
198TEST(RuleTest, ParsesPostalCodeExampleCorrectly) {
199  Rule rule;
200  ASSERT_TRUE(rule.ParseSerializedRule("{\"zipex\":\"1234,12345-6789\"}"));
201  EXPECT_EQ("1234,12345-6789", rule.GetPostalCodeExample());
202}
203
204TEST(RuleTest, ParsesPostServiceUrlCorrectly) {
205  Rule rule;
206  ASSERT_TRUE(
207      rule.ParseSerializedRule("{\"posturl\":\"http://www.testpost.com\"}"));
208  EXPECT_EQ("http://www.testpost.com", rule.GetPostServiceUrl());
209}
210
211TEST(RuleTest, PostalCodeMatcher) {
212  Rule rule;
213  ASSERT_TRUE(rule.ParseSerializedRule("{\"zip\":\"\\\\d{3}\"}"));
214  EXPECT_TRUE(rule.GetPostalCodeMatcher() != NULL);
215}
216
217TEST(RuleTest, PostalCodeMatcherInvalidRegExp) {
218  Rule rule;
219  ASSERT_TRUE(rule.ParseSerializedRule("{\"zip\":\"(\"}"));
220  EXPECT_TRUE(rule.GetPostalCodeMatcher() == NULL);
221}
222
223TEST(RuleTest, ParsesJsonRuleCorrectly) {
224  Json json;
225  ASSERT_TRUE(json.ParseObject("{\"zip\":\"\\\\d{3}\"}"));
226  Rule rule;
227  rule.ParseJsonRule(json);
228  EXPECT_TRUE(rule.GetPostalCodeMatcher() != NULL);
229}
230
231TEST(RuleTest, EmptyStringIsNotValid) {
232  Rule rule;
233  EXPECT_FALSE(rule.ParseSerializedRule(std::string()));
234}
235
236TEST(RuleTest, EmptyDictionaryIsValid) {
237  Rule rule;
238  EXPECT_TRUE(rule.ParseSerializedRule("{}"));
239}
240
241// Tests for parsing the postal code name.
242class PostalCodeNameParseTest
243    : public testing::TestWithParam<std::pair<std::string, int> > {
244 protected:
245  PostalCodeNameParseTest() {}
246  Rule rule_;
247
248 private:
249  DISALLOW_COPY_AND_ASSIGN(PostalCodeNameParseTest);
250};
251
252// Verifies that a postal code name is parsed correctly.
253TEST_P(PostalCodeNameParseTest, ParsedCorrectly) {
254  ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().first));
255  EXPECT_EQ(GetParam().second, rule_.GetPostalCodeNameMessageId());
256}
257
258// Test parsing all postal code names.
259INSTANTIATE_TEST_CASE_P(
260    AllPostalCodeNames, PostalCodeNameParseTest,
261    testing::Values(
262        std::make_pair("{\"zip_name_type\":\"postal\"}",
263                       IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL),
264        std::make_pair("{\"zip_name_type\":\"zip\"}",
265                       IDS_LIBADDRESSINPUT_ZIP_CODE_LABEL)));
266
267// Tests for parsing the administrative area name.
268class AdminAreaNameParseTest
269    : public testing::TestWithParam<std::pair<std::string, int> > {
270 protected:
271  AdminAreaNameParseTest() {}
272  Rule rule_;
273
274 private:
275  DISALLOW_COPY_AND_ASSIGN(AdminAreaNameParseTest);
276};
277
278// Verifies that an administrative area name is parsed correctly.
279TEST_P(AdminAreaNameParseTest, ParsedCorrectly) {
280  ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().first));
281  EXPECT_EQ(GetParam().second, rule_.GetAdminAreaNameMessageId());
282}
283
284// Test parsing all administrative area names.
285INSTANTIATE_TEST_CASE_P(
286    AllAdminAreaNames, AdminAreaNameParseTest,
287    testing::Values(
288        std::make_pair("{\"state_name_type\":\"area\"}",
289                       IDS_LIBADDRESSINPUT_AREA),
290        std::make_pair("{\"state_name_type\":\"county\"}",
291                       IDS_LIBADDRESSINPUT_COUNTY),
292        std::make_pair("{\"state_name_type\":\"department\"}",
293                       IDS_LIBADDRESSINPUT_DEPARTMENT),
294        std::make_pair("{\"state_name_type\":\"district\"}",
295                       IDS_LIBADDRESSINPUT_DISTRICT),
296        std::make_pair("{\"state_name_type\":\"do_si\"}",
297                       IDS_LIBADDRESSINPUT_DO_SI),
298        std::make_pair("{\"state_name_type\":\"emirate\"}",
299                       IDS_LIBADDRESSINPUT_EMIRATE),
300        std::make_pair("{\"state_name_type\":\"island\"}",
301                       IDS_LIBADDRESSINPUT_ISLAND),
302        std::make_pair("{\"state_name_type\":\"parish\"}",
303                       IDS_LIBADDRESSINPUT_PARISH),
304        std::make_pair("{\"state_name_type\":\"prefecture\"}",
305                       IDS_LIBADDRESSINPUT_PREFECTURE),
306        std::make_pair("{\"state_name_type\":\"province\"}",
307                       IDS_LIBADDRESSINPUT_PROVINCE),
308        std::make_pair("{\"state_name_type\":\"state\"}",
309                       IDS_LIBADDRESSINPUT_STATE)));
310
311// Tests for rule parsing.
312class RuleParseTest : public testing::TestWithParam<std::string> {
313 protected:
314  RuleParseTest() {}
315
316  const std::string& GetRegionData() const {
317    // GetParam() is either a region code or the region data itself.
318    // RegionDataContants::GetRegionData() returns an empty string for anything
319    // that's not a region code.
320    const std::string& data = RegionDataConstants::GetRegionData(GetParam());
321    return !data.empty() ? data : GetParam();
322  }
323
324  Rule rule_;
325  Localization localization_;
326
327 private:
328  DISALLOW_COPY_AND_ASSIGN(RuleParseTest);
329};
330
331// Verifies that a region data can be parsed successfully.
332TEST_P(RuleParseTest, RegionDataParsedSuccessfully) {
333  EXPECT_TRUE(rule_.ParseSerializedRule(GetRegionData()));
334}
335
336// Verifies that the admin area name type corresponds to a UI string.
337TEST_P(RuleParseTest, AdminAreaNameTypeHasUiString) {
338  const std::string& region_data = GetRegionData();
339  rule_.ParseSerializedRule(region_data);
340  if (region_data.find("state_name_type") != std::string::npos) {
341    EXPECT_NE(INVALID_MESSAGE_ID, rule_.GetAdminAreaNameMessageId());
342    EXPECT_FALSE(
343        localization_.GetString(rule_.GetAdminAreaNameMessageId()).empty());
344  }
345}
346
347// Verifies that the postal code name type corresponds to a UI string.
348TEST_P(RuleParseTest, PostalCodeNameTypeHasUiString) {
349  const std::string& region_data = GetRegionData();
350  rule_.ParseSerializedRule(region_data);
351  if (region_data.find("zip_name_type") != std::string::npos) {
352    EXPECT_NE(INVALID_MESSAGE_ID, rule_.GetPostalCodeNameMessageId());
353    EXPECT_FALSE(
354        localization_.GetString(rule_.GetPostalCodeNameMessageId()).empty());
355  }
356}
357
358// Verifies that the sole postal code is correctly recognised and copied.
359TEST_P(RuleParseTest, SolePostalCode) {
360  Rule rule;
361  ASSERT_TRUE(rule.ParseSerializedRule("{\"zip\":\"1234\"}"));
362  EXPECT_TRUE(rule.GetPostalCodeMatcher() != NULL);
363  EXPECT_TRUE(rule.GetSolePostalCode() == "1234");
364
365  Rule copy;
366  EXPECT_TRUE(copy.GetPostalCodeMatcher() == NULL);
367  EXPECT_TRUE(copy.GetSolePostalCode().empty());
368
369  copy.CopyFrom(rule);
370  EXPECT_TRUE(copy.GetPostalCodeMatcher() != NULL);
371  EXPECT_EQ(rule.GetSolePostalCode(), copy.GetSolePostalCode());
372}
373
374// Test parsing all region data.
375INSTANTIATE_TEST_CASE_P(
376    AllRulesTest, RuleParseTest,
377    testing::ValuesIn(RegionDataConstants::GetRegionCodes()));
378
379// Test parsing the default rule.
380INSTANTIATE_TEST_CASE_P(
381    DefaultRuleTest, RuleParseTest,
382    testing::Values(RegionDataConstants::GetDefaultRegionData()));
383
384}  // namespace
385