#include "components/autofill/core/browser/webdata/payments/autofill_wallet_sync_bridge.h"
#include <stddef.h>
#include <memory>
#include <string_view>
#include <utility>
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/data_model/autofill_profile.h"
#include "components/autofill/core/browser/data_model/bank_account.h"
#include "components/autofill/core/browser/data_model/credit_card.h"
#include "components/autofill/core/browser/data_model/credit_card_benefit.h"
#include "components/autofill/core/browser/data_model/credit_card_benefit_test_api.h"
#include "components/autofill/core/browser/data_model/credit_card_cloud_token_data.h"
#include "components/autofill/core/browser/data_model/payments_metadata.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/webdata/autofill_sync_metadata_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
#include "components/autofill/core/browser/webdata/payments/payments_autofill_table.h"
#include "components/autofill/core/browser/webdata/payments/payments_sync_bridge_test_util.h"
#include "components/autofill/core/browser/webdata/payments/payments_sync_bridge_util.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/os_crypt/sync/os_crypt_mocker.h"
#include "components/sync/base/client_tag_hash.h"
#include "components/sync/base/data_type.h"
#include "components/sync/engine/data_type_activation_response.h"
#include "components/sync/model/client_tag_based_data_type_processor.h"
#include "components/sync/model/in_memory_metadata_change_list.h"
#include "components/sync/model/sync_data.h"
#include "components/sync/protocol/autofill_specifics.pb.h"
#include "components/sync/protocol/data_type_progress_marker.pb.h"
#include "components/sync/protocol/data_type_state.pb.h"
#include "components/sync/protocol/entity_data.h"
#include "components/sync/protocol/entity_metadata.pb.h"
#include "components/sync/protocol/entity_specifics.pb.h"
#include "components/sync/test/mock_commit_queue.h"
#include "components/sync/test/mock_data_type_local_change_processor.h"
#include "components/sync/test/test_matchers.h"
#include "components/webdata/common/web_database.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace {
AutofillProfileChange;
CreditCardChange;
ScopedTempDir;
IbanChangeKey;
AutofillWalletSpecifics;
DataTypeState;
EntityMetadata;
DataBatch;
DataType;
EntityChange;
EntityData;
HasInitialSyncDone;
KeyAndData;
MockDataTypeLocalChangeProcessor;
NiceMock;
Pointee;
Return;
SizeIs;
UnorderedElementsAre;
const char kCustomerDataId[] = …;
const char kCustomerDataId2[] = …;
const char kCard1ClientTag[] = …;
const char kCustomerDataClientTag[] = …;
const char kCloudTokenDataClientTag[] = …;
const char kBankAccountClientTag[] = …;
const base::Time kJune2017 = …;
const char kDefaultCacheGuid[] = …;
void ExtractAutofillWalletSpecificsFromDataBatch(
std::unique_ptr<DataBatch> batch,
std::vector<AutofillWalletSpecifics>* output) { … }
std::string WalletMaskedCreditCardSpecificsAsDebugString(
const AutofillWalletSpecifics& specifics) { … }
std::string WalletCreditCardCloudTokenDataSpecificsAsDebugString(
const AutofillWalletSpecifics& specifics) { … }
std::string WalletBankAccountDetailsAsDebugString(
const sync_pb::BankAccountDetails& bank_account_details) { … }
std::string WalletPaymentInstrumentSupportedRailAsDebugString(
const sync_pb::PaymentInstrument payment_instrument) { … }
std::string WalletPaymentInstrumentAsDebugString(
const AutofillWalletSpecifics& specifics) { … }
std::string WalletMaskedIbanSpecificsAsDebugString(
const AutofillWalletSpecifics& specifics) { … }
std::string AutofillWalletSpecificsAsDebugString(
const AutofillWalletSpecifics& specifics) { … }
MATCHER_P(EqualsSpecifics, expected, "") { … }
MATCHER_P(RemoveChange, key, "") { … }
MATCHER_P2(AddChange, key, data, "") { … }
}
class AutofillWalletSyncBridgeTestBase { … };
class AutofillWalletSyncBridgeTest : public testing::Test,
public AutofillWalletSyncBridgeTestBase { … };
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForCard) { … }
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForCustomerData) { … }
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForCreditCardCloudTokenData) { … }
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForBankAccount) { … }
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForCard) { … }
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForCustomerData) { … }
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForCreditCardCloudTokenData) { … }
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForBankAccount) { … }
TEST_F(AutofillWalletSyncBridgeTest,
GetAllDataForDebugging_ShouldReturnAllData) { … }
TEST_F(AutofillWalletSyncBridgeTest,
GetAllDataForDebugging_MultipleCloudTokenDataForOneCard) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NewWalletCard) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_NewWalletCardNoMetricsInitialSync) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_NewWalletIbanNoMetadataInitialSync) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_NewPaymentsCustomerData) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NewCloudTokenData) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NoWalletCard) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NoWalletIban) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NoCloudTokenData) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_SameWalletCardAndCustomerDataAndCloudTokenData) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_AddRemoveAndPreserveWalletCard) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_SetsAllWalletCardData) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_SetsAllCloudTokenData) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_SetsNewMaskedIban) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_UpdateAndRemoveMaskedIban) { … }
TEST_F(AutofillWalletSyncBridgeTest, DeletesServerCvcWhenCardIsDeleted) { … }
TEST_F(AutofillWalletSyncBridgeTest, LoadMetadataCalled) { … }
TEST_F(AutofillWalletSyncBridgeTest, ApplyDisableSyncChanges_Cards) { … }
TEST_F(AutofillWalletSyncBridgeTest, ApplyDisableSyncChanges_Ibans) { … }
TEST_F(AutofillWalletSyncBridgeTest,
LargeInstrumentIdProvided_CorrectDataStored) { … }
TEST_F(AutofillWalletSyncBridgeTest, SetWalletCards_LogVirtualMetadataSynced) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_SetsNewCardBenefitWithTerms) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_SetsNewCardBenefitWithoutTerms) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NewCardBenefit) { … }
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NoCardBenefit) { … }
TEST_F(AutofillWalletSyncBridgeTest,
MergeFullSyncData_SameWalletCardAndCardBenefit) { … }
class AutofillWalletSyncBridgeTestWithBenefitSyncDisabled
: public testing::Test,
public AutofillWalletSyncBridgeTestBase { … };
TEST_F(AutofillWalletSyncBridgeTestWithBenefitSyncDisabled,
MergeFullSyncData_SetsNewCardBenefitWithTerms) { … }
TEST_F(AutofillWalletSyncBridgeTestWithBenefitSyncDisabled,
MergeFullSyncData_NewCardBenefit) { … }
TEST_F(AutofillWalletSyncBridgeTestWithBenefitSyncDisabled,
MergeFullSyncData_NoCardBenefit) { … }
TEST_F(AutofillWalletSyncBridgeTestWithBenefitSyncDisabled,
MergeFullSyncData_SameWalletCardAndCardBenefit) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(AutofillWalletSyncBridgeTest, ApplyDisableSyncChanges_BankAccount) {
base::test::ScopedFeatureList scoped_feature_list(
features::kAutofillEnableSyncingOfPixBankAccounts);
table()->SetMaskedBankAccounts(
{test::CreatePixBankAccount(1234)});
EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(),
NotifyOnAutofillChangedBySync(syncer::AUTOFILL_WALLET_DATA));
EXPECT_CALL(*backend(), NotifyOfIbanChanged).Times(0);
bridge()->ApplyDisableSyncChanges(
std::make_unique<syncer::InMemoryMetadataChangeList>());
EXPECT_TRUE(GetAllLocalData().empty());
}
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_SameBankAccountData) {
base::test::ScopedFeatureList scoped_feature_list(
features::kAutofillEnableSyncingOfPixBankAccounts);
BankAccount existing_bank_account =
test::CreatePixBankAccount(1234);
EXPECT_TRUE(table()->SetMaskedBankAccounts({existing_bank_account}));
std::vector<BankAccount> bank_accounts;
table()->GetMaskedBankAccounts(bank_accounts);
ASSERT_EQ(1U, bank_accounts.size());
AutofillWalletSpecifics bank_account_specifics;
SetAutofillWalletSpecificsFromBankAccount(existing_bank_account,
&bank_account_specifics);
StartSyncing({bank_account_specifics});
table()->GetMaskedBankAccounts(bank_accounts);
EXPECT_EQ(1U, bank_accounts.size());
EXPECT_THAT(GetAllLocalData(),
UnorderedElementsAre(EqualsSpecifics(bank_account_specifics)));
}
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NewBankAccount) {
base::test::ScopedFeatureList scoped_feature_list(
features::kAutofillEnableSyncingOfPixBankAccounts);
BankAccount existing_bank_account =
test::CreatePixBankAccount(1234);
EXPECT_TRUE(table()->SetMaskedBankAccounts({existing_bank_account}));
std::vector<BankAccount> bank_accounts;
table()->GetMaskedBankAccounts(bank_accounts);
ASSERT_EQ(1U, bank_accounts.size());
AutofillWalletSpecifics existing_bank_account_specifics;
SetAutofillWalletSpecificsFromBankAccount(existing_bank_account,
&existing_bank_account_specifics);
BankAccount new_bank_account =
test::CreatePixBankAccount(9999);
AutofillWalletSpecifics new_bank_account_specifics;
SetAutofillWalletSpecificsFromBankAccount(new_bank_account,
&new_bank_account_specifics);
StartSyncing({new_bank_account_specifics, existing_bank_account_specifics});
table()->GetMaskedBankAccounts(bank_accounts);
EXPECT_EQ(2U, bank_accounts.size());
EXPECT_THAT(
GetAllLocalData(),
UnorderedElementsAre(EqualsSpecifics(existing_bank_account_specifics),
EqualsSpecifics(new_bank_account_specifics)));
}
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_UpdatedBankAccount) {
base::test::ScopedFeatureList scoped_feature_list(
features::kAutofillEnableSyncingOfPixBankAccounts);
BankAccount existing_bank_account =
test::CreatePixBankAccount(1234);
EXPECT_TRUE(table()->SetMaskedBankAccounts({existing_bank_account}));
std::vector<BankAccount> bank_accounts;
table()->GetMaskedBankAccounts(bank_accounts);
ASSERT_EQ(1U, bank_accounts.size());
BankAccount udpated_bank_account(
existing_bank_account.payment_instrument().instrument_id(),
u"updated_nickname", GURL("http://www.example-updated.com"),
u"updated_bank_name", u"account_number_suffix_updated",
BankAccount::AccountType::kSavings);
AutofillWalletSpecifics updated_bank_account_specifics;
SetAutofillWalletSpecificsFromBankAccount(udpated_bank_account,
&updated_bank_account_specifics);
StartSyncing({updated_bank_account_specifics});
table()->GetMaskedBankAccounts(bank_accounts);
EXPECT_EQ(1U, bank_accounts.size());
EXPECT_THAT(
GetAllLocalData(),
UnorderedElementsAre(EqualsSpecifics(updated_bank_account_specifics)));
}
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_RemoveBankAccount) {
base::test::ScopedFeatureList scoped_feature_list(
features::kAutofillEnableSyncingOfPixBankAccounts);
BankAccount bank_account_1 =
test::CreatePixBankAccount(1234);
BankAccount bank_account_2 =
test::CreatePixBankAccount(9999);
EXPECT_TRUE(table()->SetMaskedBankAccounts({bank_account_1, bank_account_2}));
std::vector<BankAccount> bank_accounts;
table()->GetMaskedBankAccounts(bank_accounts);
ASSERT_EQ(2U, bank_accounts.size());
AutofillWalletSpecifics bank_account_1_specifics;
SetAutofillWalletSpecificsFromBankAccount(bank_account_1,
&bank_account_1_specifics);
StartSyncing({bank_account_1_specifics});
table()->GetMaskedBankAccounts(bank_accounts);
EXPECT_EQ(1U, bank_accounts.size());
EXPECT_THAT(GetAllLocalData(),
UnorderedElementsAre(EqualsSpecifics(bank_account_1_specifics)));
}
TEST_F(AutofillWalletSyncBridgeTest, MergeFullSyncData_NewBankAccount_ExpOff) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndDisableFeature(
features::kAutofillEnableSyncingOfPixBankAccounts);
BankAccount bank_account = test::CreatePixBankAccount(1234);
std::vector<BankAccount> bank_accounts;
AutofillWalletSpecifics bank_account_specifics;
SetAutofillWalletSpecificsFromBankAccount(bank_account,
&bank_account_specifics);
StartSyncing({bank_account_specifics});
table()->GetMaskedBankAccounts(bank_accounts);
EXPECT_EQ(0U, bank_accounts.size());
}
#endif
}