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