blob: c2f1f6f75a1da0428fb1b8b287548fde20aa93e7 [file] [log] [blame]
// Copyright 2013 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/personal_data_manager.h"
#include <stddef.h>
#include <algorithm>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/base64.h"
#include "base/command_line.h"
#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
#include "base/i18n/time_formatting.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_comparator.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/label_formatter_utils.h"
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "components/autofill/core/browser/suggestion_selection.h"
#include "components/autofill/core/browser/sync_utils.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/test_autofill_profile_validator.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/form_data.h"
#include "components/os_crypt/os_crypt_mocker.h"
#include "components/prefs/pref_service.h"
#include "components/sync/driver/sync_service_utils.h"
#include "components/sync/driver/test_sync_service.h"
#include "components/version_info/version_info.h"
#include "components/webdata/common/web_data_service_base.h"
#include "components/webdata/common/web_database_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace {
const char kPrimaryAccountEmail[] = "syncuser@example.com";
const char kSyncTransportAccountEmail[] = "transport@example.com";
enum UserMode { USER_MODE_NORMAL, USER_MODE_INCOGNITO };
const base::Time kArbitraryTime = base::Time::FromDoubleT(25);
const base::Time kSomeLaterTime = base::Time::FromDoubleT(1000);
const base::Time kMuchLaterTime = base::Time::FromDoubleT(5000);
ACTION_P(QuitMessageLoop, loop) {
loop->Quit();
}
class PersonalDataLoadedObserverMock : public PersonalDataManagerObserver {
public:
PersonalDataLoadedObserverMock() {}
~PersonalDataLoadedObserverMock() override {}
MOCK_METHOD0(OnPersonalDataChanged, void());
MOCK_METHOD0(OnPersonalDataFinishedProfileTasks, void());
};
class PersonalDataManagerMock : public PersonalDataManager {
public:
explicit PersonalDataManagerMock(const std::string& app_locale)
: PersonalDataManager(app_locale) {}
~PersonalDataManagerMock() override {}
MOCK_METHOD1(OnValidated, void(const AutofillProfile* profile));
void OnValidatedPDM(const AutofillProfile* profile) {
PersonalDataManager::OnValidated(profile);
}
};
template <typename T>
bool CompareElements(T* a, T* b) {
return a->Compare(*b) < 0;
}
template <typename T>
bool ElementsEqual(T* a, T* b) {
return a->Compare(*b) == 0;
}
// Verifies that two vectors have the same elements (according to T::Compare)
// while ignoring order. This is useful because multiple profiles or credit
// cards that are added to the SQLite DB within the same second will be returned
// in GUID (aka random) order.
template <typename T>
void ExpectSameElements(const std::vector<T*>& expectations,
const std::vector<T*>& results) {
ASSERT_EQ(expectations.size(), results.size());
std::vector<T*> expectations_copy = expectations;
std::sort(expectations_copy.begin(), expectations_copy.end(),
CompareElements<T>);
std::vector<T*> results_copy = results;
std::sort(results_copy.begin(), results_copy.end(), CompareElements<T>);
EXPECT_EQ(std::mismatch(results_copy.begin(), results_copy.end(),
expectations_copy.begin(), ElementsEqual<T>)
.first,
results_copy.end());
}
} // anonymous namespace
class PersonalDataManagerTestBase {
protected:
PersonalDataManagerTestBase()
: identity_test_env_(&test_url_loader_factory_) {
// Enable account storage by default, some tests will override this to be
// false.
scoped_features_.InitWithFeatures(
/*enabled_features=*/{features::kAutofillEnableAccountWalletStorage,
features::kAutofillProfileClientValidation},
/*disabled_features=*/{});
}
void SetUpTest() {
OSCryptMocker::SetUp();
prefs_ = test::PrefServiceForTesting();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath path = temp_dir_.GetPath().AppendASCII("TestWebDB");
profile_web_database_ =
new WebDatabaseService(path, base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get());
// Hacky: hold onto a pointer but pass ownership.
profile_autofill_table_ = new AutofillTable;
profile_web_database_->AddTable(
std::unique_ptr<WebDatabaseTable>(profile_autofill_table_));
profile_web_database_->LoadDatabase();
profile_database_service_ = new AutofillWebDataService(
profile_web_database_, base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get(),
WebDataServiceBase::ProfileErrorCallback());
profile_database_service_->Init();
account_web_database_ =
new WebDatabaseService(base::FilePath(WebDatabase::kInMemoryPath),
base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get());
account_autofill_table_ = new AutofillTable;
account_web_database_->AddTable(
std::unique_ptr<WebDatabaseTable>(account_autofill_table_));
account_web_database_->LoadDatabase();
account_database_service_ = new AutofillWebDataService(
account_web_database_, base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get(),
WebDataServiceBase::ProfileErrorCallback());
account_database_service_->Init();
test::DisableSystemServices(prefs_.get());
}
void TearDownTest() {
// Order of destruction is important as AutofillManager relies on
// PersonalDataManager to be around when it gets destroyed.
test::ReenableSystemServices();
OSCryptMocker::TearDown();
}
void ResetPersonalDataManager(UserMode user_mode,
bool use_sync_transport_mode,
PersonalDataManager* personal_data) {
bool is_incognito = (user_mode == USER_MODE_INCOGNITO);
personal_data->Init(
scoped_refptr<AutofillWebDataService>(profile_database_service_),
base::FeatureList::IsEnabled(
features::kAutofillEnableAccountWalletStorage)
? scoped_refptr<AutofillWebDataService>(account_database_service_)
: nullptr,
prefs_.get(), identity_test_env_.identity_manager(),
TestAutofillProfileValidator::GetInstance(),
/*history_service=*/nullptr, is_incognito);
personal_data->AddObserver(&personal_data_observer_);
AccountInfo account_info;
account_info.email = use_sync_transport_mode ? kSyncTransportAccountEmail
: kPrimaryAccountEmail;
sync_service_.SetAuthenticatedAccountInfo(account_info);
sync_service_.SetIsAuthenticatedAccountPrimary(!use_sync_transport_mode);
personal_data->OnSyncServiceInitialized(&sync_service_);
personal_data->OnStateChanged(&sync_service_);
WaitForOnPersonalDataChangedRepeatedly();
}
bool TurnOnSyncFeature(PersonalDataManager* personal_data)
WARN_UNUSED_RESULT {
sync_service_.SetIsAuthenticatedAccountPrimary(true);
if (!sync_service_.IsSyncFeatureEnabled())
return false;
personal_data->OnStateChanged(&sync_service_);
return personal_data->IsSyncFeatureEnabled();
}
void EnableWalletCardImport() {
identity_test_env_.MakePrimaryAccountAvailable(kPrimaryAccountEmail);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableOfferStoreUnmaskedWalletCards);
}
void RemoveByGUIDFromPersonalDataManager(const std::string& guid,
PersonalDataManager* personal_data) {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
personal_data->RemoveByGUID(guid);
run_loop.Run();
}
void SetServerCards(std::vector<CreditCard> server_cards) {
test::SetServerCreditCards(account_autofill_table_, server_cards);
}
// Verify that the web database has been updated and the notification sent.
void WaitOnceForOnPersonalDataChanged() {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
run_loop.Run();
}
// Verifies that the web database has been updated and the notification sent.
void WaitForOnPersonalDataChanged() {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
run_loop.Run();
}
// Verifies that the web database has been updated and the notification sent.
void WaitForOnPersonalDataChangedRepeatedly() {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillRepeatedly(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
run_loop.Run();
}
AccountInfo SetActiveSecondaryAccount() {
AccountInfo account_info;
account_info.email = kSyncTransportAccountEmail;
account_info.account_id = "account_id";
sync_service_.SetAuthenticatedAccountInfo(account_info);
sync_service_.SetIsAuthenticatedAccountPrimary(false);
return account_info;
}
void MoveJapanCityToStreetAddress(PersonalDataManager* personal_data,
int move_times) {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillRepeatedly(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(move_times);
personal_data->MoveJapanCityToStreetAddress();
run_loop.Run();
}
// The temporary directory should be deleted at the end to ensure that
// files are not used anymore and deletion succeeds.
base::ScopedTempDir temp_dir_;
base::test::ScopedTaskEnvironment task_environment_{
base::test::ScopedTaskEnvironment::MainThreadType::UI};
std::unique_ptr<PrefService> prefs_;
network::TestURLLoaderFactory test_url_loader_factory_;
identity::IdentityTestEnvironment identity_test_env_;
syncer::TestSyncService sync_service_;
scoped_refptr<AutofillWebDataService> profile_database_service_;
scoped_refptr<AutofillWebDataService> account_database_service_;
scoped_refptr<WebDatabaseService> profile_web_database_;
scoped_refptr<WebDatabaseService> account_web_database_;
AutofillTable* profile_autofill_table_; // weak ref
AutofillTable* account_autofill_table_; // weak ref
PersonalDataLoadedObserverMock personal_data_observer_;
base::test::ScopedFeatureList scoped_features_;
};
class PersonalDataManagerHelper : public PersonalDataManagerTestBase {
protected:
virtual ~PersonalDataManagerHelper() {
if (personal_data_)
personal_data_->Shutdown();
personal_data_.reset();
}
void ResetPersonalDataManager(UserMode user_mode,
bool use_account_server_storage = false) {
if (personal_data_)
personal_data_->Shutdown();
personal_data_.reset(new PersonalDataManager("en"));
PersonalDataManagerTestBase::ResetPersonalDataManager(
user_mode, use_account_server_storage, personal_data_.get());
}
void ResetProfiles() {
std::vector<AutofillProfile> empty_profiles;
personal_data_->SetProfiles(&empty_profiles);
WaitForOnPersonalDataChanged();
}
bool TurnOnSyncFeature() {
return PersonalDataManagerTestBase::TurnOnSyncFeature(personal_data_.get());
}
void EnableAutofillProfileCleanup() {
personal_data_->is_autofill_profile_cleanup_pending_ = true;
}
void SetUpReferenceProfile() {
ASSERT_EQ(0U, personal_data_->GetProfiles().size());
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile);
ASSERT_EQ(1U, personal_data_->GetProfiles().size());
}
// Adds three local cards to the |personal_data_|. The three cards are
// different: two are from different companies and the third doesn't have a
// number. All three have different owners and credit card number. This allows
// to test the suggestions based on name as well as on credit card number.
void SetUpReferenceLocalCreditCards() {
ASSERT_EQ(0U, personal_data_->GetCreditCards().size());
CreditCard credit_card0("287151C8-6AB1-487C-9095-28E80BE5DA15",
test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card0, "Clyde Barrow",
"378282246310005" /* American Express */, "04",
"2999", "1");
credit_card0.set_use_count(3);
credit_card0.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
personal_data_->AddCreditCard(credit_card0);
CreditCard credit_card1("1141084B-72D7-4B73-90CF-3D6AC154673B",
test::kEmptyOrigin);
credit_card1.set_use_count(300);
credit_card1.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(10));
test::SetCreditCardInfo(&credit_card1, "John Dillinger",
"4234567890123456" /* Visa */, "01", "2999", "1");
personal_data_->AddCreditCard(credit_card1);
CreditCard credit_card2("002149C1-EE28-4213-A3B9-DA243FFF021B",
test::kEmptyOrigin);
credit_card2.set_use_count(1);
credit_card2.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
test::SetCreditCardInfo(&credit_card2, "Bonnie Parker",
"5105105105105100" /* Mastercard */, "12", "2999",
"1");
personal_data_->AddCreditCard(credit_card2);
WaitOnceForOnPersonalDataChanged();
ASSERT_EQ(3U, personal_data_->GetCreditCards().size());
}
// Add 3 credit cards. One local, one masked, one full. Creates two masked
// cards on Linux, since full server cards are not supported.
void SetUpThreeCardTypes() {
EXPECT_EQ(0U, personal_data_->GetCreditCards().size());
CreditCard masked_server_card;
test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
"4234567890123456", // Visa
"04", "2999", "1");
masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
masked_server_card.set_record_type(CreditCard::FULL_SERVER_CARD);
masked_server_card.set_server_id("masked_id");
masked_server_card.set_use_count(15);
personal_data_->AddFullServerCreditCard(masked_server_card);
WaitOnceForOnPersonalDataChanged();
ASSERT_EQ(1U, personal_data_->GetCreditCards().size());
// Cards are automatically remasked on Linux since full server cards are not
// supported.
#if !defined(OS_LINUX) || defined(OS_CHROMEOS)
personal_data_->ResetFullServerCard(
personal_data_->GetCreditCards()[0]->guid());
#endif
CreditCard full_server_card;
test::SetCreditCardInfo(&full_server_card, "Buddy Holly",
"5187654321098765", // Mastercard
"10", "2998", "1");
full_server_card.set_guid("00000000-0000-0000-0000-000000000008");
full_server_card.set_record_type(CreditCard::FULL_SERVER_CARD);
full_server_card.set_server_id("full_id");
full_server_card.set_use_count(10);
personal_data_->AddFullServerCreditCard(full_server_card);
CreditCard local_card;
test::SetCreditCardInfo(&local_card, "Freddy Mercury",
"4234567890123463", // Visa
"08", "2999", "1");
local_card.set_guid("00000000-0000-0000-0000-000000000009");
local_card.set_record_type(CreditCard::LOCAL_CARD);
local_card.set_use_count(5);
personal_data_->AddCreditCard(local_card);
WaitOnceForOnPersonalDataChanged();
EXPECT_EQ(3U, personal_data_->GetCreditCards().size());
}
// Helper method to create a local card that was expired 400 days ago,
// and has not been used in last 400 days. This card is supposed to be
// deleted during a major version upgrade.
void CreateDeletableExpiredAndDisusedCreditCard() {
CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card1, "Clyde Barrow",
"378282246310005" /* American Express */, "04",
"1999", "1");
credit_card1.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(400));
personal_data_->AddCreditCard(credit_card1);
WaitForOnPersonalDataChanged();
EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
}
// Helper method to create a profile that was last used 400 days ago.
// This profile is supposed to be deleted during a major version upgrade.
void CreateDeletableDisusedProfile() {
AutofillProfile profile0(test::GetFullProfile());
profile0.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(400));
AddProfileToPersonalDataManager(profile0);
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
}
AutofillTable* GetServerDataTable() {
return personal_data_->IsSyncFeatureEnabled() ? profile_autofill_table_
: account_autofill_table_;
}
void AddProfileToPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
personal_data_->AddProfile(profile);
run_loop.Run();
}
void UpdateProfileOnPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
personal_data_->UpdateProfile(profile);
run_loop.Run();
}
void RemoveByGUIDFromPersonalDataManager(const std::string& guid) {
PersonalDataManagerTestBase::RemoveByGUIDFromPersonalDataManager(
guid, personal_data_.get());
}
void SetServerCards(const std::vector<CreditCard>& server_cards) {
test::SetServerCreditCards(GetServerDataTable(), server_cards);
}
void SetServerProfiles(const std::vector<AutofillProfile>& server_profiles) {
GetServerDataTable()->SetServerProfiles(server_profiles);
}
void SaveImportedProfileToPersonalDataManager(
const AutofillProfile& profile) {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
personal_data_->SaveImportedProfile(profile);
run_loop.Run();
}
void ConvertWalletAddressesAndUpdateWalletCards() {
// Simulate new data is coming from sync which triggers a conversion of
// wallet addresses which in turn triggers a refresh.
personal_data_->AutofillMultipleChangedBySync();
WaitForOnPersonalDataChanged();
}
std::unique_ptr<PersonalDataManager> personal_data_;
};
class PersonalDataManagerTest : public PersonalDataManagerHelper,
public testing::Test {
protected:
void SetUp() override {
SetUpTest();
ResetPersonalDataManager(USER_MODE_NORMAL);
}
void TearDown() override { TearDownTest(); }
};
class PersonalDataManagerMockTest : public PersonalDataManagerTestBase,
public testing::Test {
protected:
void SetUp() override {
SetUpTest();
ResetPersonalDataManager(USER_MODE_NORMAL);
// Reset the deduping and profile validation prefs to their default value.
personal_data_->pref_service_->SetInteger(
prefs::kAutofillLastVersionDeduped, 0);
personal_data_->pref_service_->SetInteger(
prefs::kAutofillLastVersionValidated,
atoi(version_info::GetVersionNumber().c_str()));
personal_data_->is_autofill_profile_cleanup_pending_ = true;
}
void TearDown() override {
if (personal_data_)
personal_data_->Shutdown();
personal_data_.reset();
TearDownTest();
}
void ResetPersonalDataManager(UserMode user_mode) {
if (personal_data_)
personal_data_->Shutdown();
personal_data_.reset(new PersonalDataManagerMock("en"));
PersonalDataManagerTestBase::ResetPersonalDataManager(
user_mode, /*use_account_server_storage=*/true, personal_data_.get());
}
bool TurnOnSyncFeature() {
return PersonalDataManagerTestBase::TurnOnSyncFeature(personal_data_.get());
}
void StopTheDedupeProcess() {
personal_data_->pref_service_->SetInteger(
prefs::kAutofillLastVersionDeduped,
atoi(version_info::GetVersionNumber().c_str()));
}
void ResetAutofillLastVersionValidated() {
ASSERT_TRUE(personal_data_);
personal_data_->pref_service_->SetInteger(
prefs::kAutofillLastVersionValidated, 0);
}
void AddProfileToPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(1);
ON_CALL(*personal_data_, OnValidated(testing::_))
.WillByDefault(testing::Invoke(
personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
personal_data_->AddProfile(profile);
run_loop.Run();
}
void UpdateProfileOnPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(1);
ON_CALL(*personal_data_, OnValidated(testing::_))
.WillByDefault(testing::Invoke(
personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
personal_data_->UpdateProfile(profile);
run_loop.Run();
}
void RemoveByGUIDFromPersonalDataManager(const std::string& guid) {
PersonalDataManagerTestBase::RemoveByGUIDFromPersonalDataManager(
guid, personal_data_.get());
}
void UpdateClientValidityStatesOnPersonalDataManager(
const std::vector<AutofillProfile*>& profiles) {
int num_updates = 0;
if (GetLastVersionValidatedUpdate() < CHROME_VERSION_MAJOR) {
num_updates = profiles.size();
} else {
for (auto* profile : profiles) {
if (!profile->is_client_validity_states_updated())
num_updates++;
}
}
base::RunLoop run_loop;
EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(num_updates);
ON_CALL(*personal_data_, OnValidated(testing::_))
.WillByDefault(testing::Invoke(
personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillRepeatedly(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
// Validate the profiles through the client validation API.
personal_data_->UpdateClientValidityStates(profiles);
run_loop.Run();
}
int GetLastVersionValidatedUpdate() {
return personal_data_->pref_service_->GetInteger(
prefs::kAutofillLastVersionValidated);
}
std::unique_ptr<PersonalDataManagerMock> personal_data_;
};
TEST_F(PersonalDataManagerTest, AddProfile) {
// Add profile0 to the database.
AutofillProfile profile0(test::GetFullProfile());
profile0.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("j@s.com"));
AddProfileToPersonalDataManager(profile0);
// Reload the database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify the addition.
const std::vector<AutofillProfile*>& results1 = personal_data_->GetProfiles();
ASSERT_EQ(1U, results1.size());
EXPECT_EQ(0, profile0.Compare(*results1[0]));
// Add profile with identical values. Duplicates should not get saved.
AutofillProfile profile0a = profile0;
profile0a.set_guid(base::GenerateGUID());
AddProfileToPersonalDataManager(profile0a);
// Reload the database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify the non-addition.
const std::vector<AutofillProfile*>& results2 = personal_data_->GetProfiles();
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, profile0.Compare(*results2[0]));
// New profile with different email.
AutofillProfile profile1 = profile0;
profile1.set_guid(base::GenerateGUID());
profile1.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("john@smith.com"));
// Add the different profile. This should save as a separate profile.
// Note that if this same profile was "merged" it would collapse to one
// profile with a multi-valued entry for email.
AddProfileToPersonalDataManager(profile1);
// Reload the database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify the addition.
std::vector<AutofillProfile*> profiles;
profiles.push_back(&profile0);
profiles.push_back(&profile1);
ExpectSameElements(profiles, personal_data_->GetProfiles());
}
// Adding, updating, removing operations without waiting in between.
TEST_F(PersonalDataManagerTest, AddRemoveUpdateProfileSequence) {
AutofillProfile profile(test::GetFullProfile());
personal_data_->AddProfile(profile);
personal_data_->RemoveByGUID(profile.guid());
personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
auto profiles = personal_data_->GetProfiles();
ASSERT_EQ(0U, profiles.size());
personal_data_->AddProfile(profile);
personal_data_->RemoveByGUID(profile.guid());
personal_data_->RemoveByGUID(profile.guid());
WaitForOnPersonalDataChanged();
profiles = personal_data_->GetProfiles();
ASSERT_EQ(0U, profiles.size());
personal_data_->AddProfile(profile);
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
profiles = personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles.size());
EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
base::ASCIIToUTF16("new@email.com"));
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("newer@email.com"));
personal_data_->UpdateProfile(profile);
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("newest@email.com"));
personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
profiles = personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles.size());
EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
base::ASCIIToUTF16("newest@email.com"));
}
// The changes should happen in the same order as requested. If the later change
// is validated before an earlier one, still we should process the earlier one
// first.
TEST_F(PersonalDataManagerTest, InconsistentValidationSequence) {
auto profile = test::GetFullProfile();
// Slow validation.
personal_data_->set_client_profile_validator_for_test(
TestAutofillProfileValidator::GetDelayedInstance());
personal_data_->AddProfile(profile);
// No validator, zero delay for validation.
personal_data_->set_client_profile_validator_for_test(nullptr);
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
auto profiles = personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles.size());
EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
base::ASCIIToUTF16("new@email.com"));
EXPECT_FALSE(profiles[0]->is_client_validity_states_updated());
}
// Test that a new profile has its basic information set.
TEST_F(PersonalDataManagerTest, AddProfile_BasicInformation) {
// Create the test clock and set the time to a specific value.
TestAutofillClock test_clock;
test_clock.SetNow(kArbitraryTime);
// Add a profile to the database.
AutofillProfile profile(test::GetFullProfile());
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("j@s.com"));
AddProfileToPersonalDataManager(profile);
// Reload the database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify the addition.
const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, profile.Compare(*results[0]));
// Make sure the use count and use date were set.
EXPECT_EQ(1U, results[0]->use_count());
EXPECT_EQ(kArbitraryTime, results[0]->use_date());
EXPECT_EQ(kArbitraryTime, results[0]->modification_date());
}
// Test filling profiles with unicode strings and crazy characters.
TEST_F(PersonalDataManagerTest, AddProfile_CrazyCharacters) {
std::vector<AutofillProfile> profiles;
AutofillProfile profile1;
profile1.SetRawInfo(
NAME_FIRST,
base::WideToUTF16(L"\u0623\u0648\u0628\u0627\u0645\u0627 "
L"\u064a\u0639\u062a\u0630\u0631 "
L"\u0647\u0627\u062a\u0641\u064a\u0627 "
L"\u0644\u0645\u0648\u0638\u0641\u0629 "
L"\u0633\u0648\u062f\u0627\u0621 "
L"\u0627\u0633\u062a\u0642\u0627\u0644\u062a "
L"\u0628\u0633\u0628\u0628 "
L"\u062a\u0635\u0631\u064a\u062d\u0627\u062a "
L"\u0645\u062c\u062a\u0632\u0623\u0629"));
profile1.SetRawInfo(NAME_MIDDLE, base::WideToUTF16(L"BANK\xcBERF\xc4LLE"));
profile1.SetRawInfo(EMAIL_ADDRESS,
base::WideToUTF16(L"\uacbd\uc81c \ub274\uc2a4 "
L"\ub354\ubcf4\uae30@google.com"));
profile1.SetRawInfo(
ADDRESS_HOME_LINE1,
base::WideToUTF16(L"\uad6d\uc815\uc6d0\xb7\uac80\ucc30, "
L"\ub178\ubb34\ud604\uc815\ubd80 "
L"\ub300\ubd81\uc811\ucd09 \ub2f4\ub2f9 "
L"\uc778\uc0ac\ub4e4 \uc870\uc0ac"));
profile1.SetRawInfo(
ADDRESS_HOME_CITY,
base::WideToUTF16(L"\u653f\u5e9c\u4e0d\u6392\u9664\u7acb\u6cd5"
L"\u898f\u7ba1\u5c0e\u904a"));
profile1.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"YOHO_54676"));
profile1.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::WideToUTF16(L"861088828000"));
profile1.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
base::WideToUTF16(L"India"), "en-US");
profiles.push_back(profile1);
AutofillProfile profile2;
profile2.SetRawInfo(NAME_FIRST,
base::WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a "
L"\u677e\u9690\u9547\u4ead\u67ab\u516c"
L"\u8def1915\u53f7"));
profile2.SetRawInfo(NAME_LAST, base::WideToUTF16(L"aguantó"));
profile2.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"HOME 94043"));
profiles.push_back(profile2);
AutofillProfile profile3;
profile3.SetRawInfo(EMAIL_ADDRESS, base::WideToUTF16(L"sue@example.com"));
profile3.SetRawInfo(COMPANY_NAME, base::WideToUTF16(L"Company X"));
profiles.push_back(profile3);
AutofillProfile profile4;
profile4.SetRawInfo(NAME_FIRST, base::WideToUTF16(L"Joe 3254"));
profile4.SetRawInfo(NAME_LAST,
base::WideToUTF16(L"\u8bb0\u8d262\u5e74\u591a"));
profile4.SetRawInfo(
ADDRESS_HOME_ZIP,
base::WideToUTF16(L"\uff08\u90ae\u7f16\uff1a201504\uff09"));
profile4.SetRawInfo(EMAIL_ADDRESS,
base::WideToUTF16(L"télévision@example.com"));
profile4.SetRawInfo(
COMPANY_NAME,
base::WideToUTF16(L"\u0907\u0932\u0947\u0915\u093f\u091f\u094d"
L"\u0930\u0928\u093f\u0915\u094d\u0938, "
L"\u0905\u092a\u094b\u0932\u094b "
L"\u091f\u093e\u092f\u0930\u094d\u0938 "
L"\u0906\u0926\u093f"));
profiles.push_back(profile4);
AutofillProfile profile5;
profile5.SetRawInfo(NAME_FIRST, base::WideToUTF16(L"Larry"));
profile5.SetRawInfo(
NAME_LAST, base::WideToUTF16(L"\u0938\u094d\u091f\u093e\u0902\u092a "
L"\u0921\u094d\u092f\u0942\u091f\u0940"));
profile5.SetRawInfo(ADDRESS_HOME_ZIP,
base::WideToUTF16(L"111111111111110000GOOGLE"));
profile5.SetRawInfo(EMAIL_ADDRESS, base::WideToUTF16(L"page@000000.com"));
profile5.SetRawInfo(COMPANY_NAME, base::WideToUTF16(L"Google"));
profiles.push_back(profile5);
AutofillProfile profile6;
profile6.SetRawInfo(NAME_FIRST,
base::WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a "
L"\u677e\u9690\u9547\u4ead\u67ab\u516c"
L"\u8def1915\u53f7"));
profile6.SetRawInfo(
NAME_LAST,
base::WideToUTF16(L"\u0646\u062c\u0627\u0645\u064a\u0646\u0627 "
L"\u062f\u0639\u0645\u0647\u0627 "
L"\u0644\u0644\u0631\u0626\u064a\u0633 "
L"\u0627\u0644\u0633\u0648\u062f\u0627\u0646"
L"\u064a \u0639\u0645\u0631 "
L"\u0627\u0644\u0628\u0634\u064a\u0631"));
profile6.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"HOME 94043"));
profiles.push_back(profile6);
AutofillProfile profile7;
profile7.SetRawInfo(NAME_FIRST,
base::WideToUTF16(L"&$%$$$ TESTO *&*&^&^& MOKO"));
profile7.SetRawInfo(NAME_MIDDLE, base::WideToUTF16(L"WOHOOOO$$$$$$$$****"));
profile7.SetRawInfo(EMAIL_ADDRESS, base::WideToUTF16(L"yuvu@example.com"));
profile7.SetRawInfo(ADDRESS_HOME_LINE1,
base::WideToUTF16(L"34544, anderson ST.(120230)"));
profile7.SetRawInfo(ADDRESS_HOME_CITY, base::WideToUTF16(L"Sunnyvale"));
profile7.SetRawInfo(ADDRESS_HOME_STATE, base::WideToUTF16(L"CA"));
profile7.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"94086"));
profile7.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::WideToUTF16(L"15466784565"));
profile7.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
base::WideToUTF16(L"United States"), "en-US");
profiles.push_back(profile7);
personal_data_->SetProfiles(&profiles);
WaitForOnPersonalDataChanged();
ASSERT_EQ(profiles.size(), personal_data_->GetProfiles().size());
for (size_t i = 0; i < profiles.size(); ++i) {
EXPECT_TRUE(
base::ContainsValue(profiles, *personal_data_->GetProfiles()[i]));
}
}
// Test filling in invalid values for profiles are saved as-is. Phone
// information entered into the settings UI is not validated or rejected except
// for duplicates.
TEST_F(PersonalDataManagerTest, AddProfile_Invalid) {
// First try profiles with invalid ZIP input.
AutofillProfile without_invalid;
without_invalid.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Will"));
without_invalid.SetRawInfo(ADDRESS_HOME_CITY,
base::ASCIIToUTF16("Sunnyvale"));
without_invalid.SetRawInfo(ADDRESS_HOME_STATE, base::ASCIIToUTF16("CA"));
without_invalid.SetRawInfo(ADDRESS_HOME_ZIP, base::ASCIIToUTF16("my_zip"));
without_invalid.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
base::ASCIIToUTF16("United States"), "en-US");
AutofillProfile with_invalid = without_invalid;
with_invalid.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("Invalid_Phone_Number"));
std::vector<AutofillProfile> profiles;
profiles.push_back(with_invalid);
personal_data_->SetProfiles(&profiles);
WaitForOnPersonalDataChanged();
ASSERT_EQ(1u, personal_data_->GetProfiles().size());
AutofillProfile profile = *personal_data_->GetProfiles()[0];
ASSERT_NE(without_invalid.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
}
// Tests that SaveImportedProfile sets the modification date on new profiles.
TEST_F(PersonalDataManagerTest, SaveImportedProfileSetModificationDate) {
AutofillProfile profile(test::GetFullProfile());
EXPECT_NE(base::Time(), profile.modification_date());
SaveImportedProfileToPersonalDataManager(profile);
const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles.size());
EXPECT_GT(base::TimeDelta::FromMilliseconds(1000),
AutofillClock::Now() - profiles[0]->modification_date());
}
TEST_F(PersonalDataManagerTest, AddUpdateRemoveProfiles) {
AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile0, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "903 Apple Ct.", nullptr,
"Orlando", "FL", "32801", "US", "19482937549");
AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile2, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
"Orlando", "FL", "32801", "US", "19482937549");
// Add two test profiles to the database.
AddProfileToPersonalDataManager(profile0);
AddProfileToPersonalDataManager(profile1);
std::vector<AutofillProfile*> profiles;
profiles.push_back(&profile0);
profiles.push_back(&profile1);
ExpectSameElements(profiles, personal_data_->GetProfiles());
// Update, remove, and add.
profile0.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("John"));
UpdateProfileOnPersonalDataManager(profile0);
RemoveByGUIDFromPersonalDataManager(profile1.guid());
AddProfileToPersonalDataManager(profile2);
profiles.clear();
profiles.push_back(&profile0);
profiles.push_back(&profile2);
ExpectSameElements(profiles, personal_data_->GetProfiles());
// Reset the PersonalDataManager. This tests that the personal data was saved
// to the web database, and that we can load the profiles from the web
// database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify that we've loaded the profiles from the web database.
ExpectSameElements(profiles, personal_data_->GetProfiles());
}
TEST_F(PersonalDataManagerTest, AddUpdateRemoveCreditCards) {
EnableWalletCardImport();
CreditCard credit_card0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card0, "John Dillinger",
"4234567890123456" /* Visa */, "01", "2999", "1");
CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card1, "Bonnie Parker",
"5105105105105100" /* Mastercard */, "12", "2999",
"1");
CreditCard credit_card2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card2, "Clyde Barrow",
"378282246310005" /* American Express */, "04",
"2999", "1");
// Add two test credit cards to the database.
personal_data_->AddCreditCard(credit_card0);
personal_data_->AddCreditCard(credit_card1);
WaitForOnPersonalDataChanged();
std::vector<CreditCard*> cards;
cards.push_back(&credit_card0);
cards.push_back(&credit_card1);
ExpectSameElements(cards, personal_data_->GetCreditCards());
// Update, remove, and add.
credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Joe"));
personal_data_->UpdateCreditCard(credit_card0);
RemoveByGUIDFromPersonalDataManager(credit_card1.guid());
personal_data_->AddCreditCard(credit_card2);
WaitForOnPersonalDataChanged();
cards.clear();
cards.push_back(&credit_card0);
cards.push_back(&credit_card2);
ExpectSameElements(cards, personal_data_->GetCreditCards());
// Reset the PersonalDataManager. This tests that the personal data was saved
// to the web database, and that we can load the credit cards from the web
// database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify that we've loaded the credit cards from the web database.
cards.clear();
cards.push_back(&credit_card0);
cards.push_back(&credit_card2);
ExpectSameElements(cards, personal_data_->GetCreditCards());
// Add a full server card.
CreditCard credit_card3(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card3, "Jane Doe",
"4111111111111111" /* Visa */, "04", "2999", "1");
credit_card3.set_record_type(CreditCard::FULL_SERVER_CARD);
credit_card3.set_server_id("server_id");
personal_data_->AddFullServerCreditCard(credit_card3);
WaitForOnPersonalDataChanged();
cards.push_back(&credit_card3);
ExpectSameElements(cards, personal_data_->GetCreditCards());
// Must not add a duplicate server card with same GUID.
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
personal_data_->AddFullServerCreditCard(credit_card3);
ExpectSameElements(cards, personal_data_->GetCreditCards());
// Must not add a duplicate card with same contents as another server card.
CreditCard duplicate_server_card(credit_card3);
duplicate_server_card.set_guid(base::GenerateGUID());
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
personal_data_->AddFullServerCreditCard(duplicate_server_card);
ExpectSameElements(cards, personal_data_->GetCreditCards());
}
// Test that a new credit card has its basic information set.
TEST_F(PersonalDataManagerTest, AddCreditCard_BasicInformation) {
// Create the test clock and set the time to a specific value.
TestAutofillClock test_clock;
test_clock.SetNow(kArbitraryTime);
// Add a credit card to the database.
CreditCard credit_card(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card, "John Dillinger",
"4234567890123456" /* Visa */, "01", "2999", "1");
personal_data_->AddCreditCard(credit_card);
// Reload the database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify the addition.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, credit_card.Compare(*results[0]));
// Make sure the use count and use date were set.
EXPECT_EQ(1U, results[0]->use_count());
EXPECT_EQ(kArbitraryTime, results[0]->use_date());
EXPECT_EQ(kArbitraryTime, results[0]->modification_date());
}
// Test filling credit cards with unicode strings and crazy characters.
TEST_F(PersonalDataManagerTest, AddCreditCard_CrazyCharacters) {
std::vector<CreditCard> cards;
CreditCard card1;
card1.SetRawInfo(CREDIT_CARD_NAME_FULL,
base::WideToUTF16(L"\u751f\u6d3b\u5f88\u6709\u89c4\u5f8b "
L"\u4ee5\u73a9\u4e3a\u4e3b"));
card1.SetRawInfo(CREDIT_CARD_NUMBER, base::WideToUTF16(L"6011111111111117"));
card1.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"12"));
card1.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2011"));
cards.push_back(card1);
CreditCard card2;
card2.SetRawInfo(CREDIT_CARD_NAME_FULL, base::WideToUTF16(L"John Williams"));
card2.SetRawInfo(CREDIT_CARD_NUMBER, base::WideToUTF16(L"WokoAwesome12345"));
card2.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"10"));
card2.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2015"));
cards.push_back(card2);
CreditCard card3;
card3.SetRawInfo(
CREDIT_CARD_NAME_FULL,
base::WideToUTF16(L"\u0623\u062d\u0645\u062f\u064a "
L"\u0646\u062c\u0627\u062f "
L"\u0644\u0645\u062d\u0627\u0648\u0644\u0647 "
L"\u0627\u063a\u062a\u064a\u0627\u0644 "
L"\u0641\u064a \u0645\u062f\u064a\u0646\u0629 "
L"\u0647\u0645\u062f\u0627\u0646 "));
card3.SetRawInfo(
CREDIT_CARD_NUMBER,
base::WideToUTF16(L"\u092a\u0941\u0928\u0930\u094d\u091c\u0940"
L"\u0935\u093f\u0924 \u0939\u094b\u0917\u093e "
L"\u0928\u093e\u0932\u0902\u0926\u093e"));
card3.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"10"));
card3.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2015"));
cards.push_back(card3);
CreditCard card4;
card4.SetRawInfo(
CREDIT_CARD_NAME_FULL,
base::WideToUTF16(L"\u039d\u03ad\u03b5\u03c2 "
L"\u03c3\u03c5\u03b3\u03c7\u03c9\u03bd\u03b5"
L"\u03cd\u03c3\u03b5\u03b9\u03c2 "
L"\u03ba\u03b1\u03b9 "
L"\u03ba\u03b1\u03c4\u03b1\u03c1\u03b3\u03ae"
L"\u03c3\u03b5\u03b9\u03c2"));
card4.SetRawInfo(CREDIT_CARD_NUMBER,
base::WideToUTF16(L"00000000000000000000000"));
card4.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"01"));
card4.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2016"));
cards.push_back(card4);
personal_data_->SetCreditCards(&cards);
WaitForOnPersonalDataChanged();
ASSERT_EQ(cards.size(), personal_data_->GetCreditCards().size());
for (size_t i = 0; i < cards.size(); ++i) {
EXPECT_TRUE(
base::ContainsValue(cards, *personal_data_->GetCreditCards()[i]));
}
}
// Test invalid credit card numbers typed in settings UI should be saved as-is.
TEST_F(PersonalDataManagerTest, AddCreditCard_Invalid) {
CreditCard card;
card.SetRawInfo(CREDIT_CARD_NUMBER, base::ASCIIToUTF16("Not_0123-5Checked"));
std::vector<CreditCard> cards;
cards.push_back(card);
personal_data_->SetCreditCards(&cards);
ASSERT_EQ(1u, personal_data_->GetCreditCards().size());
ASSERT_EQ(card, *personal_data_->GetCreditCards()[0]);
}
TEST_F(PersonalDataManagerTest, UpdateUnverifiedProfilesAndCreditCards) {
// Start with unverified data.
AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
EXPECT_FALSE(profile.IsVerified());
CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
test::SetCreditCardInfo(&credit_card, "John Dillinger",
"4234567890123456" /* Visa */, "01", "2999", "1");
EXPECT_FALSE(credit_card.IsVerified());
// Add the data to the database.
AddProfileToPersonalDataManager(profile);
personal_data_->AddCreditCard(credit_card);
WaitForOnPersonalDataChanged();
const std::vector<AutofillProfile*>& profiles1 =
personal_data_->GetProfiles();
const std::vector<CreditCard*>& cards1 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, profiles1.size());
ASSERT_EQ(1U, cards1.size());
EXPECT_EQ(0, profile.Compare(*profiles1[0]));
EXPECT_EQ(0, credit_card.Compare(*cards1[0]));
// Try to update with just the origin changed.
AutofillProfile original_profile(profile);
ASSERT_FALSE(original_profile.IsVerified());
CreditCard original_credit_card(credit_card);
profile.set_origin(kSettingsOrigin);
credit_card.set_origin(kSettingsOrigin);
EXPECT_TRUE(profile.IsVerified());
EXPECT_TRUE(credit_card.IsVerified());
UpdateProfileOnPersonalDataManager(profile);
personal_data_->UpdateCreditCard(credit_card);
// Credit Card origin should not be overwritten.
const std::vector<AutofillProfile*>& profiles2 =
personal_data_->GetProfiles();
const std::vector<CreditCard*>& cards2 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, profiles2.size());
ASSERT_EQ(1U, cards2.size());
EXPECT_EQ(profile.origin(), profiles2[0]->origin());
EXPECT_NE(credit_card.origin(), cards2[0]->origin());
EXPECT_NE(original_profile.origin(), profiles2[0]->origin());
EXPECT_EQ(original_credit_card.origin(), cards2[0]->origin());
// Try to update with data changed as well.
profile.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("John"));
credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Joe"));
UpdateProfileOnPersonalDataManager(profile);
personal_data_->UpdateCreditCard(credit_card);
WaitForOnPersonalDataChanged();
const std::vector<AutofillProfile*>& profiles3 =
personal_data_->GetProfiles();
const std::vector<CreditCard*>& cards3 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, profiles3.size());
ASSERT_EQ(1U, cards3.size());
EXPECT_EQ(0, profile.Compare(*profiles3[0]));
EXPECT_EQ(0, credit_card.Compare(*cards3[0]));
EXPECT_EQ(profile.origin(), profiles3[0]->origin());
EXPECT_EQ(credit_card.origin(), cards3[0]->origin());
}
// Test that updating a verified profile with another profile whose only
// difference is the origin, would not change the old profile, and thus it would
// remain verified.
TEST_F(PersonalDataManagerTest, UpdateVerifiedProfilesOrigin) {
// Start with verified data.
AutofillProfile profile(base::GenerateGUID(), kSettingsOrigin);
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
ASSERT_TRUE(profile.IsVerified());
AddProfileToPersonalDataManager(profile);
const std::vector<AutofillProfile*>& profiles1 =
personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles1.size());
EXPECT_EQ(0, profile.Compare(*profiles1[0]));
// Try to update with just the origin changed to a non-setting origin.
AutofillProfile new_profile(profile);
new_profile.set_origin("");
ASSERT_FALSE(new_profile.IsVerified());
UpdateProfileOnPersonalDataManager(profile);
// Verified profile origin should not be overwritten.
const std::vector<AutofillProfile*>& profiles2 =
personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles2.size());
EXPECT_EQ(profile.origin(), profiles2[0]->origin());
EXPECT_NE(new_profile.origin(), profiles2[0]->origin());
EXPECT_TRUE(profiles2[0]->IsVerified());
}
// Makes sure that full cards are re-masked when full PAN storage is off.
TEST_F(PersonalDataManagerTest, RefuseToStoreFullCard) {
// On Linux this should be disabled automatically. Elsewhere, only if the
// flag is passed.
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
EXPECT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableOfferStoreUnmaskedWalletCards));
#else
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableOfferStoreUnmaskedWalletCards);
#endif
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
"378282246310005" /* American Express */, "04",
"2999", "1");
SetServerCards(server_cards);
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
ASSERT_EQ(1U, personal_data_->GetCreditCards().size());
EXPECT_EQ(CreditCard::MASKED_SERVER_CARD,
personal_data_->GetCreditCards()[0]->record_type());
}
// Makes sure that full cards are only added as masked card when full PAN
// storage is disabled.
TEST_F(PersonalDataManagerTest, AddFullCardAsMaskedCard) {
// On Linux this should be disabled automatically. Elsewhere, only if the
// flag is passed.
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
EXPECT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableOfferStoreUnmaskedWalletCards));
#else
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableOfferStoreUnmaskedWalletCards);
#endif
CreditCard server_card(CreditCard::FULL_SERVER_CARD, "c789");
test::SetCreditCardInfo(&server_card, "Clyde Barrow",
"378282246310005" /* American Express */, "04",
"2999", "1");
personal_data_->AddFullServerCreditCard(server_card);
WaitForOnPersonalDataChanged();
ASSERT_EQ(1U, personal_data_->GetCreditCards().size());
EXPECT_EQ(CreditCard::MASKED_SERVER_CARD,
personal_data_->GetCreditCards()[0]->record_type());
}
TEST_F(PersonalDataManagerTest, OfferStoreUnmaskedCards) {
#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX) || \
defined(OS_IOS) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
bool should_offer = true;
#elif defined(OS_LINUX)
bool should_offer = false;
#endif
EXPECT_EQ(should_offer, OfferStoreUnmaskedCards(/*is_off_the_record=*/false));
}
// Tests that OfferStoreUnmaskedCards always returns false if the user is off
// the record.
TEST_F(PersonalDataManagerTest, OfferStoreUnmaskedCards_OffTheRecord) {
EXPECT_EQ(false, OfferStoreUnmaskedCards(/*is_off_the_record=*/true));
}
// Tests that UpdateServerCreditCard can be used to mask or unmask server cards.
TEST_F(PersonalDataManagerTest, UpdateServerCreditCards) {
EnableWalletCardImport();
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
"3456" /* Visa */, "01", "2999", "1");
server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456"));
test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker",
"5100" /* Mastercard */, "12", "2999", "1");
server_cards.back().SetNetworkForMaskedCard(kMasterCard);
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
"378282246310005" /* American Express */, "04",
"2999", "1");
SetServerCards(server_cards);
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
ASSERT_EQ(3U, personal_data_->GetCreditCards().size());
if (!OfferStoreUnmaskedCards(/*is_off_the_record=*/false)) {
for (CreditCard* card : personal_data_->GetCreditCards()) {
EXPECT_EQ(CreditCard::MASKED_SERVER_CARD, card->record_type());
}
// The rest of this test doesn't work if we're force-masking all unmasked
// cards.
return;
}
// The GUIDs will be different, so just compare the data.
for (size_t i = 0; i < 3; ++i)
EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i]));
CreditCard* unmasked_card = &server_cards.front();
unmasked_card->set_record_type(CreditCard::FULL_SERVER_CARD);
unmasked_card->SetNumber(base::ASCIIToUTF16("4234567890123456"));
personal_data_->UpdateServerCreditCard(*unmasked_card);
WaitForOnPersonalDataChanged();
for (size_t i = 0; i < 3; ++i)
EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i]));
CreditCard* remasked_card = &server_cards.back();
remasked_card->set_record_type(CreditCard::MASKED_SERVER_CARD);
remasked_card->SetNumber(base::ASCIIToUTF16("0005"));
personal_data_->UpdateServerCreditCard(*remasked_card);
WaitForOnPersonalDataChanged();
for (size_t i = 0; i < 3; ++i)
EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i]));
}
TEST_F(PersonalDataManagerTest, SavesServerCardType) {
EnableWalletCardImport();
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
"3456" /* Visa */, "01", "2999", "1");
server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.back().set_card_type(CreditCard::CARD_TYPE_DEBIT);
SetServerCards(server_cards);
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
auto cards = personal_data_->GetCreditCards();
ASSERT_EQ(1U, cards.size());
EXPECT_EQ(CreditCard::CARD_TYPE_DEBIT, cards.front()->card_type());
}
TEST_F(PersonalDataManagerTest, AddProfilesAndCreditCards) {
AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile0, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "903 Apple Ct.", nullptr,
"Orlando", "FL", "32801", "US", "19482937549");
CreditCard credit_card0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card0, "John Dillinger",
"4234567890123456" /* Visa */, "01", "2999", "1");
CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card1, "Bonnie Parker",
"5105105105105100" /* Mastercard */, "12", "2999",
"1");
// Add two test profiles to the database.
AddProfileToPersonalDataManager(profile0);
AddProfileToPersonalDataManager(profile1);
std::vector<AutofillProfile*> profiles;
profiles.push_back(&profile0);
profiles.push_back(&profile1);
ExpectSameElements(profiles, personal_data_->GetProfiles());
// Add two test credit cards to the database.
personal_data_->AddCreditCard(credit_card0);
personal_data_->AddCreditCard(credit_card1);
WaitForOnPersonalDataChanged();
std::vector<CreditCard*> cards;
cards.push_back(&credit_card0);
cards.push_back(&credit_card1);
ExpectSameElements(cards, personal_data_->GetCreditCards());
// Determine uniqueness by inserting all of the GUIDs into a set and verifying
// the size of the set matches the number of GUIDs.
std::set<std::string> guids;
guids.insert(profile0.guid());
guids.insert(profile1.guid());
guids.insert(credit_card0.guid());
guids.insert(credit_card1.guid());
EXPECT_EQ(4U, guids.size());
}
// Test for http://crbug.com/50047. Makes sure that guids are populated
// correctly on load.
TEST_F(PersonalDataManagerTest, PopulateUniqueIDsOnLoad) {
AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile0, "y", "", "", "", "", "", "", "", "", "", "",
"");
// Add the profile0 to the db.
AddProfileToPersonalDataManager(profile0);
// Verify that we've loaded the profiles from the web database.
const std::vector<AutofillProfile*>& results2 = personal_data_->GetProfiles();
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, profile0.Compare(*results2[0]));
// Add a new profile.
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "z", "", "", "", "", "", "", "", "", "", "",
"");
AddProfileToPersonalDataManager(profile1);
// Make sure the two profiles have different GUIDs, both valid.
const std::vector<AutofillProfile*>& results3 = personal_data_->GetProfiles();
ASSERT_EQ(2U, results3.size());
EXPECT_NE(results3[0]->guid(), results3[1]->guid());
EXPECT_TRUE(base::IsValidGUID(results3[0]->guid()));
EXPECT_TRUE(base::IsValidGUID(results3[1]->guid()));
}
TEST_F(PersonalDataManagerTest, SetUniqueCreditCardLabels) {
CreditCard credit_card0(base::GenerateGUID(), test::kEmptyOrigin);
credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("John"));
CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
credit_card1.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Paul"));
CreditCard credit_card2(base::GenerateGUID(), test::kEmptyOrigin);
credit_card2.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Ringo"));
CreditCard credit_card3(base::GenerateGUID(), test::kEmptyOrigin);
credit_card3.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Other"));
CreditCard credit_card4(base::GenerateGUID(), test::kEmptyOrigin);
credit_card4.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Ozzy"));
CreditCard credit_card5(base::GenerateGUID(), test::kEmptyOrigin);
credit_card5.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Dio"));
// Add the test credit cards to the database.
personal_data_->AddCreditCard(credit_card0);
personal_data_->AddCreditCard(credit_card1);
personal_data_->AddCreditCard(credit_card2);
personal_data_->AddCreditCard(credit_card3);
personal_data_->AddCreditCard(credit_card4);
personal_data_->AddCreditCard(credit_card5);
// Reset the PersonalDataManager. This tests that the personal data was saved
// to the web database, and that we can load the credit cards from the web
// database.
ResetPersonalDataManager(USER_MODE_NORMAL);
std::vector<CreditCard*> cards;
cards.push_back(&credit_card0);
cards.push_back(&credit_card1);
cards.push_back(&credit_card2);
cards.push_back(&credit_card3);
cards.push_back(&credit_card4);
cards.push_back(&credit_card5);
ExpectSameElements(cards, personal_data_->GetCreditCards());
}
TEST_F(PersonalDataManagerTest, SetEmptyProfile) {
AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile0, "", "", "", "", "", "", "", "", "", "", "",
"");
// Add the empty profile to the database.
AddProfileToPersonalDataManager(profile0);
// Reset the PersonalDataManager. This tests that the personal data was saved
// to the web database, and that we can load the profiles from the web
// database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify that we've loaded the profiles from the web database.
ASSERT_EQ(0U, personal_data_->GetProfiles().size());
}
TEST_F(PersonalDataManagerTest, SetEmptyCreditCard) {
CreditCard credit_card0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card0, "", "", "", "", "");
// Add the empty credit card to the database.
personal_data_->AddCreditCard(credit_card0);
// Note: no refresh here.
// Reset the PersonalDataManager. This tests that the personal data was saved
// to the web database, and that we can load the credit cards from the web
// database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify that we've loaded the credit cards from the web database.
ASSERT_EQ(0U, personal_data_->GetCreditCards().size());
}
TEST_F(PersonalDataManagerTest, Refresh) {
AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile0, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "903 Apple Ct.", nullptr,
"Orlando", "FL", "32801", "US", "19482937549");
// Add the test profiles to the database.
AddProfileToPersonalDataManager(profile0);
AddProfileToPersonalDataManager(profile1);
std::vector<AutofillProfile*> profiles;
profiles.push_back(&profile0);
profiles.push_back(&profile1);
ExpectSameElements(profiles, personal_data_->GetProfiles());
AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile2, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
"Orlando", "FL", "32801", "US", "19482937549");
profile_database_service_->AddAutofillProfile(profile2);
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
profiles.clear();
profiles.push_back(&profile0);
profiles.push_back(&profile1);
profiles.push_back(&profile2);
ExpectSameElements(profiles, personal_data_->GetProfiles());
profile_database_service_->RemoveAutofillProfile(profile1.guid());
profile_database_service_->RemoveAutofillProfile(profile2.guid());
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
auto results = personal_data_->GetProfiles();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(profile0, *results[0]);
profile0.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Mar"));
profile_database_service_->UpdateAutofillProfile(profile0);
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
results = personal_data_->GetProfiles();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(profile0, *results[0]);
}
// Ensure that verified profiles can be saved via SaveImportedProfile,
// overwriting existing unverified profiles.
TEST_F(PersonalDataManagerTest, SaveImportedProfileWithVerifiedData) {
// Start with an unverified profile.
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
EXPECT_FALSE(profile.IsVerified());
AddProfileToPersonalDataManager(profile);
// Make sure everything is set up correctly.
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
AutofillProfile new_verified_profile = profile;
new_verified_profile.set_guid(base::GenerateGUID());
new_verified_profile.set_origin(kSettingsOrigin);
new_verified_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("1 234 567-8910"));
EXPECT_TRUE(new_verified_profile.IsVerified());
SaveImportedProfileToPersonalDataManager(new_verified_profile);
// The new profile should be merged into the existing one.
const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
ASSERT_EQ(1U, results.size());
AutofillProfile expected(new_verified_profile);
expected.SetRawInfo(NAME_FULL,
base::ASCIIToUTF16("Marion Mitchell Morrison"));
expected.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("+1 234-567-8910"));
EXPECT_EQ(0, expected.Compare(*results[0]))
<< "result = {" << *results[0] << "} | expected = {" << expected << "}";
}
// Ensure that verified credit cards can be saved via
// OnAcceptedLocalCreditCardSave.
TEST_F(PersonalDataManagerTest, OnAcceptedLocalCreditCardSaveWithVerifiedData) {
// Start with a verified credit card.
CreditCard credit_card(base::GenerateGUID(), kSettingsOrigin);
test::SetCreditCardInfo(&credit_card, "Biggie Smalls",
"4111 1111 1111 1111" /* Visa */, "01", "2999", "");
EXPECT_TRUE(credit_card.IsVerified());
// Add the credit card to the database.
personal_data_->AddCreditCard(credit_card);
// Make sure everything is set up correctly.
WaitForOnPersonalDataChanged();
EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
CreditCard new_verified_card = credit_card;
new_verified_card.set_guid(base::GenerateGUID());
new_verified_card.SetRawInfo(CREDIT_CARD_NAME_FULL,
base::ASCIIToUTF16("B. Small"));
EXPECT_TRUE(new_verified_card.IsVerified());
personal_data_->OnAcceptedLocalCreditCardSave(new_verified_card);
WaitForOnPersonalDataChanged();
// Expect that the saved credit card is updated.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(base::ASCIIToUTF16("B. Small"),
results[0]->GetRawInfo(CREDIT_CARD_NAME_FULL));
}
TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
// Check that there are no available types with no profiles stored.
ServerFieldTypeSet non_empty_types;
personal_data_->GetNonEmptyTypes(&non_empty_types);
EXPECT_EQ(0U, non_empty_types.size());
// Test with one profile stored.
AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile0, "Marion", nullptr, "Morrison",
"johnwayne@me.xyz", nullptr, "123 Zoo St.", nullptr,
"Hollywood", "CA", "91601", "US", "14155678910");
AddProfileToPersonalDataManager(profile0);
// Make sure everything is set up correctly.
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
personal_data_->GetNonEmptyTypes(&non_empty_types);
EXPECT_EQ(15U, non_empty_types.size());
EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(NAME_LAST));
EXPECT_TRUE(non_empty_types.count(NAME_FULL));
EXPECT_TRUE(non_empty_types.count(EMAIL_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE1));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STREET_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_CITY));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STATE));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_COUNTRY));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_NUMBER));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_COUNTRY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_AND_NUMBER));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_WHOLE_NUMBER));
// Test with multiple profiles stored.
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "903 Apple Ct.", nullptr,
"Orlando", "FL", "32801", "US", "16502937549");
AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile2, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
"Orlando", "FL", "32801", "US", "16502937549");
AddProfileToPersonalDataManager(profile1);
AddProfileToPersonalDataManager(profile2);
EXPECT_EQ(3U, personal_data_->GetProfiles().size());
personal_data_->GetNonEmptyTypes(&non_empty_types);
EXPECT_EQ(19U, non_empty_types.size());
EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE_INITIAL));
EXPECT_TRUE(non_empty_types.count(NAME_LAST));
EXPECT_TRUE(non_empty_types.count(NAME_FULL));
EXPECT_TRUE(non_empty_types.count(EMAIL_ADDRESS));
EXPECT_TRUE(non_empty_types.count(COMPANY_NAME));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE1));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE2));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STREET_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_CITY));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STATE));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_COUNTRY));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_NUMBER));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_COUNTRY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_AND_NUMBER));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_WHOLE_NUMBER));
// Test with credit card information also stored.
CreditCard credit_card(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&credit_card, "John Dillinger",
"4234567890123456" /* Visa */, "01", "2999", "");
personal_data_->AddCreditCard(credit_card);
WaitForOnPersonalDataChanged();
EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
personal_data_->GetNonEmptyTypes(&non_empty_types);
EXPECT_EQ(29U, non_empty_types.size());
EXPECT_TRUE(non_empty_types.count(NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE));
EXPECT_TRUE(non_empty_types.count(NAME_MIDDLE_INITIAL));
EXPECT_TRUE(non_empty_types.count(NAME_LAST));
EXPECT_TRUE(non_empty_types.count(NAME_FULL));
EXPECT_TRUE(non_empty_types.count(EMAIL_ADDRESS));
EXPECT_TRUE(non_empty_types.count(COMPANY_NAME));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE1));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_LINE2));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STREET_ADDRESS));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_CITY));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_STATE));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_ZIP));
EXPECT_TRUE(non_empty_types.count(ADDRESS_HOME_COUNTRY));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_NUMBER));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_COUNTRY_CODE));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_CITY_AND_NUMBER));
EXPECT_TRUE(non_empty_types.count(PHONE_HOME_WHOLE_NUMBER));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_NAME_FULL));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_NAME_FIRST));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_NAME_LAST));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_NUMBER));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_TYPE));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_EXP_MONTH));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_EXP_2_DIGIT_YEAR));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_EXP_4_DIGIT_YEAR));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR));
EXPECT_TRUE(non_empty_types.count(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR));
}
TEST_F(PersonalDataManagerTest, IncognitoReadOnly) {
ASSERT_TRUE(personal_data_->GetProfiles().empty());
ASSERT_TRUE(personal_data_->GetCreditCards().empty());
AutofillProfile steve_jobs(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&steve_jobs, "Steven", "Paul", "Jobs", "sjobs@apple.com",
"Apple Computer, Inc.", "1 Infinite Loop", "",
"Cupertino", "CA", "95014", "US", "(800) 275-2273");
AddProfileToPersonalDataManager(steve_jobs);
CreditCard bill_gates(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&bill_gates, "William H. Gates", "5555555555554444",
"1", "2020", "1");
personal_data_->AddCreditCard(bill_gates);
// The personal data manager should be able to read existing profiles in an
// off-the-record context.
ResetPersonalDataManager(USER_MODE_INCOGNITO);
ASSERT_EQ(1U, personal_data_->GetProfiles().size());
ASSERT_EQ(1U, personal_data_->GetCreditCards().size());
// No adds, saves, or updates should take effect.
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
// Add profiles or credit card shouldn't work.
personal_data_->AddProfile(test::GetFullProfile());
CreditCard larry_page(base::GenerateGUID(), test::kEmptyOrigin);
test::SetCreditCardInfo(&larry_page, "Lawrence Page", "4111111111111111",
"10", "2025", "1");
personal_data_->AddCreditCard(larry_page);
ResetPersonalDataManager(USER_MODE_INCOGNITO);
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
// Saving or creating profiles from imported profiles shouldn't work.
steve_jobs.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Steve"));
personal_data_->SaveImportedProfile(steve_jobs);
bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL,
base::ASCIIToUTF16("Bill Gates"));
personal_data_->OnAcceptedLocalCreditCardSave(bill_gates);
ResetPersonalDataManager(USER_MODE_INCOGNITO);
EXPECT_EQ(base::ASCIIToUTF16("Steven"),
personal_data_->GetProfiles()[0]->GetRawInfo(NAME_FIRST));
EXPECT_EQ(
base::ASCIIToUTF16("William H. Gates"),
personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME_FULL));
// Updating existing profiles shouldn't work.
steve_jobs.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Steve"));
personal_data_->UpdateProfile(steve_jobs);
bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL,
base::ASCIIToUTF16("Bill Gates"));
personal_data_->UpdateCreditCard(bill_gates);
ResetPersonalDataManager(USER_MODE_INCOGNITO);
EXPECT_EQ(base::ASCIIToUTF16("Steven"),
personal_data_->GetProfiles()[0]->GetRawInfo(NAME_FIRST));
EXPECT_EQ(
base::ASCIIToUTF16("William H. Gates"),
personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME_FULL));
// Removing shouldn't work.
personal_data_->RemoveByGUID(steve_jobs.guid());
personal_data_->RemoveByGUID(bill_gates.guid());
ResetPersonalDataManager(USER_MODE_INCOGNITO);
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
}
TEST_F(PersonalDataManagerTest, DefaultCountryCodeIsCached) {
// The return value should always be some country code, no matter what.
std::string default_country =
personal_data_->GetDefaultCountryCodeForNewAddress();
EXPECT_EQ(2U, default_country.size());
AutofillProfile moose(base::GenerateGUID(), kSettingsOrigin);
test::SetProfileInfo(&moose, "Moose", "P", "McMahon", "mpm@example.com", "",
"1 Taiga TKTR", "", "Calgary", "AB", "T2B 2K2", "CA",
"(800) 555-9000");
AddProfileToPersonalDataManager(moose);
// Make sure everything is set up correctly.
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
// The value is cached and doesn't change even after adding an address.
EXPECT_EQ(default_country,
personal_data_->GetDefaultCountryCodeForNewAddress());
// Disabling Autofill blows away this cache and shouldn't account for Autofill
// profiles.
prefs::SetAutofillEnabled(prefs_.get(), false);
WaitForOnPersonalDataChanged();
EXPECT_EQ(default_country,
personal_data_->GetDefaultCountryCodeForNewAddress());
// Enabling Autofill blows away the cached value and should reflect the new
// value (accounting for profiles).
prefs::SetAutofillEnabled(prefs_.get(), true);
EXPECT_EQ(base::UTF16ToUTF8(moose.GetRawInfo(ADDRESS_HOME_COUNTRY)),
personal_data_->GetDefaultCountryCodeForNewAddress());
}
TEST_F(PersonalDataManagerTest, DefaultCountryCodeComesFromProfiles) {
AutofillProfile moose(base::GenerateGUID(), kSettingsOrigin);
test::SetProfileInfo(&moose, "Moose", "P", "McMahon", "mpm@example.com", "",
"1 Taiga TKTR", "", "Calgary", "AB", "T2B 2K2", "CA",
"(800) 555-9000");
AddProfileToPersonalDataManager(moose);
ResetPersonalDataManager(USER_MODE_NORMAL);
EXPECT_EQ("CA", personal_data_->GetDefaultCountryCodeForNewAddress());
// Multiple profiles cast votes.
AutofillProfile armadillo(base::GenerateGUID(), kSettingsOrigin);
test::SetProfileInfo(&armadillo, "Armin", "Dill", "Oh", "ado@example.com", "",
"1 Speed Bump", "", "Lubbock", "TX", "77500", "MX",
"(800) 555-9000");
AutofillProfile armadillo2(base::GenerateGUID(), kSettingsOrigin);
test::SetProfileInfo(&armadillo2, "Armin", "Dill", "Oh", "ado@example.com",
"", "2 Speed Bump", "", "Lubbock", "TX", "77500", "MX",
"(800) 555-9000");
AddProfileToPersonalDataManager(armadillo);
AddProfileToPersonalDataManager(armadillo2);
ResetPersonalDataManager(USER_MODE_NORMAL);
EXPECT_EQ("MX", personal_data_->GetDefaultCountryCodeForNewAddress());
RemoveByGUIDFromPersonalDataManager(armadillo.guid());
RemoveByGUIDFromPersonalDataManager(armadillo2.guid());
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verified profiles count more.
armadillo.set_origin("http://randomwebsite.com");
armadillo2.set_origin("http://randomwebsite.com");
AddProfileToPersonalDataManager(armadillo);
AddProfileToPersonalDataManager(armadillo2);
ResetPersonalDataManager(USER_MODE_NORMAL);
EXPECT_EQ("CA", personal_data_->GetDefaultCountryCodeForNewAddress());
RemoveByGUIDFromPersonalDataManager(armadillo.guid());
ResetPersonalDataManager(USER_MODE_NORMAL);
// But unverified profiles can be a tie breaker.
armadillo.set_origin(kSettingsOrigin);
AddProfileToPersonalDataManager(armadillo);
ResetPersonalDataManager(USER_MODE_NORMAL);
EXPECT_EQ("MX", personal_data_->GetDefaultCountryCodeForNewAddress());
}
TEST_F(PersonalDataManagerTest, UpdateLanguageCodeInProfile) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile);
// Make sure everything is set up correctly.
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
EXPECT_EQ(1U, personal_data_->GetProfiles().size());
profile.set_language_code("en");
UpdateProfileOnPersonalDataManager(profile);
const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, profile.Compare(*results[0]));
EXPECT_EQ("en", results[0]->language_code());
}
TEST_F(PersonalDataManagerTest, GetProfileSuggestions) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile);
ResetPersonalDataManager(USER_MODE_NORMAL);
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("123"),
false, std::vector<ServerFieldType>());
ASSERT_FALSE(suggestions.empty());
EXPECT_EQ(base::ASCIIToUTF16("123 Zoo St., Second Line, Third line, unit 5"),
suggestions[0].value);
}
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_PhoneSubstring) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile);
ResetPersonalDataManager(USER_MODE_NORMAL);
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(PHONE_HOME_WHOLE_NUMBER), base::ASCIIToUTF16("234"), false,
std::vector<ServerFieldType>());
ASSERT_FALSE(suggestions.empty());
EXPECT_EQ(base::ASCIIToUTF16("12345678910"), suggestions[0].value);
}
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_HideSubsets) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
// Dupe profile, except different in email address (irrelevant for this form).
AutofillProfile profile1 = profile;
profile1.set_guid(base::GenerateGUID());
profile1.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("spam_me@example.com"));
// Dupe profile, except different in address state.
AutofillProfile profile2 = profile;
profile2.set_guid(base::GenerateGUID());
profile2.SetRawInfo(ADDRESS_HOME_STATE, base::ASCIIToUTF16("TX"));
// Subset profile.
AutofillProfile profile3 = profile;
profile3.set_guid(base::GenerateGUID());
profile3.SetRawInfo(ADDRESS_HOME_STATE, base::string16());
// For easier results verification, make sure |profile| is suggested first.
profile.set_use_count(5);
AddProfileToPersonalDataManager(profile);
AddProfileToPersonalDataManager(profile1);
AddProfileToPersonalDataManager(profile2);
AddProfileToPersonalDataManager(profile3);
ResetPersonalDataManager(USER_MODE_NORMAL);
// Simulate a form with street address, city and state.
std::vector<ServerFieldType> types;
types.push_back(ADDRESS_HOME_CITY);
types.push_back(ADDRESS_HOME_STATE);
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("123"),
false, types);
ASSERT_EQ(2U, suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("Hollywood, CA"), suggestions[0].label);
EXPECT_EQ(base::ASCIIToUTF16("Hollywood, TX"), suggestions[1].label);
}
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_SuggestionsLimit) {
// Drawing takes noticeable time when there are more than 10 profiles.
// Therefore, we keep only the 10 first suggested profiles.
std::vector<AutofillProfile> profiles;
for (size_t i = 0; i < 2 * suggestion_selection::kMaxUniqueSuggestionsCount;
i++) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, base::StringPrintf("Marion%zu", i).c_str(),
"Mitchell", "Morrison", "johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile);
profiles.push_back(profile);
}
ResetPersonalDataManager(USER_MODE_NORMAL);
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(NAME_FIRST), base::ASCIIToUTF16("Ma"), false,
std::vector<ServerFieldType>());
ASSERT_EQ(2 * suggestion_selection::kMaxUniqueSuggestionsCount,
personal_data_->GetProfiles().size());
ASSERT_EQ(suggestion_selection::kMaxUniqueSuggestionsCount,
suggestions.size());
}
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ProfilesLimit) {
// Deduping takes noticeable time when there are more than 50 profiles.
// Therefore, keep only the 50 first pre-dedupe matching profiles.
std::vector<AutofillProfile> profiles;
for (size_t i = 0; i < suggestion_selection::kMaxSuggestedProfilesCount;
i++) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(
&profile, "Marion", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox",
base::StringPrintf("%zu123 Zoo St.\nSecond Line\nThird line", i)
.c_str(),
"unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
// Set frecency such that they appear before the "last" profile (added
// next).
profile.set_use_count(12);
profile.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
AddProfileToPersonalDataManager(profile);
profiles.push_back(profile);
}
// Add another profile that matches, but that will get stripped out.
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Marie", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"000 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
profile.set_use_count(1);
profile.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(7));
AddProfileToPersonalDataManager(profile);
ResetPersonalDataManager(USER_MODE_NORMAL);
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(NAME_FIRST), base::ASCIIToUTF16("Ma"), false,
std::vector<ServerFieldType>());
ASSERT_EQ(suggestion_selection::kMaxSuggestedProfilesCount + 1,
personal_data_->GetProfiles().size());
ASSERT_EQ(1U, suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("Marion"), suggestions[0].value);
}
// Tests that GetProfileSuggestions orders its suggestions based on the frecency
// formula.
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Ranking) {
// Set up the profiles. They are named with number suffixes X so the X is the
// order in which they should be ordered by frecency.
AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile3, "Marion3", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
profile3.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
profile3.set_use_count(5);
AddProfileToPersonalDataManager(profile3);
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
profile1.set_use_count(10);
AddProfileToPersonalDataManager(profile1);
AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(15));
profile2.set_use_count(300);
AddProfileToPersonalDataManager(profile2);
ResetPersonalDataManager(USER_MODE_NORMAL);
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(NAME_FIRST), base::ASCIIToUTF16("Ma"), false,
std::vector<ServerFieldType>());
ASSERT_EQ(3U, suggestions.size());
EXPECT_EQ(suggestions[0].value, base::ASCIIToUTF16("Marion1"));
EXPECT_EQ(suggestions[1].value, base::ASCIIToUTF16("Marion2"));
EXPECT_EQ(suggestions[2].value, base::ASCIIToUTF16("Marion3"));
}
// Tests that GetProfileSuggestions returns all profiles suggestions.
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_NumberOfSuggestions) {
// Set up 3 different profiles.
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile1);
AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile2);
AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile3, "Marion3", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
AddProfileToPersonalDataManager(profile3);
ResetPersonalDataManager(USER_MODE_NORMAL);
// Verify that all the profiles are suggested.
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(NAME_FIRST), base::string16(), false,
std::vector<ServerFieldType>());
EXPECT_EQ(3U, suggestions.size());
}
// Tests that disused profiles are suppressed when supression is enabled and
// the input field is empty.
TEST_F(PersonalDataManagerTest,
GetProfileSuggestions_SuppressDisusedProfilesOnEmptyField) {
// Set up 2 different profiles.
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(200));
AddProfileToPersonalDataManager(profile1);
AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
"johnwayne@me.xyz", "Fox",
"456 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "12345678910");
profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
AddProfileToPersonalDataManager(profile2);
ResetPersonalDataManager(USER_MODE_NORMAL);
// Query with empty string only returns profile2.
{
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::string16(), false,
std::vector<ServerFieldType>());
EXPECT_EQ(1U, suggestions.size());
}
// Query with non-alpha-numeric string only returns profile2.
{
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("--"),
false, std::vector<ServerFieldType>());
EXPECT_EQ(1U, suggestions.size());
}
// Query with prefix for profile1 returns profile1.
{
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("123"),
false, std::vector<ServerFieldType>());
ASSERT_EQ(1U, suggestions.size());
EXPECT_EQ(
base::ASCIIToUTF16("123 Zoo St., Second Line, Third line, unit 5"),
suggestions[0].value);
}
// Query with prefix for profile2 returns profile2.
{
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("456"),
false, std::vector<ServerFieldType>());
EXPECT_EQ(1U, suggestions.size());
EXPECT_EQ(
base::ASCIIToUTF16("456 Zoo St., Second Line, Third line, unit 5"),
suggestions[0].value);
}
}
// Tests that suggestions based on invalid data are handled correctly.
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
// Set up 2 different profiles: one valid and one invalid.
AutofillProfile valid_profile(test::GetFullValidProfileForCanada());
valid_profile.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
valid_profile.set_use_count(1);
AddProfileToPersonalDataManager(valid_profile);
AutofillProfile invalid_profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&invalid_profile, "Marion1", "Mitchell", "Morrison",
"invalid email", "Fox",
"123 Zoo St.\nSecond Line\nThird line", "unit 5",
"Hollywood", "CA", "91601", "US", "Invalid Phone");
invalid_profile.set_use_date(AutofillClock::Now());
invalid_profile.set_use_count(1000);
AddProfileToPersonalDataManager(invalid_profile);
auto profiles = personal_data_->GetProfiles();
ASSERT_EQ(2U, profiles.size());
// Invalid based on client, and not invalid by server. Relying on both
// validity sources.
{
base::test::ScopedFeatureList scoped_features;
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileServerValidation,
features::kAutofillProfileClientValidation},
/*disabled_features=*/{});
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
base::string16(), false,
std::vector<ServerFieldType>());
for (auto* profile : profiles) {
ASSERT_EQ(profile->guid() == valid_profile.guid(),
profile->IsValidByClient());
ASSERT_TRUE(profile->IsValidByServer());
}
ASSERT_EQ(1U, email_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
email_suggestions[0].value);
std::vector<Suggestion> name_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
base::string16(), false,
std::vector<ServerFieldType>());
ASSERT_EQ(2U, name_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
// Set the validity state of ADDRESS_HOME_STATE to INVALID on the prefs.
{
ProfileValidityMap profile_validity_map;
UserProfileValidityMap user_profile_validity_map;
std::string autofill_profile_validity;
personal_data_->pref_service_->SetString(prefs::kAutofillProfileValidity,
autofill_profile_validity);
(*profile_validity_map
.mutable_field_validity_states())[static_cast<int>(EMAIL_ADDRESS)] =
static_cast<int>(AutofillProfile::INVALID);
(*user_profile_validity_map
.mutable_profile_validity())[invalid_profile.guid()] =
profile_validity_map;
ASSERT_TRUE(user_profile_validity_map.SerializeToString(
&autofill_profile_validity));
base::Base64Encode(autofill_profile_validity, &autofill_profile_validity);
personal_data_->pref_service_->SetString(prefs::kAutofillProfileValidity,
autofill_profile_validity);
}
// Invalid based on client, and server. Relying on both validity sources.
{
base::test::ScopedFeatureList scoped_features;
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileClientValidation,
features::kAutofillProfileServerValidation},
/*disabled_features=*/{});
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
base::string16(), false,
std::vector<ServerFieldType>());
for (auto* profile : profiles) {
ASSERT_EQ(profile->guid() == valid_profile.guid(),
profile->IsValidByClient());
ASSERT_EQ(profile->guid() == valid_profile.guid(),
profile->IsValidByServer());
}
ASSERT_EQ(1U, email_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
email_suggestions[0].value);
std::vector<Suggestion> name_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
base::string16(), false,
std::vector<ServerFieldType>());
ASSERT_EQ(2U, name_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
// Invalid based on client, and server. Relying only on the client source.
{
base::test::ScopedFeatureList scoped_features;
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileClientValidation},
/*disabled_features=*/{features::kAutofillProfileServerValidation});
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
base::string16(), false,
std::vector<ServerFieldType>());
for (auto* profile : profiles) {
ASSERT_EQ(profile->guid() == valid_profile.guid(),
profile->IsValidByClient());
ASSERT_EQ(profile->guid() == valid_profile.guid(),
profile->IsValidByServer());
}
ASSERT_EQ(1U, email_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
email_suggestions[0].value);
std::vector<Suggestion> name_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
base::string16(), false,
std::vector<ServerFieldType>());
ASSERT_EQ(2U, name_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
// Invalid based on client, and server. Relying on server as a validity
// source.
{
base::test::ScopedFeatureList scoped_features;
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileServerValidation},
/*disabled_features=*/{features::kAutofillProfileClientValidation});
LOG(ERROR) << __FUNCTION__;
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
base::string16(), false,
std::vector<ServerFieldType>());
for (auto* profile : profiles) {
ASSERT_EQ(profile->guid() == valid_profile.guid(),
profile->IsValidByClient());
ASSERT_EQ(profile->guid() == valid_profile.guid(),
profile->IsValidByServer());
}
ASSERT_EQ(1U, email_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
email_suggestions[0].value);
std::vector<Suggestion> name_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
base::string16(), false,
std::vector<ServerFieldType>());
ASSERT_EQ(2U, name_suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
}
// Test that local and server profiles are not shown if
// |kAutofillProfileEnabled| is set to |false|.
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ProfileAutofillDisabled) {
///////////////////////////////////////////////////////////////////////
// Setup.
///////////////////////////////////////////////////////////////////////
const std::string kServerAddressId("server_address1");
ASSERT_TRUE(TurnOnSyncFeature());
// Add two different profiles, a local and a server one.
AutofillProfile local_profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
"Orlando", "FL", "32801", "US", "19482937549");
AddProfileToPersonalDataManager(local_profile);
// Add a different server profile.
std::vector<AutofillProfile> server_profiles;
server_profiles.push_back(
AutofillProfile(AutofillProfile::SERVER_PROFILE, kServerAddressId));
test::SetProfileInfo(&server_profiles.back(), "John", "", "Doe", "",
"ACME Corp", "500 Oak View", "Apt 8", "Houston", "TX",
"77401", "US", "");
// Wallet only provides a full name, so the above first and last names
// will be ignored when the profile is written to the DB.
server_profiles.back().SetRawInfo(NAME_FULL, base::ASCIIToUTF16("John Doe"));
SetServerProfiles(server_profiles);
// Disable Profile autofill.
prefs::SetProfileAutofillEnabled(personal_data_->pref_service_, false);
WaitForOnPersonalDataChanged();
ConvertWalletAddressesAndUpdateWalletCards();
// Check that profiles were saved.
EXPECT_EQ(2U, personal_data_->GetProfiles().size());
// Expect no autofilled values or suggestions.
EXPECT_EQ(0U, personal_data_->GetProfilesToSuggest().size());
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("123"),
false, std::vector<ServerFieldType>());
ASSERT_EQ(0U, suggestions.size());
}
// Test that local and server profiles are not loaded into memory on start-up if
// |kAutofillProfileEnabled| is set to |false|.
TEST_F(PersonalDataManagerTest,
GetProfileSuggestions_NoProfilesLoadedIfDisabled) {
///////////////////////////////////////////////////////////////////////
// Setup.
///////////////////////////////////////////////////////////////////////
const std::string kServerAddressId("server_address1");
ASSERT_TRUE(TurnOnSyncFeature());
// Add two different profiles, a local and a server one.
AutofillProfile local_profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
"Orlando", "FL", "32801", "US", "19482937549");
AddProfileToPersonalDataManager(local_profile);
// Add a different server profile.
std::vector<AutofillProfile> server_profiles;
server_profiles.push_back(
AutofillProfile(AutofillProfile::SERVER_PROFILE, kServerAddressId));
test::SetProfileInfo(&server_profiles.back(), "John", "", "Doe", "",
"ACME Corp", "500 Oak View", "Apt 8", "Houston", "TX",
"77401", "US", "");
// Wallet only provides a full name, so the above first and last names
// will be ignored when the profile is written to the DB.
server_profiles.back().SetRawInfo(NAME_FULL, base::ASCIIToUTF16("John Doe"));
SetServerProfiles(server_profiles);
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
ConvertWalletAddressesAndUpdateWalletCards();
// Expect 2 autofilled values or suggestions.
EXPECT_EQ(2U, personal_data_->GetProfiles().size());
EXPECT_EQ(2U, personal_data_->GetProfilesToSuggest().size());
// Disable Profile autofill.
prefs::SetProfileAutofillEnabled(personal_data_->pref_service_, false);
// Reload the database.
ResetPersonalDataManager(USER_MODE_NORMAL);
// Expect no profile values or suggestions were loaded.
EXPECT_EQ(0U, personal_data_->GetProfilesToSuggest().size());
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("123"),
false, std::vector<ServerFieldType>());
ASSERT_EQ(0U, suggestions.size());
}
// Test that local profiles are not added if |kAutofillProfileEnabled| is set to
// |false|.
TEST_F(PersonalDataManagerTest,
GetProfileSuggestions_NoProfilesAddedIfDisabled) {
// Disable Profile autofill.
prefs::SetProfileAutofillEnabled(personal_data_->pref_service_, false);
// Add a local profile.
AutofillProfile local_profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz",
"joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
"Orlando", "FL", "32801", "US", "19482937549");
AddProfileToPersonalDataManager(local_profile);
// Expect no profile values or suggestions were added.
EXPECT_EQ(0U, personal_data_->GetProfiles().size());
}
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForContactForm) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
"401 Merrimack St", "", "Lowell", "MA", "01852", "US",
"19786744120");
AddProfileToPersonalDataManager(profile);
base::test::ScopedFeatureList scoped_features;
scoped_features.InitAndEnableFeature(
features::kAutofillUseImprovedLabelDisambiguation);
EXPECT_THAT(
personal_data_->GetProfileSuggestions(
AutofillType(NAME_FIRST), base::string16(), false,
std::vector<ServerFieldType>{NAME_FIRST, NAME_LAST, EMAIL_ADDRESS,
PHONE_HOME_WHOLE_NUMBER}),
ElementsAre(AllOf(
testing::Field(
&Suggestion::label,
ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
base::ASCIIToUTF16("hoa.pham@comcast.net")})),
testing::Field(
&Suggestion::additional_label,
ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
base::ASCIIToUTF16("hoa.pham@comcast.net")})),
testing::Field(&Suggestion::icon, "accountBoxIcon"))));
}
#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForAddressForm) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
"401 Merrimack St", "", "Lowell", "MA", "01852", "US",
"19786744120");
AddProfileToPersonalDataManager(profile);
base::test::ScopedFeatureList scoped_features;
scoped_features.InitAndEnableFeature(
features::kAutofillUseImprovedLabelDisambiguation);
EXPECT_THAT(personal_data_->GetProfileSuggestions(
AutofillType(NAME_FULL), base::string16(), false,
std::vector<ServerFieldType>{
NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, ADDRESS_HOME_CITY,
ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP}),
ElementsAre(AllOf(
testing::Field(
&Suggestion::label,
base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")),
testing::Field(
&Suggestion::additional_label,
base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")),
testing::Field(&Suggestion::icon, "accountBoxIcon"))));
}
#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForAddressPhoneForm) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
"401 Merrimack St", "", "Lowell", "MA", "01852", "US",
"19786744120");
AddProfileToPersonalDataManager(profile);
base::test::ScopedFeatureList scoped_features;
scoped_features.InitAndEnableFeature(
features::kAutofillUseImprovedLabelDisambiguation);
EXPECT_THAT(
personal_data_->GetProfileSuggestions(
AutofillType(NAME_FULL), base::string16(), false,
std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
PHONE_HOME_WHOLE_NUMBER}),
ElementsAre(AllOf(
testing::Field(
&Suggestion::label,
ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
base::ASCIIToUTF16("401 Merrimack St")})),
testing::Field(
&Suggestion::additional_label,
ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
base::ASCIIToUTF16("401 Merrimack St")})),
testing::Field(&Suggestion::icon, "accountBoxIcon"))));
}
#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForAddressEmailForm) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
"401 Merrimack St", "", "Lowell", "MA", "01852", "US",
"19786744120");
AddProfileToPersonalDataManager(profile);
base::test::ScopedFeatureList scoped_features;
scoped_features.InitAndEnableFeature(
features::kAutofillUseImprovedLabelDisambiguation);
EXPECT_THAT(
personal_data_->GetProfileSuggestions(
AutofillType(NAME_FULL), base::string16(), false,
std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
EMAIL_ADDRESS}),
ElementsAre(AllOf(
testing::Field(
&Suggestion::label,
ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St"),
base::ASCIIToUTF16("hoa.pham@comcast.net")})),
testing::Field(
&Suggestion::additional_label,
ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St"),
base::ASCIIToUTF16("hoa.pham@comcast.net")})),
testing::Field(&Suggestion::icon, "accountBoxIcon"))));
}
#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PersonalDataManagerTest, GetProfileSuggestions_FormWithOneProfile) {
AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
"401 Merrimack St", "", "Lowell", "MA", "01852", "US",
"19786744120");
AddProfileToPersonalDataManager(profile);
base::test::ScopedFeatureList scoped_features;
scoped_features.InitAndEnableFeature(
features::kAutofillUseImprovedLabelDisambiguation);
EXPECT_THAT(
personal_data_->GetProfileSuggestions(
AutofillType(NAME_FULL), base::string16(), false,
std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
EMAIL_ADDRESS, PHONE_HOME_WHOLE_NUMBER}),
ElementsAre(AllOf(
testing::Field(
&Suggestion::label,
ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St")})),
testing::Field(
&Suggestion::additional_label,
ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St")})),
testing::Field(&Suggestion::icon, "accountBoxIcon"))));
}
#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PersonalDataManagerTest,
GetProfileSuggestions_ForAddressContactFormWithProfiles) {
AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile1, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
"401 Merrimack St", "", "Lowell", "MA", "01852", "US",
"19786744120");
AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
test::SetProfileInfo(&profile2, "Hoa", "", "Pham", "hp@aol.com", "",
"216 Broadway St", "", "Lowell", "MA", "01854", "US",
"19784523366");
// The profiles' use dates and counts are set make this test deterministic.
// The suggestion created with data from profile1 should be ranked higher
// than profile2's associated suggestion. This ensures that profile1's
// suggestion is the first element in the collection returned by
// GetProfileSuggestions.
profile1.set_use_date(AutofillClock::Now());
profile1.set_use_count(10);
profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(10));
profile2.set_use