1 // Copyright 2018 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 "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h"
6 
7 #include <stddef.h>
8 
9 #include <memory>
10 #include <utility>
11 
12 #include "base/bind.h"
13 #include "base/callback_helpers.h"
14 #include "base/feature_list.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/guid.h"
17 #include "base/location.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/run_loop.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/test/bind.h"
22 #include "base/test/scoped_feature_list.h"
23 #include "base/test/task_environment.h"
24 #include "base/time/time.h"
25 #include "components/autofill/core/browser/autofill_profile_sync_util.h"
26 #include "components/autofill/core/browser/data_model/autofill_profile.h"
27 #include "components/autofill/core/browser/geo/country_names.h"
28 #include "components/autofill/core/browser/test_autofill_clock.h"
29 #include "components/autofill/core/browser/webdata/autofill_change.h"
30 #include "components/autofill/core/browser/webdata/autofill_table.h"
31 #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
32 #include "components/autofill/core/common/autofill_constants.h"
33 #include "components/autofill/core/common/autofill_features.h"
34 #include "components/sync/base/client_tag_hash.h"
35 #include "components/sync/model/data_batch.h"
36 #include "components/sync/model/data_type_activation_request.h"
37 #include "components/sync/model/entity_data.h"
38 #include "components/sync/model/sync_data.h"
39 #include "components/sync/model/sync_error_factory.h"
40 #include "components/sync/model_impl/client_tag_based_model_type_processor.h"
41 #include "components/sync/protocol/sync.pb.h"
42 #include "components/sync/test/model/mock_model_type_change_processor.h"
43 #include "components/sync/test/model/sync_error_factory_mock.h"
44 #include "components/webdata/common/web_database.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h"
47 
48 namespace autofill {
49 
50 using base::ASCIIToUTF16;
51 using base::ScopedTempDir;
52 using base::UTF16ToUTF8;
53 using base::UTF8ToUTF16;
54 using sync_pb::AutofillProfileSpecifics;
55 using syncer::DataBatch;
56 using syncer::EntityChange;
57 using syncer::EntityChangeList;
58 using syncer::EntityData;
59 using syncer::KeyAndData;
60 using syncer::MockModelTypeChangeProcessor;
61 using syncer::ModelType;
62 using testing::_;
63 using testing::DoAll;
64 using testing::ElementsAre;
65 using testing::Eq;
66 using testing::Property;
67 using testing::Return;
68 using testing::UnorderedElementsAre;
69 
70 namespace {
71 
72 // Some guids for testing.
73 const char kGuidA[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A";
74 const char kGuidB[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
75 const char kGuidC[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44C";
76 const char kGuidD[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44D";
77 const char kGuidInvalid[] = "EDC609ED-7EEE-4F27-B00C";
78 const char kHttpOrigin[] = "http://www.example.com/";
79 const char kHttpsOrigin[] = "https://www.example.com/";
80 const int kValidityStateBitfield = 1984;
81 const char kLocaleString[] = "en-US";
82 const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
83 
CreateAutofillProfile(const AutofillProfileSpecifics & specifics)84 AutofillProfile CreateAutofillProfile(
85     const AutofillProfileSpecifics& specifics) {
86   // As more copying does not hurt in tests, we prefer to use AutofillProfile
87   // instead of std::unique_ptr<AutofillProfile> because of code brevity.
88   return *CreateAutofillProfileFromSpecifics(specifics);
89 }
90 
CreateAutofillProfileSpecifics(const AutofillProfile & entry)91 AutofillProfileSpecifics CreateAutofillProfileSpecifics(
92     const AutofillProfile& entry) {
93   // Reuse production code. We do not need EntityData, just take out the
94   // specifics.
95   std::unique_ptr<EntityData> entity_data =
96       CreateEntityDataFromAutofillProfile(entry);
97   return entity_data->specifics.autofill_profile();
98 }
99 
CreateAutofillProfileSpecifics(const std::string & guid,const std::string & origin)100 AutofillProfileSpecifics CreateAutofillProfileSpecifics(
101     const std::string& guid,
102     const std::string& origin) {
103   AutofillProfileSpecifics specifics;
104   specifics.set_guid(guid);
105   specifics.set_origin(origin);
106   // Make it consistent with the constructor of AutofillProfile constructor (the
107   // clock value is overrided by TestAutofillClock in the test fixture).
108   specifics.set_use_count(1);
109   specifics.set_use_date(kJune2017.ToTimeT());
110   return specifics;
111 }
112 
113 MATCHER_P(HasSpecifics, expected, "") {
114   AutofillProfile arg_profile =
115       CreateAutofillProfile(arg->specifics.autofill_profile());
116   AutofillProfile expected_profile = CreateAutofillProfile(expected);
117   if (!arg_profile.EqualsIncludingUsageStatsForTesting(expected_profile)) {
118     *result_listener << "entry\n[" << arg_profile << "]\n"
119                      << "did not match expected\n[" << expected_profile << "]";
120     return false;
121   }
122   return true;
123 }
124 
125 MATCHER_P(WithUsageStats, expected, "") {
126   if (!arg.EqualsIncludingUsageStatsForTesting(expected)) {
127     *result_listener << "entry\n[" << arg << "]\n"
128                      << "did not match expected\n[" << expected << "]";
129     return false;
130   }
131   return true;
132 }
133 
ExtractAutofillProfilesFromDataBatch(std::unique_ptr<DataBatch> batch,std::vector<AutofillProfile> * output)134 void ExtractAutofillProfilesFromDataBatch(
135     std::unique_ptr<DataBatch> batch,
136     std::vector<AutofillProfile>* output) {
137   while (batch->HasNext()) {
138     const KeyAndData& data_pair = batch->Next();
139     output->push_back(
140         CreateAutofillProfile(data_pair.second->specifics.autofill_profile()));
141   }
142 }
143 
144 // Returns a profile with all fields set.  Contains identical data to the data
145 // returned from ConstructCompleteSpecifics().
ConstructCompleteProfile()146 AutofillProfile ConstructCompleteProfile() {
147   AutofillProfile profile(kGuidA, kHttpsOrigin);
148 
149   profile.set_use_count(7);
150   profile.set_use_date(base::Time::FromTimeT(1423182152));
151 
152   profile.SetRawInfo(NAME_HONORIFIC_PREFIX, ASCIIToUTF16(""));
153   profile.SetRawInfo(NAME_FULL, ASCIIToUTF16("John K. Doe, Jr."));
154   profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
155   profile.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("K."));
156   profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Doe"));
157   profile.SetRawInfo(NAME_LAST_FIRST, ASCIIToUTF16("D"));
158   profile.SetRawInfo(NAME_LAST_CONJUNCTION, ASCIIToUTF16("o"));
159   profile.SetRawInfo(NAME_LAST_SECOND, ASCIIToUTF16("e"));
160 
161   profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("user@example.com"));
162   profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("1.800.555.1234"));
163 
164   profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, 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.SetRawInfo(ADDRESS_HOME_STREET_NAME, ASCIIToUTF16("Street Name"));
179   profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_STREET_NAME,
180                      ASCIIToUTF16("Dependent Street Name"));
181   profile.SetRawInfo(ADDRESS_HOME_HOUSE_NUMBER, ASCIIToUTF16("House Number"));
182   profile.SetRawInfo(ADDRESS_HOME_SUBPREMISE, ASCIIToUTF16("Subpremise"));
183   profile.SetRawInfo(ADDRESS_HOME_PREMISE_NAME, ASCIIToUTF16("Premise"));
184   profile.set_language_code("en");
185   profile.SetClientValidityFromBitfieldValue(kValidityStateBitfield);
186   return profile;
187 }
188 
189 // Returns AutofillProfileSpecifics with all Autofill profile fields set.
190 // Contains identical data to the data returned from ConstructCompleteProfile().
ConstructCompleteSpecifics()191 AutofillProfileSpecifics ConstructCompleteSpecifics() {
192   AutofillProfileSpecifics specifics;
193 
194   specifics.set_guid(kGuidA);
195   specifics.set_origin(kHttpsOrigin);
196   specifics.set_use_count(7);
197   specifics.set_use_date(1423182152);
198 
199   specifics.add_name_honorific("");
200   specifics.add_name_first("John");
201   specifics.add_name_middle("K.");
202   specifics.add_name_last("Doe");
203   specifics.add_name_full("John K. Doe, Jr.");
204   specifics.add_name_last_first("D");
205   specifics.add_name_last_conjunction("o");
206   specifics.add_name_last_second("e");
207 
208   specifics.add_name_honorific_status(
209       sync_pb::
210           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
211   specifics.add_name_first_status(
212       sync_pb::
213           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
214   specifics.add_name_middle_status(
215       sync_pb::
216           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
217   specifics.add_name_last_status(
218       sync_pb::
219           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
220   specifics.add_name_full_status(
221       sync_pb::
222           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
223   specifics.add_name_last_first_status(
224       sync_pb::
225           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
226   specifics.add_name_last_conjunction_status(
227       sync_pb::
228           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
229   specifics.add_name_last_second_status(
230       sync_pb::
231           AutofillProfileSpecifics_VerificationStatus_VERIFICATION_STATUS_UNSPECIFIED);
232 
233   specifics.add_email_address("user@example.com");
234 
235   specifics.add_phone_home_whole_number("1.800.555.1234");
236 
237   specifics.set_address_home_line1("123 Fake St.");
238   specifics.set_address_home_line2("Apt. 42");
239   specifics.set_address_home_street_address(
240       "123 Fake St.\n"
241       "Apt. 42");
242 
243   specifics.set_company_name("Google, Inc.");
244   specifics.set_address_home_city("Mountain View");
245   specifics.set_address_home_state("California");
246   specifics.set_address_home_zip("94043");
247   specifics.set_address_home_country("US");
248   specifics.set_address_home_sorting_code("CEDEX");
249   specifics.set_address_home_dependent_locality("Santa Clara");
250   specifics.set_address_home_language_code("en");
251 
252   specifics.set_address_home_thoroughfare_name("Street Name");
253   specifics.set_address_home_dependent_thoroughfare_name(
254       "Dependent Street Name");
255   specifics.set_address_home_thoroughfare_number("House Number");
256   specifics.set_address_home_subpremise_name("Subpremise");
257   specifics.set_address_home_premise_name("Premise");
258 
259   specifics.set_validity_state_bitfield(kValidityStateBitfield);
260   return specifics;
261 }
262 
263 }  // namespace
264 
265 class AutofillProfileSyncBridgeTestBase : public testing::Test {
266  public:
267   AutofillProfileSyncBridgeTestBase() = default;
268   ~AutofillProfileSyncBridgeTestBase() override = default;
269 
SetUp()270   void SetUp() override {
271     // Fix a time for implicitly constructed use_dates in AutofillProfile.
272     test_clock_.SetNow(kJune2017);
273     CountryNames::SetLocaleString(kLocaleString);
274     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
275     db_.AddTable(&table_);
276     db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase"));
277     ON_CALL(*backend(), GetDatabase()).WillByDefault(Return(&db_));
278     ResetProcessor();
279     ResetBridge();
280   }
281 
ResetProcessor()282   void ResetProcessor() {
283     real_processor_ =
284         std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
285             syncer::AUTOFILL_PROFILE, /*dump_stack=*/base::DoNothing(),
286             /*commit_only=*/false);
287     mock_processor_.DelegateCallsByDefaultTo(real_processor_.get());
288   }
289 
ResetBridge()290   void ResetBridge() {
291     bridge_.reset(new AutofillProfileSyncBridge(
292         mock_processor_.CreateForwardingProcessor(), kLocaleString, &backend_));
293   }
294 
StartSyncing(const std::vector<AutofillProfileSpecifics> & remote_data={})295   void StartSyncing(
296       const std::vector<AutofillProfileSpecifics>& remote_data = {}) {
297     base::RunLoop loop;
298     syncer::DataTypeActivationRequest request;
299     request.error_handler = base::DoNothing();
300     real_processor_->OnSyncStarting(
301         request,
302         base::BindLambdaForTesting(
__anon575ee1860202(std::unique_ptr<syncer::DataTypeActivationResponse>) 303             [&loop](std::unique_ptr<syncer::DataTypeActivationResponse>) {
304               loop.Quit();
305             }));
306     loop.Run();
307 
308     // Initialize the processor with initial_sync_done.
309     sync_pb::ModelTypeState state;
310     state.set_initial_sync_done(true);
311     syncer::UpdateResponseDataList initial_updates;
312     for (const AutofillProfileSpecifics& specifics : remote_data) {
313       initial_updates.push_back(SpecificsToUpdateResponse(specifics));
314     }
315     real_processor_->OnUpdateReceived(state, std::move(initial_updates));
316   }
317 
ApplySyncChanges(EntityChangeList changes)318   void ApplySyncChanges(EntityChangeList changes) {
319     const base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
320         bridge()->CreateMetadataChangeList(), std::move(changes));
321     EXPECT_FALSE(error) << error->ToString();
322   }
323 
AddAutofillProfilesToTable(const std::vector<AutofillProfile> & profile_list)324   void AddAutofillProfilesToTable(
325       const std::vector<AutofillProfile>& profile_list) {
326     for (const auto& profile : profile_list) {
327       table_.AddAutofillProfile(profile);
328     }
329   }
330 
GetAllLocalData()331   std::vector<AutofillProfile> GetAllLocalData() {
332     std::vector<AutofillProfile> data;
333     // Perform an async call synchronously for testing.
334     base::RunLoop loop;
335     bridge()->GetAllDataForDebugging(base::BindLambdaForTesting(
336         [&loop, &data](std::unique_ptr<DataBatch> batch) {
337           ExtractAutofillProfilesFromDataBatch(std::move(batch), &data);
338           loop.Quit();
339         }));
340     loop.Run();
341     return data;
342   }
343 
SpecificsToEntity(const AutofillProfileSpecifics & specifics)344   EntityData SpecificsToEntity(const AutofillProfileSpecifics& specifics) {
345     EntityData data;
346     *data.specifics.mutable_autofill_profile() = specifics;
347     data.client_tag_hash = syncer::ClientTagHash::FromUnhashed(
348         syncer::AUTOFILL_PROFILE, bridge()->GetClientTag(data));
349     return data;
350   }
351 
SpecificsToUpdateResponse(const AutofillProfileSpecifics & specifics)352   syncer::UpdateResponseData SpecificsToUpdateResponse(
353       const AutofillProfileSpecifics& specifics) {
354     syncer::UpdateResponseData data;
355     data.entity = SpecificsToEntity(specifics);
356     return data;
357   }
358 
bridge()359   AutofillProfileSyncBridge* bridge() { return bridge_.get(); }
360 
mock_processor()361   syncer::MockModelTypeChangeProcessor& mock_processor() {
362     return mock_processor_;
363   }
364 
table()365   AutofillTable* table() { return &table_; }
366 
backend()367   MockAutofillWebDataBackend* backend() { return &backend_; }
368 
369  private:
370   autofill::TestAutofillClock test_clock_;
371   ScopedTempDir temp_dir_;
372   base::test::SingleThreadTaskEnvironment task_environment_;
373   testing::NiceMock<MockAutofillWebDataBackend> backend_;
374   AutofillTable table_;
375   WebDatabase db_;
376   testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
377   std::unique_ptr<syncer::ClientTagBasedModelTypeProcessor> real_processor_;
378   std::unique_ptr<AutofillProfileSyncBridge> bridge_;
379 
380   DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncBridgeTestBase);
381 };
382 
383 // This class performs the sync bridge test with and without structured names
384 // enabled.
385 class AutofillProfileSyncBridgeTest : public AutofillProfileSyncBridgeTestBase,
386                                       public testing::WithParamInterface<bool> {
387  public:
SetUp()388   void SetUp() override {
389     InitializeFeatures();
390     AutofillProfileSyncBridgeTestBase::SetUp();
391   }
392 
InitializeFeatures()393   void InitializeFeatures() {
394     bool structured_names_enabled = GetParam();
395     if (structured_names_enabled) {
396       scoped_features_.InitAndEnableFeature(
397           features::kAutofillEnableSupportForMoreStructureInNames);
398     } else {
399       scoped_features_.InitAndDisableFeature(
400           features::kAutofillEnableSupportForMoreStructureInNames);
401     }
402   }
403 
UsingStructuredNames() const404   bool UsingStructuredNames() const {
405     return base::FeatureList::IsEnabled(
406         features::kAutofillEnableSupportForMoreStructureInNames);
407   }
408 
409  private:
410   base::test::ScopedFeatureList scoped_features_;
411 };
412 
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Added)413 TEST_P(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Added) {
414   StartSyncing({});
415 
416   AutofillProfile local(kGuidA, kHttpsOrigin);
417   local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
418   AutofillProfileChange change(AutofillProfileChange::ADD, kGuidA, &local);
419 
420   EXPECT_CALL(
421       mock_processor(),
422       Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
423   // The bridge does not need to commit when reacting to a notification about a
424   // local change.
425   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
426 
427   bridge()->AutofillProfileChanged(change);
428 }
429 
430 // Language code in autofill profiles should be synced to the server.
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Added_LanguageCodePropagates)431 TEST_P(AutofillProfileSyncBridgeTest,
432        AutofillProfileChanged_Added_LanguageCodePropagates) {
433   StartSyncing({});
434 
435   AutofillProfile local(kGuidA, kHttpsOrigin);
436   local.set_language_code("en");
437   AutofillProfileChange change(AutofillProfileChange::ADD, kGuidA, &local);
438 
439   EXPECT_CALL(
440       mock_processor(),
441       Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
442   // The bridge does not need to commit when reacting to a notification about a
443   // local change.
444   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
445 
446   bridge()->AutofillProfileChanged(change);
447 }
448 
449 // Validity state bitfield in autofill profiles should be synced to the server.
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Added_LocalValidityBitfieldPropagates)450 TEST_P(AutofillProfileSyncBridgeTest,
451        AutofillProfileChanged_Added_LocalValidityBitfieldPropagates) {
452   StartSyncing({});
453 
454   AutofillProfile local(kGuidA, kHttpsOrigin);
455   local.SetClientValidityFromBitfieldValue(kValidityStateBitfield);
456   AutofillProfileChange change(AutofillProfileChange::ADD, kGuidA, &local);
457 
458   EXPECT_CALL(
459       mock_processor(),
460       Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
461   // The bridge does not need to commit when reacting to a notification about a
462   // local change.
463   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
464 
465   bridge()->AutofillProfileChanged(change);
466 }
467 
468 // Local updates should be properly propagated to the server.
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Updated)469 TEST_P(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Updated) {
470   StartSyncing({});
471 
472   AutofillProfile local(kGuidA, kHttpsOrigin);
473   local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
474   AutofillProfileChange change(AutofillProfileChange::UPDATE, kGuidA, &local);
475 
476   EXPECT_CALL(
477       mock_processor(),
478       Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
479   // The bridge does not need to commit when reacting to a notification about a
480   // local change.
481   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
482 
483   bridge()->AutofillProfileChanged(change);
484 }
485 
486 // Usage stats should be updated by the client.
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Updated_UsageStatsOverwrittenByClient)487 TEST_P(AutofillProfileSyncBridgeTest,
488        AutofillProfileChanged_Updated_UsageStatsOverwrittenByClient) {
489   // Remote data has a profile with usage stats.
490   AutofillProfileSpecifics remote =
491       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
492   remote.set_address_home_language_code("en");
493   remote.set_use_count(9);
494   remote.set_use_date(25);
495 
496   StartSyncing({remote});
497   EXPECT_THAT(GetAllLocalData(),
498               ElementsAre(WithUsageStats(CreateAutofillProfile(remote))));
499 
500   // Update to the usage stats for that profile.
501   AutofillProfile local(kGuidA, kHttpsOrigin);
502   local.set_language_code("en");
503   local.set_use_count(10U);
504   local.set_use_date(base::Time::FromTimeT(30));
505   AutofillProfileChange change(AutofillProfileChange::UPDATE, kGuidA, &local);
506 
507   EXPECT_CALL(
508       mock_processor(),
509       Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
510   // The bridge does not need to commit when reacting to a notification about a
511   // local change.
512   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
513 
514   bridge()->AutofillProfileChanged(change);
515 }
516 
517 // Server profile updates should be ignored.
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Updated_IgnoreServerProfiles)518 TEST_P(AutofillProfileSyncBridgeTest,
519        AutofillProfileChanged_Updated_IgnoreServerProfiles) {
520   StartSyncing({});
521 
522   AutofillProfile server_profile(AutofillProfile::SERVER_PROFILE, "server-id");
523   AutofillProfileChange change(AutofillProfileChange::UPDATE,
524                                server_profile.guid(), &server_profile);
525 
526   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
527   // Should not crash.
528   bridge()->AutofillProfileChanged(change);
529 }
530 
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Deleted)531 TEST_P(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Deleted) {
532   StartSyncing({});
533 
534   AutofillProfile local(kGuidB, kHttpsOrigin);
535   local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
536   AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuidB, &local);
537   EXPECT_CALL(mock_processor(), Delete(kGuidB, _));
538   // The bridge does not need to commit when reacting to a notification about a
539   // local change.
540   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
541 
542   bridge()->AutofillProfileChanged(change);
543 }
544 
545 // Server profile updates should be ignored.
TEST_P(AutofillProfileSyncBridgeTest,AutofillProfileChanged_Deleted_IgnoreServerProfiles)546 TEST_P(AutofillProfileSyncBridgeTest,
547        AutofillProfileChanged_Deleted_IgnoreServerProfiles) {
548   StartSyncing({});
549 
550   AutofillProfile server_profile(AutofillProfile::SERVER_PROFILE, "server-id");
551   AutofillProfileChange change(AutofillProfileChange::REMOVE,
552                                server_profile.guid(), &server_profile);
553 
554   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
555   // Should not crash.
556   bridge()->AutofillProfileChanged(change);
557 }
558 
TEST_P(AutofillProfileSyncBridgeTest,GetAllDataForDebugging)559 TEST_P(AutofillProfileSyncBridgeTest, GetAllDataForDebugging) {
560   AutofillProfile local1 = AutofillProfile(kGuidA, kHttpsOrigin);
561   local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
562   local1.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
563   AutofillProfile local2 = AutofillProfile(kGuidB, kHttpsOrigin);
564   local2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
565   local2.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2nd st"));
566   AddAutofillProfilesToTable({local1, local2});
567 
568   EXPECT_THAT(GetAllLocalData(), UnorderedElementsAre(local1, local2));
569 }
570 
TEST_P(AutofillProfileSyncBridgeTest,GetData)571 TEST_P(AutofillProfileSyncBridgeTest, GetData) {
572   AutofillProfile local1 = AutofillProfile(kGuidA, kHttpsOrigin);
573   local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
574   local1.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
575   AutofillProfile local2 = AutofillProfile(kGuidB, kHttpsOrigin);
576   local2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
577   local2.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2nd st"));
578   AddAutofillProfilesToTable({local1, local2});
579 
580   std::vector<AutofillProfile> data;
581   base::RunLoop loop;
582   bridge()->GetData({kGuidA},
583                     base::BindLambdaForTesting(
584                         [&loop, &data](std::unique_ptr<DataBatch> batch) {
585                           ExtractAutofillProfilesFromDataBatch(std::move(batch),
586                                                                &data);
587                           loop.Quit();
588                         }));
589   loop.Run();
590 
591   EXPECT_THAT(data, ElementsAre(local1));
592 }
593 
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData)594 TEST_P(AutofillProfileSyncBridgeTest, MergeSyncData) {
595   AutofillProfile local1 = AutofillProfile(kGuidA, kHttpOrigin);
596   local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
597   local1.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
598 
599   AutofillProfile local2 = AutofillProfile(kGuidB, std::string());
600   local2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
601   local2.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2nd st"));
602 
603   AddAutofillProfilesToTable({local1, local2});
604 
605   AutofillProfile remote1 = AutofillProfile(kGuidC, kHttpOrigin);
606   remote1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
607   remote1.FinalizeAfterImport();
608 
609   AutofillProfile remote2 = AutofillProfile(kGuidD, kSettingsOrigin);
610   remote2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Harry"));
611   remote2.FinalizeAfterImport();
612 
613   AutofillProfile remote3 = AutofillProfile(kGuidB, kSettingsOrigin);
614   remote3.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom Doe"));
615   remote3.FinalizeAfterImport();
616 
617   AutofillProfileSpecifics remote1_specifics =
618       CreateAutofillProfileSpecifics(remote1);
619   AutofillProfileSpecifics remote2_specifics =
620       CreateAutofillProfileSpecifics(remote2);
621   AutofillProfileSpecifics remote3_specifics =
622       CreateAutofillProfileSpecifics(remote3);
623 
624   EXPECT_CALL(
625       mock_processor(),
626       Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local1)), _));
627   EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
628   EXPECT_CALL(*backend(), CommitChanges());
629 
630   StartSyncing({remote1_specifics, remote2_specifics, remote3_specifics});
631 
632   // Since |local2| and |remote3| have the same GUID, data from |remote3| is
633   // incorporated into the local profile which is mostly a replace operation.
634   EXPECT_THAT(
635       GetAllLocalData(),
636       UnorderedElementsAre(local1, CreateAutofillProfile(remote1_specifics),
637                            CreateAutofillProfile(remote2_specifics),
638                            CreateAutofillProfile(remote3_specifics)));
639 }
640 
641 // Tests the profile migration that is performed after specifics are converted
642 // to profiles.
TEST_P(AutofillProfileSyncBridgeTest,ProfileMigration)643 TEST_P(AutofillProfileSyncBridgeTest, ProfileMigration) {
644   // This test is only applicable when structured names are enabled.
645   if (!UsingStructuredNames())
646     return;
647 
648   AutofillProfile remote1 = AutofillProfile(kGuidC, kHttpOrigin);
649   remote1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Thomas"));
650   remote1.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("Neo"));
651   remote1.SetRawInfo(NAME_LAST, ASCIIToUTF16("Anderson"));
652 
653   AutofillProfileSpecifics remote1_specifics =
654       CreateAutofillProfileSpecifics(remote1);
655 
656   EXPECT_CALL(*backend(), CommitChanges());
657 
658   StartSyncing({remote1_specifics});
659 
660   // Create the expected profile after migration.
661   AutofillProfile finalized_profile = AutofillProfile(kGuidC, kHttpOrigin);
662   finalized_profile.SetRawInfoWithVerificationStatus(
663       NAME_FULL, ASCIIToUTF16("Thomas Neo Anderson"),
664       structured_address::VerificationStatus::kFormatted);
665   finalized_profile.SetRawInfoWithVerificationStatus(
666       NAME_FIRST, ASCIIToUTF16("Thomas"),
667       structured_address::VerificationStatus::kObserved);
668   finalized_profile.SetRawInfoWithVerificationStatus(
669       NAME_MIDDLE, ASCIIToUTF16("Neo"),
670       structured_address::VerificationStatus::kObserved);
671   finalized_profile.SetRawInfoWithVerificationStatus(
672       NAME_LAST, ASCIIToUTF16("Anderson"),
673       structured_address::VerificationStatus::kObserved);
674   finalized_profile.SetRawInfoWithVerificationStatus(
675       NAME_LAST_SECOND, ASCIIToUTF16("Anderson"),
676       structured_address::VerificationStatus::kParsed);
677   finalized_profile.SetRawInfoWithVerificationStatus(
678       NAME_LAST_FIRST, ASCIIToUTF16(""),
679       structured_address::VerificationStatus::kParsed);
680   finalized_profile.SetRawInfoWithVerificationStatus(
681       NAME_LAST_CONJUNCTION, ASCIIToUTF16(""),
682       structured_address::VerificationStatus::kParsed);
683 
684   EXPECT_THAT(GetAllLocalData(), UnorderedElementsAre(finalized_profile));
685 }
686 
687 // Ensure that all profile fields are able to be synced up from the client to
688 // the server.
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SyncAllFieldsToServer)689 TEST_P(AutofillProfileSyncBridgeTest, MergeSyncData_SyncAllFieldsToServer) {
690   AutofillProfile local = ConstructCompleteProfile();
691   AddAutofillProfilesToTable({local});
692 
693   // This complete profile is fully uploaded to sync.
694   EXPECT_CALL(mock_processor(),
695               Put(_, HasSpecifics(ConstructCompleteSpecifics()), _));
696   EXPECT_CALL(*backend(), CommitChanges());
697 
698   StartSyncing({});
699 
700   // No changes locally.
701   EXPECT_THAT(GetAllLocalData(), ElementsAre(WithUsageStats(local)));
702 }
703 
704 // Ensure that all profile fields are able to be synced down from the server to
705 // the client (and nothing gets uploaded back).
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SyncAllFieldsToClient)706 TEST_P(AutofillProfileSyncBridgeTest, MergeSyncData_SyncAllFieldsToClient) {
707   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
708   EXPECT_CALL(*backend(), CommitChanges());
709   StartSyncing({ConstructCompleteSpecifics()});
710 
711   EXPECT_THAT(GetAllLocalData(),
712               ElementsAre(WithUsageStats(ConstructCompleteProfile())));
713 }
714 
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_IdenticalProfiles)715 TEST_P(AutofillProfileSyncBridgeTest, MergeSyncData_IdenticalProfiles) {
716   AutofillProfile local1 = AutofillProfile(kGuidA, kHttpOrigin);
717   local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
718   local1.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
719 
720   AutofillProfile local2 = AutofillProfile(kGuidB, kSettingsOrigin);
721   local2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
722   local2.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2nd st"));
723 
724   AddAutofillProfilesToTable({local1, local2});
725 
726   // The synced profiles are identical to the local ones, except that the guids
727   // are different.
728 
729   AutofillProfile remote1 = AutofillProfile(kGuidC, kHttpsOrigin);
730   remote1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
731   remote1.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
732   remote1.FinalizeAfterImport();
733 
734   AutofillProfile remote2 = AutofillProfile(kGuidD, kHttpsOrigin);
735   remote2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
736   remote2.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2nd st"));
737   remote2.FinalizeAfterImport();
738 
739   AutofillProfileSpecifics remote1_specifics =
740       CreateAutofillProfileSpecifics(remote1);
741   AutofillProfileSpecifics remote2_specifics =
742       CreateAutofillProfileSpecifics(remote2);
743 
744   // Both remote profiles win, only the verified origin is taken over for the
745   // second profile.
746   AutofillProfileSpecifics merged2(remote2_specifics);
747   merged2.set_origin(kSettingsOrigin);
748   EXPECT_CALL(mock_processor(), Put(kGuidD, HasSpecifics(merged2), _));
749   EXPECT_CALL(*backend(), CommitChanges());
750 
751   StartSyncing({remote1_specifics, remote2_specifics});
752 
753   EXPECT_THAT(GetAllLocalData(),
754               UnorderedElementsAre(CreateAutofillProfile(remote1_specifics),
755                                    CreateAutofillProfile(merged2)));
756 }
757 
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_NonSimilarProfiles)758 TEST_P(AutofillProfileSyncBridgeTest, MergeSyncData_NonSimilarProfiles) {
759   AutofillProfile local = ConstructCompleteProfile();
760   local.set_guid(kGuidA);
761   local.SetRawInfo(NAME_FULL, ASCIIToUTF16("John K. Doe, Jr."));
762   local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
763   local.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("K."));
764   local.SetRawInfo(NAME_LAST, ASCIIToUTF16("Doe"));
765   AddAutofillProfilesToTable({local});
766 
767   // The remote profile are not similar as the names are different (all other
768   // fields except for guids are identical).
769   AutofillProfileSpecifics remote = ConstructCompleteSpecifics();
770   remote.set_guid(kGuidB);
771   remote.set_name_full(0, "Jane T. Roe, Sr.");
772   remote.set_name_first(0, "Jane");
773   remote.set_name_middle(0, "T.");
774   remote.set_name_last(0, "Roe");
775 
776   // The profiles are not similar enough and thus do not get merged.
777   // Expect the local one being synced up and the remote one being added to the
778   // local database.
779   EXPECT_CALL(
780       mock_processor(),
781       Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
782   EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
783   EXPECT_CALL(*backend(), CommitChanges());
784 
785   StartSyncing({remote});
786 
787   EXPECT_THAT(GetAllLocalData(),
788               UnorderedElementsAre(local, CreateAutofillProfile(remote)));
789 }
790 
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SimilarProfiles)791 TEST_P(AutofillProfileSyncBridgeTest, MergeSyncData_SimilarProfiles) {
792   AutofillProfile local1 = AutofillProfile(kGuidA, kHttpOrigin);
793   local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
794   local1.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
795   local1.FinalizeAfterImport();
796   local1.set_use_count(27);
797 
798   AutofillProfile local2 = AutofillProfile(kGuidB, kSettingsOrigin);
799   local2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
800   local2.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2nd st"));
801   local2.FinalizeAfterImport();
802   AddAutofillProfilesToTable({local1, local2});
803 
804   // The synced profiles are identical to the local ones, except that the guids
805   // and use_count values are different. Remote ones have additional company
806   // name which makes them not be identical.
807   AutofillProfile remote1 = AutofillProfile(kGuidC, kHttpOrigin);
808   remote1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
809   remote1.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
810   remote1.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
811   // Note, this populates the full name for structured profiles.
812   remote1.FinalizeAfterImport();
813   remote1.set_use_count(13);
814 
815   AutofillProfile remote2 = AutofillProfile(kGuidD, kHttpOrigin);
816   remote2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
817   remote2.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2nd st"));
818   remote2.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Fizzbang, LLC."));
819   remote2.FinalizeAfterImport();
820   remote2.set_use_count(4);
821 
822   AutofillProfileSpecifics remote1_specifics =
823       CreateAutofillProfileSpecifics(remote1);
824   AutofillProfileSpecifics remote2_specifics =
825       CreateAutofillProfileSpecifics(remote2);
826 
827   // The first profile should have its origin updated.
828   // The second profile should remain as-is, because an unverified profile
829   // should never overwrite a verified one.
830   AutofillProfileSpecifics merged1(remote1_specifics);
831   merged1.set_origin(kHttpOrigin);
832   // For the legacy implementation, the full name field gets popluated by the
833   // merging operation and must be added to the expectation.
834   // For structured names, the full name is already populated by calling
835   // |FinalizeAfterImport()|.
836   if (UsingStructuredNames()) {
837     ASSERT_GT(merged1.name_full_size(), 0);
838     ASSERT_EQ(merged1.name_full(0), "John");
839   } else {
840     merged1.set_name_full(0, "John");
841   }
842   // Merging two profile takes their max use count.
843   merged1.set_use_count(27);
844 
845   // Expect updating the first (merged) profile and adding the second local one.
846   EXPECT_CALL(mock_processor(), Put(kGuidC, HasSpecifics(merged1), _));
847   EXPECT_CALL(
848       mock_processor(),
849       Put(kGuidB, HasSpecifics(CreateAutofillProfileSpecifics(local2)), _));
850   EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
851   EXPECT_CALL(*backend(), CommitChanges());
852 
853   StartSyncing({remote1_specifics, remote2_specifics});
854 
855   EXPECT_THAT(GetAllLocalData(),
856               UnorderedElementsAre(
857                   WithUsageStats(CreateAutofillProfile(merged1)), local2,
858                   WithUsageStats(CreateAutofillProfile(remote2_specifics))));
859 }
860 
861 // Tests that MergeSimilarProfiles keeps the most recent use date of the two
862 // profiles being merged.
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SimilarProfiles_OlderUseDate)863 TEST_P(AutofillProfileSyncBridgeTest,
864        MergeSyncData_SimilarProfiles_OlderUseDate) {
865   // Different guids, same origin, difference in the phone number.
866   AutofillProfile local(kGuidA, kHttpOrigin);
867   local.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("650234567"));
868   local.set_use_date(base::Time::FromTimeT(30));
869   AddAutofillProfilesToTable({local});
870 
871   AutofillProfileSpecifics remote =
872       CreateAutofillProfileSpecifics(kGuidB, kHttpOrigin);
873   // |local| has a more recent use date.
874   remote.set_use_date(25);
875 
876   // The use date of |local| should replace the use date of |remote|.
877   AutofillProfileSpecifics merged(remote);
878   merged.set_use_date(30);
879   merged.add_phone_home_whole_number("650234567");
880   EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
881   EXPECT_CALL(*backend(), CommitChanges());
882 
883   StartSyncing({remote});
884 }
885 
886 // Tests that MergeSimilarProfiles keeps the most recent use date of the two
887 // profiles being merged.
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SimilarProfiles_NewerUseDate)888 TEST_P(AutofillProfileSyncBridgeTest,
889        MergeSyncData_SimilarProfiles_NewerUseDate) {
890   // Different guids, same origin, difference in the phone number.
891   AutofillProfile local(kGuidA, kHttpOrigin);
892   local.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("650234567"));
893   local.set_use_date(base::Time::FromTimeT(30));
894   AddAutofillProfilesToTable({local});
895 
896   AutofillProfileSpecifics remote =
897       CreateAutofillProfileSpecifics(kGuidB, kHttpOrigin);
898   // |remote| has a more recent use date.
899   remote.set_use_date(35);
900 
901   // The use date of |local| should _not_ replace the use date of |remote|.
902   AutofillProfileSpecifics merged(remote);
903   merged.add_phone_home_whole_number("650234567");
904   EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
905   EXPECT_CALL(*backend(), CommitChanges());
906 
907   StartSyncing({remote});
908 }
909 
910 // Tests that MergeSimilarProfiles saves the max of the use counts of the two
911 // profiles in |remote|.
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SimilarProfiles_NonZeroUseCounts)912 TEST_P(AutofillProfileSyncBridgeTest,
913        MergeSyncData_SimilarProfiles_NonZeroUseCounts) {
914   // Different guids, same origin, difference in the phone number.
915   AutofillProfile local(kGuidA, kHttpOrigin);
916   local.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("650234567"));
917   local.set_use_count(12);
918   AddAutofillProfilesToTable({local});
919 
920   AutofillProfileSpecifics remote =
921       CreateAutofillProfileSpecifics(kGuidB, kHttpOrigin);
922   remote.set_use_count(5);
923 
924   // The use count of |local| should replace the use count of |remote|.
925   AutofillProfileSpecifics merged(remote);
926   merged.set_use_count(12);
927   merged.add_phone_home_whole_number("650234567");
928   EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
929   EXPECT_CALL(*backend(), CommitChanges());
930 
931   StartSyncing({remote});
932 }
933 
934 // Tests that when merging similar profiles for initial sync, we add the
935 // additional information of |local| into |remote|.
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SimilarProfiles_LocalOriginPreserved)936 TEST_P(AutofillProfileSyncBridgeTest,
937        MergeSyncData_SimilarProfiles_LocalOriginPreserved) {
938   AutofillProfile local(kGuidA, kHttpsOrigin);
939   local.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("650234567"));
940   AddAutofillProfilesToTable({local});
941 
942   AutofillProfile remote_profile = AutofillProfile(kGuidB, kHttpOrigin);
943   remote_profile.FinalizeAfterImport();
944   AutofillProfileSpecifics remote =
945       CreateAutofillProfileSpecifics(remote_profile);
946   remote.set_address_home_language_code("en");
947 
948   // Expect that the resulting merged profile is written back to sync and that
949   // it has the phone number and origin from |local|.
950   AutofillProfileSpecifics merged(remote);
951   merged.set_origin(kHttpsOrigin);
952   merged.set_phone_home_whole_number(0, "650234567");
953   // TODO(jkrcal): Is this expected that language code gets deleted? Not
954   // explicitly covered by previous tests but happens.
955   merged.set_address_home_language_code("");
956   EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
957   EXPECT_CALL(*backend(), CommitChanges());
958 
959   StartSyncing({remote});
960 }
961 
962 // Sync data without origin should not overwrite existing origin in local
963 // autofill profile.
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SimilarProfiles_LocalExistingOriginPreserved)964 TEST_P(AutofillProfileSyncBridgeTest,
965        MergeSyncData_SimilarProfiles_LocalExistingOriginPreserved) {
966   AutofillProfile local(kGuidA, kHttpsOrigin);
967   AddAutofillProfilesToTable({local});
968 
969   // Remote data does not have an origin value.
970   AutofillProfileSpecifics remote = CreateAutofillProfileSpecifics(kGuidA, "");
971   remote.clear_origin();
972   remote.add_name_first("John");
973   ASSERT_FALSE(remote.has_origin());
974 
975   // Expect no sync events to add origin to the remote data.
976   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
977   EXPECT_CALL(*backend(), CommitChanges());
978   StartSyncing({remote});
979 
980   // Expect the local autofill profile to still have an origin after sync.
981   AutofillProfile merged(local);
982   merged.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
983 
984   EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
985 }
986 
987 // Ensure that no Sync events are generated to fill in missing origins from Sync
988 // with explicitly present empty ones. This ensures that the migration to add
989 // origins to profiles does not generate lots of needless Sync updates.
TEST_P(AutofillProfileSyncBridgeTest,MergeSyncData_SimilarProfiles_LocalMissingOriginPreserved)990 TEST_P(AutofillProfileSyncBridgeTest,
991        MergeSyncData_SimilarProfiles_LocalMissingOriginPreserved) {
992   AutofillProfile local = AutofillProfile(kGuidA, std::string());
993   local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
994   AddAutofillProfilesToTable({local});
995 
996   // Create a Sync profile identical to |local|, except with no origin set.
997   AutofillProfile remote_profile = AutofillProfile(kGuidA, "");
998   remote_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
999   remote_profile.FinalizeAfterImport();
1000   AutofillProfileSpecifics remote =
1001       CreateAutofillProfileSpecifics(remote_profile);
1002   remote.clear_origin();
1003   ASSERT_FALSE(remote.has_origin());
1004 
1005   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1006   EXPECT_CALL(*backend(), CommitChanges());
1007   StartSyncing({remote});
1008   EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
1009 }
1010 
TEST_P(AutofillProfileSyncBridgeTest,ApplySyncChanges)1011 TEST_P(AutofillProfileSyncBridgeTest, ApplySyncChanges) {
1012   AutofillProfile local = AutofillProfile(kGuidA, kHttpsOrigin);
1013   AddAutofillProfilesToTable({local});
1014 
1015   StartSyncing({});
1016 
1017   AutofillProfile remote_profile = AutofillProfile(kGuidB, kHttpOrigin);
1018   remote_profile.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Jane"));
1019   remote_profile.FinalizeAfterImport();
1020   AutofillProfileSpecifics remote =
1021       CreateAutofillProfileSpecifics(remote_profile);
1022 
1023   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1024   EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
1025   EXPECT_CALL(*backend(), CommitChanges());
1026 
1027   syncer::EntityChangeList entity_change_list;
1028   entity_change_list.push_back(EntityChange::CreateDelete(kGuidA));
1029   entity_change_list.push_back(
1030       EntityChange::CreateAdd(kGuidB, SpecificsToEntity(remote)));
1031   ApplySyncChanges(std::move(entity_change_list));
1032 
1033   EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
1034 }
1035 
1036 // Ensure that entries with invalid specifics are ignored.
TEST_P(AutofillProfileSyncBridgeTest,ApplySyncChanges_OmitsInvalidSpecifics)1037 TEST_P(AutofillProfileSyncBridgeTest, ApplySyncChanges_OmitsInvalidSpecifics) {
1038   StartSyncing({});
1039 
1040   AutofillProfileSpecifics remote_valid =
1041       CreateAutofillProfileSpecifics(kGuidA, std::string());
1042   AutofillProfileSpecifics remote_invalid =
1043       CreateAutofillProfileSpecifics(kGuidInvalid, std::string());
1044 
1045   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1046   EXPECT_CALL(*backend(), CommitChanges());
1047 
1048   syncer::EntityChangeList entity_change_list;
1049   entity_change_list.push_back(
1050       EntityChange::CreateAdd(kGuidA, SpecificsToEntity(remote_valid)));
1051   entity_change_list.push_back(
1052       EntityChange::CreateAdd(kGuidInvalid, SpecificsToEntity(remote_invalid)));
1053   ApplySyncChanges(std::move(entity_change_list));
1054 
1055   EXPECT_THAT(GetAllLocalData(),
1056               ElementsAre(CreateAutofillProfile(remote_valid)));
1057 }
1058 
1059 // Verifies that setting the street address field also sets the (deprecated)
1060 // address line 1 and line 2 fields.
TEST_P(AutofillProfileSyncBridgeTest,StreetAddress_SplitAutomatically)1061 TEST_P(AutofillProfileSyncBridgeTest, StreetAddress_SplitAutomatically) {
1062   AutofillProfile local;
1063   local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("123 Example St.\n"
1064                                                              "Apt. 42"));
1065   EXPECT_EQ(ASCIIToUTF16("123 Example St."),
1066             local.GetRawInfo(ADDRESS_HOME_LINE1));
1067   EXPECT_EQ(ASCIIToUTF16("Apt. 42"), local.GetRawInfo(ADDRESS_HOME_LINE2));
1068 
1069   // The same does _not_ work for profile specifics.
1070   AutofillProfileSpecifics remote;
1071   remote.set_address_home_street_address(
1072       "123 Example St.\n"
1073       "Apt. 42");
1074   EXPECT_FALSE(remote.has_address_home_line1());
1075   EXPECT_FALSE(remote.has_address_home_line2());
1076 }
1077 
1078 // Verifies that setting the (deprecated) address line 1 and line 2 fields also
1079 // sets the street address.
TEST_P(AutofillProfileSyncBridgeTest,StreetAddress_JointAutomatically)1080 TEST_P(AutofillProfileSyncBridgeTest, StreetAddress_JointAutomatically) {
1081   AutofillProfile local;
1082   local.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("123 Example St."));
1083   local.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("Apt. 42"));
1084   EXPECT_EQ(ASCIIToUTF16("123 Example St.\n"
1085                          "Apt. 42"),
1086             local.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS));
1087 
1088   // The same does _not_ work for profile specifics.
1089   AutofillProfileSpecifics remote;
1090   remote.set_address_home_line1("123 Example St.");
1091   remote.set_address_home_line2("Apt. 42");
1092   EXPECT_FALSE(remote.has_address_home_street_address());
1093 }
1094 
1095 // Ensure that the street address field takes precedence over the (deprecated)
1096 // address line 1 and line 2 fields, even though these are expected to always be
1097 // in sync in practice.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_StreetAddress_TakesPrecedenceOverAddressLines)1098 TEST_P(AutofillProfileSyncBridgeTest,
1099        RemoteWithSameGuid_StreetAddress_TakesPrecedenceOverAddressLines) {
1100   // Create remote entry with conflicting address data in the street address
1101   // field vs. the address line 1 and address line 2 fields.
1102   AutofillProfileSpecifics remote =
1103       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1104   remote.set_address_home_line1("123 Example St.");
1105   remote.set_address_home_line2("Apt. 42");
1106   remote.set_address_home_street_address(
1107       "456 El Camino Real\n"
1108       "Suite #1337");
1109   EXPECT_CALL(*backend(), CommitChanges());
1110 
1111   StartSyncing({remote});
1112 
1113   // Verify that full street address takes precedence over address lines.
1114   AutofillProfile local(kGuidA, kHttpsOrigin);
1115   local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
1116                    ASCIIToUTF16("456 El Camino Real\n"
1117                                 "Suite #1337"));
1118   local.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("456 El Camino Real"));
1119   local.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("Suite #1337"));
1120   EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
1121 }
1122 
1123 // Ensure that no Sync events are generated to fill in missing street address
1124 // fields from Sync with explicitly present ones identical to the data stored in
1125 // the line1 and line2 fields. This ensures that the migration to add the
1126 // street address field to profiles does not generate lots of needless Sync
1127 // updates.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_StreetAddress_NoUpdateToEmptyStreetAddressSyncedUp)1128 TEST_P(AutofillProfileSyncBridgeTest,
1129        RemoteWithSameGuid_StreetAddress_NoUpdateToEmptyStreetAddressSyncedUp) {
1130   AutofillProfile local(kGuidA, kHttpsOrigin);
1131   local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("123 Example St.\n"
1132                                                              "Apt. 42"));
1133   AddAutofillProfilesToTable({local});
1134 
1135   // Create a Sync profile identical to |profile|, except without street address
1136   // explicitly set.
1137   AutofillProfileSpecifics remote =
1138       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1139   remote.set_address_home_line1("123 Example St.");
1140   remote.set_address_home_line2("Apt. 42");
1141 
1142   // No update to sync, no change in local data.
1143   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1144   EXPECT_CALL(*backend(), CommitChanges());
1145   StartSyncing({remote});
1146   EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
1147 }
1148 
1149 // Missing language code field should not generate sync events.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_LanguageCode_MissingCodesNoSync)1150 TEST_P(AutofillProfileSyncBridgeTest,
1151        RemoteWithSameGuid_LanguageCode_MissingCodesNoSync) {
1152   AutofillProfile local(kGuidA, kHttpsOrigin);
1153   ASSERT_TRUE(local.language_code().empty());
1154   AddAutofillProfilesToTable({local});
1155 
1156   // Remote data does not have a language code value.
1157   AutofillProfileSpecifics remote =
1158       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1159   ASSERT_FALSE(remote.has_address_home_language_code());
1160 
1161   // No update to sync, no change in local data.
1162   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1163   EXPECT_CALL(*backend(), CommitChanges());
1164   StartSyncing({remote});
1165   EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
1166 }
1167 
1168 // Empty language code should be overwritten by sync.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_LanguageCode_ExistingRemoteWinsOverMissingLocal)1169 TEST_P(AutofillProfileSyncBridgeTest,
1170        RemoteWithSameGuid_LanguageCode_ExistingRemoteWinsOverMissingLocal) {
1171   AutofillProfile local(kGuidA, kHttpsOrigin);
1172   ASSERT_TRUE(local.language_code().empty());
1173   AddAutofillProfilesToTable({local});
1174 
1175   // Remote data has "en" language code.
1176   AutofillProfileSpecifics remote =
1177       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1178   remote.set_address_home_language_code("en");
1179 
1180   // No update to sync, remote language code overwrites the empty local one.
1181   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1182   EXPECT_CALL(*backend(), CommitChanges());
1183   StartSyncing({remote});
1184   EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
1185 }
1186 
1187 // Local language code should be overwritten by remote one.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_LanguageCode_ExistingRemoteWinsOverExistingLocal)1188 TEST_P(AutofillProfileSyncBridgeTest,
1189        RemoteWithSameGuid_LanguageCode_ExistingRemoteWinsOverExistingLocal) {
1190   AutofillProfile local(kGuidA, kHttpsOrigin);
1191   local.set_language_code("de");
1192   AddAutofillProfilesToTable({local});
1193 
1194   // Remote data has "en" language code.
1195   AutofillProfileSpecifics remote =
1196       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1197   remote.set_address_home_language_code("en");
1198 
1199   // No update to sync, remote language code overwrites the local one.
1200   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1201   EXPECT_CALL(*backend(), CommitChanges());
1202   StartSyncing({remote});
1203   EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
1204 }
1205 
1206 // Sync data without language code should not overwrite existing language code
1207 // in local autofill profile.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_LanguageCode_ExistingLocalWinsOverMissingRemote)1208 TEST_P(AutofillProfileSyncBridgeTest,
1209        RemoteWithSameGuid_LanguageCode_ExistingLocalWinsOverMissingRemote) {
1210   // Local autofill profile has "en" language code.
1211   AutofillProfile local(kGuidA, kHttpsOrigin);
1212   local.set_language_code("en");
1213   AddAutofillProfilesToTable({local});
1214 
1215   // Remote data does not have a language code value.
1216   AutofillProfile remote_profile = AutofillProfile(kGuidA, kHttpsOrigin);
1217   remote_profile.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("John"));
1218   remote_profile.FinalizeAfterImport();
1219   AutofillProfileSpecifics remote =
1220       CreateAutofillProfileSpecifics(remote_profile);
1221   ASSERT_TRUE(remote.address_home_language_code().empty());
1222 
1223   // Expect local autofill profile to still have "en" language code after
1224   AutofillProfile merged(local);
1225   merged.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
1226   merged.FinalizeAfterImport();
1227 
1228   // No update to sync, remote language code overwrites the local one.
1229   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1230   EXPECT_CALL(*backend(), CommitChanges());
1231   StartSyncing({remote});
1232   EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
1233 }
1234 
1235 // Missing validity state bitifield should not generate sync events.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_ValidityState_DefaultValueNoSync)1236 TEST_P(AutofillProfileSyncBridgeTest,
1237        RemoteWithSameGuid_ValidityState_DefaultValueNoSync) {
1238   AutofillProfile local(kGuidA, kHttpsOrigin);
1239   ASSERT_EQ(0, local.GetClientValidityBitfieldValue());
1240   ASSERT_FALSE(local.is_client_validity_states_updated());
1241   AddAutofillProfilesToTable({local});
1242 
1243   // Remote data does not have a validity state bitfield value.
1244   AutofillProfileSpecifics remote =
1245       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1246   ASSERT_FALSE(remote.has_validity_state_bitfield());
1247   ASSERT_FALSE(remote.is_client_validity_states_updated());
1248 
1249   // No update to sync, no change in local data.
1250   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1251   EXPECT_CALL(*backend(), CommitChanges());
1252   StartSyncing({remote});
1253   EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
1254 }
1255 
1256 // Default validity state bitfield should be overwritten by sync.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_ValidityState_ExistingRemoteWinsOverMissingLocal)1257 TEST_P(AutofillProfileSyncBridgeTest,
1258        RemoteWithSameGuid_ValidityState_ExistingRemoteWinsOverMissingLocal) {
1259   AutofillProfile local(kGuidA, kHttpsOrigin);
1260   ASSERT_EQ(0, local.GetClientValidityBitfieldValue());
1261   AddAutofillProfilesToTable({local});
1262 
1263   // Remote data has a non default validity state bitfield value.
1264   AutofillProfileSpecifics remote =
1265       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1266   remote.set_validity_state_bitfield(kValidityStateBitfield);
1267   ASSERT_TRUE(remote.has_validity_state_bitfield());
1268 
1269   // No update to sync, the validity bitfield should be stored to local.
1270   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1271   EXPECT_CALL(*backend(), CommitChanges());
1272   StartSyncing({remote});
1273   EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
1274 }
1275 
1276 // Local validity state bitfield should be overwritten by sync.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_ValidityState_ExistingRemoteWinsOverExistingLocal)1277 TEST_P(AutofillProfileSyncBridgeTest,
1278        RemoteWithSameGuid_ValidityState_ExistingRemoteWinsOverExistingLocal) {
1279   AutofillProfile local(kGuidA, kHttpsOrigin);
1280   local.SetClientValidityFromBitfieldValue(kValidityStateBitfield + 1);
1281   AddAutofillProfilesToTable({local});
1282 
1283   // Remote data has a non default validity state bitfield value.
1284   AutofillProfileSpecifics remote =
1285       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1286   remote.set_validity_state_bitfield(kValidityStateBitfield);
1287   ASSERT_TRUE(remote.has_validity_state_bitfield());
1288 
1289   // No update to sync, the remote validity bitfield should overwrite local.
1290   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1291   EXPECT_CALL(*backend(), CommitChanges());
1292   StartSyncing({remote});
1293   EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
1294 }
1295 
1296 // Sync data without a default validity state bitfield should not overwrite
1297 // an existing validity state bitfield in local autofill profile.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_ValidityState_ExistingLocalWinsOverMissingRemote)1298 TEST_P(AutofillProfileSyncBridgeTest,
1299        RemoteWithSameGuid_ValidityState_ExistingLocalWinsOverMissingRemote) {
1300   AutofillProfile local(kGuidA, kHttpsOrigin);
1301   local.SetClientValidityFromBitfieldValue(kValidityStateBitfield);
1302   AddAutofillProfilesToTable({local});
1303 
1304   // Remote data has a non default validity state bitfield value.
1305   AutofillProfileSpecifics remote =
1306       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1307   remote.add_name_first("John");
1308   ASSERT_FALSE(remote.has_validity_state_bitfield());
1309 
1310   // Expect local autofill profile to still have the validity state after.
1311   AutofillProfile merged(local);
1312   merged.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
1313 
1314   // No update to sync, the local validity bitfield should stay untouched.
1315   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1316   EXPECT_CALL(*backend(), CommitChanges());
1317   StartSyncing({remote});
1318   EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
1319 }
1320 
1321 // Missing full name field should not generate sync events.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_FullName_MissingValueNoSync)1322 TEST_P(AutofillProfileSyncBridgeTest,
1323        RemoteWithSameGuid_FullName_MissingValueNoSync) {
1324   // Local autofill profile has an empty full name.
1325   AutofillProfile local(kGuidA, kHttpsOrigin);
1326   local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
1327   AddAutofillProfilesToTable({local});
1328 
1329   // Remote data does not have a full name value.
1330   AutofillProfileSpecifics remote =
1331       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1332   remote.add_name_first(std::string("John"));
1333 
1334   // No update to sync, no change in local data.
1335   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1336   EXPECT_CALL(*backend(), CommitChanges());
1337   StartSyncing({remote});
1338   EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
1339 }
1340 
1341 // This test verifies that for the legacy implementation of names, the full name
1342 // is maintained from the local profile.
1343 // However, this is not a valid use case for structured names as name structures
1344 // must be either merged or fully maintained. For structured names, this test
1345 // verifies that the names are merged.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_FullName_ExistingLocalWinsOverMissingRemote)1346 TEST_P(AutofillProfileSyncBridgeTest,
1347        RemoteWithSameGuid_FullName_ExistingLocalWinsOverMissingRemote) {
1348   // Local autofill profile has a full name.
1349   AutofillProfile local(kGuidA, kHttpsOrigin);
1350   local.SetRawInfoWithVerificationStatus(
1351       NAME_FULL, ASCIIToUTF16("John Jacob Smith"),
1352       structured_address::VerificationStatus::kObserved);
1353   local.FinalizeAfterImport();
1354   AddAutofillProfilesToTable({local});
1355 
1356   if (UsingStructuredNames()) {
1357     // After finalization, the first, middle and last name should have the
1358     // status |kParsed|.
1359     ASSERT_EQ(local.GetVerificationStatus(NAME_FIRST),
1360               structured_address::VerificationStatus::kParsed);
1361     ASSERT_EQ(local.GetVerificationStatus(NAME_MIDDLE),
1362               structured_address::VerificationStatus::kParsed);
1363     ASSERT_EQ(local.GetVerificationStatus(NAME_LAST),
1364               structured_address::VerificationStatus::kParsed);
1365   }
1366 
1367   // Remote data does not have a full name value.
1368   AutofillProfile remote_profile = AutofillProfile(kGuidA, kHttpsOrigin);
1369   remote_profile.SetRawInfoWithVerificationStatus(
1370       NAME_FIRST, base::ASCIIToUTF16("John"),
1371       structured_address::VerificationStatus::kObserved);
1372   remote_profile.SetRawInfoWithVerificationStatus(
1373       NAME_MIDDLE, base::ASCIIToUTF16("Jacob"),
1374       structured_address::VerificationStatus::kObserved);
1375   remote_profile.SetRawInfoWithVerificationStatus(
1376       NAME_LAST, base::ASCIIToUTF16("Smith"),
1377       structured_address::VerificationStatus::kObserved);
1378   remote_profile.FinalizeAfterImport();
1379   AutofillProfileSpecifics remote =
1380       CreateAutofillProfileSpecifics(remote_profile);
1381 
1382   // Expect local autofill profile to still have the same full name after.
1383   AutofillProfile merged(local);
1384 
1385   // Note, for structured names, the verification status of those tokens is
1386   // |kParsed| for local and becomes |kObserved| when merged with the remote
1387   // profile.
1388   merged.SetRawInfoWithVerificationStatus(
1389       NAME_FIRST, base::ASCIIToUTF16("John"),
1390       structured_address::VerificationStatus::kObserved);
1391   merged.SetRawInfoWithVerificationStatus(
1392       NAME_MIDDLE, base::ASCIIToUTF16("Jacob"),
1393       structured_address::VerificationStatus::kObserved);
1394   merged.SetRawInfoWithVerificationStatus(
1395       NAME_LAST, base::ASCIIToUTF16("Smith"),
1396       structured_address::VerificationStatus::kObserved);
1397 
1398   // No update to sync, merged changes in local data.
1399   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1400   EXPECT_CALL(*backend(), CommitChanges());
1401   StartSyncing({remote});
1402   EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
1403 }
1404 
1405 // Missing use_count/use_date fields should not generate sync events.
TEST_P(AutofillProfileSyncBridgeTest,RemoteWithSameGuid_UsageStats_MissingValueNoSync)1406 TEST_P(AutofillProfileSyncBridgeTest,
1407        RemoteWithSameGuid_UsageStats_MissingValueNoSync) {
1408   // Local autofill profile has 0 for use_count/use_date.
1409   AutofillProfile local(kGuidA, kHttpsOrigin);
1410   local.set_language_code("en");
1411   local.set_use_count(0);
1412   local.set_use_date(base::Time());
1413   AddAutofillProfilesToTable({local});
1414 
1415   // Remote data does not have use_count/use_date.
1416   AutofillProfileSpecifics remote =
1417       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1418   remote.clear_use_count();
1419   remote.clear_use_date();
1420   remote.set_address_home_language_code("en");
1421 
1422   // No update to sync, no change in local data.
1423   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1424   EXPECT_CALL(*backend(), CommitChanges());
1425   StartSyncing({remote});
1426   EXPECT_THAT(GetAllLocalData(), ElementsAre(WithUsageStats(local)));
1427 }
1428 
1429 struct UpdatesUsageStatsTestCase {
1430   size_t local_use_count;
1431   base::Time local_use_date;
1432   size_t remote_use_count;
1433   int remote_use_date;
1434   size_t merged_use_count;
1435   base::Time merged_use_date;
1436 };
1437 
1438 class AutofillProfileSyncBridgeUpdatesUsageStatsTest
1439     : public AutofillProfileSyncBridgeTestBase,
1440       public testing::WithParamInterface<UpdatesUsageStatsTestCase> {
1441  public:
AutofillProfileSyncBridgeUpdatesUsageStatsTest()1442   AutofillProfileSyncBridgeUpdatesUsageStatsTest() {}
~AutofillProfileSyncBridgeUpdatesUsageStatsTest()1443   ~AutofillProfileSyncBridgeUpdatesUsageStatsTest() override {}
1444 
1445  private:
1446   DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncBridgeUpdatesUsageStatsTest);
1447 };
1448 
TEST_P(AutofillProfileSyncBridgeUpdatesUsageStatsTest,UpdatesUsageStats)1449 TEST_P(AutofillProfileSyncBridgeUpdatesUsageStatsTest, UpdatesUsageStats) {
1450   auto test_case = GetParam();
1451 
1452   // Local data has usage stats.
1453   AutofillProfile local(kGuidA, kHttpsOrigin);
1454   local.set_language_code("en");
1455   local.set_use_count(test_case.local_use_count);
1456   local.set_use_date(test_case.local_use_date);
1457   ASSERT_EQ(test_case.local_use_count, local.use_count());
1458   ASSERT_EQ(test_case.local_use_date, local.use_date());
1459   AddAutofillProfilesToTable({local});
1460 
1461   // Remote data has usage stats.
1462   AutofillProfileSpecifics remote =
1463       CreateAutofillProfileSpecifics(kGuidA, kHttpsOrigin);
1464   remote.set_address_home_language_code("en");
1465   remote.set_use_count(test_case.remote_use_count);
1466   remote.set_use_date(test_case.remote_use_date);
1467   ASSERT_TRUE(remote.has_use_count());
1468   ASSERT_TRUE(remote.has_use_date());
1469 
1470   // Expect the local autofill profile to have usage stats after sync.
1471   AutofillProfile merged(local);
1472   merged.set_use_count(test_case.merged_use_count);
1473   merged.set_use_date(test_case.merged_use_date);
1474 
1475   // Expect no changes to remote data.
1476   EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
1477   EXPECT_CALL(*backend(), CommitChanges());
1478 
1479   StartSyncing({remote});
1480   EXPECT_THAT(GetAllLocalData(), ElementsAre(WithUsageStats(merged)));
1481 }
1482 
1483 // Test the sync bridge with and without structured names.
1484 INSTANTIATE_TEST_SUITE_P(, AutofillProfileSyncBridgeTest, testing::Bool());
1485 
1486 INSTANTIATE_TEST_SUITE_P(
1487     AutofillProfileSyncBridgeTest,
1488     AutofillProfileSyncBridgeUpdatesUsageStatsTest,
1489     testing::Values(
1490         // Local profile with default stats.
1491         UpdatesUsageStatsTestCase{
1492             /*local_use_count=*/0U,
1493             /*local_use_date=*/base::Time(),
1494             /*remote_use_count=*/9U,
1495             /*remote_use_date=*/4321,
1496             /*merged_use_count=*/9U,
1497             /*merged_use_date=*/base::Time::FromTimeT(4321)},
1498         // Local profile has older stats than the server.
1499         UpdatesUsageStatsTestCase{
1500             /*local_use_count=*/3U,
1501             /*local_use_date=*/base::Time::FromTimeT(1234),
1502             /*remote_use_count=*/9U, /*remote_use_date=*/4321,
1503             /*merged_use_count=*/9U,
1504             /*merged_use_date=*/base::Time::FromTimeT(4321)},
1505         // Local profile has newer stats than the server
1506         UpdatesUsageStatsTestCase{
1507             /*local_use_count=*/10U,
1508             /*local_use_date=*/base::Time::FromTimeT(9999),
1509             /*remote_use_count=*/9U, /*remote_use_date=*/4321,
1510             /*merged_use_count=*/9U,
1511             /*merged_use_date=*/base::Time::FromTimeT(4321)}));
1512 
1513 }  // namespace autofill
1514