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