blob: 1a418413a4c94a10ff349245071d951dd97bdba7 [file] [log] [blame]
// Copyright (c) 2015 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 "base/command_line.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/secondary_account_helper.h"
#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/sync/test/integration/wallet_helper.h"
#include "chrome/browser/web_data_service_factory.h"
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/prefs/pref_service.h"
#include "components/sync/base/model_type.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/test/fake_server/fake_server.h"
#include "components/webdata/common/web_data_service_consumer.h"
#include "content/public/browser/notification_service.h"
#include "testing/gmock/include/gmock/gmock.h"
using autofill::AutofillProfile;
using autofill::CreditCard;
using autofill::data_util::TruncateUTF8;
using base::ASCIIToUTF16;
using wallet_helper::CreateDefaultSyncPaymentsCustomerData;
using wallet_helper::CreateDefaultSyncWalletAddress;
using wallet_helper::CreateDefaultSyncWalletCard;
using wallet_helper::CreateSyncWalletCard;
using wallet_helper::CreateSyncWalletAddress;
using wallet_helper::CreateSyncPaymentsCustomerData;
using wallet_helper::ExpectDefaultCreditCardValues;
using wallet_helper::ExpectDefaultProfileValues;
using wallet_helper::GetAccountWebDataService;
using wallet_helper::GetDefaultCreditCard;
using wallet_helper::GetPersonalDataManager;
using wallet_helper::GetProfileWebDataService;
using wallet_helper::kDefaultBillingAddressID;
using wallet_helper::kDefaultCardID;
using wallet_helper::kDefaultCustomerID;
namespace {
ACTION_P(QuitMessageLoop, loop) {
loop->Quit();
}
const char kLocalGuidA[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A";
const char kDifferentBillingAddressId[] = "another address entity ID";
template <class T>
class AutofillWebDataServiceConsumer : public WebDataServiceConsumer {
public:
AutofillWebDataServiceConsumer() {}
virtual ~AutofillWebDataServiceConsumer() {}
void OnWebDataServiceRequestDone(
WebDataServiceBase::Handle handle,
std::unique_ptr<WDTypedResult> result) override {
result_ = std::move(static_cast<WDResult<T>*>(result.get())->GetValue());
run_loop_.Quit();
}
void Wait() { run_loop_.Run(); }
T& result() { return result_; }
private:
base::RunLoop run_loop_;
T result_;
DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer);
};
class PersonalDataLoadedObserverMock
: public autofill::PersonalDataManagerObserver {
public:
PersonalDataLoadedObserverMock() {}
~PersonalDataLoadedObserverMock() override {}
MOCK_METHOD0(OnPersonalDataChanged, void());
};
class WaitForNextWalletUpdateChecker : public StatusChangeChecker,
public syncer::SyncServiceObserver {
public:
explicit WaitForNextWalletUpdateChecker(
browser_sync::ProfileSyncService* service)
: service_(service),
initial_marker_(GetInitialMarker(service)),
scoped_observer_(this) {
scoped_observer_.Add(service);
}
bool IsExitConditionSatisfied() override {
// GetLastCycleSnapshot() returns by value, so make sure to capture it for
// iterator use.
const syncer::SyncCycleSnapshot snap = service_->GetLastCycleSnapshot();
const syncer::ProgressMarkerMap& progress_markers =
snap.download_progress_markers();
auto marker_it = progress_markers.find(syncer::AUTOFILL_WALLET_DATA);
if (marker_it == progress_markers.end()) {
return false;
}
return marker_it->second != initial_marker_;
}
std::string GetDebugMessage() const override {
return "Waiting for an updated Wallet progress marker.";
}
// syncer::SyncServiceObserver implementation.
void OnSyncCycleCompleted(syncer::SyncService* sync) override {
CheckExitCondition();
}
private:
static std::string GetInitialMarker(
const browser_sync::ProfileSyncService* service) {
// GetLastCycleSnapshot() returns by value, so make sure to capture it for
// iterator use.
const syncer::SyncCycleSnapshot snap = service->GetLastCycleSnapshot();
const syncer::ProgressMarkerMap& progress_markers =
snap.download_progress_markers();
auto marker_it = progress_markers.find(syncer::AUTOFILL_WALLET_DATA);
if (marker_it == progress_markers.end()) {
return "N/A";
}
return marker_it->second;
}
const browser_sync::ProfileSyncService* service_;
const std::string initial_marker_;
ScopedObserver<browser_sync::ProfileSyncService,
WaitForNextWalletUpdateChecker>
scoped_observer_;
};
std::vector<std::unique_ptr<CreditCard>> GetServerCards(
scoped_refptr<autofill::AutofillWebDataService> service) {
AutofillWebDataServiceConsumer<std::vector<std::unique_ptr<CreditCard>>>
consumer;
service->GetServerCreditCards(&consumer);
consumer.Wait();
return std::move(consumer.result());
}
std::vector<std::unique_ptr<AutofillProfile>> GetServerProfiles(
scoped_refptr<autofill::AutofillWebDataService> service) {
AutofillWebDataServiceConsumer<std::vector<std::unique_ptr<AutofillProfile>>>
consumer;
service->GetServerProfiles(&consumer);
consumer.Wait();
return std::move(consumer.result());
}
#if !defined(OS_CHROMEOS)
std::unique_ptr<autofill::PaymentsCustomerData> GetPaymentsCustomerData(
scoped_refptr<autofill::AutofillWebDataService> service) {
AutofillWebDataServiceConsumer<
std::unique_ptr<autofill::PaymentsCustomerData>>
consumer;
service->GetPaymentsCustomerData(&consumer);
consumer.Wait();
return std::move(consumer.result());
}
#endif
} // namespace
class SingleClientWalletSyncTest : public UssWalletSwitchToggler,
public SyncTest {
public:
SingleClientWalletSyncTest() : SyncTest(SINGLE_CLIENT) {}
~SingleClientWalletSyncTest() override {}
protected:
void RefreshAndWaitForOnPersonalDataChanged(
autofill::PersonalDataManager* pdm) {
WaitForOnPersonalDataChanged(/*should_trigger_refresh=*/true, pdm);
}
void WaitForOnPersonalDataChanged(bool should_trigger_refresh,
autofill::PersonalDataManager* pdm) {
pdm->AddObserver(&personal_data_observer_);
if (should_trigger_refresh) {
pdm->Refresh();
}
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.WillRepeatedly(QuitMessageLoop(&run_loop));
run_loop.Run();
pdm->RemoveObserver(&personal_data_observer_);
}
void WaitForNumberOfCards(autofill::PersonalDataManager* pdm,
size_t expected_count) {
while (pdm->GetCreditCards().size() != expected_count) {
WaitForOnPersonalDataChanged(/*should_trigger_refresh=*/false, pdm);
}
}
PersonalDataLoadedObserverMock personal_data_observer_;
private:
DISALLOW_COPY_AND_ASSIGN(SingleClientWalletSyncTest);
};
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest, EnabledByDefault) {
InitWithDefaultFeatures();
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(GetClient(0)->service()->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// TODO(pvalenzuela): Assert that the local root node for AUTOFILL_WALLET_DATA
// exists.
ASSERT_TRUE(GetClient(0)->service()->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_METADATA));
}
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest, DownloadProfileStorage) {
InitWithFeatures(/*enabled_features=*/{},
/*disabled_features=*/
{autofill::features::kAutofillEnableAccountWalletStorage});
GetFakeServer()->SetWalletData(
{CreateDefaultSyncWalletAddress(), CreateDefaultSyncWalletCard()});
ASSERT_TRUE(SetupSync());
auto profile_data = GetProfileWebDataService(0);
ASSERT_NE(nullptr, profile_data);
auto account_data = GetAccountWebDataService(0);
ASSERT_EQ(nullptr, account_data);
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
std::vector<CreditCard*> cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
std::vector<AutofillProfile*> profiles = pdm->GetServerProfiles();
ASSERT_EQ(1uL, profiles.size());
// Check that the data was set correctly.
ExpectDefaultCreditCardValues(*cards[0]);
ExpectDefaultProfileValues(*profiles[0]);
// Check that the data is stored in the profile storage.
EXPECT_EQ(1U, GetServerCards(GetProfileWebDataService(0)).size());
EXPECT_EQ(1U, GetServerProfiles(GetProfileWebDataService(0)).size());
}
// ChromeOS does not support late signin after profile creation, so the test
// below does not apply, at least in the current form.
#if !defined(OS_CHROMEOS)
// The account storage requires USS, so we only test the USS implementation
// here.
IN_PROC_BROWSER_TEST_F(SingleClientWalletSyncTest,
DownloadAccountStorage_Card) {
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{switches::kSyncStandaloneTransport,
switches::kSyncUSSAutofillWalletData,
autofill::features::
kAutofillEnableAccountWalletStorage},
/*disabled_features=*/{});
ASSERT_TRUE(SetupClients());
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
pdm->OnSyncServiceInitialized(GetSyncService(0));
GetFakeServer()->SetWalletData(
{CreateDefaultSyncWalletAddress(), CreateDefaultSyncWalletCard()});
ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount());
ASSERT_TRUE(GetClient(0)->AwaitEngineInitialization(
/*skip_passphrase_verification=*/false));
ASSERT_TRUE(AwaitQuiescence());
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
auto profile_data = GetProfileWebDataService(0);
ASSERT_NE(nullptr, profile_data);
auto account_data = GetAccountWebDataService(0);
ASSERT_NE(nullptr, account_data);
// Check that no data is stored in the profile storage.
EXPECT_EQ(0U, GetServerCards(profile_data).size());
EXPECT_EQ(0U, GetServerProfiles(profile_data).size());
// Check that one card is stored in the account storage.
EXPECT_EQ(1U, GetServerCards(account_data).size());
ASSERT_NE(nullptr, pdm);
std::vector<CreditCard*> cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
ExpectDefaultCreditCardValues(*cards[0]);
// Now sign back out.
GetClient(0)->SignOutPrimaryAccount();
// Verify that sync is stopped.
ASSERT_EQ(syncer::SyncService::TransportState::DISABLED,
GetSyncService(0)->GetTransportState());
ASSERT_FALSE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// Wait for PDM to receive the data change.
WaitForOnPersonalDataChanged(/*should_trigger_refresh=*/false, pdm);
// Check that the account storage is now cleared.
EXPECT_EQ(0U, GetServerCards(account_data).size());
cards = pdm->GetCreditCards();
EXPECT_EQ(0U, cards.size());
}
#endif // !defined(OS_CHROMEOS)
// Wallet data should get cleared from the database when sync is disabled.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest, ClearOnDisableSync) {
InitWithDefaultFeatures();
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletAddress(),
CreateDefaultSyncWalletCard(),
CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// Make sure the data is in the DB.
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
EXPECT_EQ(1uL, pdm->GetCreditCards().size());
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Turn off sync, the data should be gone.
GetSyncService(0)->RequestStop(syncer::SyncService::CLEAR_DATA);
WaitForNumberOfCards(pdm, 0);
EXPECT_EQ(0uL, pdm->GetCreditCards().size());
EXPECT_EQ(nullptr, pdm->GetPaymentsCustomerData());
// Turn sync on again, the data should come back.
GetSyncService(0)->RequestStart();
// RequestStop(CLEAR_DATA) also clears the "first setup complete" flag, so
// set it again.
GetSyncService(0)->SetFirstSetupComplete();
// Wait until Sync restores the card and it arrives at PDM.
WaitForNumberOfCards(pdm, 1);
EXPECT_EQ(1uL, pdm->GetCreditCards().size());
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
}
// Wallet data should get cleared from the database when sync is (temporarily)
// stopped, e.g. due to the Sync feature toggle in Android settings.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest, ClearOnStopSync) {
InitWithDefaultFeatures();
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletAddress(),
CreateDefaultSyncWalletCard(),
CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// Make sure the data is in the DB.
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
EXPECT_EQ(1uL, pdm->GetCreditCards().size());
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Turn off sync, the card should be gone.
GetSyncService(0)->RequestStop(syncer::SyncService::KEEP_DATA);
WaitForNumberOfCards(pdm, 0);
EXPECT_EQ(0uL, pdm->GetCreditCards().size());
EXPECT_EQ(nullptr, pdm->GetPaymentsCustomerData());
// Turn sync on again, the data should come back.
GetSyncService(0)->RequestStart();
// Wait until Sync restores the card and it arrives at PDM.
WaitForNumberOfCards(pdm, 1);
EXPECT_EQ(1uL, pdm->GetCreditCards().size());
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
}
// ChromeOS does not sign out, so the test below does not apply.
#if !defined(OS_CHROMEOS)
// Wallet data should get cleared from the database when the user signs out.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest, ClearOnSignOut) {
InitWithDefaultFeatures();
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletAddress(),
CreateDefaultSyncWalletCard(),
CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// Make sure the data is in the DB.
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
EXPECT_EQ(1uL, pdm->GetCreditCards().size());
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Turn off sync, the data should be gone.
GetClient(0)->SignOutPrimaryAccount();
WaitForNumberOfCards(pdm, 0);
EXPECT_EQ(0uL, pdm->GetCreditCards().size());
EXPECT_EQ(nullptr, pdm->GetPaymentsCustomerData());
}
#endif // !defined(OS_CHROMEOS)
// Wallet is not using incremental updates. Make sure existing data gets
// replaced when synced down.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest,
NewSyncDataShouldReplaceExistingData) {
InitWithDefaultFeatures();
GetFakeServer()->SetWalletData(
{CreateSyncWalletCard(/*name=*/"card-1", /*last_four=*/"0001"),
CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"),
CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// Make sure the data is in the DB.
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
std::vector<CreditCard*> cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(ASCIIToUTF16("0001"), cards[0]->LastFourDigits());
std::vector<AutofillProfile*> profiles = pdm->GetServerProfiles();
ASSERT_EQ(1uL, profiles.size());
EXPECT_EQ("Company-1", TruncateUTF8(base::UTF16ToUTF8(
profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Put some completely new data in the sync server.
GetFakeServer()->SetWalletData(
{CreateSyncWalletCard(/*name=*/"new-card", /*last_four=*/"0002"),
CreateSyncWalletAddress(/*name=*/"new-address", /*company=*/"Company-2"),
CreateSyncPaymentsCustomerData(/*customer_id=*/"newid")});
// Constructing the checker captures the current progress marker. Make sure to
// do that before triggering the fetch.
WaitForNextWalletUpdateChecker checker(GetSyncService(0));
// Trigger a sync and wait for the new data to arrive.
TriggerSyncForModelTypes(0,
syncer::ModelTypeSet(syncer::AUTOFILL_WALLET_DATA));
ASSERT_TRUE(checker.Wait());
// Make sure only the new data is present.
cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(ASCIIToUTF16("0002"), cards[0]->LastFourDigits());
profiles = pdm->GetServerProfiles();
ASSERT_EQ(1uL, profiles.size());
EXPECT_EQ("Company-2", TruncateUTF8(base::UTF16ToUTF8(
profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
EXPECT_EQ("newid", pdm->GetPaymentsCustomerData()->customer_id);
}
// Wallet is not using incremental updates. The server either sends a non-empty
// update with deletion gc directives and with the (possibly empty) full data
// set, or (more often) an empty update.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest, EmptyUpdatesAreIgnored) {
InitWithDefaultFeatures();
GetFakeServer()->SetWalletData(
{CreateSyncWalletCard(/*name=*/"card-1", /*last_four=*/"0001"),
CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"),
CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// Make sure the card is in the DB.
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
std::vector<CreditCard*> cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(ASCIIToUTF16("0001"), cards[0]->LastFourDigits());
std::vector<AutofillProfile*> profiles = pdm->GetServerProfiles();
ASSERT_EQ(1uL, profiles.size());
EXPECT_EQ("Company-1", TruncateUTF8(base::UTF16ToUTF8(
profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Do not change anything on the server so that the update forced below is an
// empty one.
// Constructing the checker captures the current progress marker. Make sure to
// do that before triggering the fetch.
WaitForNextWalletUpdateChecker checker(GetSyncService(0));
// Trigger a sync and wait for the new data to arrive.
TriggerSyncForModelTypes(0,
syncer::ModelTypeSet(syncer::AUTOFILL_WALLET_DATA));
ASSERT_TRUE(checker.Wait());
// Refresh the pdm so that it gets cards from autofill table.
RefreshAndWaitForOnPersonalDataChanged(pdm);
// Make sure the same data is present on the client.
cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(ASCIIToUTF16("0001"), cards[0]->LastFourDigits());
profiles = pdm->GetServerProfiles();
ASSERT_EQ(1uL, profiles.size());
EXPECT_EQ("Company-1", TruncateUTF8(base::UTF16ToUTF8(
profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
}
// Wallet data should get cleared from the database when the wallet sync type
// flag is disabled.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest, ClearOnDisableWalletSync) {
InitWithDefaultFeatures();
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletAddress(),
CreateDefaultSyncWalletCard(),
CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// Make sure the data is in the DB.
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
EXPECT_EQ(1uL, pdm->GetCreditCards().size());
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Turn off autofill sync, the data should be gone.
ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::AUTOFILL));
WaitForOnPersonalDataChanged(/*should_trigger_refresh=*/false, pdm);
EXPECT_EQ(0uL, pdm->GetCreditCards().size());
EXPECT_EQ(nullptr, pdm->GetPaymentsCustomerData());
}
// Wallet data should get cleared from the database when the wallet autofill
// integration flag is disabled.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest,
ClearOnDisableWalletAutofill) {
InitWithDefaultFeatures();
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletAddress(),
CreateDefaultSyncWalletCard(),
CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// Make sure the card and PaymentsCustomerData are in the DB.
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
EXPECT_EQ(1uL, pdm->GetCreditCards().size());
// Turn off the wallet autofill pref, the card should be gone as a side
// effect of the wallet data type controller noticing.
autofill::prefs::SetPaymentsIntegrationEnabled(GetProfile(0)->GetPrefs(),
false);
EXPECT_EQ(0uL, pdm->GetCreditCards().size());
}
// Wallet data present on the client should be cleared in favor of the new data
// synced down form the server.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest,
NewWalletCardRemovesExistingCardAndProfile) {
InitWithDefaultFeatures();
ASSERT_TRUE(SetupClients());
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
// Add a server credit card on the client.
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
std::vector<CreditCard> credit_cards = {credit_card};
wallet_helper::SetServerCreditCards(0, credit_cards);
// Add a server profile on the client.
AutofillProfile profile(AutofillProfile::SERVER_PROFILE, "a123");
profile.SetRawInfo(autofill::COMPANY_NAME, ASCIIToUTF16("JustATest"));
std::vector<AutofillProfile> client_profiles = {profile};
wallet_helper::SetServerProfiles(0, client_profiles);
// Add PaymentsCustomerData on the client.
wallet_helper::SetPaymentsCustomerData(
0, autofill::PaymentsCustomerData(/*customer_id=*/kDefaultCustomerID));
// Refresh the pdm so that it gets data from autofill table.
RefreshAndWaitForOnPersonalDataChanged(pdm);
// Make sure the card was added correctly.
std::vector<CreditCard*> cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ("a123", cards[0]->server_id());
// Make sure the profile was added correctly.
std::vector<AutofillProfile*> profiles = pdm->GetServerProfiles();
ASSERT_EQ(1uL, profiles.size());
EXPECT_EQ("JustATest", TruncateUTF8(base::UTF16ToUTF8(
profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
// Make sure the customer data was added correctly.
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Add a new card from the server and sync it down.
GetFakeServer()->SetWalletData(
{CreateDefaultSyncWalletCard(), CreateDefaultSyncPaymentsCustomerData()});
ASSERT_TRUE(SetupSync());
// The only card present on the client should be the one from the server.
cards = pdm->GetCreditCards();
EXPECT_EQ(1uL, cards.size());
EXPECT_EQ(kDefaultCardID, cards[0]->server_id());
// There should be no profile present.
profiles = pdm->GetServerProfiles();
EXPECT_EQ(0uL, profiles.size());
// The PaymentsCustomerData should still be there.
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
}
// Wallet data present on the client should be cleared in favor of the new data
// synced down form the server.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest,
NewWalletDataRemovesExistingData) {
InitWithDefaultFeatures();
ASSERT_TRUE(SetupClients());
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
// Add a server profile on the client.
AutofillProfile profile(AutofillProfile::SERVER_PROFILE, "a123");
profile.SetRawInfo(autofill::COMPANY_NAME, ASCIIToUTF16("JustATest"));
std::vector<AutofillProfile> client_profiles = {profile};
wallet_helper::SetServerProfiles(0, client_profiles);
// Add a server credit card on the client.
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
std::vector<CreditCard> credit_cards = {credit_card};
wallet_helper::SetServerCreditCards(0, credit_cards);
// Add PaymentsCustomerData on the client.
wallet_helper::SetPaymentsCustomerData(
0, autofill::PaymentsCustomerData(/*customer_id=*/kDefaultCustomerID));
// Refresh the pdm so that it gets cards from autofill table.
RefreshAndWaitForOnPersonalDataChanged(pdm);
// Make sure the profile was added correctly.
std::vector<AutofillProfile*> profiles = pdm->GetServerProfiles();
EXPECT_EQ(1uL, profiles.size());
EXPECT_EQ("JustATest", TruncateUTF8(base::UTF16ToUTF8(
profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
// Make sure the card was added correctly.
std::vector<CreditCard*> cards = pdm->GetCreditCards();
EXPECT_EQ(1uL, cards.size());
EXPECT_EQ("a123", cards[0]->server_id());
// Make sure the customer data was added correctly.
EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
// Add a new profile and new customer data from the server and sync them down.
GetFakeServer()->SetWalletData(
{CreateDefaultSyncWalletAddress(),
CreateSyncPaymentsCustomerData(/*customer_id=*/"newid")});
ASSERT_TRUE(SetupSync());
// The only profile present on the client should be the one from the server.
profiles = pdm->GetServerProfiles();
EXPECT_EQ(1uL, profiles.size());
EXPECT_NE("JustATest", TruncateUTF8(base::UTF16ToUTF8(
profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
// There should be no cards present.
cards = pdm->GetCreditCards();
EXPECT_EQ(0uL, cards.size());
// Payments customer data should be updated.
EXPECT_EQ("newid", pdm->GetPaymentsCustomerData()->customer_id);
}
// Tests that a local billing address id set on a card on the client should not
// be overwritten when that same card is synced again.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest,
SameWalletCard_PreservesLocalBillingAddressId) {
InitWithDefaultFeatures();
ASSERT_TRUE(SetupClients());
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
// Add a server credit card on the client but with the billing address id of a
// local profile.
CreditCard credit_card = GetDefaultCreditCard();
credit_card.set_billing_address_id(kLocalGuidA);
std::vector<CreditCard> credit_cards = {credit_card};
wallet_helper::SetServerCreditCards(0, credit_cards);
// Refresh the pdm so that it gets cards from autofill table.
RefreshAndWaitForOnPersonalDataChanged(pdm);
// Make sure the card was added correctly.
std::vector<CreditCard*> cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(kDefaultCardID, cards[0]->server_id());
// Sync the same card from the server, except with a default billing address
// id.
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletCard()});
ASSERT_TRUE(SetupSync());
// The billing address is should still refer to the local profile.
cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(kDefaultCardID, cards[0]->server_id());
EXPECT_EQ(kLocalGuidA, cards[0]->billing_address_id());
}
// Tests that a server billing address id set on a card on the client is
// overwritten when that same card is synced again.
IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTest,
SameWalletCard_DiscardsOldServerBillingAddressId) {
InitWithDefaultFeatures();
ASSERT_TRUE(SetupClients());
autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
ASSERT_NE(nullptr, pdm);
// Add a server credit card on the client but with the billing address id of a
// server profile.
CreditCard credit_card = GetDefaultCreditCard();
credit_card.set_billing_address_id(kDifferentBillingAddressId);
std::vector<CreditCard> credit_cards = {credit_card};
wallet_helper::SetServerCreditCards(0, credit_cards);
// Refresh the pdm so that it gets cards from autofill table.
RefreshAndWaitForOnPersonalDataChanged(pdm);
// Make sure the card was added correctly.
std::vector<CreditCard*> cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(kDefaultCardID, cards[0]->server_id());
// Sync the same card from the server, except with a default billing address
// id.
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletCard()});
ASSERT_TRUE(SetupSync());
// The billing address should be the one from the server card.
cards = pdm->GetCreditCards();
ASSERT_EQ(1uL, cards.size());
EXPECT_EQ(kDefaultCardID, cards[0]->server_id());
EXPECT_EQ(kDefaultBillingAddressID, cards[0]->billing_address_id());
}
class SingleClientWalletSecondaryAccountSyncTest
: public SingleClientWalletSyncTest {
public:
SingleClientWalletSecondaryAccountSyncTest() {
features_.InitWithFeatures(
/*enabled_features=*/{switches::kSyncStandaloneTransport,
switches::kSyncSupportSecondaryAccount,
switches::kSyncUSSAutofillWalletData,
autofill::features::
kAutofillEnableAccountWalletStorage},
/*disabled_features=*/{});
}
~SingleClientWalletSecondaryAccountSyncTest() override {}
void SetUpInProcessBrowserTestFixture() override {
fake_gaia_cookie_manager_factory_ =
secondary_account_helper::SetUpFakeGaiaCookieManagerService();
}
void SetUpOnMainThread() override {
#if defined(OS_CHROMEOS)
secondary_account_helper::InitNetwork();
#endif // defined(OS_CHROMEOS)
}
Profile* profile() { return GetProfile(0); }
private:
base::test::ScopedFeatureList features_;
secondary_account_helper::ScopedFakeGaiaCookieManagerServiceFactory
fake_gaia_cookie_manager_factory_;
DISALLOW_COPY_AND_ASSIGN(SingleClientWalletSecondaryAccountSyncTest);
};
// ChromeOS doesn't support changes to the primary account after startup, so
// these secondary-account-related tests don't apply.
#if !defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(SingleClientWalletSecondaryAccountSyncTest,
SwitchesFromAccountToProfileStorageOnSyncOptIn) {
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
GetPersonalDataManager(0)->OnSyncServiceInitialized(GetSyncService(0));
GetFakeServer()->SetWalletData(
{CreateDefaultSyncWalletCard(), CreateDefaultSyncPaymentsCustomerData()});
// Set up Sync in transport mode for a non-primary account.
secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should use (ephemeral) account storage.
EXPECT_FALSE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_TRUE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
auto account_data = GetAccountWebDataService(0);
ASSERT_NE(nullptr, account_data);
auto profile_data = GetProfileWebDataService(0);
ASSERT_NE(nullptr, profile_data);
// Check that the data is stored in the account storage (ephemeral), but not
// in the profile storage (persisted).
EXPECT_EQ(1U, GetServerCards(account_data).size());
EXPECT_EQ(0U, GetServerCards(profile_data).size());
EXPECT_NE(nullptr, GetPaymentsCustomerData(account_data).get());
EXPECT_EQ(nullptr, GetPaymentsCustomerData(profile_data).get());
// Simulate the user opting in to full Sync: Make the account primary, and
// set first-time setup to complete.
secondary_account_helper::MakeAccountPrimary(profile(), "user@email.com");
GetSyncService(0)->SetFirstSetupComplete();
// Wait for Sync to get reconfigured into feature mode.
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should have switched to persistent storage.
EXPECT_TRUE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_FALSE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
// The data should now be in the profile storage (persisted).
EXPECT_EQ(0U, GetServerCards(account_data).size());
EXPECT_EQ(1U, GetServerCards(profile_data).size());
EXPECT_EQ(nullptr, GetPaymentsCustomerData(account_data).get());
EXPECT_NE(nullptr, GetPaymentsCustomerData(profile_data).get());
}
IN_PROC_BROWSER_TEST_F(
SingleClientWalletSecondaryAccountSyncTest,
SwitchesFromAccountToProfileStorageOnSyncOptInWithAdvancedSetup) {
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
GetPersonalDataManager(0)->OnSyncServiceInitialized(GetSyncService(0));
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletCard()});
// Set up Sync in transport mode for a non-primary account.
secondary_account_helper::SignInSecondaryAccount(profile(), "user@email.com");
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should use (ephemeral) account storage.
EXPECT_FALSE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_TRUE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
auto account_data = GetAccountWebDataService(0);
ASSERT_NE(nullptr, account_data);
auto profile_data = GetProfileWebDataService(0);
ASSERT_NE(nullptr, profile_data);
// Check that the card is stored in the account storage (ephemeral), but not
// in the profile storage (persisted).
EXPECT_EQ(1U, GetServerCards(account_data).size());
EXPECT_EQ(0U, GetServerCards(profile_data).size());
// Simulate the user opting in to full Sync: First, make the account primary.
secondary_account_helper::MakeAccountPrimary(profile(), "user@email.com");
// Now start actually configuring Sync.
auto setup_handle = GetSyncService(0)->GetSetupInProgressHandle();
// Adding a primary account triggers a restart of the Sync engine, so it
// should now be initializing again.
ASSERT_EQ(syncer::SyncService::TransportState::INITIALIZING,
GetSyncService(0)->GetTransportState());
ASSERT_TRUE(GetClient(0)->AwaitEngineInitialization(
/*skip_passphrase_verification=*/false));
// Since we're still holding on to the setup-in-progress handle, the data
// types can't be configured yet.
ASSERT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
GetSyncService(0)->GetTransportState());
GetSyncService(0)->OnUserChoseDatatypes(
/*sync_everything=*/false, syncer::ModelTypeSet(syncer::AUTOFILL));
// Once the user finishes the setup, we can actually configure.
setup_handle.reset();
ASSERT_EQ(syncer::SyncService::TransportState::CONFIGURING,
GetSyncService(0)->GetTransportState());
GetSyncService(0)->SetFirstSetupComplete();
// Wait for Sync to get reconfigured into feature mode.
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should have switched to persistent storage.
EXPECT_TRUE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_FALSE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
// The card should now be in the profile storage (persisted).
EXPECT_EQ(0U, GetServerCards(account_data).size());
EXPECT_EQ(1U, GetServerCards(profile_data).size());
}
#endif // !defined(OS_CHROMEOS)
// This tests that switching between Sync-the-feature and
// Sync-standalone-transport properly migrates server credit cards between the
// profile (i.e. persisted) and account (i.e. ephemeral) storage.
// When turning off Sync-the-feature via SyncService::RequestStop, you can
// specify either KEEP_DATA or CLEAR_DATA. For full coverage, we test all
// transitions, and each time verify that the card is in the correct storage:
// 1. Start out in Sync-the-feature mode -> profile storage.
// 2. RequestStop(KEEP_DATA) -> account storage.
// 3. Enable Sync-the-feature again -> profile storage.
// 4. RequestStop(CLEAR_DATA) -> account storage.
// 5. Enable Sync-the-feature again -> profile storage.
IN_PROC_BROWSER_TEST_F(SingleClientWalletSyncTest,
SwitchesBetweenAccountAndProfileStorageOnTogglingSync) {
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{switches::kSyncStandaloneTransport,
switches::kSyncUSSAutofillWalletData,
autofill::features::
kAutofillEnableAccountWalletStorage},
/*disabled_features=*/{});
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
GetPersonalDataManager(0)->OnSyncServiceInitialized(GetSyncService(0));
GetFakeServer()->SetWalletData({CreateDefaultSyncWalletCard()});
// STEP 1. Set up Sync in full feature mode.
ASSERT_TRUE(GetClient(0)->SetupSync());
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should use the regular persisted (non-account) storage.
EXPECT_TRUE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_FALSE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
auto account_data = GetAccountWebDataService(0);
ASSERT_NE(nullptr, account_data);
auto profile_data = GetProfileWebDataService(0);
ASSERT_NE(nullptr, profile_data);
// Check that the card is stored in the profile storage (persisted), but not
// in the account storage (ephemeral).
EXPECT_EQ(0U, GetServerCards(account_data).size());
EXPECT_EQ(1U, GetServerCards(profile_data).size());
// STEP 2. Turn off Sync-the-feature temporarily (e.g. the Sync feature toggle
// on Android), i.e. leave the Sync data around.
GetSyncService(0)->RequestStop(syncer::SyncService::KEEP_DATA);
// Wait for Sync to get reconfigured into transport mode.
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should have switched to ephemeral storage.
EXPECT_FALSE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_TRUE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
// The card should now be in the account storage (ephemeral). Note that even
// though we specified KEEP_DATA above, the card is *not* in the profile
// storage (persisted) anymore, because AUTOFILL_WALLET_DATA is special-cased
// to always clear its data when Sync is turned off.
EXPECT_EQ(1U, GetServerCards(account_data).size());
EXPECT_EQ(0U, GetServerCards(profile_data).size());
// STEP 3. Turn Sync-the-feature on again.
GetSyncService(0)->RequestStart();
// Wait for Sync to get reconfigured into full feature mode again.
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should have switched back to persistent storage.
EXPECT_TRUE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_FALSE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
// And the card should be in the profile i.e. persistent storage again.
EXPECT_EQ(0U, GetServerCards(account_data).size());
EXPECT_EQ(1U, GetServerCards(profile_data).size());
// STEP 4. Turn off Sync-the-feature again, but this time clear data.
GetSyncService(0)->RequestStop(syncer::SyncService::CLEAR_DATA);
// Wait for Sync to get reconfigured into transport mode.
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should have switched to ephemeral storage.
EXPECT_FALSE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_TRUE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
// The card should now be in the account storage (ephemeral).
EXPECT_EQ(1U, GetServerCards(account_data).size());
EXPECT_EQ(0U, GetServerCards(profile_data).size());
// STEP 5. Turn Sync-the-feature on again.
GetSyncService(0)->RequestStart();
GetSyncService(0)->SetFirstSetupComplete();
// Wait for Sync to get reconfigured into full feature mode again.
ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
/*skip_passphrase_verification=*/false));
ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
GetSyncService(0)->GetTransportState());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled());
ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());
ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(
syncer::AUTOFILL_WALLET_DATA));
// PersonalDataManager should have switched back to persistent storage.
EXPECT_TRUE(GetPersonalDataManager(0)->IsSyncFeatureEnabled());
EXPECT_FALSE(
GetPersonalDataManager(0)->IsUsingAccountStorageForServerDataForTest());
// And the card should be in the profile i.e. persistent storage again.
EXPECT_EQ(0U, GetServerCards(account_data).size());
EXPECT_EQ(1U, GetServerCards(profile_data).size());
}
INSTANTIATE_TEST_CASE_P(USS,
SingleClientWalletSyncTest,
::testing::Values(false, true));