Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / webdata / autofill_profile_syncable_service_unittest.cc
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.
4
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"
16
17 namespace autofill {
18
19 using ::testing::_;
20 using ::testing::DoAll;
21 using ::testing::Eq;
22 using ::testing::Return;
23 using ::testing::Property;
24 using base::ASCIIToUTF16;
25
26 namespace {
27
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";
36
37 class MockAutofillProfileSyncableService
38     : public AutofillProfileSyncableService {
39  public:
40   MockAutofillProfileSyncableService() {}
41   virtual ~MockAutofillProfileSyncableService() {}
42
43   using AutofillProfileSyncableService::DataBundle;
44   using AutofillProfileSyncableService::set_sync_processor;
45   using AutofillProfileSyncableService::CreateData;
46
47   MOCK_METHOD1(LoadAutofillData, bool(std::vector<AutofillProfile*>*));
48   MOCK_METHOD1(SaveChangesToWebData,
49                bool(const AutofillProfileSyncableService::DataBundle&));
50 };
51
52 ACTION_P(CopyData, data) {
53   arg0->resize(data->size());
54   std::copy(data->begin(), data->end(), arg0->begin());
55 }
56
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;
70     }
71   }
72   return true;
73 }
74
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;
83   }
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;
87   }
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;
91   }
92   return true;
93 }
94
95 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
96  public:
97   MockSyncChangeProcessor() {}
98   virtual ~MockSyncChangeProcessor() {}
99
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(); }
105 };
106
107 class TestSyncChangeProcessor : public syncer::SyncChangeProcessor {
108  public:
109   TestSyncChangeProcessor() {}
110   virtual ~TestSyncChangeProcessor() {}
111
112   virtual syncer::SyncError ProcessSyncChanges(
113       const tracked_objects::Location& location,
114       const syncer::SyncChangeList& changes) OVERRIDE {
115     changes_ = changes;
116     return syncer::SyncError();
117   }
118
119   virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
120       OVERRIDE {
121     return syncer::SyncDataList();
122   }
123
124   const syncer::SyncChangeList& changes() { return changes_; }
125
126  private:
127   syncer::SyncChangeList changes_;
128 };
129
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));
135
136   std::vector<base::string16> names;
137   names.push_back(ASCIIToUTF16("John K. Doe"));
138   names.push_back(ASCIIToUTF16("Jane Luise Smith"));
139   profile->SetRawMultiInfo(NAME_FULL, names);
140
141   std::vector<base::string16> emails;
142   emails.push_back(ASCIIToUTF16("user@example.com"));
143   emails.push_back(ASCIIToUTF16("superuser@example.org"));
144   profile->SetRawMultiInfo(EMAIL_ADDRESS, emails);
145
146   std::vector<base::string16> phones;
147   phones.push_back(ASCIIToUTF16("1.800.555.1234"));
148   phones.push_back(ASCIIToUTF16("1.866.650.0000"));
149   profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, phones);
150
151   profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
152                       ASCIIToUTF16("123 Fake St.\n"
153                                    "Apt. 42"));
154   EXPECT_EQ(ASCIIToUTF16("123 Fake St."),
155             profile->GetRawInfo(ADDRESS_HOME_LINE1));
156   EXPECT_EQ(ASCIIToUTF16("Apt. 42"), profile->GetRawInfo(ADDRESS_HOME_LINE2));
157
158   profile->SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Google, Inc."));
159   profile->SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Mountain View"));
160   profile->SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("California"));
161   profile->SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("94043"));
162   profile->SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
163   profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, ASCIIToUTF16("CEDEX"));
164   profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
165                       ASCIIToUTF16("Santa Clara"));
166   profile->set_language_code("en");
167   return profile.Pass();
168 }
169
170 // Returns SyncData with all Autofill profile fields set.  Contains identical
171 // data to the data returned from ConstructCompleteProfile().
172 syncer::SyncData ConstructCompleteSyncData() {
173   sync_pb::EntitySpecifics entity_specifics;
174   sync_pb::AutofillProfileSpecifics* specifics =
175       entity_specifics.mutable_autofill_profile();
176
177   specifics->set_guid(kGuid1);
178   specifics->set_origin(kHttpsOrigin);
179
180   specifics->add_name_first("John");
181   specifics->add_name_middle("K.");
182   specifics->add_name_last("Doe");
183
184   specifics->add_name_first("Jane");
185   specifics->add_name_middle("Luise");
186   specifics->add_name_last("Smith");
187
188   specifics->add_email_address("user@example.com");
189   specifics->add_email_address("superuser@example.org");
190
191   specifics->add_phone_home_whole_number("1.800.555.1234");
192   specifics->add_phone_home_whole_number("1.866.650.0000");
193
194   specifics->set_address_home_line1("123 Fake St.");
195   specifics->set_address_home_line2("Apt. 42");
196   specifics->set_address_home_street_address("123 Fake St.\n"
197                                              "Apt. 42");
198
199   specifics->set_company_name("Google, Inc.");
200   specifics->set_address_home_city("Mountain View");
201   specifics->set_address_home_state("California");
202   specifics->set_address_home_zip("94043");
203   specifics->set_address_home_country("US");
204   specifics->set_address_home_sorting_code("CEDEX");
205   specifics->set_address_home_dependent_locality("Santa Clara");
206   specifics->set_address_home_language_code("en");
207
208   return syncer::SyncData::CreateLocalData(kGuid1, kGuid1, entity_specifics);
209 }
210
211 }  // namespace
212
213 class AutofillProfileSyncableServiceTest : public testing::Test {
214  public:
215   AutofillProfileSyncableServiceTest() {}
216
217   virtual void SetUp() OVERRIDE {
218     sync_processor_.reset(new MockSyncChangeProcessor);
219   }
220
221   // Wrapper around AutofillProfileSyncableService::MergeDataAndStartSyncing()
222   // that also verifies expectations.
223   void MergeDataAndStartSyncing(
224       const std::vector<AutofillProfile*>& profiles_from_web_db,
225       const syncer::SyncDataList& data_list,
226       const MockAutofillProfileSyncableService::DataBundle& expected_bundle,
227       const syncer::SyncChangeList& expected_change_list) {
228     EXPECT_CALL(autofill_syncable_service_, LoadAutofillData(_))
229         .Times(1)
230         .WillOnce(DoAll(CopyData(&profiles_from_web_db), Return(true)));
231     EXPECT_CALL(autofill_syncable_service_,
232                 SaveChangesToWebData(DataBundleCheck(expected_bundle)))
233         .Times(1)
234         .WillOnce(Return(true));
235     if (expected_change_list.empty()) {
236       EXPECT_CALL(*sync_processor_, ProcessSyncChanges(_, _)).Times(0);
237     } else {
238       ON_CALL(*sync_processor_, ProcessSyncChanges(_, _))
239           .WillByDefault(Return(syncer::SyncError()));
240       EXPECT_CALL(*sync_processor_,
241                   ProcessSyncChanges(_, CheckSyncChanges(expected_change_list)))
242           .Times(1)
243           .WillOnce(Return(syncer::SyncError()));
244     }
245
246     // Takes ownership of sync_processor_.
247     autofill_syncable_service_.MergeDataAndStartSyncing(
248         syncer::AUTOFILL_PROFILE, data_list,
249         sync_processor_.PassAs<syncer::SyncChangeProcessor>(),
250         scoped_ptr<syncer::SyncErrorFactory>(
251             new syncer::SyncErrorFactoryMock()));
252   }
253
254  protected:
255   base::MessageLoop message_loop_;
256   MockAutofillProfileSyncableService autofill_syncable_service_;
257   scoped_ptr<MockSyncChangeProcessor> sync_processor_;
258 };
259
260 TEST_F(AutofillProfileSyncableServiceTest, MergeDataAndStartSyncing) {
261   std::vector<AutofillProfile*> profiles_from_web_db;
262   std::string guid_present1 = kGuid1;
263   std::string guid_present2 = kGuid2;
264   std::string guid_synced1 = kGuid3;
265   std::string guid_synced2 = kGuid4;
266   std::string origin_present1 = kHttpOrigin;
267   std::string origin_present2 = std::string();
268   std::string origin_synced1 = kHttpsOrigin;
269   std::string origin_synced2 = kSettingsOrigin;
270
271   profiles_from_web_db.push_back(
272       new AutofillProfile(guid_present1, origin_present1));
273   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
274   profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
275                                           ASCIIToUTF16("1 1st st"));
276   profiles_from_web_db.push_back(
277       new AutofillProfile(guid_present2, origin_present2));
278   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
279   profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
280                                           ASCIIToUTF16("2 2nd st"));
281
282   syncer::SyncDataList data_list;
283   AutofillProfile profile1(guid_synced1, origin_synced1);
284   profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
285   data_list.push_back(autofill_syncable_service_.CreateData(profile1));
286   AutofillProfile profile2(guid_synced2, origin_synced2);
287   profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Harry"));
288   data_list.push_back(autofill_syncable_service_.CreateData(profile2));
289   // This one will have the name and origin updated.
290   AutofillProfile profile3(guid_present2, origin_synced2);
291   profile3.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom Doe"));
292   data_list.push_back(autofill_syncable_service_.CreateData(profile3));
293
294   syncer::SyncChangeList expected_change_list;
295   expected_change_list.push_back(
296       syncer::SyncChange(FROM_HERE,
297                          syncer::SyncChange::ACTION_ADD,
298                          MockAutofillProfileSyncableService::CreateData(
299                              *profiles_from_web_db.front())));
300
301   MockAutofillProfileSyncableService::DataBundle expected_bundle;
302   expected_bundle.profiles_to_add.push_back(&profile1);
303   expected_bundle.profiles_to_add.push_back(&profile2);
304   expected_bundle.profiles_to_update.push_back(&profile3);
305
306   MergeDataAndStartSyncing(
307       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
308   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
309 }
310
311 TEST_F(AutofillProfileSyncableServiceTest, MergeIdenticalProfiles) {
312   std::vector<AutofillProfile*> profiles_from_web_db;
313   std::string guid_present1 = kGuid1;
314   std::string guid_present2 = kGuid2;
315   std::string guid_synced1 = kGuid3;
316   std::string guid_synced2 = kGuid4;
317   std::string origin_present1 = kHttpOrigin;
318   std::string origin_present2 = kSettingsOrigin;
319   std::string origin_synced1 = kHttpsOrigin;
320   std::string origin_synced2 = kHttpsOrigin;
321
322   profiles_from_web_db.push_back(
323       new AutofillProfile(guid_present1, origin_present1));
324   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
325   profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
326                                           ASCIIToUTF16("1 1st st"));
327   profiles_from_web_db.push_back(
328       new AutofillProfile(guid_present2, origin_present2));
329   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
330   profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
331                                           ASCIIToUTF16("2 2nd st"));
332
333   // The synced profiles are identical to the local ones, except that the guids
334   // are different.
335   syncer::SyncDataList data_list;
336   AutofillProfile profile1(guid_synced1, origin_synced1);
337   profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
338   profile1.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1 1st st"));
339   data_list.push_back(autofill_syncable_service_.CreateData(profile1));
340   AutofillProfile profile2(guid_synced2, origin_synced2);
341   profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
342   profile2.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("2 2nd st"));
343   data_list.push_back(autofill_syncable_service_.CreateData(profile2));
344
345   AutofillProfile expected_profile(profile2);
346   expected_profile.set_origin(kSettingsOrigin);
347   syncer::SyncChangeList expected_change_list;
348   expected_change_list.push_back(
349       syncer::SyncChange(FROM_HERE,
350                          syncer::SyncChange::ACTION_UPDATE,
351                          MockAutofillProfileSyncableService::CreateData(
352                              expected_profile)));
353
354   MockAutofillProfileSyncableService::DataBundle expected_bundle;
355   expected_bundle.profiles_to_delete.push_back(guid_present1);
356   expected_bundle.profiles_to_delete.push_back(guid_present2);
357   expected_bundle.profiles_to_add.push_back(&profile1);
358   expected_bundle.profiles_to_add.push_back(&expected_profile);
359
360   MergeDataAndStartSyncing(
361       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
362   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
363 }
364
365 TEST_F(AutofillProfileSyncableServiceTest, MergeSimilarProfiles) {
366   std::vector<AutofillProfile*> profiles_from_web_db;
367   std::string guid_present1 = kGuid1;
368   std::string guid_present2 = kGuid2;
369   std::string guid_synced1 = kGuid3;
370   std::string guid_synced2 = kGuid4;
371   std::string origin_present1 = kHttpOrigin;
372   std::string origin_present2 = kSettingsOrigin;
373   std::string origin_synced1 = kHttpsOrigin;
374   std::string origin_synced2 = kHttpsOrigin;
375
376   profiles_from_web_db.push_back(
377       new AutofillProfile(guid_present1, origin_present1));
378   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
379   profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
380                                           ASCIIToUTF16("1 1st st"));
381   profiles_from_web_db.push_back(
382       new AutofillProfile(guid_present2, origin_present2));
383   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
384   profiles_from_web_db.back()->SetRawInfo(ADDRESS_HOME_LINE1,
385                                           ASCIIToUTF16("2 2nd st"));
386
387   // The synced profiles are identical to the local ones, except that the guids
388   // are different.
389   syncer::SyncDataList data_list;
390   AutofillProfile profile1(guid_synced1, origin_synced1);
391   profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
392   profile1.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1 1st st"));
393   profile1.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
394   data_list.push_back(autofill_syncable_service_.CreateData(profile1));
395   AutofillProfile profile2(guid_synced2, origin_synced2);
396   profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
397   profile2.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("2 2nd st"));
398   profile2.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Fizzbang, LLC."));
399   data_list.push_back(autofill_syncable_service_.CreateData(profile2));
400
401   // The first profile should have its origin updated.
402   // The second profile should remain as-is, because an unverified profile
403   // should never overwrite a verified one.
404   AutofillProfile expected_profile(profile1);
405   expected_profile.set_origin(origin_present1);
406   syncer::SyncChangeList expected_change_list;
407   expected_change_list.push_back(
408       syncer::SyncChange(FROM_HERE,
409                          syncer::SyncChange::ACTION_ADD,
410                          MockAutofillProfileSyncableService::CreateData(
411                              *profiles_from_web_db.back())));
412   expected_change_list.push_back(
413       syncer::SyncChange(FROM_HERE,
414                          syncer::SyncChange::ACTION_UPDATE,
415                          MockAutofillProfileSyncableService::CreateData(
416                              expected_profile)));
417
418   MockAutofillProfileSyncableService::DataBundle expected_bundle;
419   expected_bundle.profiles_to_delete.push_back(guid_present1);
420   expected_bundle.profiles_to_add.push_back(&expected_profile);
421   expected_bundle.profiles_to_add.push_back(&profile2);
422
423   MergeDataAndStartSyncing(
424       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
425   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
426 }
427
428 // Ensure that no Sync events are generated to fill in missing origins from Sync
429 // with explicitly present empty ones.  This ensures that the migration to add
430 // origins to profiles does not generate lots of needless Sync updates.
431 TEST_F(AutofillProfileSyncableServiceTest, MergeDataEmptyOrigins) {
432   std::vector<AutofillProfile*> profiles_from_web_db;
433
434   // Create a profile with an empty origin.
435   AutofillProfile profile(kGuid1, std::string());
436   profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
437   profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1 1st st"));
438
439   profiles_from_web_db.push_back(new AutofillProfile(profile));
440
441   // Create a Sync profile identical to |profile|, except with no origin set.
442   sync_pb::EntitySpecifics specifics;
443   sync_pb::AutofillProfileSpecifics* autofill_specifics =
444       specifics.mutable_autofill_profile();
445   autofill_specifics->set_guid(profile.guid());
446   autofill_specifics->add_name_first("John");
447   autofill_specifics->add_name_middle(std::string());
448   autofill_specifics->add_name_last(std::string());
449   autofill_specifics->add_email_address(std::string());
450   autofill_specifics->add_phone_home_whole_number(std::string());
451   autofill_specifics->set_address_home_line1("1 1st st");
452   EXPECT_FALSE(autofill_specifics->has_origin());
453
454   syncer::SyncDataList data_list;
455   data_list.push_back(
456       syncer::SyncData::CreateLocalData(
457           profile.guid(), profile.guid(), specifics));
458
459   MockAutofillProfileSyncableService::DataBundle expected_bundle;
460   syncer::SyncChangeList expected_change_list;
461   MergeDataAndStartSyncing(
462       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
463   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
464 }
465
466 TEST_F(AutofillProfileSyncableServiceTest, GetAllSyncData) {
467   std::vector<AutofillProfile*> profiles_from_web_db;
468   std::string guid_present1 = kGuid1;
469   std::string guid_present2 = kGuid2;
470
471   profiles_from_web_db.push_back(
472       new AutofillProfile(guid_present1, kHttpOrigin));
473   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
474   profiles_from_web_db.push_back(
475       new AutofillProfile(guid_present2, kHttpsOrigin));
476   profiles_from_web_db.back()->SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
477
478   syncer::SyncChangeList expected_change_list;
479   expected_change_list.push_back(
480       syncer::SyncChange(FROM_HERE,
481                          syncer::SyncChange::ACTION_ADD,
482                          MockAutofillProfileSyncableService::CreateData(
483                              *profiles_from_web_db.front())));
484   expected_change_list.push_back(
485       syncer::SyncChange(FROM_HERE,
486                          syncer::SyncChange::ACTION_ADD,
487                          MockAutofillProfileSyncableService::CreateData(
488                              *profiles_from_web_db.back())));
489
490   MockAutofillProfileSyncableService::DataBundle expected_bundle;
491   syncer::SyncDataList data_list;
492   MergeDataAndStartSyncing(
493       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
494
495   syncer::SyncDataList data =
496       autofill_syncable_service_.GetAllSyncData(syncer::AUTOFILL_PROFILE);
497
498   ASSERT_EQ(2U, data.size());
499   EXPECT_EQ(guid_present1, data[0].GetSpecifics().autofill_profile().guid());
500   EXPECT_EQ(guid_present2, data[1].GetSpecifics().autofill_profile().guid());
501   EXPECT_EQ(kHttpOrigin, data[0].GetSpecifics().autofill_profile().origin());
502   EXPECT_EQ(kHttpsOrigin, data[1].GetSpecifics().autofill_profile().origin());
503
504   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
505 }
506
507 TEST_F(AutofillProfileSyncableServiceTest, ProcessSyncChanges) {
508   std::vector<AutofillProfile *> profiles_from_web_db;
509   std::string guid_present = kGuid1;
510   std::string guid_synced = kGuid2;
511
512   syncer::SyncChangeList change_list;
513   AutofillProfile profile(guid_synced, kHttpOrigin);
514   profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
515   change_list.push_back(
516       syncer::SyncChange(
517           FROM_HERE,
518           syncer::SyncChange::ACTION_ADD,
519           MockAutofillProfileSyncableService::CreateData(profile)));
520   AutofillProfile empty_profile(guid_present, kHttpsOrigin);
521   change_list.push_back(
522       syncer::SyncChange(
523           FROM_HERE,
524           syncer::SyncChange::ACTION_DELETE,
525           MockAutofillProfileSyncableService::CreateData(empty_profile)));
526
527   MockAutofillProfileSyncableService::DataBundle expected_bundle;
528   expected_bundle.profiles_to_delete.push_back(guid_present);
529   expected_bundle.profiles_to_add.push_back(&profile);
530
531   EXPECT_CALL(autofill_syncable_service_, SaveChangesToWebData(
532               DataBundleCheck(expected_bundle)))
533       .Times(1)
534       .WillOnce(Return(true));
535
536   autofill_syncable_service_.set_sync_processor(sync_processor_.release());
537   syncer::SyncError error = autofill_syncable_service_.ProcessSyncChanges(
538       FROM_HERE, change_list);
539
540   EXPECT_FALSE(error.IsSet());
541 }
542
543 TEST_F(AutofillProfileSyncableServiceTest, AutofillProfileAdded) {
544   // Will be owned by the syncable service.  Keep a reference available here for
545   // verifying test expectations.
546   TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
547   autofill_syncable_service_.set_sync_processor(sync_change_processor);
548
549   AutofillProfile profile(kGuid1, kHttpsOrigin);
550   profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
551   AutofillProfileChange change(AutofillProfileChange::ADD, kGuid1, &profile);
552   autofill_syncable_service_.AutofillProfileChanged(change);
553
554   ASSERT_EQ(1U, sync_change_processor->changes().size());
555   syncer::SyncChange result = sync_change_processor->changes()[0];
556   EXPECT_EQ(syncer::SyncChange::ACTION_ADD, result.change_type());
557
558   sync_pb::AutofillProfileSpecifics specifics =
559       result.sync_data().GetSpecifics().autofill_profile();
560   EXPECT_EQ(kGuid1, specifics.guid());
561   EXPECT_EQ(kHttpsOrigin, specifics.origin());
562   EXPECT_THAT(specifics.name_first(), testing::ElementsAre("Jane"));
563 }
564
565 TEST_F(AutofillProfileSyncableServiceTest, AutofillProfileDeleted) {
566   // Will be owned by the syncable service.  Keep a reference available here for
567   // verifying test expectations.
568   TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
569   autofill_syncable_service_.set_sync_processor(sync_change_processor);
570
571   AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, NULL);
572   autofill_syncable_service_.AutofillProfileChanged(change);
573
574   ASSERT_EQ(1U, sync_change_processor->changes().size());
575   syncer::SyncChange result = sync_change_processor->changes()[0];
576   EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, result.change_type());
577   sync_pb::AutofillProfileSpecifics specifics =
578       result.sync_data().GetSpecifics().autofill_profile();
579   EXPECT_EQ(kGuid2, specifics.guid());
580 }
581
582 TEST_F(AutofillProfileSyncableServiceTest, UpdateField) {
583   AutofillProfile profile(kGuid1, kSettingsOrigin);
584   std::string company1 = "A Company";
585   std::string company2 = "Another Company";
586   profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16(company1));
587   EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
588       COMPANY_NAME, company1, &profile));
589   EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), ASCIIToUTF16(company1));
590   EXPECT_TRUE(AutofillProfileSyncableService::UpdateField(
591       COMPANY_NAME, company2, &profile));
592   EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), ASCIIToUTF16(company2));
593   EXPECT_FALSE(AutofillProfileSyncableService::UpdateField(
594       COMPANY_NAME, company2, &profile));
595   EXPECT_EQ(profile.GetRawInfo(COMPANY_NAME), ASCIIToUTF16(company2));
596 }
597
598 TEST_F(AutofillProfileSyncableServiceTest, UpdateMultivaluedField) {
599   AutofillProfile profile(kGuid1, kHttpsOrigin);
600
601   std::vector<base::string16> values;
602   values.push_back(ASCIIToUTF16("1@1.com"));
603   values.push_back(ASCIIToUTF16("2@1.com"));
604   profile.SetRawMultiInfo(EMAIL_ADDRESS, values);
605
606   ::google::protobuf::RepeatedPtrField<std::string> specifics_fields;
607   specifics_fields.AddAllocated(new std::string("2@1.com"));
608   specifics_fields.AddAllocated(new std::string("3@1.com"));
609
610   EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
611       EMAIL_ADDRESS, specifics_fields, &profile));
612   profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
613   ASSERT_TRUE(values.size() == 2);
614   EXPECT_EQ(values[0], ASCIIToUTF16("2@1.com"));
615   EXPECT_EQ(values[1], ASCIIToUTF16("3@1.com"));
616
617   EXPECT_FALSE(AutofillProfileSyncableService::UpdateMultivaluedField(
618       EMAIL_ADDRESS, specifics_fields, &profile));
619   profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
620   ASSERT_EQ(values.size(), 2U);
621   EXPECT_EQ(values[0], ASCIIToUTF16("2@1.com"));
622   EXPECT_EQ(values[1], ASCIIToUTF16("3@1.com"));
623   EXPECT_TRUE(AutofillProfileSyncableService::UpdateMultivaluedField(
624       EMAIL_ADDRESS, ::google::protobuf::RepeatedPtrField<std::string>(),
625       &profile));
626   profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
627   ASSERT_EQ(values.size(), 1U);  // Always have at least an empty string.
628   EXPECT_EQ(values[0], ASCIIToUTF16(""));
629 }
630
631 TEST_F(AutofillProfileSyncableServiceTest, MergeProfile) {
632   AutofillProfile profile1(kGuid1, kHttpOrigin);
633   profile1.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("111 First St."));
634
635   std::vector<base::string16> values;
636   values.push_back(ASCIIToUTF16("1@1.com"));
637   values.push_back(ASCIIToUTF16("2@1.com"));
638   profile1.SetRawMultiInfo(EMAIL_ADDRESS, values);
639
640   AutofillProfile profile2(kGuid2, kHttpsOrigin);
641   profile2.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("111 First St."));
642
643   // |values| now is [ "1@1.com", "2@1.com", "3@1.com" ].
644   values.push_back(ASCIIToUTF16("3@1.com"));
645   profile2.SetRawMultiInfo(EMAIL_ADDRESS, values);
646
647   values.clear();
648   values.push_back(ASCIIToUTF16("John"));
649   profile1.SetRawMultiInfo(NAME_FIRST, values);
650   values.push_back(ASCIIToUTF16("Jane"));
651   profile2.SetRawMultiInfo(NAME_FIRST, values);
652
653   values.clear();
654   values.push_back(ASCIIToUTF16("Doe"));
655   profile1.SetRawMultiInfo(NAME_LAST, values);
656   values.push_back(ASCIIToUTF16("Other"));
657   profile2.SetRawMultiInfo(NAME_LAST, values);
658
659   values.clear();
660   values.push_back(ASCIIToUTF16("650234567"));
661   profile2.SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, values);
662
663   profile1.set_language_code("en");
664
665   EXPECT_FALSE(AutofillProfileSyncableService::MergeProfile(profile2,
666                                                             &profile1,
667                                                             "en-US"));
668
669   profile1.GetRawMultiInfo(NAME_FIRST, &values);
670   ASSERT_EQ(values.size(), 2U);
671   EXPECT_EQ(values[0], ASCIIToUTF16("John"));
672   EXPECT_EQ(values[1], ASCIIToUTF16("Jane"));
673
674   profile1.GetRawMultiInfo(NAME_LAST, &values);
675   ASSERT_EQ(values.size(), 2U);
676   EXPECT_EQ(values[0], ASCIIToUTF16("Doe"));
677   EXPECT_EQ(values[1], ASCIIToUTF16("Other"));
678
679   profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
680   ASSERT_EQ(values.size(), 3U);
681   EXPECT_EQ(values[0], ASCIIToUTF16("1@1.com"));
682   EXPECT_EQ(values[1], ASCIIToUTF16("2@1.com"));
683   EXPECT_EQ(values[2], ASCIIToUTF16("3@1.com"));
684
685   profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
686   ASSERT_EQ(values.size(), 1U);
687   EXPECT_EQ(values[0], ASCIIToUTF16("650234567"));
688
689   EXPECT_EQ(profile2.origin(), profile1.origin());
690
691   AutofillProfile profile3(kGuid3, kHttpOrigin);
692   profile3.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("111 First St."));
693
694   values.clear();
695   values.push_back(ASCIIToUTF16("Jane"));
696   profile3.SetRawMultiInfo(NAME_FIRST, values);
697
698   values.clear();
699   values.push_back(ASCIIToUTF16("Doe"));
700   profile3.SetRawMultiInfo(NAME_LAST, values);
701
702   EXPECT_TRUE(AutofillProfileSyncableService::MergeProfile(profile3,
703                                                            &profile1,
704                                                             "en-US"));
705
706   profile1.GetRawMultiInfo(NAME_FIRST, &values);
707   ASSERT_EQ(values.size(), 3U);
708   EXPECT_EQ(values[0], ASCIIToUTF16("John"));
709   EXPECT_EQ(values[1], ASCIIToUTF16("Jane"));
710   EXPECT_EQ(values[2], ASCIIToUTF16("Jane"));
711
712   profile1.GetRawMultiInfo(NAME_LAST, &values);
713   ASSERT_EQ(values.size(), 3U);
714   EXPECT_EQ(values[0], ASCIIToUTF16("Doe"));
715   EXPECT_EQ(values[1], ASCIIToUTF16("Other"));
716   EXPECT_EQ(values[2], ASCIIToUTF16("Doe"));
717
718   // Middle name should have three entries as well.
719   profile1.GetRawMultiInfo(NAME_MIDDLE, &values);
720   ASSERT_EQ(values.size(), 3U);
721   EXPECT_TRUE(values[0].empty());
722   EXPECT_TRUE(values[1].empty());
723   EXPECT_TRUE(values[2].empty());
724
725   profile1.GetRawMultiInfo(EMAIL_ADDRESS, &values);
726   ASSERT_EQ(values.size(), 3U);
727   EXPECT_EQ(values[0], ASCIIToUTF16("1@1.com"));
728   EXPECT_EQ(values[1], ASCIIToUTF16("2@1.com"));
729   EXPECT_EQ(values[2], ASCIIToUTF16("3@1.com"));
730
731   profile1.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
732   ASSERT_EQ(values.size(), 1U);
733   EXPECT_EQ(values[0], ASCIIToUTF16("650234567"));
734 }
735
736 // Ensure that all profile fields are able to be synced up from the client to
737 // the server.
738 TEST_F(AutofillProfileSyncableServiceTest, SyncAllFieldsToServer) {
739   std::vector<AutofillProfile*> profiles_from_web_db;
740
741   // Create a profile with all fields set.
742   profiles_from_web_db.push_back(ConstructCompleteProfile().release());
743
744   // Set up expectations: No changes to the WebDB, and all fields correctly
745   // copied to Sync.
746   MockAutofillProfileSyncableService::DataBundle expected_bundle;
747   syncer::SyncChangeList expected_change_list;
748   expected_change_list.push_back(
749       syncer::SyncChange(FROM_HERE,
750                          syncer::SyncChange::ACTION_ADD,
751                          ConstructCompleteSyncData()));
752
753   // Verify the expectations.
754   syncer::SyncDataList data_list;
755   MergeDataAndStartSyncing(
756       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
757   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
758 }
759
760 // Ensure that all profile fields are able to be synced down from the server to
761 // the client.
762 TEST_F(AutofillProfileSyncableServiceTest, SyncAllFieldsToClient) {
763   // Create a profile with all fields set.
764   syncer::SyncDataList data_list;
765   data_list.push_back(ConstructCompleteSyncData());
766
767   // Set up expectations: All fields correctly copied to the WebDB, and no
768   // changes propagated to Sync.
769   syncer::SyncChangeList expected_change_list;
770   scoped_ptr<AutofillProfile> expected_profile = ConstructCompleteProfile();
771   MockAutofillProfileSyncableService::DataBundle expected_bundle;
772   expected_bundle.profiles_to_add.push_back(expected_profile.get());
773
774   // Verify the expectations.
775   std::vector<AutofillProfile*> profiles_from_web_db;
776   MergeDataAndStartSyncing(
777       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
778   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
779 }
780
781 // Ensure that the street address field takes precedence over the address line 1
782 // and line 2 fields, even though these are expected to always be in sync in
783 // practice.
784 TEST_F(AutofillProfileSyncableServiceTest,
785        StreetAddressTakesPrecedenceOverAddressLines) {
786   // Create a Sync profile with conflicting address data in the street address
787   // field vs. the address line 1 and address line 2 fields.
788   sync_pb::EntitySpecifics specifics;
789   sync_pb::AutofillProfileSpecifics* autofill_specifics =
790       specifics.mutable_autofill_profile();
791   autofill_specifics->set_guid(kGuid1);
792   autofill_specifics->set_origin(kHttpsOrigin);
793   autofill_specifics->add_name_first(std::string());
794   autofill_specifics->add_name_middle(std::string());
795   autofill_specifics->add_name_last(std::string());
796   autofill_specifics->add_email_address(std::string());
797   autofill_specifics->add_phone_home_whole_number(std::string());
798   autofill_specifics->set_address_home_line1("123 Example St.");
799   autofill_specifics->set_address_home_line2("Apt. 42");
800   autofill_specifics->set_address_home_street_address("456 El Camino Real\n"
801                                                       "Suite #1337");
802
803   syncer::SyncDataList data_list;
804   data_list.push_back(
805       syncer::SyncData::CreateLocalData(kGuid1, kGuid1, specifics));
806
807   // Set up expectations: Full street address takes precedence over address
808   // lines.
809   syncer::SyncChangeList expected_change_list;
810   AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
811   expected_profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
812                               ASCIIToUTF16("456 El Camino Real\n"
813                                            "Suite #1337"));
814   EXPECT_EQ(ASCIIToUTF16("456 El Camino Real"),
815             expected_profile.GetRawInfo(ADDRESS_HOME_LINE1));
816   EXPECT_EQ(ASCIIToUTF16("Suite #1337"),
817             expected_profile.GetRawInfo(ADDRESS_HOME_LINE2));
818   MockAutofillProfileSyncableService::DataBundle expected_bundle;
819   expected_bundle.profiles_to_add.push_back(&expected_profile);
820
821   // Verify the expectations.
822   std::vector<AutofillProfile*> profiles_from_web_db;
823   MergeDataAndStartSyncing(
824       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
825   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
826 }
827
828 // Ensure that no Sync events are generated to fill in missing street address
829 // fields from Sync with explicitly present ones identical to the data stored in
830 // the line1 and line2 fields.  This ensures that the migration to add the
831 // street address field to profiles does not generate lots of needless Sync
832 // updates.
833 TEST_F(AutofillProfileSyncableServiceTest, MergeDataEmptyStreetAddress) {
834   std::vector<AutofillProfile*> profiles_from_web_db;
835
836   // Create a profile with the street address set.
837   AutofillProfile profile(kGuid1, kHttpsOrigin);
838   profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
839                      ASCIIToUTF16("123 Example St.\n"
840                                   "Apt. 42"));
841   EXPECT_EQ(ASCIIToUTF16("123 Example St."),
842             profile.GetRawInfo(ADDRESS_HOME_LINE1));
843   EXPECT_EQ(ASCIIToUTF16("Apt. 42"), profile.GetRawInfo(ADDRESS_HOME_LINE2));
844
845   profiles_from_web_db.push_back(new AutofillProfile(profile));
846
847   // Create a Sync profile identical to |profile|, except without street address
848   // explicitly set.
849   sync_pb::EntitySpecifics specifics;
850   sync_pb::AutofillProfileSpecifics* autofill_specifics =
851       specifics.mutable_autofill_profile();
852   autofill_specifics->set_guid(profile.guid());
853   autofill_specifics->set_origin(profile.origin());
854   autofill_specifics->add_name_first(std::string());
855   autofill_specifics->add_name_middle(std::string());
856   autofill_specifics->add_name_last(std::string());
857   autofill_specifics->add_email_address(std::string());
858   autofill_specifics->add_phone_home_whole_number(std::string());
859   autofill_specifics->set_address_home_line1("123 Example St.");
860   autofill_specifics->set_address_home_line2("Apt. 42");
861   EXPECT_FALSE(autofill_specifics->has_address_home_street_address());
862
863   syncer::SyncDataList data_list;
864   data_list.push_back(
865       syncer::SyncData::CreateLocalData(
866           profile.guid(), profile.guid(), specifics));
867
868   MockAutofillProfileSyncableService::DataBundle expected_bundle;
869   syncer::SyncChangeList expected_change_list;
870   MergeDataAndStartSyncing(
871       profiles_from_web_db, data_list, expected_bundle, expected_change_list);
872   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
873 }
874
875 // Sync data without origin should not overwrite existing origin in local
876 // autofill profile.
877 TEST_F(AutofillProfileSyncableServiceTest, EmptySyncPreservesOrigin) {
878   std::vector<AutofillProfile*> profiles_from_web_db;
879
880   // Local autofill profile has an origin.
881   AutofillProfile profile(kGuid1, kHttpsOrigin);
882   profiles_from_web_db.push_back(new AutofillProfile(profile));
883
884   // Remote data does not have an origin value.
885   sync_pb::EntitySpecifics specifics;
886   sync_pb::AutofillProfileSpecifics* autofill_specifics =
887       specifics.mutable_autofill_profile();
888   autofill_specifics->set_guid(profile.guid());
889   autofill_specifics->add_name_first("John");
890   autofill_specifics->add_name_middle(std::string());
891   autofill_specifics->add_name_last(std::string());
892   autofill_specifics->add_email_address(std::string());
893   autofill_specifics->add_phone_home_whole_number(std::string());
894   EXPECT_FALSE(autofill_specifics->has_origin());
895
896   syncer::SyncDataList data_list;
897   data_list.push_back(
898       syncer::SyncData::CreateLocalData(
899           profile.guid(), profile.guid(), specifics));
900
901   // Expect the local autofill profile to still have an origin after sync.
902   MockAutofillProfileSyncableService::DataBundle expected_bundle;
903   AutofillProfile expected_profile(profile.guid(), profile.origin());
904   expected_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
905   expected_bundle.profiles_to_update.push_back(&expected_profile);
906
907   // Expect no sync events to add origin to the remote data.
908   syncer::SyncChangeList expected_empty_change_list;
909
910   MergeDataAndStartSyncing(profiles_from_web_db, data_list,
911                            expected_bundle, expected_empty_change_list);
912   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
913 }
914
915 // Missing language code field should not generate sync events.
916 TEST_F(AutofillProfileSyncableServiceTest, NoLanguageCodeNoSync) {
917   std::vector<AutofillProfile*> profiles_from_web_db;
918
919   // Local autofill profile has an empty language code.
920   AutofillProfile profile(kGuid1, kHttpsOrigin);
921   EXPECT_TRUE(profile.language_code().empty());
922   profiles_from_web_db.push_back(new AutofillProfile(profile));
923
924   // Remote data does not have a language code value.
925   sync_pb::EntitySpecifics specifics;
926   sync_pb::AutofillProfileSpecifics* autofill_specifics =
927       specifics.mutable_autofill_profile();
928   autofill_specifics->set_guid(profile.guid());
929   autofill_specifics->set_origin(profile.origin());
930   autofill_specifics->add_name_first(std::string());
931   autofill_specifics->add_name_middle(std::string());
932   autofill_specifics->add_name_last(std::string());
933   autofill_specifics->add_email_address(std::string());
934   autofill_specifics->add_phone_home_whole_number(std::string());
935   EXPECT_FALSE(autofill_specifics->has_address_home_language_code());
936
937   syncer::SyncDataList data_list;
938   data_list.push_back(
939       syncer::SyncData::CreateLocalData(
940           profile.guid(), profile.guid(), specifics));
941
942   // Expect no changes to local and remote data.
943   MockAutofillProfileSyncableService::DataBundle expected_empty_bundle;
944   syncer::SyncChangeList expected_empty_change_list;
945
946   MergeDataAndStartSyncing(profiles_from_web_db, data_list,
947                            expected_empty_bundle, expected_empty_change_list);
948   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
949 }
950
951 // Empty language code should be overwritten by sync.
952 TEST_F(AutofillProfileSyncableServiceTest, SyncUpdatesEmptyLanguageCode) {
953   std::vector<AutofillProfile*> profiles_from_web_db;
954
955   // Local autofill profile has an empty language code.
956   AutofillProfile profile(kGuid1, kHttpsOrigin);
957   EXPECT_TRUE(profile.language_code().empty());
958   profiles_from_web_db.push_back(new AutofillProfile(profile));
959
960   // Remote data has "en" language code.
961   sync_pb::EntitySpecifics specifics;
962   sync_pb::AutofillProfileSpecifics* autofill_specifics =
963       specifics.mutable_autofill_profile();
964   autofill_specifics->set_guid(profile.guid());
965   autofill_specifics->set_origin(profile.origin());
966   autofill_specifics->add_name_first(std::string());
967   autofill_specifics->add_name_middle(std::string());
968   autofill_specifics->add_name_last(std::string());
969   autofill_specifics->add_email_address(std::string());
970   autofill_specifics->add_phone_home_whole_number(std::string());
971   autofill_specifics->set_address_home_language_code("en");
972   EXPECT_TRUE(autofill_specifics->has_address_home_language_code());
973
974   syncer::SyncDataList data_list;
975   data_list.push_back(
976       syncer::SyncData::CreateLocalData(
977           profile.guid(), profile.guid(), specifics));
978
979   // Expect the local autofill profile to have "en" language code after sync.
980   MockAutofillProfileSyncableService::DataBundle expected_bundle;
981   AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
982   expected_profile.set_language_code("en");
983   expected_bundle.profiles_to_update.push_back(&expected_profile);
984
985   // Expect not changes to remote data.
986   syncer::SyncChangeList expected_empty_change_list;
987
988   MergeDataAndStartSyncing(profiles_from_web_db, data_list,
989                            expected_bundle, expected_empty_change_list);
990   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
991 }
992
993 // Incorrect language code should be overwritten by sync.
994 TEST_F(AutofillProfileSyncableServiceTest, SyncUpdatesIncorrectLanguageCode) {
995   std::vector<AutofillProfile*> profiles_from_web_db;
996
997   // Local autofill profile has "de" language code.
998   AutofillProfile profile(kGuid1, kHttpsOrigin);
999   profile.set_language_code("de");
1000   profiles_from_web_db.push_back(new AutofillProfile(profile));
1001
1002   // Remote data has "en" language code.
1003   sync_pb::EntitySpecifics specifics;
1004   sync_pb::AutofillProfileSpecifics* autofill_specifics =
1005       specifics.mutable_autofill_profile();
1006   autofill_specifics->set_guid(profile.guid());
1007   autofill_specifics->set_origin(profile.origin());
1008   autofill_specifics->add_name_first(std::string());
1009   autofill_specifics->add_name_middle(std::string());
1010   autofill_specifics->add_name_last(std::string());
1011   autofill_specifics->add_email_address(std::string());
1012   autofill_specifics->add_phone_home_whole_number(std::string());
1013   autofill_specifics->set_address_home_language_code("en");
1014   EXPECT_TRUE(autofill_specifics->has_address_home_language_code());
1015
1016   syncer::SyncDataList data_list;
1017   data_list.push_back(
1018       syncer::SyncData::CreateLocalData(
1019           profile.guid(), profile.guid(), specifics));
1020
1021   // Expect the local autofill profile to have "en" language code after sync.
1022   MockAutofillProfileSyncableService::DataBundle expected_bundle;
1023   AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
1024   expected_profile.set_language_code("en");
1025   expected_bundle.profiles_to_update.push_back(&expected_profile);
1026
1027   // Expect no changes to remote data.
1028   syncer::SyncChangeList expected_empty_change_list;
1029
1030   MergeDataAndStartSyncing(profiles_from_web_db, data_list,
1031                            expected_bundle, expected_empty_change_list);
1032   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
1033 }
1034
1035 // Sync data without language code should not overwrite existing language code
1036 // in local autofill profile.
1037 TEST_F(AutofillProfileSyncableServiceTest, EmptySyncPreservesLanguageCode) {
1038   std::vector<AutofillProfile*> profiles_from_web_db;
1039
1040   // Local autofill profile has "en" language code.
1041   AutofillProfile profile(kGuid1, kHttpsOrigin);
1042   profile.set_language_code("en");
1043   profiles_from_web_db.push_back(new AutofillProfile(profile));
1044
1045   // Remote data does not have a language code value.
1046   sync_pb::EntitySpecifics specifics;
1047   sync_pb::AutofillProfileSpecifics* autofill_specifics =
1048       specifics.mutable_autofill_profile();
1049   autofill_specifics->set_guid(profile.guid());
1050   autofill_specifics->set_origin(profile.origin());
1051   autofill_specifics->add_name_first("John");
1052   autofill_specifics->add_name_middle(std::string());
1053   autofill_specifics->add_name_last(std::string());
1054   autofill_specifics->add_email_address(std::string());
1055   autofill_specifics->add_phone_home_whole_number(std::string());
1056   EXPECT_FALSE(autofill_specifics->has_address_home_language_code());
1057
1058   syncer::SyncDataList data_list;
1059   data_list.push_back(
1060       syncer::SyncData::CreateLocalData(
1061           profile.guid(), profile.guid(), specifics));
1062
1063   // Expect local autofill profile to still have "en" language code after sync.
1064   MockAutofillProfileSyncableService::DataBundle expected_bundle;
1065   AutofillProfile expected_profile(profile.guid(), profile.origin());
1066   expected_profile.set_language_code("en");
1067   expected_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
1068   expected_bundle.profiles_to_update.push_back(&expected_profile);
1069
1070   // Expect no changes to remote data.
1071   syncer::SyncChangeList expected_empty_change_list;
1072
1073   MergeDataAndStartSyncing(profiles_from_web_db, data_list,
1074                            expected_bundle, expected_empty_change_list);
1075   autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
1076 }
1077
1078 // Language code in autofill profiles should be synced to the server.
1079 TEST_F(AutofillProfileSyncableServiceTest, LanguageCodePropagates) {
1080   TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
1081   autofill_syncable_service_.set_sync_processor(sync_change_processor);
1082
1083   AutofillProfile profile(kGuid1, kHttpsOrigin);
1084   profile.set_language_code("en");
1085   AutofillProfileChange change(AutofillProfileChange::ADD, kGuid1, &profile);
1086   autofill_syncable_service_.AutofillProfileChanged(change);
1087
1088   ASSERT_EQ(1U, sync_change_processor->changes().size());
1089   syncer::SyncChange result = sync_change_processor->changes()[0];
1090   EXPECT_EQ(syncer::SyncChange::ACTION_ADD, result.change_type());
1091
1092   sync_pb::AutofillProfileSpecifics specifics =
1093       result.sync_data().GetSpecifics().autofill_profile();
1094   EXPECT_EQ(kGuid1, specifics.guid());
1095   EXPECT_EQ(kHttpsOrigin, specifics.origin());
1096   EXPECT_EQ("en", specifics.address_home_language_code());
1097 }
1098
1099 }  // namespace autofill