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