autofill names - dont parse when calling SetRawInfo(FULL_NAME)
[chromium-blink-merge.git] / components / autofill / core / browser / webdata / autofill_profile_syncable_service_unittest.cc
blob3a7b9b1d270ae1ad49d7df40abe0b02df353fa0f
1 // Copyright 2014 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/message_loop.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "components/autofill/core/browser/autofill_profile.h"
9 #include "components/autofill/core/browser/webdata/autofill_change.h"
10 #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
11 #include "sync/api/sync_error_factory.h"
12 #include "sync/api/sync_error_factory_mock.h"
13 #include "sync/protocol/sync.pb.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace autofill {
19 using ::testing::_;
20 using ::testing::DoAll;
21 using ::testing::Eq;
22 using ::testing::Return;
23 using ::testing::Property;
24 using base::ASCIIToUTF16;
26 namespace {
28 // Some guids for testing.
29 const char kGuid1[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
30 const char kGuid2[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44C";
31 const char kGuid3[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44D";
32 const char kGuid4[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44E";
33 const char kHttpOrigin[] = "http://www.example.com/";
34 const char kHttpsOrigin[] = "https://www.example.com/";
35 const char kSettingsOrigin[] = "Chrome settings";
37 class MockAutofillProfileSyncableService
38 : public AutofillProfileSyncableService {
39 public:
40 MockAutofillProfileSyncableService() {}
41 virtual ~MockAutofillProfileSyncableService() {}
43 using AutofillProfileSyncableService::DataBundle;
44 using AutofillProfileSyncableService::set_sync_processor;
45 using AutofillProfileSyncableService::CreateData;
47 MOCK_METHOD1(LoadAutofillData, bool(std::vector<AutofillProfile*>*));
48 MOCK_METHOD1(SaveChangesToWebData,
49 bool(const AutofillProfileSyncableService::DataBundle&));
52 ACTION_P(CopyData, data) {
53 arg0->resize(data->size());
54 std::copy(data->begin(), data->end(), arg0->begin());
57 MATCHER_P(CheckSyncChanges, n_sync_changes_list, "") {
58 if (arg.size() != n_sync_changes_list.size())
59 return false;
60 syncer::SyncChangeList::const_iterator passed, expected;
61 for (passed = arg.begin(), expected = n_sync_changes_list.begin();
62 passed != arg.end() && expected != n_sync_changes_list.end();
63 ++passed, ++expected) {
64 DCHECK(passed->IsValid());
65 if (passed->change_type() != expected->change_type())
66 return false;
67 if (passed->sync_data().GetSpecifics().SerializeAsString() !=
68 expected->sync_data().GetSpecifics().SerializeAsString()) {
69 return false;
72 return true;
75 MATCHER_P(DataBundleCheck, n_bundle, "") {
76 if ((arg.profiles_to_delete.size() != n_bundle.profiles_to_delete.size()) ||
77 (arg.profiles_to_update.size() != n_bundle.profiles_to_update.size()) ||
78 (arg.profiles_to_add.size() != n_bundle.profiles_to_add.size()))
79 return false;
80 for (size_t i = 0; i < arg.profiles_to_delete.size(); ++i) {
81 if (arg.profiles_to_delete[i] != n_bundle.profiles_to_delete[i])
82 return false;
84 for (size_t i = 0; i < arg.profiles_to_update.size(); ++i) {
85 if (*arg.profiles_to_update[i] != *n_bundle.profiles_to_update[i])
86 return false;
88 for (size_t i = 0; i < arg.profiles_to_add.size(); ++i) {
89 if (*arg.profiles_to_add[i] != *n_bundle.profiles_to_add[i])
90 return false;
92 return true;
95 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
96 public:
97 MockSyncChangeProcessor() {}
98 virtual ~MockSyncChangeProcessor() {}
100 MOCK_METHOD2(ProcessSyncChanges,
101 syncer::SyncError(const tracked_objects::Location&,
102 const syncer::SyncChangeList&));
103 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
104 const OVERRIDE { return syncer::SyncDataList(); }
107 class TestSyncChangeProcessor : public syncer::SyncChangeProcessor {
108 public:
109 TestSyncChangeProcessor() {}
110 virtual ~TestSyncChangeProcessor() {}
112 virtual syncer::SyncError ProcessSyncChanges(
113 const tracked_objects::Location& location,
114 const syncer::SyncChangeList& changes) OVERRIDE {
115 changes_ = changes;
116 return syncer::SyncError();
119 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
120 OVERRIDE {
121 return syncer::SyncDataList();
124 const syncer::SyncChangeList& changes() { return changes_; }
126 private:
127 syncer::SyncChangeList changes_;
130 // Returns a profile with all fields set. Contains identical data to the data
131 // returned from ConstructCompleteSyncData().
132 scoped_ptr<AutofillProfile> ConstructCompleteProfile() {
133 scoped_ptr<AutofillProfile> profile(
134 new AutofillProfile(kGuid1, kHttpsOrigin));
136 std::vector<base::string16> names;
137 names.push_back(ASCIIToUTF16("John K. Doe, Jr."));
138 names.push_back(ASCIIToUTF16("Jane Luise Smith MD"));
139 profile->SetRawMultiInfo(NAME_FULL, names);
140 names.clear();
141 names.push_back(ASCIIToUTF16("John"));
142 names.push_back(ASCIIToUTF16("Jane"));
143 profile->SetRawMultiInfo(NAME_FIRST, names);
144 names.clear();
145 names.push_back(ASCIIToUTF16("K."));
146 names.push_back(ASCIIToUTF16("Luise"));
147 profile->SetRawMultiInfo(NAME_MIDDLE, names);
148 names.clear();
149 names.push_back(ASCIIToUTF16("Doe"));
150 names.push_back(ASCIIToUTF16("Smith"));
151 profile->SetRawMultiInfo(NAME_LAST, names);
153 std::vector<base::string16> emails;
154 emails.push_back(ASCIIToUTF16("user@example.com"));
155 emails.push_back(ASCIIToUTF16("superuser@example.org"));
156 profile->SetRawMultiInfo(EMAIL_ADDRESS, emails);
158 std::vector<base::string16> phones;
159 phones.push_back(ASCIIToUTF16("1.800.555.1234"));
160 phones.push_back(ASCIIToUTF16("1.866.650.0000"));
161 profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, phones);
163 profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
164 ASCIIToUTF16("123 Fake St.\n"
165 "Apt. 42"));
166 EXPECT_EQ(ASCIIToUTF16("123 Fake St."),
167 profile->GetRawInfo(ADDRESS_HOME_LINE1));
168 EXPECT_EQ(ASCIIToUTF16("Apt. 42"), profile->GetRawInfo(ADDRESS_HOME_LINE2));
170 profile->SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Google, Inc."));
171 profile->SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Mountain View"));
172 profile->SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("California"));
173 profile->SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("94043"));
174 profile->SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
175 profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, ASCIIToUTF16("CEDEX"));
176 profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
177 ASCIIToUTF16("Santa Clara"));
178 profile->set_language_code("en");
179 return profile.Pass();
182 // Returns SyncData with all Autofill profile fields set. Contains identical
183 // data to the data returned from ConstructCompleteProfile().
184 syncer::SyncData ConstructCompleteSyncData() {
185 sync_pb::EntitySpecifics entity_specifics;
186 sync_pb::AutofillProfileSpecifics* specifics =
187 entity_specifics.mutable_autofill_profile();
189 specifics->set_guid(kGuid1);
190 specifics->set_origin(kHttpsOrigin);
192 specifics->add_name_first("John");
193 specifics->add_name_middle("K.");
194 specifics->add_name_last("Doe");
195 specifics->add_name_full("John K. Doe, Jr.");
197 specifics->add_name_first("Jane");
198 specifics->add_name_middle("Luise");
199 specifics->add_name_last("Smith");
200 specifics->add_name_full("Jane Luise Smith MD");
202 specifics->add_email_address("user@example.com");
203 specifics->add_email_address("superuser@example.org");
205 specifics->add_phone_home_whole_number("1.800.555.1234");
206 specifics->add_phone_home_whole_number("1.866.650.0000");
208 specifics->set_address_home_line1("123 Fake St.");
209 specifics->set_address_home_line2("Apt. 42");
210 specifics->set_address_home_street_address("123 Fake St.\n"
211 "Apt. 42");
213 specifics->set_company_name("Google, Inc.");
214 specifics->set_address_home_city("Mountain View");
215 specifics->set_address_home_state("California");
216 specifics->set_address_home_zip("94043");
217 specifics->set_address_home_country("US");
218 specifics->set_address_home_sorting_code("CEDEX");
219 specifics->set_address_home_dependent_locality("Santa Clara");
220 specifics->set_address_home_language_code("en");
222 return syncer::SyncData::CreateLocalData(kGuid1, kGuid1, entity_specifics);
225 } // namespace
227 class AutofillProfileSyncableServiceTest : public testing::Test {
228 public:
229 AutofillProfileSyncableServiceTest() {}
231 virtual void SetUp() OVERRIDE {
232 sync_processor_.reset(new MockSyncChangeProcessor);
235 // Wrapper around AutofillProfileSyncableService::MergeDataAndStartSyncing()
236 // that also verifies expectations.
237 void MergeDataAndStartSyncing(
238 const std::vector<AutofillProfile*>& profiles_from_web_db,
239 const syncer::SyncDataList& data_list,
240 const MockAutofillProfileSyncableService::DataBundle& expected_bundle,
241 const syncer::SyncChangeList& expected_change_list) {
242 EXPECT_CALL(autofill_syncable_service_, LoadAutofillData(_))
243 .Times(1)
244 .WillOnce(DoAll(CopyData(&profiles_from_web_db), Return(true)));
245 EXPECT_CALL(autofill_syncable_service_,
246 SaveChangesToWebData(DataBundleCheck(expected_bundle)))
247 .Times(1)
248 .WillOnce(Return(true));
249 if (expected_change_list.empty()) {
250 EXPECT_CALL(*sync_processor_, ProcessSyncChanges(_, _)).Times(0);
251 } else {
252 ON_CALL(*sync_processor_, ProcessSyncChanges(_, _))
253 .WillByDefault(Return(syncer::SyncError()));
254 EXPECT_CALL(*sync_processor_,
255 ProcessSyncChanges(_, CheckSyncChanges(expected_change_list)))
256 .Times(1)
257 .WillOnce(Return(syncer::SyncError()));
260 // Takes ownership of sync_processor_.
261 autofill_syncable_service_.MergeDataAndStartSyncing(
262 syncer::AUTOFILL_PROFILE, data_list,
263 sync_processor_.PassAs<syncer::SyncChangeProcessor>(),
264 scoped_ptr<syncer::SyncErrorFactory>(
265 new syncer::SyncErrorFactoryMock()));
268 protected:
269 base::MessageLoop message_loop_;
270 MockAutofillProfileSyncableService autofill_syncable_service_;
271 scoped_ptr<MockSyncChangeProcessor> sync_processor_;
274 TEST_F(AutofillProfileSyncableServiceTest, MergeDataAndStartSyncing) {
275 std::vector<AutofillProfile*> profiles_from_web_db;
276 std::string guid_present1 = kGuid1;
277 std::string guid_present2 = kGuid2;
278 std::string guid_synced1 = kGuid3;
279 std::string guid_synced2 = kGuid4;
280 std::string origin_present1 = kHttpOrigin;
281 std::string origin_present2 = std::string();
282 std::string origin_synced1 = kHttpsOrigin;
283 std::string origin_synced2 = kSettingsOrigin;
285 profiles_from_web_db.push_back(
286 new AutofillProfile(guid_present1, origin_present1));
287 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
288 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
289 ASCIIToUTF16("1 1st st"));
290 profiles_from_web_db.push_back(
291 new AutofillProfile(guid_present2, origin_present2));
292 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
293 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
294 ASCIIToUTF16("2 2nd st"));
296 syncer::SyncDataList data_list;
297 AutofillProfile profile1(guid_synced1, origin_synced1);
298 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
299 data_list.push_back(autofill_syncable_service_.CreateData(profile1));
300 AutofillProfile profile2(guid_synced2, origin_synced2);
301 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Harry"));
302 data_list.push_back(autofill_syncable_service_.CreateData(profile2));
303 // This one will have the name and origin updated.
304 AutofillProfile profile3(guid_present2, origin_synced2);
305 profile3.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom Doe"));
306 data_list.push_back(autofill_syncable_service_.CreateData(profile3));
308 syncer::SyncChangeList expected_change_list;
309 expected_change_list.push_back(
310 syncer::SyncChange(FROM_HERE,
311 syncer::SyncChange::ACTION_ADD,
312 MockAutofillProfileSyncableService::CreateData(
313 *profiles_from_web_db.front())));
315 MockAutofillProfileSyncableService::DataBundle expected_bundle;
316 expected_bundle.profiles_to_add.push_back(&profile1);
317 expected_bundle.profiles_to_add.push_back(&profile2);
318 expected_bundle.profiles_to_update.push_back(&profile3);
320 MergeDataAndStartSyncing(
321 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
322 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
325 TEST_F(AutofillProfileSyncableServiceTest, MergeIdenticalProfiles) {
326 std::vector<AutofillProfile*> profiles_from_web_db;
327 std::string guid_present1 = kGuid1;
328 std::string guid_present2 = kGuid2;
329 std::string guid_synced1 = kGuid3;
330 std::string guid_synced2 = kGuid4;
331 std::string origin_present1 = kHttpOrigin;
332 std::string origin_present2 = kSettingsOrigin;
333 std::string origin_synced1 = kHttpsOrigin;
334 std::string origin_synced2 = kHttpsOrigin;
336 profiles_from_web_db.push_back(
337 new AutofillProfile(guid_present1, origin_present1));
338 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
339 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
340 ASCIIToUTF16("1 1st st"));
341 profiles_from_web_db.push_back(
342 new AutofillProfile(guid_present2, origin_present2));
343 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
344 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
345 ASCIIToUTF16("2 2nd st"));
347 // The synced profiles are identical to the local ones, except that the guids
348 // are different.
349 syncer::SyncDataList data_list;
350 AutofillProfile profile1(guid_synced1, origin_synced1);
351 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
352 profile1.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1 1st st"));
353 data_list.push_back(autofill_syncable_service_.CreateData(profile1));
354 AutofillProfile profile2(guid_synced2, origin_synced2);
355 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
356 profile2.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("2 2nd st"));
357 data_list.push_back(autofill_syncable_service_.CreateData(profile2));
359 AutofillProfile expected_profile(profile2);
360 expected_profile.set_origin(kSettingsOrigin);
361 syncer::SyncChangeList expected_change_list;
362 expected_change_list.push_back(
363 syncer::SyncChange(FROM_HERE,
364 syncer::SyncChange::ACTION_UPDATE,
365 MockAutofillProfileSyncableService::CreateData(
366 expected_profile)));
368 MockAutofillProfileSyncableService::DataBundle expected_bundle;
369 expected_bundle.profiles_to_delete.push_back(guid_present1);
370 expected_bundle.profiles_to_delete.push_back(guid_present2);
371 expected_bundle.profiles_to_add.push_back(&profile1);
372 expected_bundle.profiles_to_add.push_back(&expected_profile);
374 MergeDataAndStartSyncing(
375 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
376 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
379 TEST_F(AutofillProfileSyncableServiceTest, MergeSimilarProfiles) {
380 std::vector<AutofillProfile*> profiles_from_web_db;
381 std::string guid_present1 = kGuid1;
382 std::string guid_present2 = kGuid2;
383 std::string guid_synced1 = kGuid3;
384 std::string guid_synced2 = kGuid4;
385 std::string origin_present1 = kHttpOrigin;
386 std::string origin_present2 = kSettingsOrigin;
387 std::string origin_synced1 = kHttpsOrigin;
388 std::string origin_synced2 = kHttpsOrigin;
390 profiles_from_web_db.push_back(
391 new AutofillProfile(guid_present1, origin_present1));
392 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
393 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
394 ASCIIToUTF16("1 1st st"));
395 profiles_from_web_db.push_back(
396 new AutofillProfile(guid_present2, origin_present2));
397 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
398 profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
399 ASCIIToUTF16("2 2nd st"));
401 // The synced profiles are identical to the local ones, except that the guids
402 // are different.
403 syncer::SyncDataList data_list;
404 AutofillProfile profile1(guid_synced1, origin_synced1);
405 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
406 profile1.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1 1st st"));
407 profile1.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
408 data_list.push_back(autofill_syncable_service_.CreateData(profile1));
409 AutofillProfile profile2(guid_synced2, origin_synced2);
410 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
411 profile2.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("2 2nd st"));
412 profile2.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Fizzbang, LLC."));
413 data_list.push_back(autofill_syncable_service_.CreateData(profile2));
415 // The first profile should have its origin updated.
416 // The second profile should remain as-is, because an unverified profile
417 // should never overwrite a verified one.
418 AutofillProfile expected_profile(profile1);
419 expected_profile.set_origin(origin_present1);
420 syncer::SyncChangeList expected_change_list;
421 expected_change_list.push_back(
422 syncer::SyncChange(FROM_HERE,
423 syncer::SyncChange::ACTION_ADD,
424 MockAutofillProfileSyncableService::CreateData(
425 *profiles_from_web_db.back())));
426 expected_change_list.push_back(
427 syncer::SyncChange(FROM_HERE,
428 syncer::SyncChange::ACTION_UPDATE,
429 MockAutofillProfileSyncableService::CreateData(
430 expected_profile)));
432 MockAutofillProfileSyncableService::DataBundle expected_bundle;
433 expected_bundle.profiles_to_delete.push_back(guid_present1);
434 expected_bundle.profiles_to_add.push_back(&expected_profile);
435 expected_bundle.profiles_to_add.push_back(&profile2);
437 MergeDataAndStartSyncing(
438 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
439 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
442 // Ensure that no Sync events are generated to fill in missing origins from Sync
443 // with explicitly present empty ones. This ensures that the migration to add
444 // origins to profiles does not generate lots of needless Sync updates.
445 TEST_F(AutofillProfileSyncableServiceTest, MergeDataEmptyOrigins) {
446 std::vector<AutofillProfile*> profiles_from_web_db;
448 // Create a profile with an empty origin.
449 AutofillProfile profile(kGuid1, std::string());
450 profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
451 profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1 1st st"));
453 profiles_from_web_db.push_back(new AutofillProfile(profile));
455 // Create a Sync profile identical to |profile|, except with no origin set.
456 sync_pb::EntitySpecifics specifics;
457 sync_pb::AutofillProfileSpecifics* autofill_specifics =
458 specifics.mutable_autofill_profile();
459 autofill_specifics->set_guid(profile.guid());
460 autofill_specifics->add_name_first("John");
461 autofill_specifics->add_name_middle(std::string());
462 autofill_specifics->add_name_last(std::string());
463 autofill_specifics->add_name_full(std::string());
464 autofill_specifics->add_email_address(std::string());
465 autofill_specifics->add_phone_home_whole_number(std::string());
466 autofill_specifics->set_address_home_line1("1 1st st");
467 EXPECT_FALSE(autofill_specifics->has_origin());
469 syncer::SyncDataList data_list;
470 data_list.push_back(
471 syncer::SyncData::CreateLocalData(
472 profile.guid(), profile.guid(), specifics));
474 MockAutofillProfileSyncableService::DataBundle expected_bundle;
475 syncer::SyncChangeList expected_change_list;
476 MergeDataAndStartSyncing(
477 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
478 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
481 TEST_F(AutofillProfileSyncableServiceTest, GetAllSyncData) {
482 std::vector<AutofillProfile*> profiles_from_web_db;
483 std::string guid_present1 = kGuid1;
484 std::string guid_present2 = kGuid2;
486 profiles_from_web_db.push_back(
487 new AutofillProfile(guid_present1, kHttpOrigin));
488 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
489 profiles_from_web_db.push_back(
490 new AutofillProfile(guid_present2, kHttpsOrigin));
491 profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
493 syncer::SyncChangeList expected_change_list;
494 expected_change_list.push_back(
495 syncer::SyncChange(FROM_HERE,
496 syncer::SyncChange::ACTION_ADD,
497 MockAutofillProfileSyncableService::CreateData(
498 *profiles_from_web_db.front())));
499 expected_change_list.push_back(
500 syncer::SyncChange(FROM_HERE,
501 syncer::SyncChange::ACTION_ADD,
502 MockAutofillProfileSyncableService::CreateData(
503 *profiles_from_web_db.back())));
505 MockAutofillProfileSyncableService::DataBundle expected_bundle;
506 syncer::SyncDataList data_list;
507 MergeDataAndStartSyncing(
508 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
510 syncer::SyncDataList data =
511 autofill_syncable_service_.GetAllSyncData(syncer::AUTOFILL_PROFILE);
513 ASSERT_EQ(2U, data.size());
514 EXPECT_EQ(guid_present1, data[0].GetSpecifics().autofill_profile().guid());
515 EXPECT_EQ(guid_present2, data[1].GetSpecifics().autofill_profile().guid());
516 EXPECT_EQ(kHttpOrigin, data[0].GetSpecifics().autofill_profile().origin());
517 EXPECT_EQ(kHttpsOrigin, data[1].GetSpecifics().autofill_profile().origin());
519 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
522 TEST_F(AutofillProfileSyncableServiceTest, ProcessSyncChanges) {
523 std::vector<AutofillProfile *> profiles_from_web_db;
524 std::string guid_present = kGuid1;
525 std::string guid_synced = kGuid2;
527 syncer::SyncChangeList change_list;
528 AutofillProfile profile(guid_synced, kHttpOrigin);
529 profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
530 change_list.push_back(
531 syncer::SyncChange(
532 FROM_HERE,
533 syncer::SyncChange::ACTION_ADD,
534 MockAutofillProfileSyncableService::CreateData(profile)));
535 AutofillProfile empty_profile(guid_present, kHttpsOrigin);
536 change_list.push_back(
537 syncer::SyncChange(
538 FROM_HERE,
539 syncer::SyncChange::ACTION_DELETE,
540 MockAutofillProfileSyncableService::CreateData(empty_profile)));
542 MockAutofillProfileSyncableService::DataBundle expected_bundle;
543 expected_bundle.profiles_to_delete.push_back(guid_present);
544 expected_bundle.profiles_to_add.push_back(&profile);
546 EXPECT_CALL(autofill_syncable_service_, SaveChangesToWebData(
547 DataBundleCheck(expected_bundle)))
548 .Times(1)
549 .WillOnce(Return(true));
551 autofill_syncable_service_.set_sync_processor(sync_processor_.release());
552 syncer::SyncError error = autofill_syncable_service_.ProcessSyncChanges(
553 FROM_HERE, change_list);
555 EXPECT_FALSE(error.IsSet());
558 TEST_F(AutofillProfileSyncableServiceTest, AutofillProfileAdded) {
559 // Will be owned by the syncable service. Keep a reference available here for
560 // verifying test expectations.
561 TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
562 autofill_syncable_service_.set_sync_processor(sync_change_processor);
564 AutofillProfile profile(kGuid1, kHttpsOrigin);
565 profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
566 AutofillProfileChange change(AutofillProfileChange::ADD, kGuid1, &profile);
567 autofill_syncable_service_.AutofillProfileChanged(change);
569 ASSERT_EQ(1U, sync_change_processor->changes().size());
570 syncer::SyncChange result = sync_change_processor->changes()[0];
571 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, result.change_type());
573 sync_pb::AutofillProfileSpecifics specifics =
574 result.sync_data().GetSpecifics().autofill_profile();
575 EXPECT_EQ(kGuid1, specifics.guid());
576 EXPECT_EQ(kHttpsOrigin, specifics.origin());
577 EXPECT_THAT(specifics.name_first(), testing::ElementsAre("Jane"));
580 TEST_F(AutofillProfileSyncableServiceTest, AutofillProfileDeleted) {
581 // Will be owned by the syncable service. Keep a reference available here for
582 // verifying test expectations.
583 TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
584 autofill_syncable_service_.set_sync_processor(sync_change_processor);
586 AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, NULL);
587 autofill_syncable_service_.AutofillProfileChanged(change);
589 ASSERT_EQ(1U, sync_change_processor->changes().size());
590 syncer::SyncChange result = sync_change_processor->changes()[0];
591 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, result.change_type());
592 sync_pb::AutofillProfileSpecifics specifics =
593 result.sync_data().GetSpecifics().autofill_profile();
594 EXPECT_EQ(kGuid2, specifics.guid());
597 TEST_F(AutofillProfileSyncableServiceTest, UpdateField) {
598 AutofillProfile profile(kGuid1, kSettingsOrigin);
599 std::string company1 = "A Company";
600 std::string company2 = "Another Company";
601 profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16(company1));
602 EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
603 COMPANY_NAME, company1, &profile));
604 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), ASCIIToUTF16(company1));
605 EXPECT_TRUE(AutofillProfileSyncableService::UpdateField(
606 COMPANY_NAME, company2, &profile));
607 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), ASCIIToUTF16(company2));
608 EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
609 COMPANY_NAME, company2, &profile));
610 EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), ASCIIToUTF16(company2));
613 TEST_F(AutofillProfileSyncableServiceTest, UpdateMultivaluedField) {
614 AutofillProfile profile(kGuid1, kHttpsOrigin);
616 std::vector<base::string16> values;
617 values.push_back(ASCIIToUTF16("1@1.com"));
618 values.push_back(ASCIIToUTF16("2@1.com"));
619 profile.SetRawMultiInfo(EMAIL_ADDRESS, values);
621 ::google::protobuf::RepeatedPtrField<std::string> specifics_fields;
622 specifics_fields.AddAllocated(new std::string("2@1.com"));
623 specifics_fields.AddAllocated(new std::string("3@1.com"));
625 EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
626 EMAIL_ADDRESS, specifics_fields, &profile));
627 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
628 ASSERT_TRUE(values.size() == 2);
629 EXPECT_EQ(values[0], ASCIIToUTF16("2@1.com"));
630 EXPECT_EQ(values[1], ASCIIToUTF16("3@1.com"));
632 EXPECT_FALSE(AutofillProfileSyncableService::UpdateMultivaluedField(
633 EMAIL_ADDRESS, specifics_fields, &profile));
634 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
635 ASSERT_EQ(values.size(), 2U);
636 EXPECT_EQ(values[0], ASCIIToUTF16("2@1.com"));
637 EXPECT_EQ(values[1], ASCIIToUTF16("3@1.com"));
638 EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
639 EMAIL_ADDRESS, ::google::protobuf::RepeatedPtrField<std::string>(),
640 &profile));
641 profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
642 ASSERT_EQ(values.size(), 1U); // Always have at least an empty string.
643 EXPECT_EQ(values[0], ASCIIToUTF16(""));
646 TEST_F(AutofillProfileSyncableServiceTest, MergeProfile) {
647 AutofillProfile profile1(kGuid1, kHttpOrigin);
648 profile1.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("111 First St."));
650 std::vector<base::string16> values;
651 values.push_back(ASCIIToUTF16("1@1.com"));
652 values.push_back(ASCIIToUTF16("2@1.com"));
653 profile1.SetRawMultiInfo(EMAIL_ADDRESS, values);
655 AutofillProfile profile2(kGuid2, kHttpsOrigin);
656 profile2.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("111 First St."));
658 // |values| now is [ "1@1.com", "2@1.com", "3@1.com" ].
659 values.push_back(ASCIIToUTF16("3@1.com"));
660 profile2.SetRawMultiInfo(EMAIL_ADDRESS, values);
662 values.clear();
663 values.push_back(ASCIIToUTF16("John"));
664 profile1.SetRawMultiInfo(NAME_FIRST, values);
665 values.push_back(ASCIIToUTF16("Jane"));
666 profile2.SetRawMultiInfo(NAME_FIRST, values);
668 values.clear();
669 values.push_back(ASCIIToUTF16("Doe"));
670 profile1.SetRawMultiInfo(NAME_LAST, values);
671 values.push_back(ASCIIToUTF16("Other"));
672 profile2.SetRawMultiInfo(NAME_LAST, values);
674 values.clear();
675 values.push_back(ASCIIToUTF16("650234567"));
676 profile2.SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, values);
678 profile1.set_language_code("en");
680 EXPECT_FALSE(AutofillProfileSyncableService::MergeProfile(profile2,
681 &profile1,
682 "en-US"));
684 profile1.GetRawMultiInfo(NAME_FIRST, &values);
685 ASSERT_EQ(values.size(), 2U);
686 EXPECT_EQ(values[0], ASCIIToUTF16("John"));
687 EXPECT_EQ(values[1], ASCIIToUTF16("Jane"));
689 profile1.GetRawMultiInfo(NAME_LAST, &values);
690 ASSERT_EQ(values.size(), 2U);
691 EXPECT_EQ(values[0], ASCIIToUTF16("Doe"));
692 EXPECT_EQ(values[1], ASCIIToUTF16("Other"));
694 profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
695 ASSERT_EQ(values.size(), 3U);
696 EXPECT_EQ(values[0], ASCIIToUTF16("1@1.com"));
697 EXPECT_EQ(values[1], ASCIIToUTF16("2@1.com"));
698 EXPECT_EQ(values[2], ASCIIToUTF16("3@1.com"));
700 profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
701 ASSERT_EQ(values.size(), 1U);
702 EXPECT_EQ(values[0], ASCIIToUTF16("650234567"));
704 EXPECT_EQ(profile2.origin(), profile1.origin());
706 AutofillProfile profile3(kGuid3, kHttpOrigin);
707 profile3.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("111 First St."));
709 values.clear();
710 values.push_back(ASCIIToUTF16("Jane"));
711 profile3.SetRawMultiInfo(NAME_FIRST, values);
713 values.clear();
714 values.push_back(ASCIIToUTF16("Doe"));
715 profile3.SetRawMultiInfo(NAME_LAST, values);
717 EXPECT_TRUE(AutofillProfileSyncableService::MergeProfile(profile3,
718 &profile1,
719 "en-US"));
721 profile1.GetRawMultiInfo(NAME_FIRST, &values);
722 ASSERT_EQ(values.size(), 3U);
723 EXPECT_EQ(values[0], ASCIIToUTF16("John"));
724 EXPECT_EQ(values[1], ASCIIToUTF16("Jane"));
725 EXPECT_EQ(values[2], ASCIIToUTF16("Jane"));
727 profile1.GetRawMultiInfo(NAME_LAST, &values);
728 ASSERT_EQ(values.size(), 3U);
729 EXPECT_EQ(values[0], ASCIIToUTF16("Doe"));
730 EXPECT_EQ(values[1], ASCIIToUTF16("Other"));
731 EXPECT_EQ(values[2], ASCIIToUTF16("Doe"));
733 // Middle name should have three entries as well.
734 profile1.GetRawMultiInfo(NAME_MIDDLE, &values);
735 ASSERT_EQ(values.size(), 3U);
736 EXPECT_TRUE(values[0].empty());
737 EXPECT_TRUE(values[1].empty());
738 EXPECT_TRUE(values[2].empty());
740 profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
741 ASSERT_EQ(values.size(), 3U);
742 EXPECT_EQ(values[0], ASCIIToUTF16("1@1.com"));
743 EXPECT_EQ(values[1], ASCIIToUTF16("2@1.com"));
744 EXPECT_EQ(values[2], ASCIIToUTF16("3@1.com"));
746 profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
747 ASSERT_EQ(values.size(), 1U);
748 EXPECT_EQ(values[0], ASCIIToUTF16("650234567"));
751 // Ensure that all profile fields are able to be synced up from the client to
752 // the server.
753 TEST_F(AutofillProfileSyncableServiceTest, SyncAllFieldsToServer) {
754 std::vector<AutofillProfile*> profiles_from_web_db;
756 // Create a profile with all fields set.
757 profiles_from_web_db.push_back(ConstructCompleteProfile().release());
759 // Set up expectations: No changes to the WebDB, and all fields correctly
760 // copied to Sync.
761 MockAutofillProfileSyncableService::DataBundle expected_bundle;
762 syncer::SyncChangeList expected_change_list;
763 expected_change_list.push_back(
764 syncer::SyncChange(FROM_HERE,
765 syncer::SyncChange::ACTION_ADD,
766 ConstructCompleteSyncData()));
768 // Verify the expectations.
769 syncer::SyncDataList data_list;
770 MergeDataAndStartSyncing(
771 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
772 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
775 // Ensure that all profile fields are able to be synced down from the server to
776 // the client.
777 TEST_F(AutofillProfileSyncableServiceTest, SyncAllFieldsToClient) {
778 // Create a profile with all fields set.
779 syncer::SyncDataList data_list;
780 data_list.push_back(ConstructCompleteSyncData());
782 // Set up expectations: All fields correctly copied to the WebDB, and no
783 // changes propagated to Sync.
784 syncer::SyncChangeList expected_change_list;
785 scoped_ptr<AutofillProfile> expected_profile = ConstructCompleteProfile();
786 MockAutofillProfileSyncableService::DataBundle expected_bundle;
787 expected_bundle.profiles_to_add.push_back(expected_profile.get());
789 // Verify the expectations.
790 std::vector<AutofillProfile*> profiles_from_web_db;
791 MergeDataAndStartSyncing(
792 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
793 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
796 // Ensure that the street address field takes precedence over the address line 1
797 // and line 2 fields, even though these are expected to always be in sync in
798 // practice.
799 TEST_F(AutofillProfileSyncableServiceTest,
800 StreetAddressTakesPrecedenceOverAddressLines) {
801 // Create a Sync profile with conflicting address data in the street address
802 // field vs. the address line 1 and address line 2 fields.
803 sync_pb::EntitySpecifics specifics;
804 sync_pb::AutofillProfileSpecifics* autofill_specifics =
805 specifics.mutable_autofill_profile();
806 autofill_specifics->set_guid(kGuid1);
807 autofill_specifics->set_origin(kHttpsOrigin);
808 autofill_specifics->add_name_first(std::string());
809 autofill_specifics->add_name_middle(std::string());
810 autofill_specifics->add_name_last(std::string());
811 autofill_specifics->add_email_address(std::string());
812 autofill_specifics->add_phone_home_whole_number(std::string());
813 autofill_specifics->set_address_home_line1("123 Example St.");
814 autofill_specifics->set_address_home_line2("Apt. 42");
815 autofill_specifics->set_address_home_street_address("456 El Camino Real\n"
816 "Suite #1337");
818 syncer::SyncDataList data_list;
819 data_list.push_back(
820 syncer::SyncData::CreateLocalData(kGuid1, kGuid1, specifics));
822 // Set up expectations: Full street address takes precedence over address
823 // lines.
824 syncer::SyncChangeList expected_change_list;
825 AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
826 expected_profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
827 ASCIIToUTF16("456 El Camino Real\n"
828 "Suite #1337"));
829 EXPECT_EQ(ASCIIToUTF16("456 El Camino Real"),
830 expected_profile.GetRawInfo(ADDRESS_HOME_LINE1));
831 EXPECT_EQ(ASCIIToUTF16("Suite #1337"),
832 expected_profile.GetRawInfo(ADDRESS_HOME_LINE2));
833 MockAutofillProfileSyncableService::DataBundle expected_bundle;
834 expected_bundle.profiles_to_add.push_back(&expected_profile);
836 // Verify the expectations.
837 std::vector<AutofillProfile*> profiles_from_web_db;
838 MergeDataAndStartSyncing(
839 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
840 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
843 // Ensure that no Sync events are generated to fill in missing street address
844 // fields from Sync with explicitly present ones identical to the data stored in
845 // the line1 and line2 fields. This ensures that the migration to add the
846 // street address field to profiles does not generate lots of needless Sync
847 // updates.
848 TEST_F(AutofillProfileSyncableServiceTest, MergeDataEmptyStreetAddress) {
849 std::vector<AutofillProfile*> profiles_from_web_db;
851 // Create a profile with the street address set.
852 AutofillProfile profile(kGuid1, kHttpsOrigin);
853 profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
854 ASCIIToUTF16("123 Example St.\n"
855 "Apt. 42"));
856 EXPECT_EQ(ASCIIToUTF16("123 Example St."),
857 profile.GetRawInfo(ADDRESS_HOME_LINE1));
858 EXPECT_EQ(ASCIIToUTF16("Apt. 42"), profile.GetRawInfo(ADDRESS_HOME_LINE2));
860 profiles_from_web_db.push_back(new AutofillProfile(profile));
862 // Create a Sync profile identical to |profile|, except without street address
863 // explicitly set.
864 sync_pb::EntitySpecifics specifics;
865 sync_pb::AutofillProfileSpecifics* autofill_specifics =
866 specifics.mutable_autofill_profile();
867 autofill_specifics->set_guid(profile.guid());
868 autofill_specifics->set_origin(profile.origin());
869 autofill_specifics->add_name_first(std::string());
870 autofill_specifics->add_name_middle(std::string());
871 autofill_specifics->add_name_last(std::string());
872 autofill_specifics->add_name_full(std::string());
873 autofill_specifics->add_email_address(std::string());
874 autofill_specifics->add_phone_home_whole_number(std::string());
875 autofill_specifics->set_address_home_line1("123 Example St.");
876 autofill_specifics->set_address_home_line2("Apt. 42");
877 EXPECT_FALSE(autofill_specifics->has_address_home_street_address());
879 syncer::SyncDataList data_list;
880 data_list.push_back(
881 syncer::SyncData::CreateLocalData(
882 profile.guid(), profile.guid(), specifics));
884 MockAutofillProfileSyncableService::DataBundle expected_bundle;
885 syncer::SyncChangeList expected_change_list;
886 MergeDataAndStartSyncing(
887 profiles_from_web_db, data_list, expected_bundle, expected_change_list);
888 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
891 // Sync data without origin should not overwrite existing origin in local
892 // autofill profile.
893 TEST_F(AutofillProfileSyncableServiceTest, EmptySyncPreservesOrigin) {
894 std::vector<AutofillProfile*> profiles_from_web_db;
896 // Local autofill profile has an origin.
897 AutofillProfile profile(kGuid1, kHttpsOrigin);
898 profiles_from_web_db.push_back(new AutofillProfile(profile));
900 // Remote data does not have an origin value.
901 sync_pb::EntitySpecifics specifics;
902 sync_pb::AutofillProfileSpecifics* autofill_specifics =
903 specifics.mutable_autofill_profile();
904 autofill_specifics->set_guid(profile.guid());
905 autofill_specifics->add_name_first("John");
906 autofill_specifics->add_name_middle(std::string());
907 autofill_specifics->add_name_last(std::string());
908 autofill_specifics->add_name_full(std::string());
909 autofill_specifics->add_email_address(std::string());
910 autofill_specifics->add_phone_home_whole_number(std::string());
911 EXPECT_FALSE(autofill_specifics->has_origin());
913 syncer::SyncDataList data_list;
914 data_list.push_back(
915 syncer::SyncData::CreateLocalData(
916 profile.guid(), profile.guid(), specifics));
918 // Expect the local autofill profile to still have an origin after sync.
919 MockAutofillProfileSyncableService::DataBundle expected_bundle;
920 AutofillProfile expected_profile(profile.guid(), profile.origin());
921 expected_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
922 expected_bundle.profiles_to_update.push_back(&expected_profile);
924 // Expect no sync events to add origin to the remote data.
925 syncer::SyncChangeList expected_empty_change_list;
927 MergeDataAndStartSyncing(profiles_from_web_db, data_list,
928 expected_bundle, expected_empty_change_list);
929 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
932 // Missing language code field should not generate sync events.
933 TEST_F(AutofillProfileSyncableServiceTest, NoLanguageCodeNoSync) {
934 std::vector<AutofillProfile*> profiles_from_web_db;
936 // Local autofill profile has an empty language code.
937 AutofillProfile profile(kGuid1, kHttpsOrigin);
938 EXPECT_TRUE(profile.language_code().empty());
939 profiles_from_web_db.push_back(new AutofillProfile(profile));
941 // Remote data does not have a language code value.
942 sync_pb::EntitySpecifics specifics;
943 sync_pb::AutofillProfileSpecifics* autofill_specifics =
944 specifics.mutable_autofill_profile();
945 autofill_specifics->set_guid(profile.guid());
946 autofill_specifics->set_origin(profile.origin());
947 autofill_specifics->add_name_first(std::string());
948 autofill_specifics->add_name_middle(std::string());
949 autofill_specifics->add_name_last(std::string());
950 autofill_specifics->add_name_full(std::string());
951 autofill_specifics->add_email_address(std::string());
952 autofill_specifics->add_phone_home_whole_number(std::string());
953 EXPECT_FALSE(autofill_specifics->has_address_home_language_code());
955 syncer::SyncDataList data_list;
956 data_list.push_back(
957 syncer::SyncData::CreateLocalData(
958 profile.guid(), profile.guid(), specifics));
960 // Expect no changes to local and remote data.
961 MockAutofillProfileSyncableService::DataBundle expected_empty_bundle;
962 syncer::SyncChangeList expected_empty_change_list;
964 MergeDataAndStartSyncing(profiles_from_web_db, data_list,
965 expected_empty_bundle, expected_empty_change_list);
966 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
969 // Empty language code should be overwritten by sync.
970 TEST_F(AutofillProfileSyncableServiceTest, SyncUpdatesEmptyLanguageCode) {
971 std::vector<AutofillProfile*> profiles_from_web_db;
973 // Local autofill profile has an empty language code.
974 AutofillProfile profile(kGuid1, kHttpsOrigin);
975 EXPECT_TRUE(profile.language_code().empty());
976 profiles_from_web_db.push_back(new AutofillProfile(profile));
978 // Remote data has "en" language code.
979 sync_pb::EntitySpecifics specifics;
980 sync_pb::AutofillProfileSpecifics* autofill_specifics =
981 specifics.mutable_autofill_profile();
982 autofill_specifics->set_guid(profile.guid());
983 autofill_specifics->set_origin(profile.origin());
984 autofill_specifics->add_name_first(std::string());
985 autofill_specifics->add_name_middle(std::string());
986 autofill_specifics->add_name_last(std::string());
987 autofill_specifics->add_name_full(std::string());
988 autofill_specifics->add_email_address(std::string());
989 autofill_specifics->add_phone_home_whole_number(std::string());
990 autofill_specifics->set_address_home_language_code("en");
991 EXPECT_TRUE(autofill_specifics->has_address_home_language_code());
993 syncer::SyncDataList data_list;
994 data_list.push_back(
995 syncer::SyncData::CreateLocalData(
996 profile.guid(), profile.guid(), specifics));
998 // Expect the local autofill profile to have "en" language code after sync.
999 MockAutofillProfileSyncableService::DataBundle expected_bundle;
1000 AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
1001 expected_profile.set_language_code("en");
1002 expected_bundle.profiles_to_update.push_back(&expected_profile);
1004 // Expect not changes to remote data.
1005 syncer::SyncChangeList expected_empty_change_list;
1007 MergeDataAndStartSyncing(profiles_from_web_db, data_list,
1008 expected_bundle, expected_empty_change_list);
1009 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
1012 // Incorrect language code should be overwritten by sync.
1013 TEST_F(AutofillProfileSyncableServiceTest, SyncUpdatesIncorrectLanguageCode) {
1014 std::vector<AutofillProfile*> profiles_from_web_db;
1016 // Local autofill profile has "de" language code.
1017 AutofillProfile profile(kGuid1, kHttpsOrigin);
1018 profile.set_language_code("de");
1019 profiles_from_web_db.push_back(new AutofillProfile(profile));
1021 // Remote data has "en" language code.
1022 sync_pb::EntitySpecifics specifics;
1023 sync_pb::AutofillProfileSpecifics* autofill_specifics =
1024 specifics.mutable_autofill_profile();
1025 autofill_specifics->set_guid(profile.guid());
1026 autofill_specifics->set_origin(profile.origin());
1027 autofill_specifics->add_name_first(std::string());
1028 autofill_specifics->add_name_middle(std::string());
1029 autofill_specifics->add_name_last(std::string());
1030 autofill_specifics->add_name_full(std::string());
1031 autofill_specifics->add_email_address(std::string());
1032 autofill_specifics->add_phone_home_whole_number(std::string());
1033 autofill_specifics->set_address_home_language_code("en");
1034 EXPECT_TRUE(autofill_specifics->has_address_home_language_code());
1036 syncer::SyncDataList data_list;
1037 data_list.push_back(
1038 syncer::SyncData::CreateLocalData(
1039 profile.guid(), profile.guid(), specifics));
1041 // Expect the local autofill profile to have "en" language code after sync.
1042 MockAutofillProfileSyncableService::DataBundle expected_bundle;
1043 AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
1044 expected_profile.set_language_code("en");
1045 expected_bundle.profiles_to_update.push_back(&expected_profile);
1047 // Expect no changes to remote data.
1048 syncer::SyncChangeList expected_empty_change_list;
1050 MergeDataAndStartSyncing(profiles_from_web_db, data_list,
1051 expected_bundle, expected_empty_change_list);
1052 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
1055 // Sync data without language code should not overwrite existing language code
1056 // in local autofill profile.
1057 TEST_F(AutofillProfileSyncableServiceTest, EmptySyncPreservesLanguageCode) {
1058 std::vector<AutofillProfile*> profiles_from_web_db;
1060 // Local autofill profile has "en" language code.
1061 AutofillProfile profile(kGuid1, kHttpsOrigin);
1062 profile.set_language_code("en");
1063 profiles_from_web_db.push_back(new AutofillProfile(profile));
1065 // Remote data does not have a language code value.
1066 sync_pb::EntitySpecifics specifics;
1067 sync_pb::AutofillProfileSpecifics* autofill_specifics =
1068 specifics.mutable_autofill_profile();
1069 autofill_specifics->set_guid(profile.guid());
1070 autofill_specifics->set_origin(profile.origin());
1071 autofill_specifics->add_name_first("John");
1072 autofill_specifics->add_name_middle(std::string());
1073 autofill_specifics->add_name_last(std::string());
1074 autofill_specifics->add_name_full(std::string());
1075 autofill_specifics->add_email_address(std::string());
1076 autofill_specifics->add_phone_home_whole_number(std::string());
1077 EXPECT_FALSE(autofill_specifics->has_address_home_language_code());
1079 syncer::SyncDataList data_list;
1080 data_list.push_back(
1081 syncer::SyncData::CreateLocalData(
1082 profile.guid(), profile.guid(), specifics));
1084 // Expect local autofill profile to still have "en" language code after sync.
1085 MockAutofillProfileSyncableService::DataBundle expected_bundle;
1086 AutofillProfile expected_profile(profile.guid(), profile.origin());
1087 expected_profile.set_language_code("en");
1088 expected_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
1089 expected_bundle.profiles_to_update.push_back(&expected_profile);
1091 // Expect no changes to remote data.
1092 syncer::SyncChangeList expected_empty_change_list;
1094 MergeDataAndStartSyncing(profiles_from_web_db, data_list,
1095 expected_bundle, expected_empty_change_list);
1096 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
1099 // Language code in autofill profiles should be synced to the server.
1100 TEST_F(AutofillProfileSyncableServiceTest, LanguageCodePropagates) {
1101 TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
1102 autofill_syncable_service_.set_sync_processor(sync_change_processor);
1104 AutofillProfile profile(kGuid1, kHttpsOrigin);
1105 profile.set_language_code("en");
1106 AutofillProfileChange change(AutofillProfileChange::ADD, kGuid1, &profile);
1107 autofill_syncable_service_.AutofillProfileChanged(change);
1109 ASSERT_EQ(1U, sync_change_processor->changes().size());
1110 syncer::SyncChange result = sync_change_processor->changes()[0];
1111 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, result.change_type());
1113 sync_pb::AutofillProfileSpecifics specifics =
1114 result.sync_data().GetSpecifics().autofill_profile();
1115 EXPECT_EQ(kGuid1, specifics.guid());
1116 EXPECT_EQ(kHttpsOrigin, specifics.origin());
1117 EXPECT_EQ("en", specifics.address_home_language_code());
1120 // Missing full name field should not generate sync events.
1121 TEST_F(AutofillProfileSyncableServiceTest, NoFullNameNoSync) {
1122 std::vector<AutofillProfile*> profiles_from_web_db;
1124 // Local autofill profile has an empty full name.
1125 AutofillProfile profile(kGuid1, kHttpsOrigin);
1126 profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
1127 profiles_from_web_db.push_back(new AutofillProfile(profile));
1129 // Remote data does not have a full name.
1130 sync_pb::EntitySpecifics specifics;
1131 sync_pb::AutofillProfileSpecifics* autofill_specifics =
1132 specifics.mutable_autofill_profile();
1133 autofill_specifics->set_guid(profile.guid());
1134 autofill_specifics->set_origin(profile.origin());
1135 autofill_specifics->add_name_first(std::string("John"));
1136 autofill_specifics->add_name_middle(std::string());
1137 autofill_specifics->add_name_last(std::string());
1138 autofill_specifics->add_email_address(std::string());
1139 autofill_specifics->add_phone_home_whole_number(std::string());
1141 syncer::SyncDataList data_list;
1142 data_list.push_back(
1143 syncer::SyncData::CreateLocalData(
1144 profile.guid(), profile.guid(), specifics));
1146 // Expect no changes to local and remote data.
1147 MockAutofillProfileSyncableService::DataBundle expected_empty_bundle;
1148 syncer::SyncChangeList expected_empty_change_list;
1150 MergeDataAndStartSyncing(profiles_from_web_db, data_list,
1151 expected_empty_bundle, expected_empty_change_list);
1152 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
1155 TEST_F(AutofillProfileSyncableServiceTest, EmptySyncPreservesFullName) {
1156 std::vector<AutofillProfile*> profiles_from_web_db;
1158 // Local autofill profile has a full name.
1159 AutofillProfile profile(kGuid1, kHttpsOrigin);
1160 profile.SetInfo(AutofillType(NAME_FULL),
1161 ASCIIToUTF16("John Jacob Smith, Jr"), "en-US");
1162 profiles_from_web_db.push_back(new AutofillProfile(profile));
1164 // Remote data does not have a full name value.
1165 sync_pb::EntitySpecifics specifics;
1166 sync_pb::AutofillProfileSpecifics* autofill_specifics =
1167 specifics.mutable_autofill_profile();
1168 autofill_specifics->set_guid(profile.guid());
1169 autofill_specifics->set_origin(profile.origin());
1170 autofill_specifics->add_name_first(std::string("John"));
1171 autofill_specifics->add_name_middle(std::string("Jacob"));
1172 autofill_specifics->add_name_last(std::string("Smith"));
1174 syncer::SyncDataList data_list;
1175 data_list.push_back(
1176 syncer::SyncData::CreateLocalData(
1177 profile.guid(), profile.guid(), specifics));
1179 // Expect local autofill profile to still have the same full name after sync.
1180 MockAutofillProfileSyncableService::DataBundle expected_bundle;
1181 AutofillProfile expected_profile(profile.guid(), profile.origin());
1182 expected_profile.SetInfo(AutofillType(NAME_FULL),
1183 ASCIIToUTF16("John Jacob Smith, Jr"),
1184 "en-US");
1185 expected_bundle.profiles_to_update.push_back(&expected_profile);
1187 // Expect no changes to remote data.
1188 syncer::SyncChangeList expected_empty_change_list;
1190 MergeDataAndStartSyncing(profiles_from_web_db, data_list,
1191 expected_bundle, expected_empty_change_list);
1192 autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
1195 } // namespace autofill