1// Copyright 2013 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.
4
5#include "base/message_loop/message_loop.h"
6#include "base/strings/string16.h"
7#include "base/strings/utf_string_conversions.h"
8#include "components/autofill/core/browser/phone_number_i18n.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "third_party/libphonenumber/src/phonenumber_api.h"
11
12using base::ASCIIToUTF16;
13using base::UTF8ToUTF16;
14
15namespace autofill {
16
17using i18n::NormalizePhoneNumber;
18using i18n::ParsePhoneNumber;
19using i18n::ConstructPhoneNumber;
20using i18n::PhoneNumbersMatch;
21
22TEST(PhoneNumberI18NTest, NormalizePhoneNumber) {
23  // "Large" digits.
24  base::string16 phone1(UTF8ToUTF16(
25      "\xEF\xBC\x91\xEF\xBC\x96\xEF\xBC\x95\xEF\xBC\x90"
26      "\xEF\xBC\x97\xEF\xBC\x94\xEF\xBC\x99\xEF\xBC\x98"
27      "\xEF\xBC\x93\xEF\xBC\x92\xEF\xBC\x93"));
28  EXPECT_EQ(NormalizePhoneNumber(phone1, "US"), ASCIIToUTF16("16507498323"));
29
30  // Devanagari script digits.
31  base::string16 phone2(UTF8ToUTF16(
32      "\xD9\xA1\xD9\xA6\xD9\xA5\xD9\xA0\xD9\xA8\xD9\xA3"
33      "\xD9\xA2\xD9\xA3\xD9\xA7\xD9\xA4\xD9\xA9"));
34  EXPECT_EQ(NormalizePhoneNumber(phone2, "US"), ASCIIToUTF16("16508323749"));
35
36  base::string16 phone3(UTF8ToUTF16("16503334\xef\xbc\x92\x35\xd9\xa5"));
37  EXPECT_EQ(NormalizePhoneNumber(phone3, "US"), ASCIIToUTF16("16503334255"));
38
39  base::string16 phone4(UTF8ToUTF16("+1(650)2346789"));
40  EXPECT_EQ(NormalizePhoneNumber(phone4, "US"), ASCIIToUTF16("16502346789"));
41
42  base::string16 phone5(UTF8ToUTF16("6502346789"));
43  EXPECT_EQ(NormalizePhoneNumber(phone5, "US"), ASCIIToUTF16("6502346789"));
44}
45
46TEST(PhoneNumberI18NTest, ParsePhoneNumber) {
47  const struct test_case {
48    // Expected parsing result.
49    bool valid;
50    // Inputs.
51    std::string input;
52    std::string assumed_region;
53    // Further expectations.
54    std::string number;
55    std::string city_code;
56    std::string country_code;
57    std::string deduced_region;
58  } test_cases[] = {
59    // Test for empty string.  Should give back empty strings.
60    { false, "", "US" },
61    // Test for string with less than 7 digits.  Should give back empty strings.
62    { false, "1234", "US" },
63    // Test for string with exactly 7 digits.
64    // Not a valid number - starts with 1
65    { false, "17134567", "US" },
66    // Not a valid number - does not have area code.
67    { false, "7134567", "US" },
68    // Valid Canadian toll-free number.
69    { true, "3101234", "US", "3101234", "", "", "CA" },
70    // Test for string with greater than 7 digits but less than 10 digits.
71    // Should fail parsing in US.
72    { false, "123456789", "US" },
73    // Test for string with greater than 7 digits but less than 10 digits and
74    // separators.
75    // Should fail parsing in US.
76    { false, "12.345-6789", "US" },
77    // Test for string with exactly 10 digits.
78    // Should give back phone number and city code.
79    // This one going to fail because of the incorrect area code.
80    { false, "1234567890", "US" },
81    // This one going to fail because of the incorrect number (starts with 1).
82    { false, "6501567890", "US" },
83    { true, "6504567890", "US", "4567890", "650", "", "US" },
84    // Test for string with exactly 10 digits and separators.
85    // Should give back phone number and city code.
86    { true, "(650) 456-7890", "US", "4567890", "650", "", "US" },
87    // Tests for string with over 10 digits.
88    // 01 is incorrect prefix in the USA, and if we interpret 011 as prefix, the
89    // rest is too short for international number - the parsing should fail.
90    { false, "0116504567890", "US" },
91    // 011 is a correct "dial out" prefix in the USA - the parsing should
92    // succeed.
93    { true, "01116504567890", "US", "4567890", "650", "1", "US" },
94    // 011 is a correct "dial out" prefix in the USA but the rest of the number
95    // can't parse as a US number.
96    { true, "01178124567890", "US", "4567890", "812", "7", "RU" },
97    // Test for string with over 10 digits with separator characters.
98    // Should give back phone number, city code, and country code. "011" is
99    // US "dial out" code, which is discarded.
100    { true, "(0111) 650-456.7890", "US", "4567890", "650", "1" , "US" },
101    // Now try phone from Czech republic - it has 00 dial out code, 420 country
102    // code and variable length area codes.
103    { true, "+420 27-89.10.112", "US", "910112", "278", "420", "CZ" },
104    { false, "27-89.10.112", "US" },
105    { true, "27-89.10.112", "CZ", "910112", "278", "", "CZ" },
106    { false, "420 57-89.10.112", "US" },
107    { true, "420 57-89.10.112", "CZ", "910112", "578", "420", "CZ" },
108    // Parses vanity numbers.
109    { true, "1-650-FLOWERS", "US", "3569377", "650", "1", "US" },
110    // 800 is not an area code, but the destination code. In our library these
111    // codes should be treated the same as area codes.
112    { true, "1-800-FLOWERS", "US", "3569377", "800", "1", "US" },
113  };
114
115  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
116    SCOPED_TRACE("Testing phone number " + test_cases[i].input);
117
118    base::string16 country_code, city_code, number;
119    std::string deduced_region;
120    ::i18n::phonenumbers::PhoneNumber unused_i18n_number;
121    EXPECT_EQ(test_cases[i].valid,
122              ParsePhoneNumber(ASCIIToUTF16(test_cases[i].input),
123                               test_cases[i].assumed_region,
124                               &country_code,
125                               &city_code,
126                               &number,
127                               &deduced_region,
128                               &unused_i18n_number));
129    EXPECT_EQ(ASCIIToUTF16(test_cases[i].number), number);
130    EXPECT_EQ(ASCIIToUTF16(test_cases[i].city_code), city_code);
131    EXPECT_EQ(ASCIIToUTF16(test_cases[i].country_code), country_code);
132    EXPECT_EQ(test_cases[i].deduced_region, deduced_region);
133  }
134}
135
136TEST(PhoneNumberI18NTest, ConstructPhoneNumber) {
137  base::string16 number;
138  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"),
139                                   ASCIIToUTF16("650"),
140                                   ASCIIToUTF16("2345678"),
141                                   "US",
142                                   &number));
143  EXPECT_EQ(number, ASCIIToUTF16("+1 650-234-5678"));
144  EXPECT_TRUE(ConstructPhoneNumber(base::string16(),
145                                   ASCIIToUTF16("650"),
146                                   ASCIIToUTF16("2345678"),
147                                   "US",
148                                   &number));
149  EXPECT_EQ(number, ASCIIToUTF16("(650) 234-5678"));
150  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"),
151                                   base::string16(),
152                                   ASCIIToUTF16("6502345678"),
153                                   "US",
154                                   &number));
155  EXPECT_EQ(number, ASCIIToUTF16("+1 650-234-5678"));
156  EXPECT_TRUE(ConstructPhoneNumber(base::string16(),
157                                   base::string16(),
158                                   ASCIIToUTF16("6502345678"),
159                                   "US",
160                                   &number));
161  EXPECT_EQ(number, ASCIIToUTF16("(650) 234-5678"));
162
163  EXPECT_FALSE(ConstructPhoneNumber(base::string16(),
164                                    ASCIIToUTF16("650"),
165                                    ASCIIToUTF16("234567890"),
166                                    "US",
167                                    &number));
168  EXPECT_EQ(number, base::string16());
169  // Italian number
170  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"),
171                                   ASCIIToUTF16("347"),
172                                   ASCIIToUTF16("2345678"),
173                                   "IT",
174                                   &number));
175  EXPECT_EQ(number, ASCIIToUTF16("+39 347 234 5678"));
176  EXPECT_TRUE(ConstructPhoneNumber(base::string16(),
177                                   ASCIIToUTF16("347"),
178                                   ASCIIToUTF16("2345678"),
179                                   "IT",
180                                   &number));
181  EXPECT_EQ(number, ASCIIToUTF16("347 234 5678"));
182  // German number.
183  EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("49"),
184                                   ASCIIToUTF16("024"),
185                                   ASCIIToUTF16("2345678901"),
186                                   "DE",
187                                   &number));
188  EXPECT_EQ(number, ASCIIToUTF16("+49 2423 45678901"));
189  EXPECT_TRUE(ConstructPhoneNumber(base::string16(),
190                                   ASCIIToUTF16("024"),
191                                   ASCIIToUTF16("2345678901"),
192                                   "DE",
193                                   &number));
194  EXPECT_EQ(number, ASCIIToUTF16("02423 45678901"));
195}
196
197TEST(PhoneNumberI18NTest, PhoneNumbersMatch) {
198  // Same numbers, defined country code.
199  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"),
200                                ASCIIToUTF16("4158889999"),
201                                "US",
202                                "en-US"));
203  // Same numbers, undefined country code.
204  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"),
205                                ASCIIToUTF16("4158889999"),
206                                std::string(),
207                                "en-US"));
208
209  // Numbers differ by country code only.
210  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("14158889999"),
211                                ASCIIToUTF16("4158889999"),
212                                "US",
213                                "en-US"));
214
215  // Same numbers, different formats.
216  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"),
217                                ASCIIToUTF16("415-888-9999"),
218                                "US",
219                                "en-US"));
220  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"),
221                                ASCIIToUTF16("(415)888-9999"),
222                                "US",
223                                "en-US"));
224  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"),
225                                ASCIIToUTF16("415 888 9999"),
226                                "US",
227                                "en-US"));
228  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"),
229                                ASCIIToUTF16("415 TUV WXYZ"),
230                                "US",
231                                "en-US"));
232  EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("1(415)888-99-99"),
233                                ASCIIToUTF16("+14158889999"),
234                                "US",
235                                "en-US"));
236
237  // Partial matches don't count.
238  EXPECT_FALSE(PhoneNumbersMatch(ASCIIToUTF16("14158889999"),
239                                 ASCIIToUTF16("8889999"),
240                                 "US",
241                                 "en-US"));
242
243  // Different numbers don't match.
244  EXPECT_FALSE(PhoneNumbersMatch(ASCIIToUTF16("14158889999"),
245                                 ASCIIToUTF16("1415888"),
246                                 "US",
247                                 "en-US"));
248}
249
250}  // namespace autofill
251