Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: chrome/browser/webdata/autofill_profile_syncable_service_unittest.cc

Issue 129463002: Move AutofillProfileSyncableService into the Autofill component. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Propagate define Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "base/location.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/webdata/autofill_profile_syncable_service.h"
9 #include "components/autofill/core/browser/autofill_profile.h"
10 #include "components/autofill/core/browser/webdata/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"
17
18 namespace autofill {
19
20 using ::testing::_;
21 using ::testing::DoAll;
22 using ::testing::Eq;
23 using ::testing::Return;
24 using ::testing::Property;
25 using base::ASCIIToUTF16;
26 using base::UTF8ToUTF16;
27 using content::BrowserThread;
28
29 namespace {
30
31 // Some guids for testing.
32 const char kGuid1[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
33 const char kGuid2[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44C";
34 const char kGuid3[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44D";
35 const char kGuid4[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44E";
36 const char kHttpOrigin[] = "http://www.example.com/";
37 const char kHttpsOrigin[] = "https://www.example.com/";
38 const char kSettingsOrigin[] = "Chrome settings";
39
40 class MockAutofillProfileSyncableService
41 : public AutofillProfileSyncableService {
42 public:
43 MockAutofillProfileSyncableService() {}
44 virtual ~MockAutofillProfileSyncableService() {}
45
46 using AutofillProfileSyncableService::DataBundle;
47 using AutofillProfileSyncableService::set_sync_processor;
48 using AutofillProfileSyncableService::CreateData;
49
50 MOCK_METHOD1(LoadAutofillData, bool(std::vector<AutofillProfile*>*));
51 MOCK_METHOD1(SaveChangesToWebData,
52 bool(const AutofillProfileSyncableService::DataBundle&));
53 };
54
55 ACTION_P(CopyData, data) {
56 arg0->resize(data->size());
57 std::copy(data->begin(), data->end(), arg0->begin());
58 }
59
60 MATCHER_P(CheckSyncChanges, n_sync_changes_list, "") {
61 if (arg.size() != n_sync_changes_list.size())
62 return false;
63 syncer::SyncChangeList::const_iterator passed, expected;
64 for (passed = arg.begin(), expected = n_sync_changes_list.begin();
65 passed != arg.end() && expected != n_sync_changes_list.end();
66 ++passed, ++expected) {
67 DCHECK(passed->IsValid());
68 if (passed->change_type() != expected->change_type())
69 return false;
70 if (passed->sync_data().GetSpecifics().SerializeAsString() !=
71 expected->sync_data().GetSpecifics().SerializeAsString()) {
72 return false;
73 }
74 }
75 return true;
76 }
77
78 MATCHER_P(DataBundleCheck, n_bundle, "") {
79 if ((arg.profiles_to_delete.size() != n_bundle.profiles_to_delete.size()) ||
80 (arg.profiles_to_update.size() != n_bundle.profiles_to_update.size()) ||
81 (arg.profiles_to_add.size() != n_bundle.profiles_to_add.size()))
82 return false;
83 for (size_t i = 0; i < arg.profiles_to_delete.size(); ++i) {
84 if (arg.profiles_to_delete[i] != n_bundle.profiles_to_delete[i])
85 return false;
86 }
87 for (size_t i = 0; i < arg.profiles_to_update.size(); ++i) {
88 if (*arg.profiles_to_update[i] != *n_bundle.profiles_to_update[i])
89 return false;
90 }
91 for (size_t i = 0; i < arg.profiles_to_add.size(); ++i) {
92 if (*arg.profiles_to_add[i] != *n_bundle.profiles_to_add[i])
93 return false;
94 }
95 return true;
96 }
97
98 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
99 public:
100 MockSyncChangeProcessor() {}
101 virtual ~MockSyncChangeProcessor() {}
102
103 MOCK_METHOD2(ProcessSyncChanges,
104 syncer::SyncError(const tracked_objects::Location&,
105 const syncer::SyncChangeList&));
106 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
107 const OVERRIDE { return syncer::SyncDataList(); }
108 };
109
110 class TestSyncChangeProcessor : public syncer::SyncChangeProcessor {
111 public:
112 TestSyncChangeProcessor() {}
113 virtual ~TestSyncChangeProcessor() {}
114
115 virtual syncer::SyncError ProcessSyncChanges(
116 const tracked_objects::Location& location,
117 const syncer::SyncChangeList& changes) OVERRIDE {
118 changes_ = changes;
119 return syncer::SyncError();
120 }
121
122 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
123 OVERRIDE {
124 return syncer::SyncDataList();
125 }
126
127 const syncer::SyncChangeList& changes() { return changes_; }
128
129 private:
130 syncer::SyncChangeList changes_;
131 };
132
133 // Returns a profile with all fields set. Contains identical data to the data
134 // returned from ConstructCompleteSyncData().
135 scoped_ptr<AutofillProfile> ConstructCompleteProfile() {
136 scoped_ptr<AutofillProfile> profile(
137 new AutofillProfile(kGuid1, kHttpsOrigin));
138
139 std::vector<base::string16> names;
140 names.push_back(ASCIIToUTF16("John K. Doe"));
141 names.push_back(ASCIIToUTF16("Jane Luise Smith"));
142 profile->SetRawMultiInfo(NAME_FULL, names);
143
144 std::vector<base::string16> emails;
145 emails.push_back(ASCIIToUTF16("user@example.com"));
146 emails.push_back(ASCIIToUTF16("superuser@example.org"));
147 profile->SetRawMultiInfo(EMAIL_ADDRESS, emails);
148
149 std::vector<base::string16> phones;
150 phones.push_back(ASCIIToUTF16("1.800.555.1234"));
151 phones.push_back(ASCIIToUTF16("1.866.650.0000"));
152 profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, phones);
153
154 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
155 ASCIIToUTF16("123 Fake St.\n"
156 "Apt. 42"));
157 EXPECT_EQ(ASCIIToUTF16("123 Fake St."),
158 profile->GetRawInfo(ADDRESS_HOME_LINE1));
159 EXPECT_EQ(ASCIIToUTF16("Apt. 42"), profile->GetRawInfo(ADDRESS_HOME_LINE2));
160
161 profile->SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Google, Inc."));
162 profile->SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Mountain View"));
163 profile->SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("California"));
164 profile->SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("94043"));
165 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
166 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, ASCIIToUTF16("CEDEX"));
167 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
168 ASCIIToUTF16("Santa Clara"));
169 return profile.Pass();
170 }
171
172 // Returns SyncData with all Autofill profile fields set. Contains identical
173 // data to the data returned from ConstructCompleteProfile().
174 syncer::SyncData ConstructCompleteSyncData() {
175 sync_pb::EntitySpecifics entity_specifics;
176 sync_pb::AutofillProfileSpecifics* specifics =
177 entity_specifics.mutable_autofill_profile();
178
179 specifics->set_guid(kGuid1);
180 specifics->set_origin(kHttpsOrigin);
181
182 specifics->add_name_first("John");
183 specifics->add_name_middle("K.");
184 specifics->add_name_last("Doe");
185
186 specifics->add_name_first("Jane");
187 specifics->add_name_middle("Luise");
188 specifics->add_name_last("Smith");
189
190 specifics->add_email_address("user@example.com");
191 specifics->add_email_address("superuser@example.org");
192
193 specifics->add_phone_home_whole_number("1.800.555.1234");
194 specifics->add_phone_home_whole_number("1.866.650.0000");
195
196 specifics->set_address_home_line1("123 Fake St.");
197 specifics->set_address_home_line2("Apt. 42");
198 specifics->set_address_home_street_address("123 Fake St.\n"
199 "Apt. 42");
200
201 specifics->set_company_name("Google, Inc.");
202 specifics->set_address_home_city("Mountain View");
203 specifics->set_address_home_state("California");
204 specifics->set_address_home_zip("94043");
205 specifics->set_address_home_country("US");
206 specifics->set_address_home_sorting_code("CEDEX");
207 specifics->set_address_home_dependent_locality("Santa Clara");
208
209 return syncer::SyncData::CreateLocalData(kGuid1, kGuid1, entity_specifics);
210 }
211
212 } // namespace
213
214 class AutofillProfileSyncableServiceTest : public testing::Test {
215 public:
216 AutofillProfileSyncableServiceTest()
217 : ui_thread_(BrowserThread::UI, &message_loop_),
218 db_thread_(BrowserThread::DB, &message_loop_) {}
219
220 virtual void SetUp() OVERRIDE {
221 sync_processor_.reset(new MockSyncChangeProcessor);
222 }
223
224 // Wrapper around AutofillProfileSyncableService::MergeDataAndStartSyncing()
225 // that also verifies expectations.
226 void MergeDataAndStartSyncing(
227 const std::vector<AutofillProfile*>& profiles_from_web_db,
228 const syncer::SyncDataList& data_list,
229 const MockAutofillProfileSyncableService::DataBundle& expected_bundle,
230 const syncer::SyncChangeList& expected_change_list) {
231 EXPECT_CALL(autofill_syncable_service_, LoadAutofillData(_))
232 .Times(1)
233 .WillOnce(DoAll(CopyData(&profiles_from_web_db), Return(true)));
234 EXPECT_CALL(autofill_syncable_service_,
235 SaveChangesToWebData(DataBundleCheck(expected_bundle)))
236 .Times(1)
237 .WillOnce(Return(true));
238 if (expected_change_list.empty()) {
239 EXPECT_CALL(*sync_processor_, ProcessSyncChanges(_, _)).Times(0);
240 } else {
241 ON_CALL(*sync_processor_, ProcessSyncChanges(_, _))
242 .WillByDefault(Return(syncer::SyncError()));
243 EXPECT_CALL(*sync_processor_,
244 ProcessSyncChanges(_, CheckSyncChanges(expected_change_list)))
245 .Times(1)
246 .WillOnce(Return(syncer::SyncError()));
247 }
248
249 // Takes ownership of sync_processor_.
250 autofill_syncable_service_.MergeDataAndStartSyncing(
251 syncer::AUTOFILL_PROFILE, data_list,
252 sync_processor_.PassAs<syncer::SyncChangeProcessor>(),
253 scoped_ptr<syncer::SyncErrorFactory>(
254 new syncer::SyncErrorFactoryMock()));
255 }
256
257 protected:
258 base::MessageLoop message_loop_;
259 content::TestBrowserThread ui_thread_;
260 content::TestBrowserThread db_thread_;
261 MockAutofillProfileSyncableService autofill_syncable_service_;
262 scoped_ptr<MockSyncChangeProcessor> sync_processor_;
263 };
264
265 TEST_F(AutofillProfileSyncableServiceTest, MergeDataAndStartSyncing) {
266 std::vector<AutofillProfile*> profiles_from_web_db;
267 std::string guid_present1 = kGuid1;
268 std::string guid_present2 = kGuid2;
269 std::string guid_synced1 = kGuid3;
270 std::string guid_synced2 = kGuid4;
271 std::string origin_present1 = kHttpOrigin;
272 std::string origin_present2 = std::string();
273 std::string origin_synced1 = kHttpsOrigin;
274 std::string origin_synced2 = kSettingsOrigin;
275
276 profiles_from_web_db.push_back(
277 new AutofillProfile(guid_present1, origin_present1));
278 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
279 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
280 UTF8ToUTF16("1 1st st"));
281 profiles_from_web_db.push_back(
282 new AutofillProfile(guid_present2, origin_present2));
283 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom"));
284 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
285 UTF8ToUTF16("2 2nd st"));
286
287 syncer::SyncDataList data_list;
288 AutofillProfile profile1(guid_synced1, origin_synced1);
289 profile1.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
290 data_list.push_back(autofill_syncable_service_.CreateData(profile1));
291 AutofillProfile profile2(guid_synced2, origin_synced2);
292 profile2.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Harry"));
293 data_list.push_back(autofill_syncable_service_.CreateData(profile2));
294 // This one will have the name and origin updated.
295 AutofillProfile profile3(guid_present2, origin_synced2);
296 profile3.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom Doe"));
297 data_list.push_back(autofill_syncable_service_.CreateData(profile3));
298
299 syncer::SyncChangeList expected_change_list;
300 expected_change_list.push_back(
301 syncer::SyncChange(FROM_HERE,
302 syncer::SyncChange::ACTION_ADD,
303 MockAutofillProfileSyncableService::CreateData(
304 *profiles_from_web_db.front())));
305
306 MockAutofillProfileSyncableService::DataBundle expected_bundle;
307 expected_bundle.profiles_to_add.push_back(&profile1);
308 expected_bundle.profiles_to_add.push_back(&profile2);
309 expected_bundle.profiles_to_update.push_back(&profile3);
310
311 MergeDataAndStartSyncing(
312 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
313 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
314 }
315
316 TEST_F(AutofillProfileSyncableServiceTest, MergeIdenticalProfiles) {
317 std::vector<AutofillProfile*> profiles_from_web_db;
318 std::string guid_present1 = kGuid1;
319 std::string guid_present2 = kGuid2;
320 std::string guid_synced1 = kGuid3;
321 std::string guid_synced2 = kGuid4;
322 std::string origin_present1 = kHttpOrigin;
323 std::string origin_present2 = kSettingsOrigin;
324 std::string origin_synced1 = kHttpsOrigin;
325 std::string origin_synced2 = kHttpsOrigin;
326
327 profiles_from_web_db.push_back(
328 new AutofillProfile(guid_present1, origin_present1));
329 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
330 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
331 UTF8ToUTF16("1 1st st"));
332 profiles_from_web_db.push_back(
333 new AutofillProfile(guid_present2, origin_present2));
334 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom"));
335 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
336 UTF8ToUTF16("2 2nd st"));
337
338 // The synced profiles are identical to the local ones, except that the guids
339 // are different.
340 syncer::SyncDataList data_list;
341 AutofillProfile profile1(guid_synced1, origin_synced1);
342 profile1.SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
343 profile1.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("1 1st st"));
344 data_list.push_back(autofill_syncable_service_.CreateData(profile1));
345 AutofillProfile profile2(guid_synced2, origin_synced2);
346 profile2.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom"));
347 profile2.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("2 2nd st"));
348 data_list.push_back(autofill_syncable_service_.CreateData(profile2));
349
350 AutofillProfile expected_profile(profile2);
351 expected_profile.set_origin(kSettingsOrigin);
352 syncer::SyncChangeList expected_change_list;
353 expected_change_list.push_back(
354 syncer::SyncChange(FROM_HERE,
355 syncer::SyncChange::ACTION_UPDATE,
356 MockAutofillProfileSyncableService::CreateData(
357 expected_profile)));
358
359 MockAutofillProfileSyncableService::DataBundle expected_bundle;
360 expected_bundle.profiles_to_delete.push_back(guid_present1);
361 expected_bundle.profiles_to_delete.push_back(guid_present2);
362 expected_bundle.profiles_to_add.push_back(&profile1);
363 expected_bundle.profiles_to_add.push_back(&expected_profile);
364
365 MergeDataAndStartSyncing(
366 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
367 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
368 }
369
370 TEST_F(AutofillProfileSyncableServiceTest, MergeSimilarProfiles) {
371 std::vector<AutofillProfile*> profiles_from_web_db;
372 std::string guid_present1 = kGuid1;
373 std::string guid_present2 = kGuid2;
374 std::string guid_synced1 = kGuid3;
375 std::string guid_synced2 = kGuid4;
376 std::string origin_present1 = kHttpOrigin;
377 std::string origin_present2 = kSettingsOrigin;
378 std::string origin_synced1 = kHttpsOrigin;
379 std::string origin_synced2 = kHttpsOrigin;
380
381 profiles_from_web_db.push_back(
382 new AutofillProfile(guid_present1, origin_present1));
383 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
384 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
385 UTF8ToUTF16("1 1st st"));
386 profiles_from_web_db.push_back(
387 new AutofillProfile(guid_present2, origin_present2));
388 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom"));
389 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
390 UTF8ToUTF16("2 2nd st"));
391
392 // The synced profiles are identical to the local ones, except that the guids
393 // are different.
394 syncer::SyncDataList data_list;
395 AutofillProfile profile1(guid_synced1, origin_synced1);
396 profile1.SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
397 profile1.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("1 1st st"));
398 profile1.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("Frobbers, Inc."));
399 data_list.push_back(autofill_syncable_service_.CreateData(profile1));
400 AutofillProfile profile2(guid_synced2, origin_synced2);
401 profile2.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Tom"));
402 profile2.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("2 2nd st"));
403 profile2.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("Fizzbang, LLC."));
404 data_list.push_back(autofill_syncable_service_.CreateData(profile2));
405
406 // The first profile should have its origin updated.
407 // The second profile should remain as-is, because an unverified profile
408 // should never overwrite a verified one.
409 AutofillProfile expected_profile(profile1);
410 expected_profile.set_origin(origin_present1);
411 syncer::SyncChangeList expected_change_list;
412 expected_change_list.push_back(
413 syncer::SyncChange(FROM_HERE,
414 syncer::SyncChange::ACTION_ADD,
415 MockAutofillProfileSyncableService::CreateData(
416 *profiles_from_web_db.back())));
417 expected_change_list.push_back(
418 syncer::SyncChange(FROM_HERE,
419 syncer::SyncChange::ACTION_UPDATE,
420 MockAutofillProfileSyncableService::CreateData(
421 expected_profile)));
422
423 MockAutofillProfileSyncableService::DataBundle expected_bundle;
424 expected_bundle.profiles_to_delete.push_back(guid_present1);
425 expected_bundle.profiles_to_add.push_back(&expected_profile);
426 expected_bundle.profiles_to_add.push_back(&profile2);
427
428 MergeDataAndStartSyncing(
429 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
430 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
431 }
432
433 // Ensure that no Sync events are generated to fill in missing origins from Sync
434 // with explicitly present empty ones. This ensures that the migration to add
435 // origins to profiles does not generate lots of needless Sync updates.
436 TEST_F(AutofillProfileSyncableServiceTest, MergeDataEmptyOrigins) {
437 std::vector<AutofillProfile*> profiles_from_web_db;
438
439 // Create a profile with an empty origin.
440 AutofillProfile profile(kGuid1, std::string());
441 profile.SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
442 profile.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("1 1st st"));
443
444 profiles_from_web_db.push_back(new AutofillProfile(profile));
445
446 // Create a Sync profile identical to |profile|, except with no origin set.
447 sync_pb::EntitySpecifics specifics;
448 sync_pb::AutofillProfileSpecifics* autofill_specifics =
449 specifics.mutable_autofill_profile();
450 autofill_specifics->set_guid(profile.guid());
451 autofill_specifics->add_name_first("John");
452 autofill_specifics->add_name_middle(std::string());
453 autofill_specifics->add_name_last(std::string());
454 autofill_specifics->add_email_address(std::string());
455 autofill_specifics->add_phone_home_whole_number(std::string());
456 autofill_specifics->set_address_home_line1("1 1st st");
457 EXPECT_FALSE(autofill_specifics->has_origin());
458
459 syncer::SyncDataList data_list;
460 data_list.push_back(
461 syncer::SyncData::CreateLocalData(
462 profile.guid(), profile.guid(), specifics));
463
464 MockAutofillProfileSyncableService::DataBundle expected_bundle;
465 syncer::SyncChangeList expected_change_list;
466 MergeDataAndStartSyncing(
467 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
468 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
469 }
470
471 TEST_F(AutofillProfileSyncableServiceTest, GetAllSyncData) {
472 std::vector<AutofillProfile*> profiles_from_web_db;
473 std::string guid_present1 = kGuid1;
474 std::string guid_present2 = kGuid2;
475
476 profiles_from_web_db.push_back(
477 new AutofillProfile(guid_present1, kHttpOrigin));
478 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("John"));
479 profiles_from_web_db.push_back(
480 new AutofillProfile(guid_present2, kHttpsOrigin));
481 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
482
483 syncer::SyncChangeList expected_change_list;
484 expected_change_list.push_back(
485 syncer::SyncChange(FROM_HERE,
486 syncer::SyncChange::ACTION_ADD,
487 MockAutofillProfileSyncableService::CreateData(
488 *profiles_from_web_db.front())));
489 expected_change_list.push_back(
490 syncer::SyncChange(FROM_HERE,
491 syncer::SyncChange::ACTION_ADD,
492 MockAutofillProfileSyncableService::CreateData(
493 *profiles_from_web_db.back())));
494
495 MockAutofillProfileSyncableService::DataBundle expected_bundle;
496 syncer::SyncDataList data_list;
497 MergeDataAndStartSyncing(
498 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
499
500 syncer::SyncDataList data =
501 autofill_syncable_service_.GetAllSyncData(syncer::AUTOFILL_PROFILE);
502
503 ASSERT_EQ(2U, data.size());
504 EXPECT_EQ(guid_present1, data[0].GetSpecifics().autofill_profile().guid());
505 EXPECT_EQ(guid_present2, data[1].GetSpecifics().autofill_profile().guid());
506 EXPECT_EQ(kHttpOrigin, data[0].GetSpecifics().autofill_profile().origin());
507 EXPECT_EQ(kHttpsOrigin, data[1].GetSpecifics().autofill_profile().origin());
508
509 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
510 }
511
512 TEST_F(AutofillProfileSyncableServiceTest, ProcessSyncChanges) {
513 std::vector<AutofillProfile *> profiles_from_web_db;
514 std::string guid_present = kGuid1;
515 std::string guid_synced = kGuid2;
516
517 syncer::SyncChangeList change_list;
518 AutofillProfile profile(guid_synced, kHttpOrigin);
519 profile.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
520 change_list.push_back(
521 syncer::SyncChange(
522 FROM_HERE,
523 syncer::SyncChange::ACTION_ADD,
524 MockAutofillProfileSyncableService::CreateData(profile)));
525 AutofillProfile empty_profile(guid_present, kHttpsOrigin);
526 change_list.push_back(
527 syncer::SyncChange(
528 FROM_HERE,
529 syncer::SyncChange::ACTION_DELETE,
530 MockAutofillProfileSyncableService::CreateData(empty_profile)));
531
532 MockAutofillProfileSyncableService::DataBundle expected_bundle;
533 expected_bundle.profiles_to_delete.push_back(guid_present);
534 expected_bundle.profiles_to_add.push_back(&profile);
535
536 EXPECT_CALL(autofill_syncable_service_, SaveChangesToWebData(
537 DataBundleCheck(expected_bundle)))
538 .Times(1)
539 .WillOnce(Return(true));
540
541 autofill_syncable_service_.set_sync_processor(sync_processor_.release());
542 syncer::SyncError error = autofill_syncable_service_.ProcessSyncChanges(
543 FROM_HERE, change_list);
544
545 EXPECT_FALSE(error.IsSet());
546 }
547
548 TEST_F(AutofillProfileSyncableServiceTest, AutofillProfileAdded) {
549 // Will be owned by the syncable service. Keep a reference available here for
550 // verifying test expectations.
551 TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
552 autofill_syncable_service_.set_sync_processor(sync_change_processor);
553
554 AutofillProfile profile(kGuid1, kHttpsOrigin);
555 profile.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Jane"));
556 AutofillProfileChange change(AutofillProfileChange::ADD, kGuid1, &profile);
557 autofill_syncable_service_.AutofillProfileChanged(change);
558
559 ASSERT_EQ(1U, sync_change_processor->changes().size());
560 syncer::SyncChange result = sync_change_processor->changes()[0];
561 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, result.change_type());
562
563 sync_pb::AutofillProfileSpecifics specifics =
564 result.sync_data().GetSpecifics().autofill_profile();
565 EXPECT_EQ(kGuid1, specifics.guid());
566 EXPECT_EQ(kHttpsOrigin, specifics.origin());
567 EXPECT_THAT(specifics.name_first(), testing::ElementsAre("Jane"));
568 }
569
570 TEST_F(AutofillProfileSyncableServiceTest, AutofillProfileDeleted) {
571 // Will be owned by the syncable service. Keep a reference available here for
572 // verifying test expectations.
573 TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
574 autofill_syncable_service_.set_sync_processor(sync_change_processor);
575
576 AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, NULL);
577 autofill_syncable_service_.AutofillProfileChanged(change);
578
579 ASSERT_EQ(1U, sync_change_processor->changes().size());
580 syncer::SyncChange result = sync_change_processor->changes()[0];
581 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, result.change_type());
582 sync_pb::AutofillProfileSpecifics specifics =
583 result.sync_data().GetSpecifics().autofill_profile();
584 EXPECT_EQ(kGuid2, specifics.guid());
585 }
586
587 TEST_F(AutofillProfileSyncableServiceTest, UpdateField) {
588 AutofillProfile profile(kGuid1, kSettingsOrigin);
589 std::string company1 = "A Company";
590 std::string company2 = "Another Company";
591 profile.SetRawInfo(COMPANY_NAME, UTF8ToUTF16(company1));
592 EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
593 COMPANY_NAME, company1, &profile));
594 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), UTF8ToUTF16(company1));
595 EXPECT_TRUE(AutofillProfileSyncableService::UpdateField(
596 COMPANY_NAME, company2, &profile));
597 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), UTF8ToUTF16(company2));
598 EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
599 COMPANY_NAME, company2, &profile));
600 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), UTF8ToUTF16(company2));
601 }
602
603 TEST_F(AutofillProfileSyncableServiceTest, UpdateMultivaluedField) {
604 AutofillProfile profile(kGuid1, kHttpsOrigin);
605
606 std::vector<base::string16> values;
607 values.push_back(UTF8ToUTF16("1@1.com"));
608 values.push_back(UTF8ToUTF16("2@1.com"));
609 profile.SetRawMultiInfo(EMAIL_ADDRESS, values);
610
611 ::google::protobuf::RepeatedPtrField<std::string> specifics_fields;
612 specifics_fields.AddAllocated(new std::string("2@1.com"));
613 specifics_fields.AddAllocated(new std::string("3@1.com"));
614
615 EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
616 EMAIL_ADDRESS, specifics_fields, &profile));
617 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
618 ASSERT_TRUE(values.size() == 2);
619 EXPECT_EQ(values[0], UTF8ToUTF16("2@1.com"));
620 EXPECT_EQ(values[1], UTF8ToUTF16("3@1.com"));
621
622 EXPECT_FALSE(AutofillProfileSyncableService::UpdateMultivaluedField(
623 EMAIL_ADDRESS, specifics_fields, &profile));
624 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
625 ASSERT_EQ(values.size(), 2U);
626 EXPECT_EQ(values[0], UTF8ToUTF16("2@1.com"));
627 EXPECT_EQ(values[1], UTF8ToUTF16("3@1.com"));
628 EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
629 EMAIL_ADDRESS, ::google::protobuf::RepeatedPtrField<std::string>(),
630 &profile));
631 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
632 ASSERT_EQ(values.size(), 1U); // Always have at least an empty string.
633 EXPECT_EQ(values[0], UTF8ToUTF16(""));
634 }
635
636 TEST_F(AutofillProfileSyncableServiceTest, MergeProfile) {
637 AutofillProfile profile1(kGuid1, kHttpOrigin);
638 profile1.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("111 First St."));
639
640 std::vector<base::string16> values;
641 values.push_back(UTF8ToUTF16("1@1.com"));
642 values.push_back(UTF8ToUTF16("2@1.com"));
643 profile1.SetRawMultiInfo(EMAIL_ADDRESS, values);
644
645 AutofillProfile profile2(kGuid2, kHttpsOrigin);
646 profile2.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("111 First St."));
647
648 // |values| now is [ "1@1.com", "2@1.com", "3@1.com" ].
649 values.push_back(UTF8ToUTF16("3@1.com"));
650 profile2.SetRawMultiInfo(EMAIL_ADDRESS, values);
651
652 values.clear();
653 values.push_back(UTF8ToUTF16("John"));
654 profile1.SetRawMultiInfo(NAME_FIRST, values);
655 values.push_back(UTF8ToUTF16("Jane"));
656 profile2.SetRawMultiInfo(NAME_FIRST, values);
657
658 values.clear();
659 values.push_back(UTF8ToUTF16("Doe"));
660 profile1.SetRawMultiInfo(NAME_LAST, values);
661 values.push_back(UTF8ToUTF16("Other"));
662 profile2.SetRawMultiInfo(NAME_LAST, values);
663
664 values.clear();
665 values.push_back(UTF8ToUTF16("650234567"));
666 profile2.SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, values);
667
668 EXPECT_FALSE(AutofillProfileSyncableService::MergeProfile(profile2,
669 &profile1,
670 "en-US"));
671
672 profile1.GetRawMultiInfo(NAME_FIRST, &values);
673 ASSERT_EQ(values.size(), 2U);
674 EXPECT_EQ(values[0], UTF8ToUTF16("John"));
675 EXPECT_EQ(values[1], UTF8ToUTF16("Jane"));
676
677 profile1.GetRawMultiInfo(NAME_LAST, &values);
678 ASSERT_EQ(values.size(), 2U);
679 EXPECT_EQ(values[0], UTF8ToUTF16("Doe"));
680 EXPECT_EQ(values[1], UTF8ToUTF16("Other"));
681
682 profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
683 ASSERT_EQ(values.size(), 3U);
684 EXPECT_EQ(values[0], UTF8ToUTF16("1@1.com"));
685 EXPECT_EQ(values[1], UTF8ToUTF16("2@1.com"));
686 EXPECT_EQ(values[2], UTF8ToUTF16("3@1.com"));
687
688 profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
689 ASSERT_EQ(values.size(), 1U);
690 EXPECT_EQ(values[0], UTF8ToUTF16("650234567"));
691
692 EXPECT_EQ(profile2.origin(), profile1.origin());
693
694 AutofillProfile profile3(kGuid3, kHttpOrigin);
695 profile3.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("111 First St."));
696
697 values.clear();
698 values.push_back(UTF8ToUTF16("Jane"));
699 profile3.SetRawMultiInfo(NAME_FIRST, values);
700
701 values.clear();
702 values.push_back(UTF8ToUTF16("Doe"));
703 profile3.SetRawMultiInfo(NAME_LAST, values);
704
705 EXPECT_TRUE(AutofillProfileSyncableService::MergeProfile(profile3,
706 &profile1,
707 "en-US"));
708
709 profile1.GetRawMultiInfo(NAME_FIRST, &values);
710 ASSERT_EQ(values.size(), 3U);
711 EXPECT_EQ(values[0], UTF8ToUTF16("John"));
712 EXPECT_EQ(values[1], UTF8ToUTF16("Jane"));
713 EXPECT_EQ(values[2], UTF8ToUTF16("Jane"));
714
715 profile1.GetRawMultiInfo(NAME_LAST, &values);
716 ASSERT_EQ(values.size(), 3U);
717 EXPECT_EQ(values[0], UTF8ToUTF16("Doe"));
718 EXPECT_EQ(values[1], UTF8ToUTF16("Other"));
719 EXPECT_EQ(values[2], UTF8ToUTF16("Doe"));
720
721 // Middle name should have three entries as well.
722 profile1.GetRawMultiInfo(NAME_MIDDLE, &values);
723 ASSERT_EQ(values.size(), 3U);
724 EXPECT_TRUE(values[0].empty());
725 EXPECT_TRUE(values[1].empty());
726 EXPECT_TRUE(values[2].empty());
727
728 profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
729 ASSERT_EQ(values.size(), 3U);
730 EXPECT_EQ(values[0], UTF8ToUTF16("1@1.com"));
731 EXPECT_EQ(values[1], UTF8ToUTF16("2@1.com"));
732 EXPECT_EQ(values[2], UTF8ToUTF16("3@1.com"));
733
734 profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
735 ASSERT_EQ(values.size(), 1U);
736 EXPECT_EQ(values[0], UTF8ToUTF16("650234567"));
737 }
738
739 // Ensure that all profile fields are able to be synced up from the client to
740 // the server.
741 TEST_F(AutofillProfileSyncableServiceTest, SyncAllFieldsToServer) {
742 std::vector<AutofillProfile*> profiles_from_web_db;
743
744 // Create a profile with all fields set.
745 profiles_from_web_db.push_back(ConstructCompleteProfile().release());
746
747 // Set up expectations: No changes to the WebDB, and all fields correctly
748 // copied to Sync.
749 MockAutofillProfileSyncableService::DataBundle expected_bundle;
750 syncer::SyncChangeList expected_change_list;
751 expected_change_list.push_back(
752 syncer::SyncChange(FROM_HERE,
753 syncer::SyncChange::ACTION_ADD,
754 ConstructCompleteSyncData()));
755
756 // Verify the expectations.
757 syncer::SyncDataList data_list;
758 MergeDataAndStartSyncing(
759 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
760 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
761 }
762
763 // Ensure that all profile fields are able to be synced down from the server to
764 // the client.
765 TEST_F(AutofillProfileSyncableServiceTest, SyncAllFieldsToClient) {
766 // Create a profile with all fields set.
767 syncer::SyncDataList data_list;
768 data_list.push_back(ConstructCompleteSyncData());
769
770 // Set up expectations: All fields correctly copied to the WebDB, and no
771 // changes propagated to Sync.
772 syncer::SyncChangeList expected_change_list;
773 scoped_ptr<AutofillProfile> expected_profile = ConstructCompleteProfile();
774 MockAutofillProfileSyncableService::DataBundle expected_bundle;
775 expected_bundle.profiles_to_add.push_back(expected_profile.get());
776
777 // Verify the expectations.
778 std::vector<AutofillProfile*> profiles_from_web_db;
779 MergeDataAndStartSyncing(
780 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
781 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
782 }
783
784 // Ensure that the street address field takes precedence over the address line 1
785 // and line 2 fields, even though these are expected to always be in sync in
786 // practice.
787 TEST_F(AutofillProfileSyncableServiceTest,
788 StreetAddressTakesPrecedenceOverAddressLines) {
789 // Create a Sync profile with conflicting address data in the street address
790 // field vs. the address line 1 and address line 2 fields.
791 sync_pb::EntitySpecifics specifics;
792 sync_pb::AutofillProfileSpecifics* autofill_specifics =
793 specifics.mutable_autofill_profile();
794 autofill_specifics->set_guid(kGuid1);
795 autofill_specifics->set_origin(kHttpsOrigin);
796 autofill_specifics->add_name_first(std::string());
797 autofill_specifics->add_name_middle(std::string());
798 autofill_specifics->add_name_last(std::string());
799 autofill_specifics->add_email_address(std::string());
800 autofill_specifics->add_phone_home_whole_number(std::string());
801 autofill_specifics->set_address_home_line1("123 Example St.");
802 autofill_specifics->set_address_home_line2("Apt. 42");
803 autofill_specifics->set_address_home_street_address("456 El Camino Real\n"
804 "Suite #1337");
805
806 syncer::SyncDataList data_list;
807 data_list.push_back(
808 syncer::SyncData::CreateLocalData(kGuid1, kGuid1, specifics));
809
810 // Set up expectations: Full street address takes precedence over address
811 // lines.
812 syncer::SyncChangeList expected_change_list;
813 AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
814 expected_profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
815 ASCIIToUTF16("456 El Camino Real\n"
816 "Suite #1337"));
817 EXPECT_EQ(ASCIIToUTF16("456 El Camino Real"),
818 expected_profile.GetRawInfo(ADDRESS_HOME_LINE1));
819 EXPECT_EQ(ASCIIToUTF16("Suite #1337"),
820 expected_profile.GetRawInfo(ADDRESS_HOME_LINE2));
821 MockAutofillProfileSyncableService::DataBundle expected_bundle;
822 expected_bundle.profiles_to_add.push_back(&expected_profile);
823
824 // Verify the expectations.
825 std::vector<AutofillProfile*> profiles_from_web_db;
826 MergeDataAndStartSyncing(
827 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
828 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
829 }
830
831 // Ensure that no Sync events are generated to fill in missing street address
832 // fields from Sync with explicitly present ones identical to the data stored in
833 // the line1 and line2 fields. This ensures that the migration to add the
834 // street address field to profiles does not generate lots of needless Sync
835 // updates.
836 TEST_F(AutofillProfileSyncableServiceTest, MergeDataEmptyStreetAddress) {
837 std::vector<AutofillProfile*> profiles_from_web_db;
838
839 // Create a profile with the street address set.
840 AutofillProfile profile(kGuid1, kHttpsOrigin);
841 profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
842 ASCIIToUTF16("123 Example St.\n"
843 "Apt. 42"));
844 EXPECT_EQ(ASCIIToUTF16("123 Example St."),
845 profile.GetRawInfo(ADDRESS_HOME_LINE1));
846 EXPECT_EQ(ASCIIToUTF16("Apt. 42"), profile.GetRawInfo(ADDRESS_HOME_LINE2));
847
848 profiles_from_web_db.push_back(new AutofillProfile(profile));
849
850 // Create a Sync profile identical to |profile|, except without street address
851 // explicitly set.
852 sync_pb::EntitySpecifics specifics;
853 sync_pb::AutofillProfileSpecifics* autofill_specifics =
854 specifics.mutable_autofill_profile();
855 autofill_specifics->set_guid(profile.guid());
856 autofill_specifics->set_origin(profile.origin());
857 autofill_specifics->add_name_first(std::string());
858 autofill_specifics->add_name_middle(std::string());
859 autofill_specifics->add_name_last(std::string());
860 autofill_specifics->add_email_address(std::string());
861 autofill_specifics->add_phone_home_whole_number(std::string());
862 autofill_specifics->set_address_home_line1("123 Example St.");
863 autofill_specifics->set_address_home_line2("Apt. 42");
864 EXPECT_FALSE(autofill_specifics->has_address_home_street_address());
865
866 syncer::SyncDataList data_list;
867 data_list.push_back(
868 syncer::SyncData::CreateLocalData(
869 profile.guid(), profile.guid(), specifics));
870
871 MockAutofillProfileSyncableService::DataBundle expected_bundle;
872 syncer::SyncChangeList expected_change_list;
873 MergeDataAndStartSyncing(
874 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
875 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
876 }
877
878 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/webdata/autofill_profile_syncable_service.cc ('k') | chrome/browser/webdata/web_data_service_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698