Commit 4b02e3f5 authored by Jan Krcal's avatar Jan Krcal Committed by Commit Bot

[Autofill wallet] Implement local changes for metadata sync

This CL implements the following features in the wallet_metadata USS
sync bridge:
 - caching current sync data and filling the cache on start,
 - informing the processor the bridge is ready to sync,
 - reacting to local single modifications of server profiles and cards
   (i.e. to updating the use stats when the address/card is used).

Bug: 853688
Change-Id: I07405e02cdf9cd0eb814179d883594253859845c
Reviewed-on: https://chromium-review.googlesource.com/1151628
Commit-Queue: Jan Krcal <jkrcal@chromium.org>
Reviewed-by: default avatarSebastien Seguin-Gagnon <sebsg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581183}
parent 965888f3
...@@ -2393,7 +2393,8 @@ bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element, ...@@ -2393,7 +2393,8 @@ bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element,
bool AutofillTable::SupportsMetadataForModelType( bool AutofillTable::SupportsMetadataForModelType(
syncer::ModelType model_type) const { syncer::ModelType model_type) const {
return (model_type == syncer::AUTOFILL || return (model_type == syncer::AUTOFILL ||
model_type == syncer::AUTOFILL_PROFILE); model_type == syncer::AUTOFILL_PROFILE ||
model_type == syncer::AUTOFILL_WALLET_METADATA);
} }
int AutofillTable::GetKeyValueForModelType(syncer::ModelType model_type) const { int AutofillTable::GetKeyValueForModelType(syncer::ModelType model_type) const {
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/sync/model/entity_data.h" #include "components/sync/model/entity_data.h"
#include "components/sync/model/mutable_data_batch.h" #include "components/sync/model/mutable_data_batch.h"
#include "components/sync/model_impl/client_tag_based_model_type_processor.h" #include "components/sync/model_impl/client_tag_based_model_type_processor.h"
#include "components/sync/model_impl/sync_metadata_store_change_list.h"
namespace autofill { namespace autofill {
...@@ -26,6 +27,7 @@ namespace { ...@@ -26,6 +27,7 @@ namespace {
using sync_pb::WalletMetadataSpecifics; using sync_pb::WalletMetadataSpecifics;
using syncer::EntityData; using syncer::EntityData;
using syncer::MetadataChangeList;
// Address to this variable used as the user data key. // Address to this variable used as the user data key.
static int kAutofillWalletMetadataSyncBridgeUserDataKey = 0; static int kAutofillWalletMetadataSyncBridgeUserDataKey = 0;
...@@ -62,7 +64,7 @@ std::unique_ptr<EntityData> CreateEntityDataFromAutofillDataModel( ...@@ -62,7 +64,7 @@ std::unique_ptr<EntityData> CreateEntityDataFromAutofillDataModel(
} }
// Returns EntityData for wallet_metadata for |local_profile|. // Returns EntityData for wallet_metadata for |local_profile|.
std::unique_ptr<EntityData> CreateWalletMetadataEntityDataFromAutofillProfile( std::unique_ptr<EntityData> CreateMetadataEntityDataFromAutofillServerProfile(
const AutofillProfile& local_profile) { const AutofillProfile& local_profile) {
std::unique_ptr<EntityData> entity_data = std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillDataModel( CreateEntityDataFromAutofillDataModel(
...@@ -76,7 +78,7 @@ std::unique_ptr<EntityData> CreateWalletMetadataEntityDataFromAutofillProfile( ...@@ -76,7 +78,7 @@ std::unique_ptr<EntityData> CreateWalletMetadataEntityDataFromAutofillProfile(
} }
// Returns EntityData for wallet_metadata for |local_card|. // Returns EntityData for wallet_metadata for |local_card|.
std::unique_ptr<EntityData> CreateEntityDataFromCreditCard( std::unique_ptr<EntityData> CreateMetadataEntityDataFromCard(
const CreditCard& local_card) { const CreditCard& local_card) {
std::unique_ptr<EntityData> entity_data = std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillDataModel( CreateEntityDataFromAutofillDataModel(
...@@ -103,7 +105,7 @@ void AutofillWalletMetadataSyncBridge::CreateForWebDataServiceAndBackend( ...@@ -103,7 +105,7 @@ void AutofillWalletMetadataSyncBridge::CreateForWebDataServiceAndBackend(
&kAutofillWalletMetadataSyncBridgeUserDataKey, &kAutofillWalletMetadataSyncBridgeUserDataKey,
std::make_unique<AutofillWalletMetadataSyncBridge>( std::make_unique<AutofillWalletMetadataSyncBridge>(
std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
syncer::AUTOFILL_WALLET_DATA, syncer::AUTOFILL_WALLET_METADATA,
/*dump_stack=*/base::RepeatingClosure()), /*dump_stack=*/base::RepeatingClosure()),
web_data_backend)); web_data_backend));
} }
...@@ -121,14 +123,22 @@ AutofillWalletMetadataSyncBridge::AutofillWalletMetadataSyncBridge( ...@@ -121,14 +123,22 @@ AutofillWalletMetadataSyncBridge::AutofillWalletMetadataSyncBridge(
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor,
AutofillWebDataBackend* web_data_backend) AutofillWebDataBackend* web_data_backend)
: ModelTypeSyncBridge(std::move(change_processor)), : ModelTypeSyncBridge(std::move(change_processor)),
web_data_backend_(web_data_backend) {} web_data_backend_(web_data_backend),
scoped_observer_(this) {
DCHECK(web_data_backend_);
scoped_observer_.Add(web_data_backend_);
LoadDataCacheAndMetadata();
}
AutofillWalletMetadataSyncBridge::~AutofillWalletMetadataSyncBridge() {} AutofillWalletMetadataSyncBridge::~AutofillWalletMetadataSyncBridge() {}
std::unique_ptr<syncer::MetadataChangeList> std::unique_ptr<syncer::MetadataChangeList>
AutofillWalletMetadataSyncBridge::CreateMetadataChangeList() { AutofillWalletMetadataSyncBridge::CreateMetadataChangeList() {
NOTIMPLEMENTED(); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return nullptr; return std::make_unique<syncer::SyncMetadataStoreChangeList>(
GetAutofillTable(), syncer::AUTOFILL_WALLET_METADATA);
} }
base::Optional<syncer::ModelError> base::Optional<syncer::ModelError>
...@@ -175,10 +185,111 @@ std::string AutofillWalletMetadataSyncBridge::GetStorageKey( ...@@ -175,10 +185,111 @@ std::string AutofillWalletMetadataSyncBridge::GetStorageKey(
entity_data.specifics.wallet_metadata().id()); entity_data.specifics.wallet_metadata().id());
} }
void AutofillWalletMetadataSyncBridge::AutofillProfileChanged(
const AutofillProfileChange& change) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const AutofillProfile* changed = change.data_model();
if (!changed || changed->record_type() != AutofillProfile::SERVER_PROFILE) {
return;
}
// The only legal change on a server profile is that its use count or use date
// or has-converted status gets updated. Other changes (adding, deleting) are
// only done by the AutofillWalletSyncBridge and result only in the
// AutofillMultipleChanged() notification.
DCHECK(change.type() == AutofillProfileChange::UPDATE);
SyncUpUpdatedEntity(
CreateMetadataEntityDataFromAutofillServerProfile(*changed));
}
void AutofillWalletMetadataSyncBridge::CreditCardChanged(
const CreditCardChange& change) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const CreditCard* changed = change.data_model();
if (!changed || changed->record_type() == CreditCard::LOCAL_CARD) {
return;
}
// The only legal change on a server card is that its use count or use date or
// billing address id gets updated. Other changes (adding, deleting) are only
// done by the AutofillWalletSyncBridge and result only in the
// AutofillMultipleChanged() notification.
DCHECK(change.type() == CreditCardChange::UPDATE);
SyncUpUpdatedEntity(CreateMetadataEntityDataFromCard(*changed));
}
void AutofillWalletMetadataSyncBridge::AutofillMultipleChanged() {
NOTIMPLEMENTED();
}
void AutofillWalletMetadataSyncBridge::SyncUpUpdatedEntity(
std::unique_ptr<EntityData> entity_after_change) {
std::string storage_key = GetStorageKey(*entity_after_change);
auto it = cache_.find(storage_key);
// This *changed* entity should already be in the cache, ignore otherwise.
if (it == cache_.end())
return;
const WalletMetadataSpecifics& specifics_before = it->second;
const WalletMetadataSpecifics& specifics_after =
entity_after_change->specifics.wallet_metadata();
if (specifics_before.use_count() < specifics_after.use_count() &&
specifics_before.use_date() < specifics_after.use_date()) {
std::unique_ptr<MetadataChangeList> metadata_change_list =
CreateMetadataChangeList();
cache_[storage_key] = specifics_after;
change_processor()->Put(storage_key, std::move(entity_after_change),
metadata_change_list.get());
}
}
AutofillTable* AutofillWalletMetadataSyncBridge::GetAutofillTable() { AutofillTable* AutofillWalletMetadataSyncBridge::GetAutofillTable() {
return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase()); return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
} }
void AutofillWalletMetadataSyncBridge::LoadDataCacheAndMetadata() {
if (!web_data_backend_ || !web_data_backend_->GetDatabase() ||
!GetAutofillTable()) {
change_processor()->ReportError(
{FROM_HERE, "Failed to load AutofillWebDatabase."});
return;
}
// Load the data cache.
std::vector<std::unique_ptr<AutofillProfile>> profiles;
std::vector<std::unique_ptr<CreditCard>> cards;
if (!GetAutofillTable()->GetServerProfiles(&profiles) ||
!GetAutofillTable()->GetServerCreditCards(&cards)) {
change_processor()->ReportError(
{FROM_HERE, "Failed reading autofill data from WebDatabase."});
return;
}
for (const std::unique_ptr<AutofillProfile>& entry : profiles) {
cache_[GetStorageKeyForEntryServerId(entry->server_id())] =
CreateMetadataEntityDataFromAutofillServerProfile(*entry)
->specifics.wallet_metadata();
}
for (const std::unique_ptr<CreditCard>& entry : cards) {
cache_[GetStorageKeyForEntryServerId(entry->server_id())] =
CreateMetadataEntityDataFromCard(*entry)->specifics.wallet_metadata();
}
// Load the metadata and send to the processor.
auto batch = std::make_unique<syncer::MetadataBatch>();
if (!GetAutofillTable()->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_METADATA,
batch.get())) {
change_processor()->ReportError(
{FROM_HERE, "Failed reading autofill metadata from WebDatabase."});
return;
}
change_processor()->ModelReadyToSync(std::move(batch));
}
void AutofillWalletMetadataSyncBridge::GetDataImpl( void AutofillWalletMetadataSyncBridge::GetDataImpl(
base::Optional<std::unordered_set<std::string>> storage_keys_set, base::Optional<std::unordered_set<std::string>> storage_keys_set,
DataCallback callback) { DataCallback callback) {
...@@ -199,14 +310,14 @@ void AutofillWalletMetadataSyncBridge::GetDataImpl( ...@@ -199,14 +310,14 @@ void AutofillWalletMetadataSyncBridge::GetDataImpl(
std::string key = GetStorageKeyForEntryServerId(entry->server_id()); std::string key = GetStorageKeyForEntryServerId(entry->server_id());
if (!storage_keys_set || base::ContainsKey(*storage_keys_set, key)) { if (!storage_keys_set || base::ContainsKey(*storage_keys_set, key)) {
batch->Put(key, batch->Put(key,
CreateWalletMetadataEntityDataFromAutofillProfile(*entry)); CreateMetadataEntityDataFromAutofillServerProfile(*entry));
} }
} }
for (const std::unique_ptr<CreditCard>& entry : cards) { for (const std::unique_ptr<CreditCard>& entry : cards) {
std::string key = GetStorageKeyForEntryServerId(entry->server_id()); std::string key = GetStorageKeyForEntryServerId(entry->server_id());
if (!storage_keys_set || base::ContainsKey(*storage_keys_set, key)) { if (!storage_keys_set || base::ContainsKey(*storage_keys_set, key)) {
batch->Put(GetStorageKeyForEntryServerId(entry->server_id()), batch->Put(GetStorageKeyForEntryServerId(entry->server_id()),
CreateEntityDataFromCreditCard(*entry)); CreateMetadataEntityDataFromCard(*entry));
} }
} }
......
...@@ -10,13 +10,20 @@ ...@@ -10,13 +10,20 @@
#include <unordered_set> #include <unordered_set>
#include "base/macros.h" #include "base/macros.h"
#include "base/scoped_observer.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/supports_user_data.h" #include "base/supports_user_data.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
#include "components/sync/model/metadata_change_list.h" #include "components/sync/model/metadata_change_list.h"
#include "components/sync/model/model_error.h" #include "components/sync/model/model_error.h"
#include "components/sync/model/model_type_change_processor.h" #include "components/sync/model/model_type_change_processor.h"
#include "components/sync/model/model_type_sync_bridge.h" #include "components/sync/model/model_type_sync_bridge.h"
namespace syncer {
struct EntityData;
} // namespace syncer
namespace autofill { namespace autofill {
class AutofillTable; class AutofillTable;
...@@ -25,8 +32,10 @@ class AutofillWebDataService; ...@@ -25,8 +32,10 @@ class AutofillWebDataService;
// Sync bridge responsible for propagating local changes to the processor and // Sync bridge responsible for propagating local changes to the processor and
// applying remote changes to the local database. // applying remote changes to the local database.
class AutofillWalletMetadataSyncBridge : public base::SupportsUserData::Data, class AutofillWalletMetadataSyncBridge
public syncer::ModelTypeSyncBridge { : public base::SupportsUserData::Data,
public syncer::ModelTypeSyncBridge,
public AutofillWebDataServiceObserverOnDBSequence {
public: public:
// Factory method that hides dealing with change_processor and also stores the // Factory method that hides dealing with change_processor and also stores the
// created bridge within |web_data_service|. This method should only be // created bridge within |web_data_service|. This method should only be
...@@ -58,10 +67,23 @@ class AutofillWalletMetadataSyncBridge : public base::SupportsUserData::Data, ...@@ -58,10 +67,23 @@ class AutofillWalletMetadataSyncBridge : public base::SupportsUserData::Data,
std::string GetClientTag(const syncer::EntityData& entity_data) override; std::string GetClientTag(const syncer::EntityData& entity_data) override;
std::string GetStorageKey(const syncer::EntityData& entity_data) override; std::string GetStorageKey(const syncer::EntityData& entity_data) override;
// AutofillWebDataServiceObserverOnDBSequence implementation.
void AutofillProfileChanged(const AutofillProfileChange& change) override;
void CreditCardChanged(const CreditCardChange& change) override;
void AutofillMultipleChanged() override;
private: private:
// Syncs up an updated entity |entity_after_change| (if needed).
void SyncUpUpdatedEntity(
std::unique_ptr<syncer::EntityData> entity_after_change);
// Returns the table associated with the |web_data_backend_|. // Returns the table associated with the |web_data_backend_|.
AutofillTable* GetAutofillTable(); AutofillTable* GetAutofillTable();
// Synchronously load |cache_| and sync metadata from the autofill table
// and pass the latter to the processor so that it can start tracking changes.
void LoadDataCacheAndMetadata();
// Reads local wallet metadata from the database and passes them into // Reads local wallet metadata from the database and passes them into
// |callback|. If |storage_keys_set| is not set, it returns all data entries. // |callback|. If |storage_keys_set| is not set, it returns all data entries.
// Otherwise, it returns only entries with storage key in |storage_keys_set|. // Otherwise, it returns only entries with storage key in |storage_keys_set|.
...@@ -73,6 +95,14 @@ class AutofillWalletMetadataSyncBridge : public base::SupportsUserData::Data, ...@@ -73,6 +95,14 @@ class AutofillWalletMetadataSyncBridge : public base::SupportsUserData::Data,
// SupportsUserData, so it's guaranteed to outlive |this|. // SupportsUserData, so it's guaranteed to outlive |this|.
AutofillWebDataBackend* const web_data_backend_; AutofillWebDataBackend* const web_data_backend_;
ScopedObserver<AutofillWebDataBackend, AutofillWalletMetadataSyncBridge>
scoped_observer_;
// Cache of the data (local data + data that hasn't synced down yet); keyed by
// storage keys. Needed for figuring out what to sync up when larger changes
// happen in the local database.
std::unordered_map<std::string, sync_pb::WalletMetadataSpecifics> cache_;
// The bridge should be used on the same sequence where it is constructed. // The bridge should be used on the same sequence where it is constructed.
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
......
...@@ -46,6 +46,7 @@ using syncer::EntityDataPtr; ...@@ -46,6 +46,7 @@ using syncer::EntityDataPtr;
using syncer::KeyAndData; using syncer::KeyAndData;
using syncer::MockModelTypeChangeProcessor; using syncer::MockModelTypeChangeProcessor;
using syncer::ModelType; using syncer::ModelType;
using testing::_;
using testing::ElementsAre; using testing::ElementsAre;
using testing::IsEmpty; using testing::IsEmpty;
using testing::UnorderedElementsAre; using testing::UnorderedElementsAre;
...@@ -90,32 +91,79 @@ class FakeAutofillBackend : public AutofillWebDataBackend { ...@@ -90,32 +91,79 @@ class FakeAutofillBackend : public AutofillWebDataBackend {
WebDatabase* db_; WebDatabase* db_;
}; };
WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddress( base::Time UseDateFromProtoValue(int64_t use_date_proto_value) {
const std::string& specifics_id) { return base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromMicroseconds(use_date_proto_value));
}
int64_t UseDateToProtoValue(base::Time use_date) {
return use_date.ToDeltaSinceWindowsEpoch().InMicroseconds();
}
WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddressWithUseStats(
const std::string& specifics_id,
size_t use_count,
int64_t use_date) {
WalletMetadataSpecifics specifics; WalletMetadataSpecifics specifics;
specifics.set_id(specifics_id); specifics.set_id(specifics_id);
specifics.set_type(WalletMetadataSpecifics::ADDRESS); specifics.set_type(WalletMetadataSpecifics::ADDRESS);
// Set default values according to the constructor of AutofillProfile (the specifics.set_use_count(use_count);
// clock value is overrided by TestAutofillClock in the test fixture). specifics.set_use_date(use_date);
specifics.set_use_count(1); // Set the default value according to the constructor of AutofillProfile.
specifics.set_use_date(kJune2017.ToDeltaSinceWindowsEpoch().InMicroseconds());
specifics.set_address_has_converted(false); specifics.set_address_has_converted(false);
return specifics; return specifics;
} }
WalletMetadataSpecifics CreateWalletMetadataSpecificsForCard( WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddress(
const std::string& specifics_id) { const std::string& specifics_id) {
// Set default values according to the constructor of AutofillProfile (the
// clock value is overrided by TestAutofillClock in the test fixture).
return CreateWalletMetadataSpecificsForAddressWithUseStats(
specifics_id, /*use_count=*/1,
/*use_date=*/UseDateToProtoValue(kJune2017));
}
WalletMetadataSpecifics CreateWalletMetadataSpecificsForCardWithUseStats(
const std::string& specifics_id,
size_t use_count,
int64_t use_date) {
WalletMetadataSpecifics specifics; WalletMetadataSpecifics specifics;
specifics.set_id(specifics_id); specifics.set_id(specifics_id);
specifics.set_type(WalletMetadataSpecifics::CARD); specifics.set_type(WalletMetadataSpecifics::CARD);
// Make it consistent with the constructor of CreditCard (the clock value is specifics.set_use_count(use_count);
// overrided by TestAutofillClock in the test fixture). specifics.set_use_date(use_date);
specifics.set_use_count(1); // Set the default value according to the constructor of AutofillProfile.
specifics.set_use_date(kJune2017.ToDeltaSinceWindowsEpoch().InMicroseconds());
specifics.set_card_billing_address_id(""); specifics.set_card_billing_address_id("");
return specifics; return specifics;
} }
WalletMetadataSpecifics CreateWalletMetadataSpecificsForCard(
const std::string& specifics_id) {
// Set default values according to the constructor of AutofillProfile (the
// clock value is overrided by TestAutofillClock in the test fixture).
return CreateWalletMetadataSpecificsForCardWithUseStats(
specifics_id, /*use_count=*/1,
/*use_date=*/UseDateToProtoValue(kJune2017));
}
AutofillProfile CreateServerProfileWithUseStats(const std::string& server_id,
size_t use_count,
int64_t use_date) {
AutofillProfile profile = CreateServerProfile(server_id);
profile.set_use_count(use_count);
profile.set_use_date(UseDateFromProtoValue(use_date));
return profile;
}
CreditCard CreateServerCreditCardWithUseStats(const std::string& server_id,
size_t use_count,
int64_t use_date) {
CreditCard card = CreateServerCreditCard(server_id);
card.set_use_count(use_count);
card.set_use_date(UseDateFromProtoValue(use_date));
return card;
}
void ExtractWalletMetadataSpecificsFromDataBatch( void ExtractWalletMetadataSpecificsFromDataBatch(
std::unique_ptr<DataBatch> batch, std::unique_ptr<DataBatch> batch,
std::vector<WalletMetadataSpecifics>* output) { std::vector<WalletMetadataSpecifics>* output) {
...@@ -130,9 +178,8 @@ std::string WalletMetadataSpecificsAsDebugString( ...@@ -130,9 +178,8 @@ std::string WalletMetadataSpecificsAsDebugString(
std::ostringstream output; std::ostringstream output;
output << "[id: " << specifics.id() output << "[id: " << specifics.id()
<< ", type: " << static_cast<int>(specifics.type()) << ", type: " << static_cast<int>(specifics.type())
<< ", use_count: " << specifics.use_count() << ", use_date: " << ", use_count: " << specifics.use_count()
<< base::Time::FromDeltaSinceWindowsEpoch( << ", use_date: " << UseDateFromProtoValue(specifics.use_date())
base::TimeDelta::FromMicroseconds(specifics.use_date()))
<< ", card_billing_address_id: " << ", card_billing_address_id: "
<< (specifics.has_card_billing_address_id() << (specifics.has_card_billing_address_id()
? specifics.card_billing_address_id() ? specifics.card_billing_address_id()
...@@ -156,6 +203,20 @@ MATCHER_P(EqualsSpecifics, expected, "") { ...@@ -156,6 +203,20 @@ MATCHER_P(EqualsSpecifics, expected, "") {
return true; return true;
} }
MATCHER_P(HasSpecifics, expected, "") {
const WalletMetadataSpecifics& arg_specifics =
arg->specifics.wallet_metadata();
if (arg_specifics.SerializeAsString() != expected.SerializeAsString()) {
*result_listener << "entry\n"
<< WalletMetadataSpecificsAsDebugString(arg_specifics)
<< "\ndid not match expected\n"
<< WalletMetadataSpecificsAsDebugString(expected);
return false;
}
return true;
}
} // namespace } // namespace
class AutofillWalletMetadataSyncBridgeTest : public testing::Test { class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
...@@ -172,7 +233,6 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test { ...@@ -172,7 +233,6 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase")); db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase"));
backend_.SetWebDatabase(&db_); backend_.SetWebDatabase(&db_);
ResetProcessor(); ResetProcessor();
ResetBridge();
} }
void ResetProcessor() { void ResetProcessor() {
...@@ -251,6 +311,7 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test { ...@@ -251,6 +311,7 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
// The following 2 tests make sure client tags stay stable. // The following 2 tests make sure client tags stay stable.
TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForAddress) { TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForAddress) {
ResetBridge();
WalletMetadataSpecifics specifics = WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForAddress(kAddr1SpecificsId); CreateWalletMetadataSpecificsForAddress(kAddr1SpecificsId);
EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)), EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
...@@ -258,6 +319,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForAddress) { ...@@ -258,6 +319,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForAddress) {
} }
TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForCard) { TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForCard) {
ResetBridge();
WalletMetadataSpecifics specifics = WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForCard(kCard1SpecificsId); CreateWalletMetadataSpecificsForCard(kCard1SpecificsId);
EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)), EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
...@@ -266,6 +328,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForCard) { ...@@ -266,6 +328,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForCard) {
// The following 2 tests make sure storage keys stay stable. // The following 2 tests make sure storage keys stay stable.
TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForAddress) { TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForAddress) {
ResetBridge();
WalletMetadataSpecifics specifics = WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForAddress(kAddr1SpecificsId); CreateWalletMetadataSpecificsForAddress(kAddr1SpecificsId);
EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics)), EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics)),
...@@ -273,6 +336,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForAddress) { ...@@ -273,6 +336,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForAddress) {
} }
TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForCard) { TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForCard) {
ResetBridge();
WalletMetadataSpecifics specifics = WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForCard(kCard1SpecificsId); CreateWalletMetadataSpecificsForCard(kCard1SpecificsId);
EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics)), EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics)),
...@@ -285,6 +349,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, ...@@ -285,6 +349,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
CreateServerProfile(kAddr2ServerId)}); CreateServerProfile(kAddr2ServerId)});
table()->SetServerCreditCards({CreateServerCreditCard(kCard1ServerId), table()->SetServerCreditCards({CreateServerCreditCard(kCard1ServerId),
CreateServerCreditCard(kCard2ServerId)}); CreateServerCreditCard(kCard2ServerId)});
ResetBridge();
EXPECT_THAT( EXPECT_THAT(
GetAllLocalData(), GetAllLocalData(),
...@@ -301,6 +366,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, ...@@ -301,6 +366,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
TEST_F(AutofillWalletMetadataSyncBridgeTest, TEST_F(AutofillWalletMetadataSyncBridgeTest,
GetData_ShouldNotReturnNonexistentData) { GetData_ShouldNotReturnNonexistentData) {
ResetBridge();
EXPECT_THAT(GetLocalData({kAddr1SpecificsId}), IsEmpty()); EXPECT_THAT(GetLocalData({kAddr1SpecificsId}), IsEmpty());
} }
...@@ -309,6 +375,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnSelectedData) { ...@@ -309,6 +375,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnSelectedData) {
CreateServerProfile(kAddr2ServerId)}); CreateServerProfile(kAddr2ServerId)});
table()->SetServerCreditCards({CreateServerCreditCard(kCard1ServerId), table()->SetServerCreditCards({CreateServerCreditCard(kCard1ServerId),
CreateServerCreditCard(kCard2ServerId)}); CreateServerCreditCard(kCard2ServerId)});
ResetBridge();
EXPECT_THAT(GetLocalData({kAddr1SpecificsId, kCard1SpecificsId}), EXPECT_THAT(GetLocalData({kAddr1SpecificsId, kCard1SpecificsId}),
UnorderedElementsAre( UnorderedElementsAre(
...@@ -321,17 +388,16 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnSelectedData) { ...@@ -321,17 +388,16 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnSelectedData) {
TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) { TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) {
AutofillProfile profile = CreateServerProfile(kAddr1ServerId); AutofillProfile profile = CreateServerProfile(kAddr1ServerId);
profile.set_use_count(5); profile.set_use_count(5);
profile.set_use_date(base::Time::FromDeltaSinceWindowsEpoch( profile.set_use_date(UseDateFromProtoValue(2));
base::TimeDelta::FromMicroseconds(2)));
profile.set_has_converted(true); profile.set_has_converted(true);
table()->SetServerProfiles({profile}); table()->SetServerProfiles({profile});
CreditCard card = CreateServerCreditCard(kCard1ServerId); CreditCard card = CreateServerCreditCard(kCard1ServerId);
card.set_use_count(6); card.set_use_count(6);
card.set_use_date(base::Time::FromDeltaSinceWindowsEpoch( card.set_use_date(UseDateFromProtoValue(3));
base::TimeDelta::FromMicroseconds(3)));
card.set_billing_address_id(kAddr1ServerId); card.set_billing_address_id(kAddr1ServerId);
table()->SetServerCreditCards({card}); table()->SetServerCreditCards({card});
ResetBridge();
// Expect to retrieve following specifics: // Expect to retrieve following specifics:
WalletMetadataSpecifics profile_specifics = WalletMetadataSpecifics profile_specifics =
...@@ -351,4 +417,84 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) { ...@@ -351,4 +417,84 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) {
EqualsSpecifics(card_specifics))); EqualsSpecifics(card_specifics)));
} }
// Verify that lower values of metadata are not sent to the sync server when
// local metadata is updated.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
DontSendLowerValueToServerOnSingleChange) {
table()->SetServerProfiles({CreateServerProfileWithUseStats(
kAddr1ServerId, /*use_count=*/2, /*use_date=*/5)});
table()->SetServerCreditCards({CreateServerCreditCardWithUseStats(
kCard1ServerId, /*use_count=*/3, /*use_date=*/6)});
ResetBridge();
AutofillProfile updated_profile = CreateServerProfileWithUseStats(
kAddr1ServerId, /*use_count=*/1, /*use_date=*/4);
CreditCard updated_card = CreateServerCreditCardWithUseStats(
kCard1ServerId, /*use_count=*/2, /*use_date=*/5);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
bridge()->AutofillProfileChanged(AutofillProfileChange(
AutofillProfileChange::UPDATE, updated_profile.guid(), &updated_profile));
bridge()->CreditCardChanged(CreditCardChange(
CreditCardChange::UPDATE, updated_card.guid(), &updated_card));
}
// Verify that one-off addition of metadata is not sent to the sync
// server. Metadata add and delete trigger multiple changes notification
// instead.
TEST_F(AutofillWalletMetadataSyncBridgeTest, DontAddToServerOnSingleChange) {
table()->SetServerProfiles({CreateServerProfileWithUseStats(
kAddr1ServerId, /*use_count=*/1, /*use_date=*/2)});
table()->SetServerCreditCards({CreateServerCreditCardWithUseStats(
kCard1ServerId, /*use_count=*/3, /*use_date=*/4)});
ResetBridge();
AutofillProfile new_profile = CreateServerProfileWithUseStats(
kAddr2ServerId, /*use_count=*/10, /*use_date=*/20);
CreditCard new_card = CreateServerCreditCardWithUseStats(
kCard2ServerId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
bridge()->AutofillProfileChanged(AutofillProfileChange(
AutofillProfileChange::UPDATE, new_profile.guid(), &new_profile));
bridge()->CreditCardChanged(
CreditCardChange(CreditCardChange::UPDATE, new_card.guid(), &new_card));
}
// Verify that higher values of metadata are sent to the sync server when local
// metadata is updated.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
SendHigherValuesToServerOnLocalSingleChange) {
table()->SetServerProfiles({CreateServerProfileWithUseStats(
kAddr1ServerId, /*use_count=*/1, /*use_date=*/2)});
table()->SetServerCreditCards({CreateServerCreditCardWithUseStats(
kCard1ServerId, /*use_count=*/3, /*use_date=*/4)});
ResetBridge();
AutofillProfile updated_profile = CreateServerProfileWithUseStats(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
CreditCard updated_card = CreateServerCreditCardWithUseStats(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
WalletMetadataSpecifics expected_profile_specifics =
CreateWalletMetadataSpecificsForAddressWithUseStats(
kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
WalletMetadataSpecifics expected_card_specifics =
CreateWalletMetadataSpecificsForCardWithUseStats(
kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(
mock_processor(),
Put(kAddr1SpecificsId, HasSpecifics(expected_profile_specifics), _));
EXPECT_CALL(mock_processor(),
Put(kCard1SpecificsId, HasSpecifics(expected_card_specifics), _));
bridge()->AutofillProfileChanged(AutofillProfileChange(
AutofillProfileChange::UPDATE, updated_profile.guid(), &updated_profile));
bridge()->CreditCardChanged(CreditCardChange(
CreditCardChange::UPDATE, updated_card.guid(), &updated_card));
}
} // namespace autofill } // namespace autofill
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment