blob: 36da4fdf765a50ecade966ae5ed874443eca27e3 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/autofill_profile_comparator.h"
#include "base/guid.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/contact_info.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/field_types.h"
#include "testing/gtest/include/gtest/gtest.h"
// Field Type Constants
using autofill::ADDRESS_HOME_CITY;
using autofill::ADDRESS_HOME_COUNTRY;
using autofill::ADDRESS_HOME_DEPENDENT_LOCALITY;
using autofill::ADDRESS_HOME_LINE1;
using autofill::ADDRESS_HOME_LINE2;
using autofill::ADDRESS_HOME_LINE3;
using autofill::ADDRESS_HOME_SORTING_CODE;
using autofill::ADDRESS_HOME_STATE;
using autofill::ADDRESS_HOME_STREET_ADDRESS;
using autofill::ADDRESS_HOME_ZIP;
using autofill::COMPANY_NAME;
using autofill::EMAIL_ADDRESS;
using autofill::NAME_FIRST;
using autofill::NAME_FULL;
using autofill::NAME_LAST;
using autofill::NAME_MIDDLE;
using autofill::PHONE_HOME_WHOLE_NUMBER;
using autofill::PHONE_HOME_EXTENSION;
using autofill::PHONE_HOME_NUMBER;
using autofill::PHONE_HOME_CITY_CODE;
using autofill::PHONE_HOME_COUNTRY_CODE;
using autofill::PHONE_HOME_CITY_AND_NUMBER;
// Classes, Functions, and other Symbols
using autofill::Address;
using autofill::AutofillProfile;
using autofill::AutofillType;
using autofill::CompanyInfo;
using autofill::EmailInfo;
using autofill::NameInfo;
using autofill::PhoneNumber;
using autofill::ServerFieldType;
using base::UTF8ToUTF16;
namespace {
const char kLocale[] = "en-US";
class AutofillProfileComparatorTest : public ::testing::Test {
public:
// Expose the protected methods of autofill::AutofillProfileComparator for
// testing.
class AutofillProfileComparator
: public ::autofill::AutofillProfileComparator {
public:
typedef ::autofill::AutofillProfileComparator Super;
using Super::Super;
using Super::UniqueTokens;
using Super::CompareTokens;
using Super::GetNamePartVariants;
using Super::IsNameVariantOf;
using Super::HaveMergeableNames;
using Super::HaveMergeableEmailAddresses;
using Super::HaveMergeableCompanyNames;
using Super::HaveMergeablePhoneNumbers;
using Super::HaveMergeableAddresses;
using Super::DIFFERENT_TOKENS;
using Super::SAME_TOKENS;
using Super::S1_CONTAINS_S2;
using Super::S2_CONTAINS_S1;
};
AutofillProfileComparatorTest() {
autofill::CountryNames::SetLocaleString(kLocale);
}
NameInfo CreateNameInfo(const char* first,
const char* middle,
const char* last,
const char* full) {
NameInfo name;
name.SetRawInfo(NAME_FIRST, base::UTF8ToUTF16(first));
name.SetRawInfo(NAME_MIDDLE, base::UTF8ToUTF16(middle));
name.SetRawInfo(NAME_LAST, base::UTF8ToUTF16(last));
name.SetRawInfo(NAME_FULL, base::UTF8ToUTF16(full));
return name;
}
AutofillProfile CreateProfileWithName(const char* first,
const char* middle,
const char* last) {
AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
autofill::test::SetProfileInfo(&profile, first, middle, last, "", "", "",
"", "", "", "", "", "");
return profile;
}
AutofillProfile CreateProfileWithName(const NameInfo& name) {
AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
profile.SetRawInfo(NAME_FULL, name.GetRawInfo(NAME_FULL));
profile.SetRawInfo(NAME_FIRST, name.GetRawInfo(NAME_FIRST));
profile.SetRawInfo(NAME_MIDDLE, name.GetRawInfo(NAME_MIDDLE));
profile.SetRawInfo(NAME_LAST, name.GetRawInfo(NAME_LAST));
return profile;
}
AutofillProfile CreateProfileWithEmail(const char* email) {
AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
autofill::test::SetProfileInfo(&profile, "", "", "", email, "", "", "", "",
"", "", "", "");
return profile;
}
AutofillProfile CreateProfileWithCompanyName(const char* company_name) {
AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
autofill::test::SetProfileInfo(&profile, "", "", "", "", company_name, "",
"", "", "", "", "", "");
return profile;
}
AutofillProfile CreateProfileWithPhoneNumber(const char* phone_number) {
AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
autofill::test::SetProfileInfo(&profile, "", "", "", "", "", "", "", "", "",
"", "", phone_number);
return profile;
}
AutofillProfile CreateProfileWithAddress(const char* line1,
const char* line2,
const char* city,
const char* state,
const char* zip,
const char* country) {
AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
autofill::test::SetProfileInfo(&profile, "", "", "", "", "", line1, line2,
city, state, zip, country, "");
return profile;
}
AutofillProfile CopyAndModify(
const AutofillProfile& profile,
const std::vector<std::pair<ServerFieldType, const char*>>& updates) {
AutofillProfile new_profile = profile;
for (const auto& update : updates) {
new_profile.SetRawInfo(update.first, UTF8ToUTF16(update.second));
}
return new_profile;
}
void MergeNamesAndExpect(const AutofillProfile& a,
const AutofillProfile& b,
const NameInfo& expected) {
NameInfo actual;
ASSERT_TRUE(comparator_.MergeNames(a, b, &actual));
// Is the "processed" data correct?
EXPECT_EQ(expected.GetInfo(AutofillType(NAME_FULL), kLocale),
actual.GetInfo(AutofillType(NAME_FULL), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(NAME_FIRST), kLocale),
actual.GetInfo(AutofillType(NAME_FIRST), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(NAME_MIDDLE), kLocale),
actual.GetInfo(AutofillType(NAME_MIDDLE), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(NAME_LAST), kLocale),
actual.GetInfo(AutofillType(NAME_LAST), kLocale));
// Is the raw data correct?
EXPECT_EQ(expected.GetRawInfo(NAME_FULL), actual.GetRawInfo(NAME_FULL));
EXPECT_EQ(expected.GetRawInfo(NAME_FIRST), actual.GetRawInfo(NAME_FIRST));
EXPECT_EQ(expected.GetRawInfo(NAME_MIDDLE), actual.GetRawInfo(NAME_MIDDLE));
EXPECT_EQ(expected.GetRawInfo(NAME_LAST), actual.GetRawInfo(NAME_LAST));
}
void MergeEmailAddressesAndExpect(const AutofillProfile& a,
const AutofillProfile& b,
const EmailInfo& expected) {
EmailInfo actual;
ASSERT_TRUE(comparator_.MergeEmailAddresses(a, b, &actual));
EXPECT_EQ(expected.GetRawInfo(EMAIL_ADDRESS),
actual.GetRawInfo(EMAIL_ADDRESS));
}
void MergeCompanyNamesAndExpect(const AutofillProfile& a,
const AutofillProfile& b,
const CompanyInfo& expected) {
CompanyInfo actual;
ASSERT_TRUE(comparator_.MergeCompanyNames(a, b, &actual));
EXPECT_EQ(expected.GetRawInfo(COMPANY_NAME),
actual.GetRawInfo(COMPANY_NAME));
}
void MergePhoneNumbersAndExpect(const AutofillProfile& a,
const AutofillProfile& b,
const std::string& expected_str) {
AutofillProfile dummy;
// Merge the phone numbers.
PhoneNumber actual(&dummy);
ASSERT_TRUE(comparator_.MergePhoneNumbers(a, b, &actual));
// Construct the expected value.
PhoneNumber expected(&dummy);
expected.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, UTF8ToUTF16(expected_str));
// Validate that we get what we expect.
EXPECT_EQ(expected.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
actual.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
EXPECT_EQ(expected.GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), kLocale),
actual.GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(PHONE_HOME_COUNTRY_CODE), kLocale),
actual.GetInfo(AutofillType(PHONE_HOME_COUNTRY_CODE), kLocale));
EXPECT_EQ(
expected.GetInfo(AutofillType(PHONE_HOME_CITY_AND_NUMBER), kLocale),
actual.GetInfo(AutofillType(PHONE_HOME_CITY_AND_NUMBER), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(PHONE_HOME_CITY_CODE), kLocale),
actual.GetInfo(AutofillType(PHONE_HOME_CITY_CODE), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(PHONE_HOME_NUMBER), kLocale),
actual.GetInfo(AutofillType(PHONE_HOME_NUMBER), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(PHONE_HOME_EXTENSION), kLocale),
actual.GetInfo(AutofillType(PHONE_HOME_EXTENSION), kLocale));
}
void MergeAddressesAndExpect(const AutofillProfile& a,
const AutofillProfile& b,
const Address& expected) {
Address actual;
ASSERT_TRUE(comparator_.MergeAddresses(a, b, &actual));
EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_LINE1), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_LINE1), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_LINE2), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_LINE2), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_LINE3), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_LINE3), kLocale));
EXPECT_EQ(
expected.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), kLocale));
EXPECT_EQ(
expected.GetInfo(AutofillType(ADDRESS_HOME_DEPENDENT_LOCALITY),
kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_DEPENDENT_LOCALITY), kLocale));
EXPECT_EQ(
expected.GetInfo(AutofillType(ADDRESS_HOME_SORTING_CODE), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_SORTING_CODE), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_CITY), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_CITY), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_STATE), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_STATE), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_ZIP), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_ZIP), kLocale));
EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_COUNTRY), kLocale),
actual.GetInfo(AutofillType(ADDRESS_HOME_COUNTRY), kLocale));
}
AutofillProfileComparator comparator_{kLocale};
private:
DISALLOW_COPY_AND_ASSIGN(AutofillProfileComparatorTest);
};
} // namespace
TEST_F(AutofillProfileComparatorTest, UniqueTokens) {
base::string16 kInput = UTF8ToUTF16("a b a a b");
std::vector<base::string16> tokens = {UTF8ToUTF16("a"), UTF8ToUTF16("b")};
EXPECT_EQ(std::set<base::StringPiece16>(tokens.begin(), tokens.end()),
comparator_.UniqueTokens(kInput));
}
TEST_F(AutofillProfileComparatorTest, CompareTokens) {
base::string16 kEmptyStr = UTF8ToUTF16("");
base::string16 kHello = UTF8ToUTF16("hello");
base::string16 kHelloThere = UTF8ToUTF16("hello there");
base::string16 kHelloThereAlice = UTF8ToUTF16("hello there alice");
base::string16 kHelloThereBob = UTF8ToUTF16("hello there bob");
EXPECT_EQ(AutofillProfileComparator::SAME_TOKENS,
comparator_.CompareTokens(kHelloThereBob, kHelloThereBob));
EXPECT_EQ(AutofillProfileComparator::S2_CONTAINS_S1,
comparator_.CompareTokens(kEmptyStr, kHello));
EXPECT_EQ(AutofillProfileComparator::S1_CONTAINS_S2,
comparator_.CompareTokens(kHello, kEmptyStr));
EXPECT_EQ(AutofillProfileComparator::S1_CONTAINS_S2,
comparator_.CompareTokens(kHelloThere, kHello));
EXPECT_EQ(AutofillProfileComparator::S2_CONTAINS_S1,
comparator_.CompareTokens(kHello, kHelloThere));
EXPECT_EQ(AutofillProfileComparator::DIFFERENT_TOKENS,
comparator_.CompareTokens(kHelloThereAlice, kHelloThereBob));
EXPECT_EQ(AutofillProfileComparator::DIFFERENT_TOKENS,
comparator_.CompareTokens(kHelloThereBob, kHelloThereAlice));
}
TEST_F(AutofillProfileComparatorTest, NormalizeForComparison) {
EXPECT_EQ(UTF8ToUTF16("timothe"),
comparator_.NormalizeForComparison(UTF8ToUTF16("Timothé")));
EXPECT_EQ(UTF8ToUTF16("sven ake"),
comparator_.NormalizeForComparison(UTF8ToUTF16(" sven-åke ")));
EXPECT_EQ(UTF8ToUTF16("c 㸐"),
comparator_.NormalizeForComparison(UTF8ToUTF16("Ç 㸐")));
EXPECT_EQ(UTF8ToUTF16("902103214"),
comparator_.NormalizeForComparison(
base::UTF8ToUTF16("90210-3214"),
AutofillProfileComparator::DISCARD_WHITESPACE));
EXPECT_EQ(UTF8ToUTF16("timothe noel etienne perier"),
comparator_.NormalizeForComparison(
UTF8ToUTF16("Timothé-Noël Étienne Périer")));
// NOP.
EXPECT_EQ(base::string16(),
comparator_.NormalizeForComparison(base::string16()));
// Simple punctuation removed.
EXPECT_EQ(UTF8ToUTF16("1600 amphitheatre pkwy"),
comparator_.NormalizeForComparison(
UTF8ToUTF16("1600 Amphitheatre, Pkwy.")));
// Unicode punctuation (hyphen and space), multiple spaces collapsed.
EXPECT_EQ(UTF8ToUTF16("mid island plaza"),
comparator_.NormalizeForComparison(
base::WideToUTF16(L"Mid\x2013Island\x2003 Plaza")));
// Newline character removed.
EXPECT_EQ(UTF8ToUTF16("1600 amphitheatre pkwy app 2"),
comparator_.NormalizeForComparison(
UTF8ToUTF16("1600 amphitheatre pkwy \n App. 2")));
// Diacritics removed.
EXPECT_EQ(UTF8ToUTF16("まeoa정"),
comparator_.NormalizeForComparison(UTF8ToUTF16("まéÖä정")));
// Spaces removed.
EXPECT_EQ(UTF8ToUTF16("유재석"), comparator_.NormalizeForComparison(
UTF8ToUTF16("유 재석"),
AutofillProfileComparator::DISCARD_WHITESPACE));
// Punctuation removed, Japanese kana normalized.
EXPECT_EQ(UTF8ToUTF16("ヒルケイツ"), comparator_.NormalizeForComparison(
UTF8ToUTF16("ビル・ゲイツ"),
AutofillProfileComparator::DISCARD_WHITESPACE));
}
TEST_F(AutofillProfileComparatorTest, GetNamePartVariants) {
std::set<base::string16> expected_variants = {
UTF8ToUTF16("timothe noel"),
UTF8ToUTF16("timothe n"),
UTF8ToUTF16("timothe"),
UTF8ToUTF16("t noel"),
UTF8ToUTF16("t n"),
UTF8ToUTF16("t"),
UTF8ToUTF16("noel"),
UTF8ToUTF16("n"),
UTF8ToUTF16(""),
UTF8ToUTF16("tn"),
};
EXPECT_EQ(expected_variants,
comparator_.GetNamePartVariants(UTF8ToUTF16("timothe noel")));
}
TEST_F(AutofillProfileComparatorTest, IsNameVariantOf) {
const base::string16 kNormalizedFullName =
UTF8ToUTF16("timothe noel etienne perier");
EXPECT_TRUE(
comparator_.IsNameVariantOf(kNormalizedFullName, kNormalizedFullName));
EXPECT_TRUE(comparator_.IsNameVariantOf(
kNormalizedFullName, UTF8ToUTF16("t noel etienne perier")));
EXPECT_TRUE(comparator_.IsNameVariantOf(kNormalizedFullName,
UTF8ToUTF16("timothe perier")));
EXPECT_TRUE(comparator_.IsNameVariantOf(kNormalizedFullName,
UTF8ToUTF16("t perier")));
EXPECT_TRUE(comparator_.IsNameVariantOf(kNormalizedFullName,
UTF8ToUTF16("noel perier")));
EXPECT_TRUE(comparator_.IsNameVariantOf(kNormalizedFullName,
UTF8ToUTF16("t n etienne perier")));
EXPECT_TRUE(comparator_.IsNameVariantOf(kNormalizedFullName,
UTF8ToUTF16("tn perier")));
EXPECT_TRUE(comparator_.IsNameVariantOf(kNormalizedFullName,
UTF8ToUTF16("te perier")));
EXPECT_FALSE(comparator_.IsNameVariantOf(kNormalizedFullName,
UTF8ToUTF16("etienne noel perier")));
}
TEST_F(AutofillProfileComparatorTest, HaveMergeableNames) {
AutofillProfile empty = CreateProfileWithName("", "", "");
AutofillProfile p1 = CreateProfileWithName("sven-åke", "", "larsson");
AutofillProfile p2 = CreateProfileWithName("Åke", "", "Larsson");
AutofillProfile p3 = CreateProfileWithName("A", "", "Larsson");
AutofillProfile p4 = CreateProfileWithName("sven", "ake", "Larsson");
AutofillProfile initials = CreateProfileWithName("SA", "", "Larsson");
AutofillProfile different = CreateProfileWithName("Joe", "", "Larsson");
// |p1|, |p2|, |p3|, |p4| and |empty| should all be the mergeable with
// one another. The order of the comparands should not matter.
EXPECT_TRUE(comparator_.HaveMergeableNames(p1, empty));
EXPECT_TRUE(comparator_.HaveMergeableNames(p1, p1));
EXPECT_TRUE(comparator_.HaveMergeableNames(p1, p2));
EXPECT_TRUE(comparator_.HaveMergeableNames(p1, p3));
EXPECT_TRUE(comparator_.HaveMergeableNames(p1, p4));
EXPECT_TRUE(comparator_.HaveMergeableNames(p2, empty));
EXPECT_TRUE(comparator_.HaveMergeableNames(p2, p1));
EXPECT_TRUE(comparator_.HaveMergeableNames(p2, p2));
EXPECT_TRUE(comparator_.HaveMergeableNames(p2, p3));
EXPECT_TRUE(comparator_.HaveMergeableNames(p2, p4));
EXPECT_TRUE(comparator_.HaveMergeableNames(p3, empty));
EXPECT_TRUE(comparator_.HaveMergeableNames(p3, p1));
EXPECT_TRUE(comparator_.HaveMergeableNames(p3, p2));
EXPECT_TRUE(comparator_.HaveMergeableNames(p3, p3));
EXPECT_TRUE(comparator_.HaveMergeableNames(p3, p4));
EXPECT_TRUE(comparator_.HaveMergeableNames(p4, empty));
EXPECT_TRUE(comparator_.HaveMergeableNames(p4, p1));
EXPECT_TRUE(comparator_.HaveMergeableNames(p4, p2));
EXPECT_TRUE(comparator_.HaveMergeableNames(p4, p3));
EXPECT_TRUE(comparator_.HaveMergeableNames(p4, p4));
EXPECT_TRUE(comparator_.HaveMergeableNames(empty, empty));
EXPECT_TRUE(comparator_.HaveMergeableNames(empty, p1));
EXPECT_TRUE(comparator_.HaveMergeableNames(empty, p2));
EXPECT_TRUE(comparator_.HaveMergeableNames(empty, p3));
EXPECT_TRUE(comparator_.HaveMergeableNames(empty, p4));
// |initials| is mergeable with |p1| and |p4| but not |p2| or |p3|.
EXPECT_TRUE(comparator_.HaveMergeableNames(initials, empty));
EXPECT_TRUE(comparator_.HaveMergeableNames(initials, p1));
EXPECT_TRUE(comparator_.HaveMergeableNames(initials, p4));
EXPECT_TRUE(comparator_.HaveMergeableNames(empty, initials));
EXPECT_TRUE(comparator_.HaveMergeableNames(p1, initials));
EXPECT_TRUE(comparator_.HaveMergeableNames(p4, initials));
EXPECT_FALSE(comparator_.HaveMergeableNames(initials, p2));
EXPECT_FALSE(comparator_.HaveMergeableNames(initials, p3));
EXPECT_FALSE(comparator_.HaveMergeableNames(p2, initials));
EXPECT_FALSE(comparator_.HaveMergeableNames(p3, initials));
// None of the non-empty profiles should match |different|. The order of the
// comparands should not matter.
EXPECT_FALSE(comparator_.HaveMergeableNames(p1, different));
EXPECT_FALSE(comparator_.HaveMergeableNames(p2, different));
EXPECT_FALSE(comparator_.HaveMergeableNames(p3, different));
EXPECT_FALSE(comparator_.HaveMergeableNames(p4, different));
EXPECT_FALSE(comparator_.HaveMergeableNames(initials, different));
EXPECT_FALSE(comparator_.HaveMergeableNames(different, p1));
EXPECT_FALSE(comparator_.HaveMergeableNames(different, p2));
EXPECT_FALSE(comparator_.HaveMergeableNames(different, p3));
EXPECT_FALSE(comparator_.HaveMergeableNames(different, p4));
EXPECT_FALSE(comparator_.HaveMergeableNames(different, initials));
}
TEST_F(AutofillProfileComparatorTest, HaveMergeableEmailAddresses) {
AutofillProfile empty = CreateProfileWithEmail("");
AutofillProfile p1 = CreateProfileWithEmail("FOO@BAR.COM");
AutofillProfile p2 = CreateProfileWithEmail("foo@bar.com");
AutofillProfile different = CreateProfileWithEmail("not@the-same.com");
EXPECT_TRUE(comparator_.HaveMergeableEmailAddresses(p1, p2));
EXPECT_TRUE(comparator_.HaveMergeableEmailAddresses(p2, p1));
EXPECT_TRUE(comparator_.HaveMergeableEmailAddresses(p1, empty));
EXPECT_TRUE(comparator_.HaveMergeableEmailAddresses(empty, p2));
EXPECT_FALSE(comparator_.HaveMergeableEmailAddresses(p1, different));
EXPECT_FALSE(comparator_.HaveMergeableEmailAddresses(different, p1));
}
TEST_F(AutofillProfileComparatorTest, HaveMergeableCompanyNames) {
AutofillProfile empty = CreateProfileWithCompanyName("");
AutofillProfile p1 = CreateProfileWithCompanyName("Nestlé S.A.");
AutofillProfile p2 = CreateProfileWithCompanyName("Nestle");
AutofillProfile different = CreateProfileWithCompanyName("Other Corp");
EXPECT_TRUE(comparator_.HaveMergeableCompanyNames(p1, p2));
EXPECT_TRUE(comparator_.HaveMergeableCompanyNames(p2, p1));
EXPECT_TRUE(comparator_.HaveMergeableCompanyNames(p1, empty));
EXPECT_TRUE(comparator_.HaveMergeableCompanyNames(empty, p2));
EXPECT_FALSE(comparator_.HaveMergeableCompanyNames(p1, different));
EXPECT_FALSE(comparator_.HaveMergeableCompanyNames(different, p1));
}
TEST_F(AutofillProfileComparatorTest, HaveMergeablePhoneNumbers) {
AutofillProfile empty = CreateProfileWithPhoneNumber("");
AutofillProfile p1 = CreateProfileWithPhoneNumber("+1 (800) 670-8700");
AutofillProfile p2 = CreateProfileWithPhoneNumber("800.670.8700x321");
AutofillProfile p3 = CreateProfileWithPhoneNumber("670-8700 ext321");
AutofillProfile p4 = CreateProfileWithPhoneNumber("6708700");
AutofillProfile different = CreateProfileWithPhoneNumber("1-800-321-4567");
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p1, p1));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p1, p2));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p1, p3));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p1, p4));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p2, p1));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p2, p2));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p2, p3));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p2, p4));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p3, p1));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p3, p2));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p3, p3));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p3, p4));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p4, p1));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p4, p2));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p4, p3));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p4, p4));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(p1, empty));
EXPECT_TRUE(comparator_.HaveMergeablePhoneNumbers(empty, p2));
EXPECT_FALSE(comparator_.HaveMergeablePhoneNumbers(p1, different));
EXPECT_FALSE(comparator_.HaveMergeablePhoneNumbers(different, p1));
}
TEST_F(AutofillProfileComparatorTest, HaveMergeableAddresses) {
// TODO(rogerm): Replace some of the tokens to also test the address
// normalization string replacement rules. For example:
// - State/Province abbreviations
// - Street/St/Saint/Sainte
// - etc...
AutofillProfile empty = CreateProfileWithAddress("", "", "", "", "", "");
AutofillProfile p1 = CreateProfileWithAddress(
"1 Some Street", "Unit 3", "Carver", "CA - California", "90210", "US");
p1.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, UTF8ToUTF16("Some String"));
p1.SetRawInfo(ADDRESS_HOME_SORTING_CODE, UTF8ToUTF16("64205 Biarritz CEDEX"));
AutofillProfile p2 = CreateProfileWithAddress(
"Unit 3", "1 Some Street", "Suburb", "california", "90 210-3214", "");
AutofillProfile p3 = CreateProfileWithAddress("1 Some Street #3", "",
"Carver City", "ca", "", "us");
AutofillProfile differentCountry =
CopyAndModify(p1, {{ADDRESS_HOME_COUNTRY, "CA"}});
AutofillProfile differentZip =
CopyAndModify(p1, {{ADDRESS_HOME_ZIP, "32145"}});
AutofillProfile differentState = CopyAndModify(
p1, {{ADDRESS_HOME_ZIP, ""}, {ADDRESS_HOME_STATE, "Florida"}});
AutofillProfile differentCity = CopyAndModify(
p1, {{ADDRESS_HOME_ZIP, ""}, {ADDRESS_HOME_CITY, "Metropolis"}});
AutofillProfile differentAddress =
CopyAndModify(p1, {{ADDRESS_HOME_LINE1, "17 Park Lane"},
{ADDRESS_HOME_LINE2, "Suite 150"}});
AutofillProfile differentLocality =
CopyAndModify(p1, {{ADDRESS_HOME_DEPENDENT_LOCALITY, "Funky Chicken"}});
AutofillProfile differentSortingCode =
CopyAndModify(p1, {{ADDRESS_HOME_SORTING_CODE, "98000 Monaco"}});
EXPECT_TRUE(comparator_.HaveMergeableAddresses(p1, empty));
EXPECT_TRUE(comparator_.HaveMergeableAddresses(empty, p2));
EXPECT_TRUE(comparator_.HaveMergeableAddresses(p1, p3));
EXPECT_TRUE(comparator_.HaveMergeableAddresses(p3, p1));
// |p2| matches neither |p1| nor |p3| because we can't resolve the mismatched
// city/suburb names.
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, p2));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p2, p1));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p2, p3));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p3, p2));
// Changing things about |p1| causes its copies to stop being mergeable.
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, differentCountry));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, differentZip));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, differentState));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, differentCity));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, differentAddress));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, differentLocality));
EXPECT_FALSE(comparator_.HaveMergeableAddresses(p1, differentSortingCode));
}
TEST_F(AutofillProfileComparatorTest, AreMergeable) {
AutofillProfile p(base::GenerateGUID(), "https://www.example.com/");
autofill::test::SetProfileInfo(&p, "Marion", "Mitchell", "Morrison",
"marion@me.xyz", "Fox", "123 Zoo St.",
"Unit 5", "Hollywood", "CA", "91601", "US",
"+1 (234) 567-8910");
AutofillProfile mergeable =
CopyAndModify(p, {{NAME_FIRST, "MÁRÍÕÑ"},
{NAME_MIDDLE, "M."},
{EMAIL_ADDRESS, "MARION@ME.XYZ"},
{COMPANY_NAME, "Fox Industries Inc."},
{ADDRESS_HOME_LINE1, "123 zoo st. w., #5"},
{ADDRESS_HOME_LINE1, ""},
{ADDRESS_HOME_STATE, "california"},
{PHONE_HOME_WHOLE_NUMBER, "5678910 ext. 77"}});
AutofillProfile not_mergeable_by_name =
CopyAndModify(p, {{NAME_FIRST, "Steven"}});
AutofillProfile not_mergeable_by_email_address =
CopyAndModify(p, {{EMAIL_ADDRESS, "marion.morrision@me.xyz"}});
AutofillProfile not_mergeable_by_company_name =
CopyAndModify(p, {{COMPANY_NAME, "Hound Corp"}});
AutofillProfile not_mergeable_by_address =
CopyAndModify(p, {{ADDRESS_HOME_LINE2, "Unit 7"}});
AutofillProfile not_mergeable_by_phone_number =
CopyAndModify(p, {{PHONE_HOME_WHOLE_NUMBER, "555-1234"}});
EXPECT_TRUE(comparator_.AreMergeable(p, p));
EXPECT_TRUE(comparator_.AreMergeable(p, mergeable));
EXPECT_FALSE(comparator_.AreMergeable(p, not_mergeable_by_name));
EXPECT_FALSE(comparator_.AreMergeable(p, not_mergeable_by_email_address));
EXPECT_FALSE(comparator_.AreMergeable(p, not_mergeable_by_company_name));
EXPECT_FALSE(comparator_.AreMergeable(p, not_mergeable_by_address));
EXPECT_FALSE(comparator_.AreMergeable(p, not_mergeable_by_phone_number));
}
TEST_F(AutofillProfileComparatorTest, MergeNames) {
NameInfo name1;
name1.SetRawInfo(NAME_FULL, UTF8ToUTF16("John Quincy Public"));
name1.SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
name1.SetRawInfo(NAME_MIDDLE, UTF8ToUTF16("Quincy"));
name1.SetRawInfo(NAME_LAST, UTF8ToUTF16("Public"));
NameInfo name2;
name2.SetRawInfo(NAME_FULL, UTF8ToUTF16("John Q. Public"));
name2.SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
name2.SetRawInfo(NAME_MIDDLE, UTF8ToUTF16("Q."));
name2.SetRawInfo(NAME_LAST, UTF8ToUTF16("Public"));
NameInfo name3;
name3.SetRawInfo(NAME_FULL, UTF8ToUTF16("J Public"));
name3.SetRawInfo(NAME_FIRST, UTF8ToUTF16("J"));
name3.SetRawInfo(NAME_MIDDLE, UTF8ToUTF16(""));
name3.SetRawInfo(NAME_LAST, UTF8ToUTF16("Public"));
NameInfo name4;
name4.SetRawInfo(NAME_FULL, UTF8ToUTF16("John Quincy Public"));
NameInfo name5;
name5.SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
name5.SetRawInfo(NAME_LAST, UTF8ToUTF16("Public"));
NameInfo synthesized;
synthesized.SetRawInfo(NAME_FULL, UTF8ToUTF16("John Public"));
synthesized.SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
synthesized.SetRawInfo(NAME_MIDDLE, UTF8ToUTF16(""));
synthesized.SetRawInfo(NAME_LAST, UTF8ToUTF16("Public"));
AutofillProfile p1 = CreateProfileWithName(name1);
AutofillProfile p2 = CreateProfileWithName(name2);
AutofillProfile p3 = CreateProfileWithName(name3);
AutofillProfile p4 = CreateProfileWithName(name4);
AutofillProfile p5 = CreateProfileWithName(name5);
MergeNamesAndExpect(p1, p1, name1);
MergeNamesAndExpect(p1, p2, name1);
MergeNamesAndExpect(p1, p3, name1);
MergeNamesAndExpect(p1, p4, name1);
MergeNamesAndExpect(p1, p5, name1);
MergeNamesAndExpect(p2, p1, name1);
MergeNamesAndExpect(p2, p2, name2);
MergeNamesAndExpect(p2, p3, name2);
MergeNamesAndExpect(p2, p4, name1);
MergeNamesAndExpect(p2, p5, name2);
MergeNamesAndExpect(p3, p1, name1);
MergeNamesAndExpect(p3, p2, name2);
MergeNamesAndExpect(p3, p3, name3);
MergeNamesAndExpect(p3, p4, name1);
MergeNamesAndExpect(p3, p5, synthesized);
// P4 can be teased apart and reconstituted as name1.
MergeNamesAndExpect(p4, p1, name1);
MergeNamesAndExpect(p4, p2, name1);
MergeNamesAndExpect(p4, p3, name1);
MergeNamesAndExpect(p4, p4, name1);
MergeNamesAndExpect(p4, p5, name1);
// P5 expands the first name if it's not complete.
MergeNamesAndExpect(p5, p1, name1);
MergeNamesAndExpect(p5, p2, name2);
MergeNamesAndExpect(p5, p3, synthesized);
MergeNamesAndExpect(p5, p4, name1);
MergeNamesAndExpect(p5, p5, synthesized); // We flesh out missing data.
}
TEST_F(AutofillProfileComparatorTest, MergeCJKNames) {
// Korean names that are all mergeable, but constructed differently.
NameInfo name1 = CreateNameInfo("호", "", "이영", "이영 호");
NameInfo name2 = CreateNameInfo("이영호", "", "", "이영호");
NameInfo name3 = CreateNameInfo("영호", "", "이", "이영호");
NameInfo name4 = CreateNameInfo("영호", "", "이", "");
NameInfo name5 = CreateNameInfo("영호", "", "이", "이 영호");
// Mergeable foreign name in Japanese with a 'KATAKANA MIDDLE DOT'.
NameInfo name6 = CreateNameInfo("", "", "", "ゲイツ・ビル");
NameInfo name7 = CreateNameInfo("ビル", "", "ゲイツ", "");
// Set the use dates for the profiles, because |MergeCJKNames()| tries to use
// the most recent profile if there is a conflict. The ordering is
// p1 > p2 > p3 > p4 > p5, with p1 being the most recent.
AutofillProfile p1 = CreateProfileWithName(name1);
p1.set_use_date(base::Time::Now());
AutofillProfile p2 = CreateProfileWithName(name2);
p2.set_use_date(base::Time::Now() - base::TimeDelta::FromHours(1));
AutofillProfile p3 = CreateProfileWithName(name3);
p3.set_use_date(base::Time::Now() - base::TimeDelta::FromHours(2));
AutofillProfile p4 = CreateProfileWithName(name4);
p4.set_use_date(base::Time::Now() - base::TimeDelta::FromHours(3));
AutofillProfile p5 = CreateProfileWithName(name5);
p5.set_use_date(base::Time::Now() - base::TimeDelta::FromHours(4));
AutofillProfile p6 = CreateProfileWithName(name6);
AutofillProfile p7 = CreateProfileWithName(name7);
// Because |p1| is the most recent, it always wins over others.
MergeNamesAndExpect(p1, p2, CreateNameInfo("호", "", "이영", "이영 호"));
MergeNamesAndExpect(p1, p3, CreateNameInfo("호", "", "이영", "이영 호"));
MergeNamesAndExpect(p1, p4, CreateNameInfo("호", "", "이영", "이영 호"));
MergeNamesAndExpect(p1, p5, CreateNameInfo("호", "", "이영", "이영 호"));
// |p2| is more recent than |p3|, |p4|, and |p5|. However, it does not have a
// surname entry (it was probably parsed with the old logic), so the other
// profiles are used as the source for given/surname.
MergeNamesAndExpect(p2, p3, CreateNameInfo("영호", "", "이", "이영호"));
MergeNamesAndExpect(p2, p4, CreateNameInfo("영호", "", "이", "이영호"));
MergeNamesAndExpect(p2, p5, CreateNameInfo("영호", "", "이", "이영호"));
// |p3| is more recent than |p4| and |p5|.
MergeNamesAndExpect(p3, p4, CreateNameInfo("영호", "", "이", "이영호"));
MergeNamesAndExpect(p3, p5, CreateNameInfo("영호", "", "이", "이영호"));
// |p4| is more recent than |p5|. However, it does not have an explicit full
// name, so use the one from |p5|.
MergeNamesAndExpect(p4, p5, CreateNameInfo("영호", "", "이", "이 영호"));
// There is no conflict between |p6| and |p7|, so use the parts from both.
MergeNamesAndExpect(p6, p7,
CreateNameInfo("ビル", "", "ゲイツ", "ゲイツ・ビル"));
}
TEST_F(AutofillProfileComparatorTest, MergeEmailAddresses) {
static const char kEmailA[] = "testaccount@domain.net";
static const char kEmailB[] = "TestAccount@Domain.Net";
EmailInfo email_a;
email_a.SetRawInfo(EMAIL_ADDRESS, UTF8ToUTF16(kEmailA));
AutofillProfile profile_a = CreateProfileWithEmail(kEmailA);
profile_a.set_use_date(base::Time::Now());
EmailInfo email_b;
email_b.SetRawInfo(EMAIL_ADDRESS, UTF8ToUTF16(kEmailB));
AutofillProfile profile_b = CreateProfileWithEmail(kEmailB);
profile_b.set_use_date(profile_a.use_date() + base::TimeDelta::FromDays(1));
MergeEmailAddressesAndExpect(profile_a, profile_a, email_a);
MergeEmailAddressesAndExpect(profile_b, profile_b, email_b);
MergeEmailAddressesAndExpect(profile_a, profile_b, email_b);
MergeEmailAddressesAndExpect(profile_b, profile_a, email_b);
}
TEST_F(AutofillProfileComparatorTest, MergeCompanyNames) {
static const char kCompanyA[] = "Some Company";
static const char kCompanyB[] = "SÔMÈ ÇÖMPÁÑÝ";
static const char kCompanyC[] = "SÔMÈ ÇÖMPÁÑÝ A.G.";
CompanyInfo company_a;
company_a.SetRawInfo(COMPANY_NAME, UTF8ToUTF16(kCompanyA));
AutofillProfile profile_a = CreateProfileWithCompanyName(kCompanyA);
profile_a.set_use_date(base::Time::Now());
// Company Name B is post_normalization identical to Company Name A. The use
// date will be used to choose between them.
CompanyInfo company_b;
company_b.SetRawInfo(COMPANY_NAME, UTF8ToUTF16(kCompanyB));
AutofillProfile profile_b = CreateProfileWithCompanyName(kCompanyB);
profile_b.set_use_date(profile_a.use_date() + base::TimeDelta::FromDays(1));
// Company Name C is the most complete. Even though it has the earliest use
// date, it will be preferred to the other two.
CompanyInfo company_c;
company_c.SetRawInfo(COMPANY_NAME, UTF8ToUTF16(kCompanyC));
AutofillProfile profile_c = CreateProfileWithCompanyName(kCompanyC);
profile_c.set_use_date(profile_a.use_date() - base::TimeDelta::FromDays(1));
MergeCompanyNamesAndExpect(profile_a, profile_a, company_a);
MergeCompanyNamesAndExpect(profile_a, profile_b, company_b);
MergeCompanyNamesAndExpect(profile_a, profile_c, company_c);
MergeCompanyNamesAndExpect(profile_b, profile_a, company_b);
MergeCompanyNamesAndExpect(profile_b, profile_b, company_b);
MergeCompanyNamesAndExpect(profile_b, profile_c, company_c);
MergeCompanyNamesAndExpect(profile_c, profile_a, company_c);
MergeCompanyNamesAndExpect(profile_c, profile_b, company_c);
MergeCompanyNamesAndExpect(profile_c, profile_c, company_c);
}
TEST_F(AutofillProfileComparatorTest, MergePhoneNumbers_NA) {
static const char kPhoneA[] = "5550199";
static const char kPhoneB[] = "555.0199";
static const char kPhoneC[] = "555-0199 ext321";
static const char kPhoneD[] = "8005550199";
static const char kPhoneE[] = "800-555-0199 #321";
static const char kPhoneF[] = "1-800-555-0199 #321";
static const char kPhoneG[] = "+1 (800) 555.0199;ext=321";
static const char kMergedShortNumber[] = "5550199";
static const char kMergedShortNumberExt[] = "5550199 ext. 321";
static const char kMergedFullNumber[] = "+1 800-555-0199";
static const char kMergedFullNumberExt[] = "+1 800-555-0199 ext. 321";
AutofillProfile profile_a = CreateProfileWithPhoneNumber(kPhoneA);
AutofillProfile profile_b = CreateProfileWithPhoneNumber(kPhoneB);
AutofillProfile profile_c = CreateProfileWithPhoneNumber(kPhoneC);
AutofillProfile profile_d = CreateProfileWithPhoneNumber(kPhoneD);
AutofillProfile profile_e = CreateProfileWithPhoneNumber(kPhoneE);
AutofillProfile profile_f = CreateProfileWithPhoneNumber(kPhoneF);
AutofillProfile profile_g = CreateProfileWithPhoneNumber(kPhoneG);
// Profile A
MergePhoneNumbersAndExpect(profile_a, profile_a, kPhoneA);
MergePhoneNumbersAndExpect(profile_a, profile_b, kMergedShortNumber);
MergePhoneNumbersAndExpect(profile_a, profile_c, kMergedShortNumberExt);
MergePhoneNumbersAndExpect(profile_a, profile_d, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_a, profile_e, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_a, profile_f, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_a, profile_g, kMergedFullNumberExt);
// Profile B
MergePhoneNumbersAndExpect(profile_b, profile_a, kMergedShortNumber);
MergePhoneNumbersAndExpect(profile_b, profile_b, kPhoneB);
MergePhoneNumbersAndExpect(profile_b, profile_c, kMergedShortNumberExt);
MergePhoneNumbersAndExpect(profile_b, profile_d, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_b, profile_e, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_b, profile_f, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_b, profile_g, kMergedFullNumberExt);
// Profile C
MergePhoneNumbersAndExpect(profile_c, profile_a, kMergedShortNumberExt);
MergePhoneNumbersAndExpect(profile_c, profile_b, kMergedShortNumberExt);
MergePhoneNumbersAndExpect(profile_c, profile_c, kPhoneC);
MergePhoneNumbersAndExpect(profile_c, profile_d, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_c, profile_e, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_c, profile_f, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_c, profile_g, kMergedFullNumberExt);
// Profile D
MergePhoneNumbersAndExpect(profile_d, profile_a, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_d, profile_b, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_d, profile_c, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_d, profile_d, kPhoneD);
MergePhoneNumbersAndExpect(profile_d, profile_e, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_d, profile_f, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_d, profile_g, kMergedFullNumberExt);
// Profile E
MergePhoneNumbersAndExpect(profile_e, profile_a, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_e, profile_b, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_e, profile_c, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_e, profile_d, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_e, profile_e, kPhoneE);
MergePhoneNumbersAndExpect(profile_e, profile_f, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_e, profile_g, kMergedFullNumberExt);
// Profile F
MergePhoneNumbersAndExpect(profile_f, profile_a, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_f, profile_b, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_f, profile_c, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_f, profile_d, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_f, profile_e, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_f, profile_f, kPhoneF);
MergePhoneNumbersAndExpect(profile_f, profile_g, kMergedFullNumberExt);
// Profile G
MergePhoneNumbersAndExpect(profile_g, profile_a, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_g, profile_b, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_g, profile_c, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_g, profile_d, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_g, profile_e, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_g, profile_f, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_g, profile_g, kPhoneG);
}
TEST_F(AutofillProfileComparatorTest, MergePhoneNumbers_Intl) {
const base::string16 kGermany = UTF8ToUTF16("DE");
const AutofillType kCountry(ADDRESS_HOME_COUNTRY);
static const char kPhoneA[] = "+49492180185611";
static const char kPhoneB[] = "+49 4921 801 856-11";
static const char kPhoneC[] = "+49 4921 8018 5611;ext=22";
static const char kPhoneD[] = "04921 80185611"; // National Format.
static const char kMergedFullNumber[] = "+49 4921 80185611";
static const char kMergedFullNumberExt[] = "+49 4921 80185611 ext. 22";
AutofillProfile profile_a = CreateProfileWithPhoneNumber(kPhoneA);
AutofillProfile profile_b = CreateProfileWithPhoneNumber(kPhoneB);
AutofillProfile profile_c = CreateProfileWithPhoneNumber(kPhoneC);
AutofillProfile profile_d = CreateProfileWithPhoneNumber(kPhoneD);
profile_a.SetInfo(kCountry, kGermany, kLocale);
profile_b.SetInfo(kCountry, kGermany, kLocale);
profile_c.SetInfo(kCountry, kGermany, kLocale);
profile_d.SetInfo(kCountry, kGermany, kLocale);
// Profile A
MergePhoneNumbersAndExpect(profile_a, profile_a, kPhoneA);
MergePhoneNumbersAndExpect(profile_a, profile_b, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_a, profile_c, kMergedFullNumberExt);
// Profile B
MergePhoneNumbersAndExpect(profile_b, profile_a, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_b, profile_b, kPhoneB);
MergePhoneNumbersAndExpect(profile_b, profile_c, kMergedFullNumberExt);
// Profile C
MergePhoneNumbersAndExpect(profile_c, profile_a, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_c, profile_b, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_c, profile_c, kPhoneC);
// Profile D
MergePhoneNumbersAndExpect(profile_d, profile_a, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_d, profile_b, kMergedFullNumber);
MergePhoneNumbersAndExpect(profile_d, profile_c, kMergedFullNumberExt);
MergePhoneNumbersAndExpect(profile_d, profile_d, kPhoneD);
}
TEST_F(AutofillProfileComparatorTest, MergeAddresses) {
AutofillProfile p1 = CreateProfileWithAddress(
"1 Some Street", "Unit 3", "Carver", "CA - California", "90210", "US");
AutofillProfile p2 = CreateProfileWithAddress(
"1 Some Street #3", "", "Carver City", "ca", "90210-1234", "us");
Address expected;
expected.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("1 Some Street"));
expected.SetRawInfo(ADDRESS_HOME_LINE2, UTF8ToUTF16("Unit 3"));
expected.SetRawInfo(ADDRESS_HOME_CITY, UTF8ToUTF16("Carver City"));
expected.SetRawInfo(ADDRESS_HOME_STATE, UTF8ToUTF16("ca"));
expected.SetRawInfo(ADDRESS_HOME_ZIP, UTF8ToUTF16("90210-1234"));
expected.SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16("US"));
MergeAddressesAndExpect(p1, p2, expected);
}
TEST_F(AutofillProfileComparatorTest, MergeAddressesMostUniqueTokens) {
AutofillProfile p1 = CreateProfileWithAddress(
"1 Some Street", "Unit 3", "Carver", "CA - California", "90210", "US");
AutofillProfile p2 = CreateProfileWithAddress(
"1 Some Other Street", "Unit 3", "Carver City", "ca", "90210-1234", "us");
Address expected;
expected.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("1 Some Other Street"));
expected.SetRawInfo(ADDRESS_HOME_LINE2, UTF8ToUTF16("Unit 3"));
expected.SetRawInfo(ADDRESS_HOME_CITY, UTF8ToUTF16("Carver City"));
expected.SetRawInfo(ADDRESS_HOME_STATE, UTF8ToUTF16("ca"));
expected.SetRawInfo(ADDRESS_HOME_ZIP, UTF8ToUTF16("90210-1234"));
expected.SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16("US"));
MergeAddressesAndExpect(p1, p2, expected);
MergeAddressesAndExpect(p2, p1, expected);
}
TEST_F(AutofillProfileComparatorTest, MergeAddressesWithRewrite) {
AutofillProfile p1 = CreateProfileWithAddress(
"6543 CH BACON", "APP 3", "MONTRÉAL", "QUÉBEC", "HHH999", "ca");
AutofillProfile p2 = CreateProfileWithAddress(
"6543, Bacon Rd", "", "Montreal", "QC", "hhh 999", "CA");
p2.set_use_date(p1.use_date() + base::TimeDelta::FromMinutes(1));
Address expected;
expected.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("6543 CH BACON"));
expected.SetRawInfo(ADDRESS_HOME_LINE2, UTF8ToUTF16("APP 3"));
expected.SetRawInfo(ADDRESS_HOME_CITY, UTF8ToUTF16("Montreal"));
expected.SetRawInfo(ADDRESS_HOME_STATE, UTF8ToUTF16("QC"));
expected.SetRawInfo(ADDRESS_HOME_ZIP, UTF8ToUTF16("hhh 999"));
expected.SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16("CA"));
MergeAddressesAndExpect(p1, p2, expected);
MergeAddressesAndExpect(p2, p1, expected);
}
TEST_F(AutofillProfileComparatorTest,
MergeAddressesDependendLocalityAndSortingCode) {
AutofillProfile p1 = CreateProfileWithAddress(
"6543 CH BACON", "APP 3", "MONTRÉAL", "QUÉBEC", "HHH999", "ca");
p1.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, UTF8ToUTF16("Some String"));
p1.SetRawInfo(ADDRESS_HOME_SORTING_CODE, UTF8ToUTF16("64205 Biarritz CEDEX"));
AutofillProfile p2 = CreateProfileWithAddress(
"6543, Bacon Rd", "", "Montreal", "QC", "hhh 999", "CA");
p2.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
UTF8ToUTF16("Some Other String"));
p2.SetRawInfo(ADDRESS_HOME_SORTING_CODE, UTF8ToUTF16("64205 Biarritz"));
p2.set_use_date(p1.use_date() + base::TimeDelta::FromMinutes(1));
Address expected;
expected.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("6543 CH BACON"));
expected.SetRawInfo(ADDRESS_HOME_LINE2, UTF8ToUTF16("APP 3"));
expected.SetRawInfo(ADDRESS_HOME_CITY, UTF8ToUTF16("Montreal"));
expected.SetRawInfo(ADDRESS_HOME_STATE, UTF8ToUTF16("QC"));
expected.SetRawInfo(ADDRESS_HOME_ZIP, UTF8ToUTF16("hhh 999"));
expected.SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16("CA"));
expected.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
UTF8ToUTF16("Some Other String"));
expected.SetRawInfo(ADDRESS_HOME_SORTING_CODE,
UTF8ToUTF16("64205 Biarritz")); // Preferred by use date.
MergeAddressesAndExpect(p1, p2, expected);
MergeAddressesAndExpect(p2, p1, expected);
}