Move c/b/webdata/code which does not depend on chrome/ to components/webdata/
[chromium-blink-merge.git] / chrome / browser / webdata / autofill_profile_syncable_service_unittest.cc
blobd3070c042787dcb085147a71efbd176a1cb5dce1
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/location.h"
6 #include "base/message_loop.h"
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/webdata/autofill_profile_syncable_service.h"
9 #include "components/autofill/browser/autofill_profile.h"
10 #include "components/webdata/autofill/autofill_change.h"
11 #include "content/public/test/test_browser_thread.h"
12 #include "sync/api/sync_error_factory.h"
13 #include "sync/api/sync_error_factory_mock.h"
14 #include "sync/protocol/sync.pb.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using ::testing::_;
19 using ::testing::DoAll;
20 using ::testing::Eq;
21 using ::testing::Return;
22 using ::testing::Property;
23 using content::BrowserThread;
24 class AutofillProfile;
26 // Some guids for testing.
27 std::string kGuid1 = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
28 std::string kGuid2 = "EDC609ED-7EEE-4F27-B00C-423242A9C44C";
29 std::string kGuid3 = "EDC609ED-7EEE-4F27-B00C-423242A9C44D";
30 std::string kGuid4 = "EDC609ED-7EEE-4F27-B00C-423242A9C44E";
32 class MockAutofillProfileSyncableService
33 : public AutofillProfileSyncableService {
34 public:
35 MockAutofillProfileSyncableService() {
37 virtual ~MockAutofillProfileSyncableService() {}
39 MOCK_METHOD1(LoadAutofillData, bool(std::vector<AutofillProfile*>*));
40 MOCK_METHOD1(SaveChangesToWebData,
41 bool(const AutofillProfileSyncableService::DataBundle&));
44 ACTION_P(CopyData, data) {
45 arg0->resize(data->size());
46 std::copy(data->begin(), data->end(), arg0->begin());
49 MATCHER_P(CheckSyncChanges, n_sync_changes_list, "") {
50 if (arg.size() != n_sync_changes_list.size())
51 return false;
52 syncer::SyncChangeList::const_iterator passed, expected;
53 for (passed = arg.begin(), expected = n_sync_changes_list.begin();
54 passed != arg.end() && expected != n_sync_changes_list.end();
55 ++passed, ++expected) {
56 DCHECK(passed->IsValid());
57 if (passed->change_type() != expected->change_type())
58 return false;
59 if (passed->sync_data().GetSpecifics().autofill_profile().guid() !=
60 expected->sync_data().GetSpecifics().autofill_profile().guid()) {
61 return false;
64 return true;
67 MATCHER_P(DataBundleCheck, n_bundle, "") {
68 if ((arg.profiles_to_delete.size() != n_bundle.profiles_to_delete.size()) ||
69 (arg.profiles_to_update.size() != n_bundle.profiles_to_update.size()) ||
70 (arg.profiles_to_add.size() != n_bundle.profiles_to_add.size())) {
71 return false;
73 for (size_t i = 0; i < arg.profiles_to_delete.size(); ++i) {
74 if (arg.profiles_to_delete[i] != n_bundle.profiles_to_delete[i])
75 return false;
77 for (size_t i = 0; i < arg.profiles_to_update.size(); ++i) {
78 if (arg.profiles_to_update[i]->guid() !=
79 n_bundle.profiles_to_update[i]->guid()) {
80 return false;
83 for (size_t i = 0; i < arg.profiles_to_add.size(); ++i) {
84 if (arg.profiles_to_add[i]->Compare(*n_bundle.profiles_to_add[i]))
85 return false;
87 return true;
90 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
91 public:
92 MockSyncChangeProcessor() {}
93 virtual ~MockSyncChangeProcessor() {}
95 MOCK_METHOD2(ProcessSyncChanges,
96 syncer::SyncError(const tracked_objects::Location&,
97 const syncer::SyncChangeList&));
100 class AutofillProfileSyncableServiceTest : public testing::Test {
101 public:
102 AutofillProfileSyncableServiceTest()
103 : ui_thread_(BrowserThread::UI, &message_loop_),
104 db_thread_(BrowserThread::DB, &message_loop_) {}
106 virtual void SetUp() OVERRIDE {
107 sync_processor_.reset(new MockSyncChangeProcessor);
110 protected:
111 MessageLoop message_loop_;
112 content::TestBrowserThread ui_thread_;
113 content::TestBrowserThread db_thread_;
114 MockAutofillProfileSyncableService autofill_syncable_service_;
115 scoped_ptr<MockSyncChangeProcessor> sync_processor_;
118 TEST_F(AutofillProfileSyncableServiceTest, MergeDataAndStartSyncing) {
119 std::vector<AutofillProfile *> profiles_from_web_db;
120 std::string guid_present1 = kGuid1;
121 std::string guid_present2 = kGuid2;
122 std::string guid_synced1 = kGuid3;
123 std::string guid_synced2 = kGuid4;
125 profiles_from_web_db.push_back(new AutofillProfile(guid_present1));
126 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
127 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
128 UTF8ToUTF16("1 1st st"));
129 profiles_from_web_db.push_back(new AutofillProfile(guid_present2));
130 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom"));
131 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
132 UTF8ToUTF16("2 2nd st"));
134 syncer::SyncDataList data_list;
135 AutofillProfile profile1(guid_synced1);
136 profile1.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
137 data_list.push_back(autofill_syncable_service_.CreateData(profile1));
138 AutofillProfile profile2(guid_synced2);
139 profile2.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Harry"));
140 data_list.push_back(autofill_syncable_service_.CreateData(profile2));
141 // This one will have the name updated.
142 AutofillProfile profile3(guid_present2);
143 profile3.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom Doe"));
144 data_list.push_back(autofill_syncable_service_.CreateData(profile3));
146 syncer::SyncChangeList expected_change_list;
147 expected_change_list.push_back(
148 syncer::SyncChange(FROM_HERE,
149 syncer::SyncChange::ACTION_ADD,
150 AutofillProfileSyncableService::CreateData(
151 (*profiles_from_web_db.front()))));
153 AutofillProfileSyncableService::DataBundle expected_bundle;
154 expected_bundle.profiles_to_add.push_back(&profile1);
155 expected_bundle.profiles_to_add.push_back(&profile2);
156 expected_bundle.profiles_to_update.push_back(&profile3);
158 EXPECT_CALL(autofill_syncable_service_, LoadAutofillData(_))
159 .Times(1)
160 .WillOnce(DoAll(CopyData(&profiles_from_web_db), Return(true)));
161 EXPECT_CALL(autofill_syncable_service_,
162 SaveChangesToWebData(DataBundleCheck(expected_bundle)))
163 .Times(1)
164 .WillOnce(Return(true));
165 ON_CALL(*sync_processor_, ProcessSyncChanges(_, _))
166 .WillByDefault(Return(syncer::SyncError()));
167 EXPECT_CALL(*sync_processor_,
168 ProcessSyncChanges(_, CheckSyncChanges(expected_change_list)))
169 .Times(1)
170 .WillOnce(Return(syncer::SyncError()));
172 // Takes ownership of sync_processor_.
173 autofill_syncable_service_.MergeDataAndStartSyncing(
174 syncer::AUTOFILL_PROFILE, data_list,
175 sync_processor_.PassAs<syncer::SyncChangeProcessor>(),
176 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
177 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
180 TEST_F(AutofillProfileSyncableServiceTest, GetAllSyncData) {
181 std::vector<AutofillProfile *> profiles_from_web_db;
182 std::string guid_present1 = kGuid1;
183 std::string guid_present2 = kGuid2;
185 profiles_from_web_db.push_back(new AutofillProfile(guid_present1));
186 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
187 profiles_from_web_db.push_back(new AutofillProfile(guid_present2));
188 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
190 EXPECT_CALL(autofill_syncable_service_, LoadAutofillData(_))
191 .Times(1)
192 .WillOnce(DoAll(CopyData(&profiles_from_web_db), Return(true)));
193 EXPECT_CALL(autofill_syncable_service_, SaveChangesToWebData(_))
194 .Times(1)
195 .WillOnce(Return(true));
196 ON_CALL(*sync_processor_, ProcessSyncChanges(_, _))
197 .WillByDefault(Return(syncer::SyncError()));
198 EXPECT_CALL(*sync_processor_,
199 ProcessSyncChanges(
201 Property(&syncer::SyncChangeList::size, Eq(2U))))
202 .Times(1)
203 .WillOnce(Return(syncer::SyncError()));
205 syncer::SyncDataList data_list;
206 // Takes ownership of sync_processor_.
207 autofill_syncable_service_.MergeDataAndStartSyncing(
208 syncer::AUTOFILL_PROFILE, data_list,
209 sync_processor_.PassAs<syncer::SyncChangeProcessor>(),
210 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
212 syncer::SyncDataList data =
213 autofill_syncable_service_.GetAllSyncData(syncer::AUTOFILL_PROFILE);
215 EXPECT_EQ(2U, data.size());
216 EXPECT_EQ(guid_present1, data.front().GetSpecifics()
217 .autofill_profile().guid());
218 EXPECT_EQ(guid_present2, data.back().GetSpecifics()
219 .autofill_profile().guid());
222 TEST_F(AutofillProfileSyncableServiceTest, ProcessSyncChanges) {
223 std::vector<AutofillProfile *> profiles_from_web_db;
224 std::string guid_present = kGuid1;
225 std::string guid_synced = kGuid2;
227 syncer::SyncChangeList change_list;
228 AutofillProfile profile(guid_synced);
229 profile.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
230 change_list.push_back(
231 syncer::SyncChange(FROM_HERE,
232 syncer::SyncChange::ACTION_ADD,
233 AutofillProfileSyncableService::CreateData(profile)));
234 AutofillProfile empty_profile(guid_present);
235 change_list.push_back(
236 syncer::SyncChange(
237 FROM_HERE,
238 syncer::SyncChange::ACTION_DELETE,
239 AutofillProfileSyncableService::CreateData(empty_profile)));
241 AutofillProfileSyncableService::DataBundle expected_bundle;
242 expected_bundle.profiles_to_delete.push_back(guid_present);
243 expected_bundle.profiles_to_add.push_back(&profile);
245 EXPECT_CALL(autofill_syncable_service_, SaveChangesToWebData(
246 DataBundleCheck(expected_bundle)))
247 .Times(1)
248 .WillOnce(Return(true));
250 autofill_syncable_service_.set_sync_processor(sync_processor_.release());
251 syncer::SyncError error = autofill_syncable_service_.ProcessSyncChanges(
252 FROM_HERE, change_list);
254 EXPECT_FALSE(error.IsSet());
257 TEST_F(AutofillProfileSyncableServiceTest, ActOnChange) {
258 AutofillProfile profile(kGuid1);
259 profile.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
260 AutofillProfileChange change1(AutofillProfileChange::ADD, kGuid1, &profile);
261 AutofillProfileChange change2(AutofillProfileChange::REMOVE, kGuid2, NULL);
262 ON_CALL(*sync_processor_, ProcessSyncChanges(_, _))
263 .WillByDefault(
264 Return(syncer::SyncError(FROM_HERE, std::string("an error"),
265 syncer::AUTOFILL_PROFILE)));
266 EXPECT_CALL(*sync_processor_, ProcessSyncChanges(_, _)).Times(2);
268 autofill_syncable_service_.set_sync_processor(sync_processor_.release());
269 autofill_syncable_service_.ActOnChange(change1);
270 autofill_syncable_service_.ActOnChange(change2);
273 TEST_F(AutofillProfileSyncableServiceTest, UpdateField) {
274 AutofillProfile profile(kGuid1);
275 std::string company1 = "A Company";
276 std::string company2 = "Another Company";
277 profile.SetRawInfo(COMPANY_NAME, UTF8ToUTF16(company1));
278 EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
279 COMPANY_NAME, company1, &profile));
280 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), UTF8ToUTF16(company1));
281 EXPECT_TRUE(AutofillProfileSyncableService::UpdateField(
282 COMPANY_NAME, company2, &profile));
283 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), UTF8ToUTF16(company2));
284 EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
285 COMPANY_NAME, company2, &profile));
286 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), UTF8ToUTF16(company2));
289 TEST_F(AutofillProfileSyncableServiceTest, UpdateMultivaluedField) {
290 AutofillProfile profile(kGuid1);
292 std::vector<string16> values;
293 values.push_back(UTF8ToUTF16("1@1.com"));
294 values.push_back(UTF8ToUTF16("2@1.com"));
295 profile.SetRawMultiInfo(EMAIL_ADDRESS, values);
297 ::google::protobuf::RepeatedPtrField<std::string> specifics_fields;
298 specifics_fields.AddAllocated(new std::string("2@1.com"));
299 specifics_fields.AddAllocated(new std::string("3@1.com"));
301 EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
302 EMAIL_ADDRESS, specifics_fields, &profile));
303 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
304 ASSERT_TRUE(values.size() == 2);
305 EXPECT_EQ(values[0], UTF8ToUTF16("2@1.com"));
306 EXPECT_EQ(values[1], UTF8ToUTF16("3@1.com"));
308 EXPECT_FALSE(AutofillProfileSyncableService::UpdateMultivaluedField(
309 EMAIL_ADDRESS, specifics_fields, &profile));
310 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
311 ASSERT_EQ(values.size(), 2U);
312 EXPECT_EQ(values[0], UTF8ToUTF16("2@1.com"));
313 EXPECT_EQ(values[1], UTF8ToUTF16("3@1.com"));
314 EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
315 EMAIL_ADDRESS, ::google::protobuf::RepeatedPtrField<std::string>(),
316 &profile));
317 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
318 ASSERT_EQ(values.size(), 1U); // Always have at least an empty string.
319 EXPECT_EQ(values[0], UTF8ToUTF16(""));
322 TEST_F(AutofillProfileSyncableServiceTest, MergeProfile) {
323 AutofillProfile profile1(kGuid1);
324 profile1.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("111 First St."));
326 std::vector<string16> values;
327 values.push_back(UTF8ToUTF16("1@1.com"));
328 values.push_back(UTF8ToUTF16("2@1.com"));
329 profile1.SetRawMultiInfo(EMAIL_ADDRESS, values);
331 AutofillProfile profile2(kGuid2);
332 profile2.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("111 First St."));
334 // |values| now is [ "1@1.com", "2@1.com", "3@1.com" ].
335 values.push_back(UTF8ToUTF16("3@1.com"));
336 profile2.SetRawMultiInfo(EMAIL_ADDRESS, values);
338 values.clear();
339 values.push_back(UTF8ToUTF16("John"));
340 profile1.SetRawMultiInfo(NAME_FIRST, values);
341 values.push_back(UTF8ToUTF16("Jane"));
342 profile2.SetRawMultiInfo(NAME_FIRST, values);
344 values.clear();
345 values.push_back(UTF8ToUTF16("Doe"));
346 profile1.SetRawMultiInfo(NAME_LAST, values);
347 values.push_back(UTF8ToUTF16("Other"));
348 profile2.SetRawMultiInfo(NAME_LAST, values);
350 values.clear();
351 values.push_back(UTF8ToUTF16("650234567"));
352 profile2.SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, values);
354 EXPECT_FALSE(AutofillProfileSyncableService::MergeProfile(profile2,
355 &profile1));
357 profile1.GetRawMultiInfo(NAME_FIRST, &values);
358 ASSERT_EQ(values.size(), 2U);
359 EXPECT_EQ(values[0], UTF8ToUTF16("John"));
360 EXPECT_EQ(values[1], UTF8ToUTF16("Jane"));
362 profile1.GetRawMultiInfo(NAME_LAST, &values);
363 ASSERT_EQ(values.size(), 2U);
364 EXPECT_EQ(values[0], UTF8ToUTF16("Doe"));
365 EXPECT_EQ(values[1], UTF8ToUTF16("Other"));
367 profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
368 ASSERT_EQ(values.size(), 3U);
369 EXPECT_EQ(values[0], UTF8ToUTF16("1@1.com"));
370 EXPECT_EQ(values[1], UTF8ToUTF16("2@1.com"));
371 EXPECT_EQ(values[2], UTF8ToUTF16("3@1.com"));
373 profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
374 ASSERT_EQ(values.size(), 1U);
375 EXPECT_EQ(values[0], UTF8ToUTF16("650234567"));
377 AutofillProfile profile3(kGuid3);
378 profile3.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("111 First St."));
380 values.clear();
381 values.push_back(UTF8ToUTF16("Jane"));
382 profile3.SetRawMultiInfo(NAME_FIRST, values);
384 values.clear();
385 values.push_back(UTF8ToUTF16("Doe"));
386 profile3.SetRawMultiInfo(NAME_LAST, values);
388 EXPECT_TRUE(AutofillProfileSyncableService::MergeProfile(profile3,
389 &profile1));
391 profile1.GetRawMultiInfo(NAME_FIRST, &values);
392 ASSERT_EQ(values.size(), 3U);
393 EXPECT_EQ(values[0], UTF8ToUTF16("John"));
394 EXPECT_EQ(values[1], UTF8ToUTF16("Jane"));
395 EXPECT_EQ(values[2], UTF8ToUTF16("Jane"));
397 profile1.GetRawMultiInfo(NAME_LAST, &values);
398 ASSERT_EQ(values.size(), 3U);
399 EXPECT_EQ(values[0], UTF8ToUTF16("Doe"));
400 EXPECT_EQ(values[1], UTF8ToUTF16("Other"));
401 EXPECT_EQ(values[2], UTF8ToUTF16("Doe"));
403 // Middle name should have three entries as well.
404 profile1.GetRawMultiInfo(NAME_MIDDLE, &values);
405 ASSERT_EQ(values.size(), 3U);
406 EXPECT_TRUE(values[0].empty());
407 EXPECT_TRUE(values[1].empty());
408 EXPECT_TRUE(values[2].empty());
410 profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
411 ASSERT_EQ(values.size(), 3U);
412 EXPECT_EQ(values[0], UTF8ToUTF16("1@1.com"));
413 EXPECT_EQ(values[1], UTF8ToUTF16("2@1.com"));
414 EXPECT_EQ(values[2], UTF8ToUTF16("3@1.com"));
416 profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
417 ASSERT_EQ(values.size(), 1U);
418 EXPECT_EQ(values[0], UTF8ToUTF16("650234567"));