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 62 // strings. 63 {false, "1234", "US"}, 64 // Test for string with exactly 7 digits. 65 // Not a valid number - starts with 1 66 {false, "17134567", "US"}, 67 // Not a valid number - does not have area code. 68 {false, "7134567", "US"}, 69 // Valid Canadian toll-free number. 70 {true, "3101234", "US", "3101234", "", "", "CA"}, 71 // Test for string with greater than 7 digits but less than 10 digits. 72 // Should fail parsing in US. 73 {false, "123456789", "US"}, 74 // Test for string with greater than 7 digits but less than 10 digits 75 // and 76 // separators. 77 // Should fail parsing in US. 78 {false, "12.345-6789", "US"}, 79 // Test for string with exactly 10 digits. 80 // Should give back phone number and city code. 81 // This one going to fail because of the incorrect area code. 82 {false, "1234567890", "US"}, 83 // This one going to fail because of the incorrect number (starts with 84 // 1). 85 {false, "6501567890", "US"}, 86 {true, "6504567890", "US", "4567890", "650", "", "US"}, 87 // Test for string with exactly 10 digits and separators. 88 // Should give back phone number and city code. 89 {true, "(650) 456-7890", "US", "4567890", "650", "", "US"}, 90 // Tests for string with over 10 digits. 91 // 01 is incorrect prefix in the USA, and if we interpret 011 as prefix, 92 // the 93 // rest is too short for international number - the parsing should fail. 94 {false, "0116504567890", "US"}, 95 // 011 is a correct "dial out" prefix in the USA - the parsing should 96 // succeed. 97 {true, "01116504567890", "US", "4567890", "650", "1", "US"}, 98 // 011 is a correct "dial out" prefix in the USA but the rest of the 99 // number 100 // can't parse as a US number. 101 {true, "01178124567890", "US", "4567890", "812", "7", "RU"}, 102 // Test for string with over 10 digits with separator characters. 103 // Should give back phone number, city code, and country code. "011" is 104 // US "dial out" code, which is discarded. 105 {true, "(0111) 650-456.7890", "US", "4567890", "650", "1", "US"}, 106 // Now try phone from Czech republic - it has 00 dial out code, 420 107 // country 108 // code and variable length area codes. 109 {true, "+420 27-89.10.112", "US", "910112", "278", "420", "CZ"}, 110 {false, "27-89.10.112", "US"}, 111 {true, "27-89.10.112", "CZ", "910112", "278", "", "CZ"}, 112 {false, "420 57-89.10.112", "US"}, 113 {true, "420 57-89.10.112", "CZ", "910112", "578", "420", "CZ"}, 114 // Parses vanity numbers. 115 {true, "1-650-FLOWERS", "US", "3569377", "650", "1", "US"}, 116 // 800 is not an area code, but the destination code. In our library 117 // these 118 // codes should be treated the same as area codes. 119 {true, "1-800-FLOWERS", "US", "3569377", "800", "1", "US"}, 120 // Don't add a country code where there was none. 121 {true, "(08) 450 777 7777", "DE", "7777777", "8450", "", "DE"}, 122 }; 123 124 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 125 SCOPED_TRACE("Testing phone number " + test_cases[i].input); 126 127 base::string16 country_code, city_code, number; 128 std::string deduced_region; 129 ::i18n::phonenumbers::PhoneNumber unused_i18n_number; 130 EXPECT_EQ(test_cases[i].valid, 131 ParsePhoneNumber(ASCIIToUTF16(test_cases[i].input), 132 test_cases[i].assumed_region, 133 &country_code, 134 &city_code, 135 &number, 136 &deduced_region, 137 &unused_i18n_number)); 138 EXPECT_EQ(ASCIIToUTF16(test_cases[i].number), number); 139 EXPECT_EQ(ASCIIToUTF16(test_cases[i].city_code), city_code); 140 EXPECT_EQ(ASCIIToUTF16(test_cases[i].country_code), country_code); 141 EXPECT_EQ(test_cases[i].deduced_region, deduced_region); 142 } 143} 144 145TEST(PhoneNumberI18NTest, ConstructPhoneNumber) { 146 base::string16 number; 147 EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"), 148 ASCIIToUTF16("650"), 149 ASCIIToUTF16("2345678"), 150 "US", 151 &number)); 152 EXPECT_EQ(ASCIIToUTF16("1 650-234-5678"), number); 153 EXPECT_TRUE(ConstructPhoneNumber(base::string16(), 154 ASCIIToUTF16("650"), 155 ASCIIToUTF16("2345678"), 156 "US", 157 &number)); 158 EXPECT_EQ(ASCIIToUTF16("(650) 234-5678"), number); 159 EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"), 160 base::string16(), 161 ASCIIToUTF16("6502345678"), 162 "US", 163 &number)); 164 EXPECT_EQ(ASCIIToUTF16("1 650-234-5678"), number); 165 EXPECT_TRUE(ConstructPhoneNumber(base::string16(), 166 base::string16(), 167 ASCIIToUTF16("6502345678"), 168 "US", 169 &number)); 170 EXPECT_EQ(ASCIIToUTF16("(650) 234-5678"), number); 171 172 EXPECT_FALSE(ConstructPhoneNumber(base::string16(), 173 ASCIIToUTF16("650"), 174 ASCIIToUTF16("234567890"), 175 "US", 176 &number)); 177 EXPECT_EQ(base::string16(), number); 178 // Italian number 179 EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"), 180 ASCIIToUTF16("347"), 181 ASCIIToUTF16("2345678"), 182 "IT", 183 &number)); 184 EXPECT_EQ(ASCIIToUTF16("+39 347 234 5678"), number); 185 EXPECT_TRUE(ConstructPhoneNumber(base::string16(), 186 ASCIIToUTF16("347"), 187 ASCIIToUTF16("2345678"), 188 "IT", 189 &number)); 190 EXPECT_EQ(ASCIIToUTF16("347 234 5678"), number); 191 // German number. 192 EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("49"), 193 ASCIIToUTF16("024"), 194 ASCIIToUTF16("2345678901"), 195 "DE", 196 &number)); 197 EXPECT_EQ(ASCIIToUTF16("+49 2423 45678901"), number); 198 EXPECT_TRUE(ConstructPhoneNumber(base::string16(), 199 ASCIIToUTF16("024"), 200 ASCIIToUTF16("2345678901"), 201 "DE", 202 &number)); 203 EXPECT_EQ(ASCIIToUTF16("02423 45678901"), number); 204} 205 206TEST(PhoneNumberI18NTest, PhoneNumbersMatch) { 207 // Same numbers, defined country code. 208 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"), 209 ASCIIToUTF16("4158889999"), 210 "US", 211 "en-US")); 212 // Same numbers, undefined country code. 213 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"), 214 ASCIIToUTF16("4158889999"), 215 std::string(), 216 "en-US")); 217 218 // Numbers differ by country code only. 219 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("14158889999"), 220 ASCIIToUTF16("4158889999"), 221 "US", 222 "en-US")); 223 224 // Same numbers, different formats. 225 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"), 226 ASCIIToUTF16("415-888-9999"), 227 "US", 228 "en-US")); 229 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"), 230 ASCIIToUTF16("(415)888-9999"), 231 "US", 232 "en-US")); 233 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"), 234 ASCIIToUTF16("415 888 9999"), 235 "US", 236 "en-US")); 237 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("4158889999"), 238 ASCIIToUTF16("415 TUV WXYZ"), 239 "US", 240 "en-US")); 241 EXPECT_TRUE(PhoneNumbersMatch(ASCIIToUTF16("1(415)888-99-99"), 242 ASCIIToUTF16("+14158889999"), 243 "US", 244 "en-US")); 245 246 // Partial matches don't count. 247 EXPECT_FALSE(PhoneNumbersMatch(ASCIIToUTF16("14158889999"), 248 ASCIIToUTF16("8889999"), 249 "US", 250 "en-US")); 251 252 // Different numbers don't match. 253 EXPECT_FALSE(PhoneNumbersMatch(ASCIIToUTF16("14158889999"), 254 ASCIIToUTF16("1415888"), 255 "US", 256 "en-US")); 257} 258 259} // namespace autofill 260