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