diff options
author | skrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-05 04:13:24 +0000 |
---|---|---|
committer | skrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-05 04:13:24 +0000 |
commit | 55f9c5a5466d0c7d5550252b653162d7dc775442 (patch) | |
tree | 0bf06f2e83478a50222b23c2bdf39cb9e83ecf63 /chrome | |
parent | 52aac9e4ff1d4181f1b980a29446fdf5036a185a (diff) | |
download | chromium_src-55f9c5a5466d0c7d5550252b653162d7dc775442.zip chromium_src-55f9c5a5466d0c7d5550252b653162d7dc775442.tar.gz chromium_src-55f9c5a5466d0c7d5550252b653162d7dc775442.tar.bz2 |
Add integration test for autofill profiles.
I also expanded on the orignial autofill "steady" test to include removals. Plus a little refactoring of the WDS test.
Review URL: http://codereview.chromium.org/1963001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46438 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/sync/syncable/syncable.cc | 4 | ||||
-rw-r--r-- | chrome/browser/webdata/autofill_entry.h | 1 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service_test_util.h | 14 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service_unittest.cc | 9 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 2 | ||||
-rw-r--r-- | chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc | 365 |
6 files changed, 374 insertions, 21 deletions
diff --git a/chrome/browser/sync/syncable/syncable.cc b/chrome/browser/sync/syncable/syncable.cc index d6eb33d..d1f1172 100644 --- a/chrome/browser/sync/syncable/syncable.cc +++ b/chrome/browser/sync/syncable/syncable.cc @@ -49,6 +49,7 @@ #include "chrome/browser/sync/util/crypto_helpers.h" #include "chrome/browser/sync/util/fast_dump.h" #include "chrome/common/deprecated/event_sys-inl.h" +#include "net/base/escape.h" namespace { enum InvariantCheckLevel { @@ -1544,7 +1545,8 @@ std::ostream& operator<<(std::ostream& stream, const syncable::Entry& entry) { } for ( ; i < PROTO_FIELDS_END; ++i) { s << g_metas_columns[i].name << colon - << kernel->ref(static_cast<ProtoField>(i)).SerializeAsString() + << EscapePath( + kernel->ref(static_cast<ProtoField>(i)).SerializeAsString()) << separator; } s << "TempFlags: "; diff --git a/chrome/browser/webdata/autofill_entry.h b/chrome/browser/webdata/autofill_entry.h index 8781fbd..cb310c3 100644 --- a/chrome/browser/webdata/autofill_entry.h +++ b/chrome/browser/webdata/autofill_entry.h @@ -7,7 +7,6 @@ #include <vector> #include "base/string16.h" -#include "base/string_util.h" #include "base/time.h" #include "base/utf_string_conversions.h" diff --git a/chrome/browser/webdata/web_data_service_test_util.h b/chrome/browser/webdata/web_data_service_test_util.h index 31abfac..dba6fc3 100644 --- a/chrome/browser/webdata/web_data_service_test_util.h +++ b/chrome/browser/webdata/web_data_service_test_util.h @@ -12,6 +12,7 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/webdata/web_data_service.h" +template <class T> class AutofillWebDataServiceConsumer: public WebDataServiceConsumer { public: AutofillWebDataServiceConsumer() : handle_(0) {} @@ -20,23 +21,20 @@ class AutofillWebDataServiceConsumer: public WebDataServiceConsumer { virtual void OnWebDataServiceRequestDone(WebDataService::Handle handle, const WDTypedResult* result) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - DCHECK(result->GetType() == AUTOFILL_VALUE_RESULT); handle_ = handle; - const WDResult<std::vector<string16> >* autofill_result = - static_cast<const WDResult<std::vector<string16> >*>(result); - // Copy the values. - values_ = autofill_result->GetValue(); + const WDResult<T>* wrapped_result = + static_cast<const WDResult<T>*>(result); + result_ = wrapped_result->GetValue(); - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); MessageLoop::current()->Quit(); } WebDataService::Handle handle() { return handle_; } - const std::vector<string16>& values() { return values_; } + T& result() { return result_; } private: WebDataService::Handle handle_; - std::vector<string16> values_; + T result_; DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer); }; diff --git a/chrome/browser/webdata/web_data_service_unittest.cc b/chrome/browser/webdata/web_data_service_unittest.cc index 043a091..c11d4b7 100644 --- a/chrome/browser/webdata/web_data_service_unittest.cc +++ b/chrome/browser/webdata/web_data_service_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <string> #include <vector> #include "base/basictypes.h" @@ -169,7 +170,7 @@ TEST_F(WebDataServiceAutofillTest, FormFillAdd) { // The event will be signaled when the mock observer is notified. done_event_.TimedWait(test_timeout_); - AutofillWebDataServiceConsumer consumer; + AutofillWebDataServiceConsumer<std::vector<string16> > consumer; WebDataService::Handle handle; static const int limit = 10; handle = wds_->GetFormValuesForElementName( @@ -179,8 +180,8 @@ TEST_F(WebDataServiceAutofillTest, FormFillAdd) { MessageLoop::current()->Run(); EXPECT_EQ(handle, consumer.handle()); - ASSERT_EQ(1U, consumer.values().size()); - EXPECT_EQ(value1_, consumer.values()[0]); + ASSERT_EQ(1U, consumer.result().size()); + EXPECT_EQ(value1_, consumer.result()[0]); } TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) { @@ -212,7 +213,7 @@ TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) { done_event_.TimedWait(test_timeout_); } -TEST_F(WebDataServiceAutofillTest,FormFillRemoveMany) { +TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) { TimeDelta one_day(TimeDelta::FromDays(1)); Time t = Time::Now(); diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 27ee306..1f601b3 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1902,6 +1902,8 @@ 'defines': [ 'ALLOW_IN_PROC_BROWSER_TEST' ], 'sources': [ 'app/chrome_dll_resource.h', + 'browser/autofill/autofill_common_unittest.cc', + 'browser/autofill/autofill_common_unittest.h', 'test/in_process_browser_test.cc', 'test/in_process_browser_test.h', 'test/test_launcher/out_of_proc_test_runner.cc', diff --git a/chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc b/chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc index e09f26e..24dbf5a 100644 --- a/chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc +++ b/chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc @@ -7,18 +7,26 @@ #include "base/command_line.h" #include "base/ref_counted.h" +#include "base/stl_util-inl.h" #include "base/string16.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/waitable_event.h" +#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_profile.h" +#include "chrome/browser/autofill/autofill_type.h" +#include "chrome/browser/autofill/field_types.h" +#include "chrome/browser/autofill/personal_data_manager.h" #include "chrome/browser/browser.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/browser/sync/profile_sync_test_util.h" #include "chrome/browser/webdata/autofill_entry.h" #include "chrome/browser/webdata/web_database.h" #include "chrome/browser/webdata/web_data_service.h" #include "chrome/browser/webdata/web_data_service_test_util.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/notification_observer_mock.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" @@ -99,11 +107,39 @@ class AutofillDBThreadObserverHelper : public DBThreadObserverHelper { } }; -} // namespace; +enum ProfileType { + MARION, + HOMER +}; + +void FillProfile(ProfileType type, AutoFillProfile* profile) { + switch (type) { + case MARION: + autofill_unittest::SetProfileInfo(profile, + "Billing", "Marion", "Mitchell", "Morrison", + "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", + "91601", "US", "12345678910", "01987654321"); + break; + case HOMER: + autofill_unittest::SetProfileInfo(profile, + "Shipping", "Homer", "J.", "Simpson", + "homer@snpp.com", "SNPP", "1 Main St", "PO Box 1", "Springfield", "MA", + "94101", "US", "14155551212", "14155551313"); + break; + } +} + +class MockPersonalDataManagerObserver : public PersonalDataManager::Observer { + public: + MOCK_METHOD0(OnPersonalDataLoaded, void()); +}; + +} // namespace class TwoClientLiveAutofillSyncTest : public LiveSyncTest { public: typedef std::set<AutofillKey> AutofillKeys; + typedef std::vector<AutoFillProfile*> AutoFillProfiles; TwoClientLiveAutofillSyncTest() : name1_(ASCIIToUTF16("name1")), name2_(ASCIIToUTF16("name2")), @@ -127,6 +163,8 @@ class TwoClientLiveAutofillSyncTest : public LiveSyncTest { profile2_.get(), username_, password_)); wds1_ = browser()->profile()->GetWebDataService(Profile::EXPLICIT_ACCESS); wds2_ = profile2_->GetWebDataService(Profile::EXPLICIT_ACCESS); + pdm1_ = browser()->profile()->GetPersonalDataManager(); + pdm2_ = profile2_->GetPersonalDataManager(); } void SetupSync() { @@ -141,7 +179,11 @@ class TwoClientLiveAutofillSyncTest : public LiveSyncTest { profile2_.reset(); } - void AddToWds(WebDataService* wds, const AutofillKeys& keys) { + virtual void SetUpCommandLine(CommandLine* command_line) { + command_line->AppendSwitch(switches::kEnableSyncAutofill); + } + + void AddFormFieldsToWebData(WebDataService* wds, const AutofillKeys& keys) { std::vector<webkit_glue::FormField> form_fields; for (AutofillKeys::const_iterator i = keys.begin(); i != keys.end(); ++i) { form_fields.push_back( @@ -162,6 +204,62 @@ class TwoClientLiveAutofillSyncTest : public LiveSyncTest { done_event.Wait(); } + void RemoveKeyFromWebData(WebDataService* wds, const AutofillKey& key) { + WaitableEvent done_event(false, false); + scoped_refptr<AutofillDBThreadObserverHelper> observer_helper( + new AutofillDBThreadObserverHelper()); + observer_helper->Init(); + + EXPECT_CALL(*observer_helper->observer(), Observe(_, _, _)). + WillOnce(SignalEvent(&done_event)); + wds->RemoveFormValueForElementName(key.name(), key.value()); + done_event.Wait(); + } + + void SetProfiles(PersonalDataManager* pdm, + std::vector<AutoFillProfile>* profiles) { + MockPersonalDataManagerObserver observer; + EXPECT_CALL(observer, OnPersonalDataLoaded()). + WillOnce(QuitUIMessageLoop()); + pdm->SetObserver(&observer); + pdm->SetProfiles(profiles); + MessageLoop::current()->Run(); + pdm->RemoveObserver(&observer); + } + + void AddProfile(PersonalDataManager* pdm, const AutoFillProfile& profile) { + const AutoFillProfiles& all_profiles = GetAllAutoFillProfiles(pdm); + std::vector<AutoFillProfile> profiles; + for (size_t i = 0; i < all_profiles.size(); ++i) + profiles.push_back(*all_profiles[i]); + profiles.push_back(profile); + SetProfiles(pdm, &profiles); + } + + void RemoveProfile(PersonalDataManager* pdm, const string16& label) { + const AutoFillProfiles& all_profiles = GetAllAutoFillProfiles(pdm); + std::vector<AutoFillProfile> profiles; + for (size_t i = 0; i < all_profiles.size(); ++i) { + if (all_profiles[i]->Label() != label) + profiles.push_back(*all_profiles[i]); + } + SetProfiles(pdm, &profiles); + } + + void UpdateProfile(PersonalDataManager* pdm, + const string16& label, + const AutoFillType& type, + const string16& value) { + const AutoFillProfiles& all_profiles = GetAllAutoFillProfiles(pdm); + std::vector<AutoFillProfile> profiles; + for (size_t i = 0; i < all_profiles.size(); ++i) { + profiles.push_back(*all_profiles[i]); + if (all_profiles[i]->Label() == label) + profiles.back().SetInfo(type, value); + } + SetProfiles(pdm, &profiles); + } + void GetAllAutofillKeys(WebDataService* wds, AutofillKeys* keys) { scoped_refptr<GetAllAutofillEntries> get_all_entries = new GetAllAutofillEntries(wds); @@ -173,6 +271,48 @@ class TwoClientLiveAutofillSyncTest : public LiveSyncTest { } } + const AutoFillProfiles& GetAllAutoFillProfiles(PersonalDataManager* pdm) { + MockPersonalDataManagerObserver observer; + EXPECT_CALL(observer, OnPersonalDataLoaded()). + WillOnce(QuitUIMessageLoop()); + pdm->SetObserver(&observer); + pdm->Refresh(); + MessageLoop::current()->Run(); + pdm->RemoveObserver(&observer); + return pdm->profiles(); + } + + bool CompareAutoFillProfiles(const AutoFillProfiles& expected_profiles, + const AutoFillProfiles& profiles) { + std::map<string16, AutoFillProfile> expected_profiles_map; + for (size_t i = 0; i < expected_profiles.size(); ++i) { + const AutoFillProfile* p = expected_profiles[i]; + expected_profiles_map[p->Label()] = *p; + } + + for (size_t i = 0; i < profiles.size(); ++i) { + const AutoFillProfile* p = profiles[i]; + if (!expected_profiles_map.count(p->Label())) { + LOG(INFO) << "Label " << p->Label() << " not in expected"; + return false; + } + AutoFillProfile* expected_profile = &expected_profiles_map[p->Label()]; + expected_profile->set_unique_id(p->unique_id()); + if (*expected_profile != *p) { + LOG(INFO) << "Profile mismatch"; + return false; + } + expected_profiles_map.erase(p->Label()); + } + + if (expected_profiles_map.size()) { + LOG(INFO) << "Labels in expected but not supplied"; + return false; + } + + return true; + } + ProfileSyncServiceTestHarness* client1() { return client1_.get(); } ProfileSyncServiceTestHarness* client2() { return client2_.get(); } @@ -191,6 +331,8 @@ class TwoClientLiveAutofillSyncTest : public LiveSyncTest { scoped_ptr<Profile> profile2_; WebDataService* wds1_; WebDataService* wds2_; + PersonalDataManager* pdm1_; + PersonalDataManager* pdm2_; DISALLOW_COPY_AND_ASSIGN(TwoClientLiveAutofillSyncTest); }; @@ -204,7 +346,7 @@ IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, Client1HasData) { keys.insert(AutofillKey("name2", "value3")); keys.insert(AutofillKey(WideToUTF16(L"Sigur R\u00F3s"), WideToUTF16(L"\u00C1g\u00E6tis byrjun"))); - AddToWds(wds1_, keys); + AddFormFieldsToWebData(wds1_, keys); SetupSync(); @@ -222,14 +364,14 @@ IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, BothHaveData) { keys1.insert(AutofillKey("name1", "value1")); keys1.insert(AutofillKey("name1", "value2")); keys1.insert(AutofillKey("name2", "value3")); - AddToWds(wds1_, keys1); + AddFormFieldsToWebData(wds1_, keys1); AutofillKeys keys2; keys2.insert(AutofillKey("name1", "value2")); keys2.insert(AutofillKey("name2", "value3")); keys2.insert(AutofillKey("name3", "value4")); keys2.insert(AutofillKey("name4", "value4")); - AddToWds(wds2_, keys2); + AddFormFieldsToWebData(wds2_, keys2); SetupSync(); // Wait for client1 to get the new keys from client2. @@ -257,21 +399,230 @@ IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, Steady) { SetupHarness(); SetupSync(); + // Client1 adds a key. AutofillKeys add_one_key; add_one_key.insert(AutofillKey("name1", "value1")); - AddToWds(wds1_, add_one_key); + AddFormFieldsToWebData(wds1_, add_one_key); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); AutofillKeys expected_keys; expected_keys.insert(AutofillKey("name1", "value1")); + AutofillKeys keys; + GetAllAutofillKeys(wds1_, &keys); + EXPECT_EQ(expected_keys, keys); + keys.clear(); + GetAllAutofillKeys(wds2_, &keys); + EXPECT_EQ(expected_keys, keys); + + // Client2 adds a key. + add_one_key.clear(); + add_one_key.insert(AutofillKey("name2", "value2")); + AddFormFieldsToWebData(wds2_, add_one_key); EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); - AutofillKeys keys; + expected_keys.insert(AutofillKey("name2", "value2")); + keys.clear(); + GetAllAutofillKeys(wds1_, &keys); + EXPECT_EQ(expected_keys, keys); + keys.clear(); + GetAllAutofillKeys(wds2_, &keys); + EXPECT_EQ(expected_keys, keys); + + // Client1 adds a key with the same name. + add_one_key.clear(); + add_one_key.insert(AutofillKey("name2", "value3")); + AddFormFieldsToWebData(wds1_, add_one_key); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + expected_keys.insert(AutofillKey("name2", "value3")); + keys.clear(); GetAllAutofillKeys(wds1_, &keys); EXPECT_EQ(expected_keys, keys); keys.clear(); GetAllAutofillKeys(wds2_, &keys); EXPECT_EQ(expected_keys, keys); + // Client2 removes a key. + RemoveKeyFromWebData(wds2_, AutofillKey("name2", "value2")); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + expected_keys.erase(AutofillKey("name2", "value2")); + keys.clear(); + GetAllAutofillKeys(wds1_, &keys); + EXPECT_EQ(expected_keys, keys); + keys.clear(); + GetAllAutofillKeys(wds2_, &keys); + EXPECT_EQ(expected_keys, keys); + + // Client1 removes the rest. + RemoveKeyFromWebData(wds1_, AutofillKey("name1", "value1")); + RemoveKeyFromWebData(wds1_, AutofillKey("name2", "value3")); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + keys.clear(); + GetAllAutofillKeys(wds1_, &keys); + EXPECT_EQ(0U, keys.size()); + keys.clear(); + GetAllAutofillKeys(wds2_, &keys); + EXPECT_EQ(0U, keys.size()); + + Cleanup(); +} + +IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, ProfileClient1HasData) { + SetupHarness(); + + AutoFillProfiles expected_profiles; + expected_profiles.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(MARION, expected_profiles[0]); + expected_profiles.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(HOMER, expected_profiles[1]); + AddProfile(pdm1_, *expected_profiles[0]); + AddProfile(pdm1_, *expected_profiles[1]); + + SetupSync(); + + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + Cleanup(); + STLDeleteElements(&expected_profiles); +} + +IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, + ProfileSameLabelOnDifferentClients) { + SetupHarness(); + + AutoFillProfiles profiles1; + profiles1.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(HOMER, profiles1[0]); + + AutoFillProfiles profiles2; + profiles2.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(MARION, profiles2[0]); + profiles2[0]->set_label(ASCIIToUTF16("Shipping")); + + AddProfile(pdm1_, *profiles1[0]); + AddProfile(pdm2_, *profiles2[0]); + + SetupSync(); + + // Since client1 associates first, client2's "Shipping" profile will + // be overwritten by the one stored in the cloud by profile1. + EXPECT_TRUE(CompareAutoFillProfiles(profiles1, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(profiles1, + GetAllAutoFillProfiles(pdm2_))); + Cleanup(); + STLDeleteElements(&profiles1); + STLDeleteElements(&profiles2); +} + +IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, + ProfileSameLabelOnClient1) { + SetupHarness(); + + AutoFillProfiles expected_profiles; + expected_profiles.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(HOMER, expected_profiles[0]); + expected_profiles.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(HOMER, expected_profiles[1]); + + AddProfile(pdm1_, *expected_profiles[0]); + AddProfile(pdm1_, *expected_profiles[1]); + + SetupSync(); + + // One of the duplicate profiles will have its label renamed to + // "Shipping2". + expected_profiles[0]->set_label(ASCIIToUTF16("Shipping2")); + + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + Cleanup(); + STLDeleteElements(&expected_profiles); +} + + +IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, ProfileSteady) { + SetupHarness(); + SetupSync(); + + // Client1 adds a profile. + AutoFillProfiles expected_profiles; + expected_profiles.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(HOMER, expected_profiles[0]); + AddProfile(pdm1_, *expected_profiles[0]); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + + // Client2 adds a profile. + expected_profiles.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(MARION, expected_profiles[1]); + AddProfile(pdm2_, *expected_profiles[1]); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + + // Client1 adds a conflicting profile. + expected_profiles.push_back(new AutoFillProfile(string16(), 0)); + FillProfile(MARION, expected_profiles[2]); + AddProfile(pdm1_, *expected_profiles[2]); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + // The conflicting profile's label will be made unique. + expected_profiles[2]->set_label(ASCIIToUTF16("Billing2")); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + + // Client2 removes a profile. + delete expected_profiles.front(); + expected_profiles.erase(expected_profiles.begin()); + RemoveProfile(pdm2_, ASCIIToUTF16("Shipping")); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + + // Client1 updates a profile. + expected_profiles[0]->SetInfo(AutoFillType(NAME_FIRST), + ASCIIToUTF16("Bart")); + UpdateProfile(pdm1_, + ASCIIToUTF16("Billing"), + AutoFillType(NAME_FIRST), + ASCIIToUTF16("Bart")); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + + // Client2 removes everything. + STLDeleteElements(&expected_profiles); + RemoveProfile(pdm2_, ASCIIToUTF16("Billing")); + RemoveProfile(pdm2_, ASCIIToUTF16("Billing2")); + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm1_))); + EXPECT_TRUE(CompareAutoFillProfiles(expected_profiles, + GetAllAutoFillProfiles(pdm2_))); + Cleanup(); } |