blob: b9677d58b27fd4c2d56941b44b85caa4fd158392 [file] [log] [blame]
// Copyright 2018 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_sync_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/sync/model/entity_data.h"
#include "components/sync/protocol/sync.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace {
using base::ASCIIToUTF16;
using base::UTF16ToUTF8;
using base::UTF8ToUTF16;
using sync_pb::AutofillProfileSpecifics;
using syncer::EntityData;
// Some guids for testing.
const char kGuid[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A";
const char kGuidInvalid[] = "EDC609ED";
const char kLocaleString[] = "en-US";
const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
// Returns a profile with all fields set. Contains identical data to the data
// returned from ConstructCompleteSpecifics().
AutofillProfile ConstructCompleteProfile() {
AutofillProfile profile(kGuid, "https://www.example.com/");
profile.set_use_count(7);
profile.set_use_date(base::Time::FromTimeT(1423182152));
profile.SetRawInfo(NAME_FULL, ASCIIToUTF16("John K. Doe, Jr."));
profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
profile.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("K."));
profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Doe"));
profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("user@example.com"));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("1.800.555.1234"));
profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("123 Fake St.\n"
"Apt. 42"));
EXPECT_EQ(ASCIIToUTF16("123 Fake St."),
profile.GetRawInfo(ADDRESS_HOME_LINE1));
EXPECT_EQ(ASCIIToUTF16("Apt. 42"), profile.GetRawInfo(ADDRESS_HOME_LINE2));
profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Google, Inc."));
profile.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Mountain View"));
profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("California"));
profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("94043"));
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE, ASCIIToUTF16("CEDEX"));
profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
ASCIIToUTF16("Santa Clara"));
profile.set_language_code("en");
profile.SetClientValidityFromBitfieldValue(1984);
profile.set_is_client_validity_states_updated(true);
return profile;
}
// Returns AutofillProfileSpecifics with all Autofill profile fields set.
// Contains identical data to the data returned from ConstructCompleteProfile().
AutofillProfileSpecifics ConstructCompleteSpecifics() {
AutofillProfileSpecifics specifics;
specifics.set_guid(kGuid);
specifics.set_origin("https://www.example.com/");
specifics.set_use_count(7);
specifics.set_use_date(1423182152);
specifics.add_name_first("John");
specifics.add_name_middle("K.");
specifics.add_name_last("Doe");
specifics.add_name_full("John K. Doe, Jr.");
specifics.add_email_address("user@example.com");
specifics.add_phone_home_whole_number("1.800.555.1234");
specifics.set_address_home_line1("123 Fake St.");
specifics.set_address_home_line2("Apt. 42");
specifics.set_address_home_street_address(
"123 Fake St.\n"
"Apt. 42");
specifics.set_company_name("Google, Inc.");
specifics.set_address_home_city("Mountain View");
specifics.set_address_home_state("California");
specifics.set_address_home_zip("94043");
specifics.set_address_home_country("US");
specifics.set_address_home_sorting_code("CEDEX");
specifics.set_address_home_dependent_locality("Santa Clara");
specifics.set_address_home_language_code("en");
specifics.set_validity_state_bitfield(1984);
specifics.set_is_client_validity_states_updated(true);
return specifics;
}
class AutofillProfileSyncUtilTest : public testing::Test {
public:
AutofillProfileSyncUtilTest() {
// Fix a time for implicitly constructed use_dates in AutofillProfile.
test_clock_.SetNow(kJune2017);
CountryNames::SetLocaleString(kLocaleString);
}
private:
autofill::TestAutofillClock test_clock_;
};
// Ensure that all profile fields are able to be synced up from the client to
// the server.
TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile) {
AutofillProfile profile = ConstructCompleteProfile();
AutofillProfileSpecifics specifics = ConstructCompleteSpecifics();
std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillProfile(profile);
// The non-unique name should be set to the guid of the profile.
EXPECT_EQ(entity_data->non_unique_name, profile.guid());
EXPECT_EQ(specifics.SerializeAsString(),
entity_data->specifics.autofill_profile().SerializeAsString());
}
// Test that fields not set for the input are also not set on the output.
TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile_Empty) {
AutofillProfile profile(kGuid, std::string());
ASSERT_FALSE(profile.HasRawInfo(NAME_FULL));
ASSERT_FALSE(profile.HasRawInfo(COMPANY_NAME));
std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillProfile(profile);
EXPECT_EQ(0, entity_data->specifics.autofill_profile().name_full_size());
EXPECT_FALSE(entity_data->specifics.autofill_profile().has_company_name());
}
// Test that long fields get trimmed.
TEST_F(AutofillProfileSyncUtilTest,
CreateEntityDataFromAutofillProfile_Trimmed) {
std::string kNameLong(AutofillTable::kMaxDataLength + 1, 'a');
std::string kNameTrimmed(AutofillTable::kMaxDataLength, 'a');
AutofillProfile profile(kGuid, std::string());
profile.SetRawInfo(NAME_FULL, ASCIIToUTF16(kNameLong));
std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillProfile(profile);
EXPECT_EQ(kNameTrimmed,
entity_data->specifics.autofill_profile().name_full(0));
}
// Test that long non-ascii fields get correctly trimmed.
TEST_F(AutofillProfileSyncUtilTest,
CreateEntityDataFromAutofillProfile_TrimmedNonASCII) {
// Make the UTF8 string have odd number of bytes and append many 2-bytes
// characters so that simple ASCII trimming would make the UTF8 string
// invalid.
std::string kNameLong("aä");
std::string kNameTrimmed("a");
for (unsigned int i = 0; i < AutofillTable::kMaxDataLength / 2 - 1; ++i) {
kNameLong += "ä";
kNameTrimmed += "ä";
}
AutofillProfile profile(kGuid, std::string());
profile.SetRawInfo(NAME_FULL, UTF8ToUTF16(kNameLong));
std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillProfile(profile);
EXPECT_EQ(kNameTrimmed,
entity_data->specifics.autofill_profile().name_full(0));
}
// Ensure that all profile fields are able to be synced down from the server to
// the client (and nothing gets uploaded back).
TEST_F(AutofillProfileSyncUtilTest, CreateAutofillProfileFromSpecifics) {
// Fix a time for implicitly constructed use_dates in AutofillProfile.
autofill::TestAutofillClock test_clock;
test_clock.SetNow(kJune2017);
CountryNames::SetLocaleString(kLocaleString);
AutofillProfileSpecifics specifics = ConstructCompleteSpecifics();
AutofillProfile profile = ConstructCompleteProfile();
std::unique_ptr<AutofillProfile> converted_profile =
CreateAutofillProfileFromSpecifics(specifics);
EXPECT_TRUE(profile.EqualsIncludingUsageStatsForTesting(*converted_profile));
}
// Test that fields not set for the input are also not set on the output.
TEST_F(AutofillProfileSyncUtilTest, CreateAutofillProfileFromSpecifics_Empty) {
AutofillProfileSpecifics specifics;
specifics.set_guid(kGuid);
std::unique_ptr<AutofillProfile> profile =
CreateAutofillProfileFromSpecifics(specifics);
EXPECT_FALSE(profile->HasRawInfo(NAME_FULL));
EXPECT_FALSE(profile->HasRawInfo(COMPANY_NAME));
}
// Test that nullptr is produced if the input guid is invalid.
TEST_F(AutofillProfileSyncUtilTest,
CreateAutofillProfileFromSpecifics_Invalid) {
AutofillProfileSpecifics specifics;
specifics.set_guid(kGuidInvalid);
EXPECT_EQ(nullptr, CreateAutofillProfileFromSpecifics(specifics));
}
// Test that if conflicting info is set for address home, the (deprecated) line1
// & line2 fields get overwritten by the street_address field.
TEST_F(AutofillProfileSyncUtilTest,
CreateAutofillProfileFromSpecifics_HomeAddressWins) {
AutofillProfileSpecifics specifics;
specifics.set_guid(kGuid);
specifics.set_address_home_street_address(
"123 New St.\n"
"Apt. 42");
specifics.set_address_home_line1("456 Old St.");
specifics.set_address_home_line2("Apt. 43");
std::unique_ptr<AutofillProfile> profile =
CreateAutofillProfileFromSpecifics(specifics);
EXPECT_EQ("123 New St.",
UTF16ToUTF8(profile->GetRawInfo(ADDRESS_HOME_LINE1)));
EXPECT_EQ("Apt. 42", UTF16ToUTF8(profile->GetRawInfo(ADDRESS_HOME_LINE2)));
}
// Test that country names (used in the past for the field) get correctly parsed
// into country code.
TEST_F(AutofillProfileSyncUtilTest,
CreateAutofillProfileFromSpecifics_CountryNameParsed) {
CountryNames::SetLocaleString(kLocaleString);
AutofillProfileSpecifics specifics;
specifics.set_guid(kGuid);
specifics.set_address_home_country("Germany");
EXPECT_EQ("DE", UTF16ToUTF8(
CreateAutofillProfileFromSpecifics(specifics)->GetRawInfo(
ADDRESS_HOME_COUNTRY)));
specifics.set_address_home_country("united states");
EXPECT_EQ("US", UTF16ToUTF8(
CreateAutofillProfileFromSpecifics(specifics)->GetRawInfo(
ADDRESS_HOME_COUNTRY)));
}
// Tests that guid is returned as storage key.
TEST_F(AutofillProfileSyncUtilTest, GetStorageKeyFromAutofillProfile) {
AutofillProfile profile(kGuid, std::string());
EXPECT_EQ(kGuid, GetStorageKeyFromAutofillProfile(profile));
}
// Tests that guid is returned as storage key.
TEST_F(AutofillProfileSyncUtilTest, GetStorageKeyFromAutofillProfileSpecifics) {
AutofillProfileSpecifics specifics;
specifics.set_guid(kGuid);
EXPECT_EQ(kGuid, GetStorageKeyFromAutofillProfileSpecifics(specifics));
}
// Tests that empty string is returned for entry with invalid guid.
TEST_F(AutofillProfileSyncUtilTest,
GetStorageKeyFromAutofillProfileSpecifics_Invalid) {
AutofillProfileSpecifics specifics;
specifics.set_guid(kGuidInvalid);
EXPECT_EQ(std::string(),
GetStorageKeyFromAutofillProfileSpecifics(specifics));
}
} // namespace
} // namespace autofill