Commit ba52e783 authored by Jan Krcal's avatar Jan Krcal Committed by Commit Bot

Reland "Fix flaky test ServerAddressConvertsToSameLocalAddress"

This is a reland of commit b3873b4d.

The CL fixes a race condition in production code of autofill profile
sync bridge by modifying merge logic of the datatype. Previously, the
logic for dealing with duplicate entities was to always prefer the
remote one and silently delete the local one. This could end up with
two clients having a different entry each and the sync server having
both duplicate entries. The new behavior, introduced in this CL is to
keep the profile with greater GUID, lexicographically.

This change should also remove flakiness of one integration test (that
uncovered the actual issue), so the CL reenables the test.

The original CL caused flakiness in another integration test since GUIDs
in that test are randomly attributed. In this reland, we fix this by
making the expectation on the number of sync deletions depend on which
one of the test GUIDs is bigger.

Bug: 917498
Change-Id: I13994ac5bef8fcae41d37350e08ee80ab90f0916
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2002571
Auto-Submit: Jan Krcal <jkrcal@chromium.org>
Commit-Queue: Jan Krcal <jkrcal@chromium.org>
Commit-Queue: Maxim Kolosovskiy <kolos@chromium.org>
Reviewed-by: default avatarMaxim Kolosovskiy <kolos@chromium.org>
Reviewed-by: default avatarMikel Astiz <mastiz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#733636}
parent 9eaac33c
...@@ -188,7 +188,6 @@ IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest, ...@@ -188,7 +188,6 @@ IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
LOCAL_DELETION, 0); LOCAL_DELETION, 0);
} }
// Flaky on all platform. See crbug.com/971666
IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest, IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
AddDuplicateProfiles_OneIsVerified) { AddDuplicateProfiles_OneIsVerified) {
ASSERT_TRUE(SetupClients()); ASSERT_TRUE(SetupClients());
...@@ -210,13 +209,20 @@ IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest, ...@@ -210,13 +209,20 @@ IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin()); EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin()); EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE", // Among duplicate profiles, sync prefers the one with largest GUID. If
LOCAL_DELETION, 0); // |profile0| (committed first) has a smaller GUID, client 1 should upload its
// deletion to the server. Otherwise, no deletion should occur.
if (profile1.guid() > profile0.guid()) {
histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE",
LOCAL_DELETION, 1);
} else {
histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE",
LOCAL_DELETION, 0);
}
} }
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
TwoClientAutofillProfileSyncTest, AddDuplicateProfiles_OneAtStart_OtherComesLater) {
AddDuplicateProfiles_OneIsVerified_NonverifiedComesLater) {
ASSERT_TRUE(SetupClients()); ASSERT_TRUE(SetupClients());
base::HistogramTester histograms; base::HistogramTester histograms;
...@@ -225,26 +231,23 @@ IN_PROC_BROWSER_TEST_F( ...@@ -225,26 +231,23 @@ IN_PROC_BROWSER_TEST_F(
autofill::test::GetVerifiedProfile(); // I.e. Full + Verified. autofill::test::GetVerifiedProfile(); // I.e. Full + Verified.
std::string verified_origin = profile1.origin(); std::string verified_origin = profile1.origin();
// We start by having the verified profile. AddProfile(0, profile0);
AddProfile(1, profile1);
ASSERT_TRUE(SetupSync()); ASSERT_TRUE(SetupSync());
EXPECT_TRUE(AutofillProfileChecker(0, 1).Wait()); EXPECT_TRUE(AutofillProfileChecker(0, 1).Wait());
EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size()); EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
// Add the same (but non-verified) profile on the other client, afterwards. // Add the same (but verified) profile on the other client, afterwards.
AddProfile(0, profile0); AddProfile(1, profile1);
EXPECT_TRUE(AutofillProfileChecker(0, 1).Wait()); EXPECT_TRUE(AutofillProfileChecker(0, 1).Wait());
// The profiles should de-duplicate via sync on both other client, the // The latter addition is caught in deduplication logic in PDM to sync. As a
// verified one should win. // result, both clients end up with the non-verified profile.
EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size()); EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size()); EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin()); EXPECT_NE(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin()); EXPECT_NE(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE", histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE",
LOCAL_DELETION, 0); LOCAL_DELETION, 0);
......
...@@ -465,7 +465,7 @@ IN_PROC_BROWSER_TEST_F( ...@@ -465,7 +465,7 @@ IN_PROC_BROWSER_TEST_F(
// Flaky. http://crbug.com/917498 // Flaky. http://crbug.com/917498
IN_PROC_BROWSER_TEST_F(TwoClientWalletSyncTest, IN_PROC_BROWSER_TEST_F(TwoClientWalletSyncTest,
DISABLED_ServerAddressConvertsToSameLocalAddress) { ServerAddressConvertsToSameLocalAddress) {
GetFakeServer()->SetWalletData( GetFakeServer()->SetWalletData(
{CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"), {CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"),
CreateDefaultSyncPaymentsCustomerData()}); CreateDefaultSyncPaymentsCustomerData()});
......
per-file *sync_bridge*=jkrcal@chromium.org per-file *sync_bridge*=jkrcal@chromium.org
per-file *sync_bridge*=file://components/sync/OWNERS per-file *sync_bridge*=file://components/sync/OWNERS
per-file *syncable_service*=jkrcal@chromium.org per-file autofill_profile_sync_difference_tracker*=jkrcal@chromium.org
per-file *syncable_service*=file://components/sync/OWNERS per-file autofill_profile_sync_difference_tracker*=file://components/sync/OWNERS
per-file *type_controller*=jkrcal@chromium.org per-file *type_controller*=jkrcal@chromium.org
per-file *type_controller*=file://components/sync/OWNERS per-file *type_controller*=file://components/sync/OWNERS
...@@ -251,13 +251,18 @@ base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker( ...@@ -251,13 +251,18 @@ base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
base::Unretained(web_data_backend_)))); base::Unretained(web_data_backend_))));
std::vector<std::unique_ptr<AutofillProfile>> profiles_to_upload_to_sync; std::vector<std::unique_ptr<AutofillProfile>> profiles_to_upload_to_sync;
RETURN_IF_ERROR(tracker->FlushToSync(&profiles_to_upload_to_sync)); std::vector<std::string> profiles_to_delete_from_sync;
RETURN_IF_ERROR(tracker->FlushToSync(&profiles_to_upload_to_sync,
&profiles_to_delete_from_sync));
for (const std::unique_ptr<AutofillProfile>& entry : for (const std::unique_ptr<AutofillProfile>& entry :
profiles_to_upload_to_sync) { profiles_to_upload_to_sync) {
change_processor()->Put(GetStorageKeyFromAutofillProfile(*entry), change_processor()->Put(GetStorageKeyFromAutofillProfile(*entry),
CreateEntityDataFromAutofillProfile(*entry), CreateEntityDataFromAutofillProfile(*entry),
metadata_change_list.get()); metadata_change_list.get());
} }
for (const std::string& storage_key : profiles_to_delete_from_sync) {
change_processor()->Delete(storage_key, metadata_change_list.get());
}
return static_cast<syncer::SyncMetadataStoreChangeList*>( return static_cast<syncer::SyncMetadataStoreChangeList*>(
metadata_change_list.get()) metadata_change_list.get())
......
...@@ -64,6 +64,11 @@ AutofillProfileSyncDifferenceTracker::IncorporateRemoteProfile( ...@@ -64,6 +64,11 @@ AutofillProfileSyncDifferenceTracker::IncorporateRemoteProfile(
} }
// Check if profile appears under a different storage key to be de-duplicated. // Check if profile appears under a different storage key to be de-duplicated.
// TODO(crbug.com/1043683): Deal with rare cases when an remote update
// contains several exact duplicates (with different guids). We should not
// only search in local only entries but also in |update_to_local_| and
// |add_to_local_|. Likely needs a bit of refactoring to make the resulting
// code easy to understand.
for (const auto& pair : *GetLocalOnlyEntries()) { for (const auto& pair : *GetLocalOnlyEntries()) {
const std::string& local_storage_key = pair.first; const std::string& local_storage_key = pair.first;
const AutofillProfile& local = *pair.second; const AutofillProfile& local = *pair.second;
...@@ -71,30 +76,76 @@ AutofillProfileSyncDifferenceTracker::IncorporateRemoteProfile( ...@@ -71,30 +76,76 @@ AutofillProfileSyncDifferenceTracker::IncorporateRemoteProfile(
// Look for exact duplicates, compare only profile contents (and // Look for exact duplicates, compare only profile contents (and
// ignore origin and language code in comparison). // ignore origin and language code in comparison).
if (local.Compare(*remote) == 0) { if (local.Compare(*remote) == 0) {
// We found a duplicate, we keep the new (remote) one and delete the // A duplicate found: keep the version with the bigger storage key.
// local one.
DVLOG(2) DVLOG(2)
<< "[AUTOFILL SYNC] The profile " << "[AUTOFILL SYNC] The profile "
<< base::UTF16ToUTF8(local.GetRawInfo(NAME_FIRST)) << base::UTF16ToUTF8(local.GetRawInfo(NAME_FIRST))
<< base::UTF16ToUTF8(local.GetRawInfo(NAME_LAST)) << base::UTF16ToUTF8(local.GetRawInfo(NAME_LAST))
<< " already exists with a different storage key; keep the remote key" << " already exists with a different storage key; keep the bigger "
<< remote_storage_key << " and delete the local key " << (remote_storage_key > local_storage_key ? "remote" : "local")
<< local_storage_key; << " key " << std::max(remote_storage_key, local_storage_key)
<< " and delete the smaller key "
// Ensure that a verified profile can never revert back to an unverified << std::min(remote_storage_key, local_storage_key);
// one. In such a case, take over the local origin for the new (remote) if (remote_storage_key > local_storage_key) {
// entry. // We keep the remote entity and delete the local one.
if (local.IsVerified() && !remote->IsVerified()) { // Ensure that a verified profile can never revert back to an unverified
remote->set_origin(local.origin()); // one. In such a case, take over the old origin for the new entry.
// Save a copy of the remote profile also to sync. if (local.IsVerified() && !remote->IsVerified()) {
save_to_sync_.push_back(std::make_unique<AutofillProfile>(*remote)); remote->set_origin(local.origin());
// Save a copy of the remote profile also to sync.
save_to_sync_.push_back(std::make_unique<AutofillProfile>(*remote));
}
add_to_local_.push_back(std::move(remote));
// Deleting from sync is a no-op if it is local-only so far.
// There are a few ways how a synced local entry A could theoretically
// receive a remote duplicate B with a larger GUID:
// 1) Remote entity B got uploaded by another client through initial
// sync. That client thus also knew about A and issued a deletion of
// A at the same time. This client (if receiving creation of B
// first) resolves the conflict in the same way and re-issues the
// deletion of A. In most cases the redundant deletion does not even
// get sent as the processor already knows A got deleted remotely.
// 2) Remote entity B got uploaded by another client through race
// condition (i.e. not knowing about A, yet). In practice, this only
// happens when two clients simultaneously convert a server profile
// into local profiles. If the other client goes offline before
// receiving A, this client is responsible for deleting A from the
// server and thus must issue a deletion. (In most cases, the other
// client does not go offline and thus both clients issue a deletion
// of A independently).
// 3) (a paranoid case) Remote entity B got uploaded by another client
// by an error, i.e. already as a duplicate given their local state.
// Through standard flows, it should be impossible (duplicates are
// cought early in PDM code so such a change attempt does not even
// propagate to the sync bridge). Still, it's good to treat this
// case here for robustness.
delete_from_sync_.insert(local_storage_key);
DeleteFromLocal(local_storage_key);
} else {
// We keep the local entity and delete the remote one.
// Ensure that a verified profile can never revert back to an unverified
// one. In such a case, modify the origin and re-upload. Otherwise,
// there's no need to upload it: either is was already uploaded before
// (if this is incremental sync) or we'll upload it with all the
// remaining data in GetLocalOnlyEntries (if this is an initial sync).
if (remote->IsVerified() && !local.IsVerified()) {
auto modified_local = std::make_unique<AutofillProfile>(local);
modified_local->set_origin(remote->origin());
update_to_local_.push_back(
std::make_unique<AutofillProfile>(*modified_local));
save_to_sync_.push_back(std::move(modified_local));
// The local entity is already marked for upload so it is not local
// only anymore (we do not want to upload it once again while flushing
// if this is initial sync).
GetLocalOnlyEntries()->erase(local_storage_key);
}
delete_from_sync_.insert(remote_storage_key);
} }
// Delete the local profile that gets replaced by |remote|. return base::nullopt;
DeleteFromLocal(local_storage_key);
break;
} }
} }
// If no duplicate was found, just add the remote profile.
add_to_local_.push_back(std::move(remote)); add_to_local_.push_back(std::move(remote));
return base::nullopt; return base::nullopt;
} }
...@@ -132,10 +183,14 @@ Optional<ModelError> AutofillProfileSyncDifferenceTracker::FlushToLocal( ...@@ -132,10 +183,14 @@ Optional<ModelError> AutofillProfileSyncDifferenceTracker::FlushToLocal(
} }
Optional<ModelError> AutofillProfileSyncDifferenceTracker::FlushToSync( Optional<ModelError> AutofillProfileSyncDifferenceTracker::FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync) { std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
std::vector<std::string>* profiles_to_delete_from_sync) {
for (std::unique_ptr<AutofillProfile>& entry : save_to_sync_) { for (std::unique_ptr<AutofillProfile>& entry : save_to_sync_) {
profiles_to_upload_to_sync->push_back(std::move(entry)); profiles_to_upload_to_sync->push_back(std::move(entry));
} }
for (const std::string& entry : delete_from_sync_) {
profiles_to_delete_from_sync->push_back(std::move(entry));
}
return base::nullopt; return base::nullopt;
} }
...@@ -200,9 +255,11 @@ AutofillProfileInitialSyncDifferenceTracker::IncorporateRemoteDelete( ...@@ -200,9 +255,11 @@ AutofillProfileInitialSyncDifferenceTracker::IncorporateRemoteDelete(
} }
Optional<ModelError> AutofillProfileInitialSyncDifferenceTracker::FlushToSync( Optional<ModelError> AutofillProfileInitialSyncDifferenceTracker::FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync) { std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
std::vector<std::string>* profiles_to_delete_from_sync) {
// First, flush standard updates to sync. // First, flush standard updates to sync.
AutofillProfileSyncDifferenceTracker::FlushToSync(profiles_to_upload_to_sync); AutofillProfileSyncDifferenceTracker::FlushToSync(
profiles_to_upload_to_sync, profiles_to_delete_from_sync);
// For initial sync, we additionally need to upload all local only entries. // For initial sync, we additionally need to upload all local only entries.
if (!GetLocalOnlyEntries()) { if (!GetLocalOnlyEntries()) {
......
...@@ -50,11 +50,12 @@ class AutofillProfileSyncDifferenceTracker { ...@@ -50,11 +50,12 @@ class AutofillProfileSyncDifferenceTracker {
base::OnceClosure autofill_changes_callback); base::OnceClosure autofill_changes_callback);
// Writes into |profiles_to_upload_to_sync| all autofill profiles to be sent // Writes into |profiles_to_upload_to_sync| all autofill profiles to be sent
// to the sync server. After flushing, not further remote changes should get // to the sync server, and into |profiles_to_delete_from_sync| the storage
// incorporated. // keys of all profiles to be deleted from the server. After flushing, no
// further remote changes should get incorporated.
virtual base::Optional<syncer::ModelError> FlushToSync( virtual base::Optional<syncer::ModelError> FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
profiles_to_upload_to_sync); std::vector<std::string>* profiles_to_delete_from_sync);
protected: protected:
// If the entry is found, |entry| will be return, otherwise base::nullopt is // If the entry is found, |entry| will be return, otherwise base::nullopt is
...@@ -89,7 +90,7 @@ class AutofillProfileSyncDifferenceTracker { ...@@ -89,7 +90,7 @@ class AutofillProfileSyncDifferenceTracker {
// We use unique_ptrs for storing AutofillProfile to avoid unnecessary copies. // We use unique_ptrs for storing AutofillProfile to avoid unnecessary copies.
// Local data, mapped by storage key. Use unique_to_local() to access it. // Local data, mapped by storage key. Use GetLocalOnlyEntries() to access it.
std::map<std::string, std::unique_ptr<AutofillProfile>> local_only_entries_; std::map<std::string, std::unique_ptr<AutofillProfile>> local_only_entries_;
// Contain changes (originating from sync) that need to be saved to the local // Contain changes (originating from sync) that need to be saved to the local
...@@ -98,9 +99,13 @@ class AutofillProfileSyncDifferenceTracker { ...@@ -98,9 +99,13 @@ class AutofillProfileSyncDifferenceTracker {
std::vector<std::unique_ptr<AutofillProfile>> add_to_local_; std::vector<std::unique_ptr<AutofillProfile>> add_to_local_;
std::vector<std::unique_ptr<AutofillProfile>> update_to_local_; std::vector<std::unique_ptr<AutofillProfile>> update_to_local_;
// Contains merged data for entries that existed on both sync and local sides // Contains data for entries that existed on both sync and local sides
// and need to be saved back to sync. // and need to be saved back to sync.
std::vector<std::unique_ptr<AutofillProfile>> save_to_sync_; std::vector<std::unique_ptr<AutofillProfile>> save_to_sync_;
// Contains storage keys for entries that existed on both sync and local
// sides and need to be deleted from sync (because the conflict resolution
// preferred the local copies).
std::set<std::string> delete_from_sync_;
private: private:
DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncDifferenceTracker); DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncDifferenceTracker);
...@@ -116,8 +121,8 @@ class AutofillProfileInitialSyncDifferenceTracker ...@@ -116,8 +121,8 @@ class AutofillProfileInitialSyncDifferenceTracker
const std::string& storage_key) override; const std::string& storage_key) override;
base::Optional<syncer::ModelError> FlushToSync( base::Optional<syncer::ModelError> FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync) std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
override; std::vector<std::string>* profiles_to_delete_from_sync) override;
// Performs an additional pass through remote entries incorporated from sync // Performs an additional pass through remote entries incorporated from sync
// to find any similarities with local entries. Should be run after all // to find any similarities with local entries. Should be run after all
......
...@@ -30,13 +30,18 @@ using testing::ElementsAre; ...@@ -30,13 +30,18 @@ using testing::ElementsAre;
using testing::IsEmpty; using testing::IsEmpty;
// Some guids for testing. // Some guids for testing.
const char kGuidA[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A"; const char kSmallerGuid[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A";
const char kGuidB[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44B"; const char kBiggerGuid[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
const char kHttpOrigin[] = "http://www.example.com/"; const char kHttpOrigin[] = "http://www.example.com/";
const char kHttpsOrigin[] = "https://www.example.com/"; const char kHttpsOrigin[] = "https://www.example.com/";
const char kLocaleString[] = "en-US"; const char kLocaleString[] = "en-US";
const base::Time kJune2017 = base::Time::FromDoubleT(1497552271); const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
struct UpdatesToSync {
std::vector<AutofillProfile> profiles_to_upload_to_sync;
std::vector<std::string> profiles_to_delete_from_sync;
};
} // namespace } // namespace
class AutofillProfileSyncDifferenceTrackerTestBase : public testing::Test { class AutofillProfileSyncDifferenceTrackerTestBase : public testing::Test {
...@@ -65,24 +70,26 @@ class AutofillProfileSyncDifferenceTrackerTestBase : public testing::Test { ...@@ -65,24 +70,26 @@ class AutofillProfileSyncDifferenceTrackerTestBase : public testing::Test {
std::make_unique<AutofillProfile>(profile))); std::make_unique<AutofillProfile>(profile)));
} }
std::vector<AutofillProfile> FlushAndReturnProfilesToUploadToSync() { UpdatesToSync FlushToSync() {
EXPECT_EQ(base::nullopt, EXPECT_EQ(base::nullopt,
tracker()->FlushToLocal( tracker()->FlushToLocal(
/*autofill_changes_callback=*/base::DoNothing())); /*autofill_changes_callback=*/base::DoNothing()));
UpdatesToSync updates;
std::vector<std::unique_ptr<AutofillProfile>> vector_of_unique_ptrs; std::vector<std::unique_ptr<AutofillProfile>> vector_of_unique_ptrs;
EXPECT_EQ(base::nullopt, EXPECT_EQ(base::nullopt,
tracker()->FlushToSync( tracker()->FlushToSync(
/*profiles_to_upload_to_sync=*/&vector_of_unique_ptrs)); /*profiles_to_upload_to_sync=*/&vector_of_unique_ptrs,
/*profiles_to_delete_from_sync=*/&updates
.profiles_to_delete_from_sync));
// Copy all the elements by value so that we have a vector that is easier to // Copy all the elements by value so that we have a vector that is easier to
// work with in the test. // work with in the test.
std::vector<AutofillProfile> vector_of_values;
for (const std::unique_ptr<AutofillProfile>& entry : for (const std::unique_ptr<AutofillProfile>& entry :
vector_of_unique_ptrs) { vector_of_unique_ptrs) {
vector_of_values.push_back(*entry); updates.profiles_to_upload_to_sync.push_back(*entry);
} }
return vector_of_values; return updates;
} }
std::vector<AutofillProfile> GetAllLocalData() { std::vector<AutofillProfile> GetAllLocalData() {
...@@ -130,63 +137,69 @@ class AutofillProfileSyncDifferenceTrackerTest ...@@ -130,63 +137,69 @@ class AutofillProfileSyncDifferenceTrackerTest
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldOverwriteProfileWithSameKey) { IncorporateRemoteProfileShouldOverwriteProfileWithSameKey) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile is completely different but it has the same key. // The remote profile is completely different but it has the same key.
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin); AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom")); remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
IncorporateRemoteProfile(remote); IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins. // Nothing gets uploaded to sync and the remote profile wins.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty()); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
} }
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldOverwriteUnverifiedProfileByVerified) { IncorporateRemoteProfileShouldOverwriteUnverifiedProfileByVerified) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpsOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile has the same key but it is not verified. // The remote profile has the same key but it is not verified.
AutofillProfile remote = AutofillProfile(kGuidA, kSettingsOrigin); AutofillProfile remote = AutofillProfile(kSmallerGuid, kSettingsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom")); remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
IncorporateRemoteProfile(remote); IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the local profile wins. // Nothing gets uploaded to sync and the local profile wins.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty()); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
} }
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldNotOverwriteVerifiedProfileByUnverified) { IncorporateRemoteProfileShouldNotOverwriteVerifiedProfileByUnverified) {
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile has the same key but it is not verified. // The remote profile has the same key but it is not verified.
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin); AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom")); remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
IncorporateRemoteProfile(remote); IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the local profile wins. // Nothing gets uploaded to sync and the local profile wins.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty()); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(local)); EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
} }
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldNotOverwriteFullNameByEmptyString) { IncorporateRemoteProfileShouldNotOverwriteFullNameByEmptyString) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
local.SetRawInfo(NAME_FULL, ASCIIToUTF16("John")); local.SetRawInfo(NAME_FULL, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile has the same key. // The remote profile has the same key.
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin); AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2st st"));
AutofillProfile merged(remote); AutofillProfile merged(remote);
...@@ -196,40 +209,46 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest, ...@@ -196,40 +209,46 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
// Nothing gets uploaded to sync and the remote profile wins except for the // Nothing gets uploaded to sync and the remote profile wins except for the
// full name. // full name.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty()); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged)); EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
} }
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(
IncorporateRemoteProfileShouldMergeIdenticalProfilesWithDifferentKeys) { AutofillProfileSyncDifferenceTrackerTest,
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin); IncorporateRemoteProfileShouldKeepRemoteKeyWhenMergingDuplicateProfileWithBiggerKey) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile is identical to the local one, except that the guids and // The remote profile is identical to the local one, except that the guids and
// origins are different. // origins are different.
AutofillProfile remote = AutofillProfile(kGuidB, kHttpsOrigin); AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
IncorporateRemoteProfile(remote); IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins. // Nothing gets uploaded to sync and the remote profile wins.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty()); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
} }
TEST_F( TEST_F(
AutofillProfileSyncDifferenceTrackerTest, AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldMergeIdenticalProfilesWithDifferentKeysButKeepVerifiedOrigin) { IncorporateRemoteProfileShouldKeepRemoteKeyAndLocalOriginWhenMergingDuplicateProfileWithBiggerKey) {
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile has the same key. // The remote profile has the same key.
AutofillProfile remote = AutofillProfile(kGuidB, kHttpsOrigin); AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
...@@ -240,7 +259,61 @@ TEST_F( ...@@ -240,7 +259,61 @@ TEST_F(
// Nothing gets uploaded to sync and the remote profile wins except for the // Nothing gets uploaded to sync and the remote profile wins except for the
// full name. // full name.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(merged)); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(merged));
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
TEST_F(
AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldKeepLocalKeyWhenMergingDuplicateProfileWithSmallerKey) {
AutofillProfile local = AutofillProfile(kBiggerGuid, kHttpOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile is identical to the local one, except that the guids and
// origins are different.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
TEST_F(
AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldKeepLocalKeyAndRemoteOriginWhenMergingDuplicateProfileWithSmallerKey) {
AutofillProfile local = AutofillProfile(kBiggerGuid, kHttpsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile has the same key.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kSettingsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AutofillProfile merged(local);
merged.set_origin(kSettingsOrigin);
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins except for the
// full name.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(merged));
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged)); EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
} }
...@@ -255,10 +328,10 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest, ...@@ -255,10 +328,10 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(AutofillProfileSyncDifferenceTrackerTest,
FlushToLocalShouldCallbackWhenProfileDeleted) { FlushToLocalShouldCallbackWhenProfileDeleted) {
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
tracker()->IncorporateRemoteDelete(kGuidA); tracker()->IncorporateRemoteDelete(kSmallerGuid);
MockCallback<base::OnceClosure> autofill_changes_callback; MockCallback<base::OnceClosure> autofill_changes_callback;
EXPECT_CALL(autofill_changes_callback, Run()).Times(1); EXPECT_CALL(autofill_changes_callback, Run()).Times(1);
...@@ -271,7 +344,7 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest, ...@@ -271,7 +344,7 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(AutofillProfileSyncDifferenceTrackerTest,
FlushToLocalShouldCallbackWhenProfileAdded) { FlushToLocalShouldCallbackWhenProfileAdded) {
AutofillProfile remote = AutofillProfile(kGuidA, kSettingsOrigin); AutofillProfile remote = AutofillProfile(kSmallerGuid, kSettingsOrigin);
IncorporateRemoteProfile(remote); IncorporateRemoteProfile(remote);
MockCallback<base::OnceClosure> autofill_changes_callback; MockCallback<base::OnceClosure> autofill_changes_callback;
...@@ -285,10 +358,10 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest, ...@@ -285,10 +358,10 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
TEST_F(AutofillProfileSyncDifferenceTrackerTest, TEST_F(AutofillProfileSyncDifferenceTrackerTest,
FlushToLocalShouldCallbackWhenProfileUpdated) { FlushToLocalShouldCallbackWhenProfileUpdated) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpsOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpsOrigin);
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin); AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
IncorporateRemoteProfile(remote); IncorporateRemoteProfile(remote);
...@@ -297,7 +370,7 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest, ...@@ -297,7 +370,7 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
EXPECT_EQ(base::nullopt, EXPECT_EQ(base::nullopt,
tracker()->FlushToLocal(autofill_changes_callback.Get())); tracker()->FlushToLocal(autofill_changes_callback.Get()));
// On top of that, the profile with key kGuidA should also get updated. // On top of that, the profile with key kSmallerGuid should also get updated.
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
} }
...@@ -324,13 +397,13 @@ class AutofillProfileInitialSyncDifferenceTrackerTest ...@@ -324,13 +397,13 @@ class AutofillProfileInitialSyncDifferenceTrackerTest
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncShouldSyncUpChanges) { MergeSimilarEntriesForInitialSyncShouldSyncUpChanges) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
local.set_use_count(27); local.set_use_count(27);
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile matches the local one (except for origin and use count). // The remote profile matches the local one (except for origin and use count).
AutofillProfile remote = AutofillProfile(kGuidB, kHttpsOrigin); AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc.")); remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
remote.set_use_count(13); remote.set_use_count(13);
...@@ -346,19 +419,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, ...@@ -346,19 +419,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSync(); MergeSimilarEntriesForInitialSync();
// The merged profile needs to get uploaded back to sync and stored locally. // The merged profile needs to get uploaded back to sync and stored locally.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(merged)); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(merged));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged)); EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
} }
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncShouldNotSyncUpWhenNotNeeded) { MergeSimilarEntriesForInitialSyncShouldNotSyncUpWhenNotNeeded) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
local.set_use_count(13); local.set_use_count(13);
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile matches the local one and has some additional data. // The remote profile matches the local one and has some additional data.
AutofillProfile remote = AutofillProfile(kGuidB, kHttpOrigin); AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc.")); remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
// Merging two profile takes their max use count, so use count of 27 is taken. // Merging two profile takes their max use count, so use count of 27 is taken.
...@@ -368,19 +443,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, ...@@ -368,19 +443,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSync(); MergeSimilarEntriesForInitialSync();
// Nothing gets uploaded to sync and the remote profile wins. // Nothing gets uploaded to sync and the remote profile wins.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty()); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
} }
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncNotMatchNonsimilarEntries) { MergeSimilarEntriesForInitialSyncNotMatchNonsimilarEntries) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
local.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc.")); local.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile has a different street address. // The remote profile has a different street address.
AutofillProfile remote = AutofillProfile(kGuidB, kHttpOrigin); AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc.")); remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
...@@ -389,19 +466,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, ...@@ -389,19 +466,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
// The local profile gets uploaded (due to initial sync) and the remote // The local profile gets uploaded (due to initial sync) and the remote
// profile gets stored locally. // profile gets stored locally.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(local)); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(local));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote));
} }
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncDoesNotMatchLocalVerifiedEntry) { MergeSimilarEntriesForInitialSyncDoesNotMatchLocalVerifiedEntry) {
// The local entry is verified, should not get merged. // The local entry is verified, should not get merged.
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile is similar to the local one. // The remote profile is similar to the local one.
AutofillProfile remote = AutofillProfile(kGuidB, kHttpOrigin); AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc.")); remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
...@@ -410,19 +489,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, ...@@ -410,19 +489,21 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
// The local profile gets uploaded (due to initial sync) and the remote // The local profile gets uploaded (due to initial sync) and the remote
// profile gets stored locally. // profile gets stored locally.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(local)); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(local));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote));
} }
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncDoesNotMatchRemoteVerifiedEntry) { MergeSimilarEntriesForInitialSyncDoesNotMatchRemoteVerifiedEntry) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin); AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local}); AddAutofillProfilesToTable({local});
// The remote profile is similar to the local one but is verified and thus it // The remote profile is similar to the local one but is verified and thus it
// should not get merged. // should not get merged.
AutofillProfile remote = AutofillProfile(kGuidB, kSettingsOrigin); AutofillProfile remote = AutofillProfile(kBiggerGuid, kSettingsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st")); remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc.")); remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
...@@ -431,7 +512,9 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest, ...@@ -431,7 +512,9 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
// The local profile gets uploaded (due to initial sync) and the remote // The local profile gets uploaded (due to initial sync) and the remote
// profile gets stored locally. // profile gets stored locally.
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(local)); UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(local));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote)); EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote));
} }
......
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