summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorskrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-05 04:13:24 +0000
committerskrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-05 04:13:24 +0000
commit55f9c5a5466d0c7d5550252b653162d7dc775442 (patch)
tree0bf06f2e83478a50222b23c2bdf39cb9e83ecf63 /chrome
parent52aac9e4ff1d4181f1b980a29446fdf5036a185a (diff)
downloadchromium_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.cc4
-rw-r--r--chrome/browser/webdata/autofill_entry.h1
-rw-r--r--chrome/browser/webdata/web_data_service_test_util.h14
-rw-r--r--chrome/browser/webdata/web_data_service_unittest.cc9
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc365
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();
}