Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Side by Side Diff: components/browser_sync/browser/profile_sync_service_autofill_unittest.cc

Issue 2345843003: [Sync] Merge //components/browser_sync into one directory. (Closed)
Patch Set: Address comment + rebase. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2012 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 <stddef.h>
6 #include <stdint.h>
7
8 #include <memory>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "base/bind.h"
15 #include "base/bind_helpers.h"
16 #include "base/callback.h"
17 #include "base/location.h"
18 #include "base/macros.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/memory/ref_counted.h"
21 #include "base/run_loop.h"
22 #include "base/strings/string16.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/synchronization/waitable_event.h"
25 #include "base/threading/thread.h"
26 #include "base/threading/thread_task_runner_handle.h"
27 #include "base/time/time.h"
28 #include "components/autofill/core/browser/autofill_test_utils.h"
29 #include "components/autofill/core/browser/country_names.h"
30 #include "components/autofill/core/browser/field_types.h"
31 #include "components/autofill/core/browser/personal_data_manager.h"
32 #include "components/autofill/core/browser/webdata/autocomplete_syncable_service .h"
33 #include "components/autofill/core/browser/webdata/autofill_change.h"
34 #include "components/autofill/core/browser/webdata/autofill_data_type_controller .h"
35 #include "components/autofill/core/browser/webdata/autofill_entry.h"
36 #include "components/autofill/core/browser/webdata/autofill_profile_data_type_co ntroller.h"
37 #include "components/autofill/core/browser/webdata/autofill_profile_syncable_ser vice.h"
38 #include "components/autofill/core/browser/webdata/autofill_table.h"
39 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
40 #include "components/autofill/core/common/autofill_pref_names.h"
41 #include "components/browser_sync/browser/abstract_profile_sync_service_test.h"
42 #include "components/browser_sync/browser/profile_sync_service.h"
43 #include "components/browser_sync/browser/test_profile_sync_service.h"
44 #include "components/sync/base/model_type.h"
45 #include "components/sync/core/data_type_debug_info_listener.h"
46 #include "components/sync/core/read_node.h"
47 #include "components/sync/core/read_transaction.h"
48 #include "components/sync/core/write_node.h"
49 #include "components/sync/core/write_transaction.h"
50 #include "components/sync/driver/data_type_controller.h"
51 #include "components/sync/driver/data_type_manager_impl.h"
52 #include "components/sync/driver/sync_api_component_factory_mock.h"
53 #include "components/sync/protocol/autofill_specifics.pb.h"
54 #include "components/sync/syncable/mutable_entry.h"
55 #include "components/sync/syncable/syncable_write_transaction.h"
56 #include "components/syncable_prefs/pref_service_syncable.h"
57 #include "components/version_info/version_info.h"
58 #include "components/webdata/common/web_database.h"
59 #include "components/webdata_services/web_data_service_test_util.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "testing/gtest/include/gtest/gtest.h"
62
63 using autofill::AutocompleteSyncableService;
64 using autofill::AutofillChange;
65 using autofill::AutofillChangeList;
66 using autofill::AutofillEntry;
67 using autofill::AutofillKey;
68 using autofill::AutofillProfile;
69 using autofill::AutofillProfileChange;
70 using autofill::AutofillProfileSyncableService;
71 using autofill::AutofillTable;
72 using autofill::AutofillWebDataService;
73 using autofill::NAME_FULL;
74 using autofill::PersonalDataManager;
75 using autofill::ServerFieldType;
76 using base::ASCIIToUTF16;
77 using base::Time;
78 using base::TimeDelta;
79 using base::WaitableEvent;
80 using browser_sync::AutofillDataTypeController;
81 using browser_sync::AutofillProfileDataTypeController;
82 using syncer::AUTOFILL;
83 using syncer::AUTOFILL_PROFILE;
84 using syncer::BaseNode;
85 using syncer::syncable::CREATE;
86 using syncer::syncable::GET_TYPE_ROOT;
87 using syncer::syncable::MutableEntry;
88 using syncer::syncable::UNITTEST;
89 using syncer::syncable::WriterTag;
90 using syncer::syncable::WriteTransaction;
91 using testing::_;
92 using testing::DoAll;
93 using testing::ElementsAre;
94 using testing::Not;
95 using testing::SetArgumentPointee;
96 using testing::Return;
97
98 namespace {
99
100 void RegisterAutofillPrefs(user_prefs::PrefRegistrySyncable* registry) {
101 registry->RegisterBooleanPref(autofill::prefs::kAutofillEnabled, true);
102 registry->RegisterBooleanPref(autofill::prefs::kAutofillWalletImportEnabled,
103 true);
104 registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileUseDatesFixed,
105 true);
106 registry->RegisterIntegerPref(autofill::prefs::kAutofillLastVersionDeduped,
107 atoi(version_info::GetVersionNumber().c_str()));
108 }
109
110 void RunAndSignal(const base::Closure& cb, WaitableEvent* event) {
111 cb.Run();
112 event->Signal();
113 }
114
115 AutofillEntry MakeAutofillEntry(const char* name,
116 const char* value,
117 int time_shift0,
118 int time_shift1) {
119 // Time deep in the past would cause Autocomplete sync to discard the
120 // entries.
121 static Time base_time = Time::Now().LocalMidnight();
122
123 Time date_created = base_time + TimeDelta::FromSeconds(time_shift0);
124 Time date_last_used = date_created;
125 if (time_shift1 >= 0)
126 date_last_used = base_time + TimeDelta::FromSeconds(time_shift1);
127 return AutofillEntry(AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)),
128 date_created, date_last_used);
129 }
130
131 AutofillEntry MakeAutofillEntry(const char* name,
132 const char* value,
133 int time_shift) {
134 return MakeAutofillEntry(name, value, time_shift, -1);
135 }
136
137 } // namespace
138
139 class AutofillTableMock : public AutofillTable {
140 public:
141 AutofillTableMock() {}
142 MOCK_METHOD2(RemoveFormElement,
143 bool(const base::string16& name,
144 const base::string16& value)); // NOLINT
145 MOCK_METHOD1(GetAllAutofillEntries,
146 bool(std::vector<AutofillEntry>* entries)); // NOLINT
147 MOCK_METHOD4(GetAutofillTimestamps,
148 bool(const base::string16& name, // NOLINT
149 const base::string16& value,
150 Time* date_created,
151 Time* date_last_used));
152 MOCK_METHOD1(UpdateAutofillEntries,
153 bool(const std::vector<AutofillEntry>&)); // NOLINT
154 MOCK_METHOD1(GetAutofillProfiles,
155 bool(std::vector<AutofillProfile*>*)); // NOLINT
156 MOCK_METHOD1(UpdateAutofillProfile,
157 bool(const AutofillProfile&)); // NOLINT
158 MOCK_METHOD1(AddAutofillProfile,
159 bool(const AutofillProfile&)); // NOLINT
160 MOCK_METHOD1(RemoveAutofillProfile,
161 bool(const std::string&)); // NOLINT
162 };
163
164 MATCHER_P(MatchProfiles, profile, "") {
165 return (profile.Compare(arg) == 0);
166 }
167
168 class WebDatabaseFake : public WebDatabase {
169 public:
170 explicit WebDatabaseFake(AutofillTable* autofill_table) {
171 AddTable(autofill_table);
172 }
173 };
174
175 class MockAutofillBackend : public autofill::AutofillWebDataBackend {
176 public:
177 MockAutofillBackend(
178 WebDatabase* web_database,
179 const base::Closure& on_changed,
180 const base::Callback<void(syncer::ModelType)>& on_sync_started,
181 const scoped_refptr<base::SequencedTaskRunner>& ui_thread)
182 : web_database_(web_database),
183 on_changed_(on_changed),
184 on_sync_started_(on_sync_started),
185 ui_thread_(ui_thread) {}
186
187 ~MockAutofillBackend() override {}
188 WebDatabase* GetDatabase() override { return web_database_; }
189 void AddObserver(
190 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {}
191 void RemoveObserver(
192 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {}
193 void RemoveExpiredFormElements() override {}
194 void NotifyOfMultipleAutofillChanges() override {
195 DCHECK(!ui_thread_->RunsTasksOnCurrentThread());
196 ui_thread_->PostTask(FROM_HERE, on_changed_);
197 }
198 void NotifyThatSyncHasStarted(syncer::ModelType model_type) override {
199 DCHECK(!ui_thread_->RunsTasksOnCurrentThread());
200 ui_thread_->PostTask(FROM_HERE, base::Bind(on_sync_started_, model_type));
201 }
202
203 private:
204 WebDatabase* web_database_;
205 base::Closure on_changed_;
206 base::Callback<void(syncer::ModelType)> on_sync_started_;
207 const scoped_refptr<base::SequencedTaskRunner> ui_thread_;
208 };
209
210 class ProfileSyncServiceAutofillTest;
211
212 template<class AutofillProfile>
213 syncer::ModelType GetModelType() {
214 return syncer::UNSPECIFIED;
215 }
216
217 template<>
218 syncer::ModelType GetModelType<AutofillEntry>() {
219 return AUTOFILL;
220 }
221
222 template<>
223 syncer::ModelType GetModelType<AutofillProfile>() {
224 return AUTOFILL_PROFILE;
225 }
226
227 class TokenWebDataServiceFake : public TokenWebData {
228 public:
229 TokenWebDataServiceFake(
230 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
231 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread)
232 : TokenWebData(ui_thread, db_thread) {}
233
234 bool IsDatabaseLoaded() override { return true; }
235
236 AutofillWebDataService::Handle GetAllTokens(
237 WebDataServiceConsumer* consumer) override {
238 // TODO(tim): It would be nice if WebDataService was injected on
239 // construction of ProfileOAuth2TokenService rather than fetched by
240 // Initialize so that this isn't necessary (we could pass a NULL service).
241 // We currently do return it via EXPECT_CALLs, but without depending on
242 // order-of-initialization (which seems way more fragile) we can't tell
243 // which component is asking at what time, and some components in these
244 // Autofill tests require a WebDataService.
245 return 0;
246 }
247
248 private:
249 ~TokenWebDataServiceFake() override {}
250
251 DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake);
252 };
253
254 class WebDataServiceFake : public AutofillWebDataService {
255 public:
256 WebDataServiceFake(
257 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
258 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread)
259 : AutofillWebDataService(ui_thread, db_thread),
260 web_database_(NULL),
261 autocomplete_syncable_service_(NULL),
262 autofill_profile_syncable_service_(NULL),
263 syncable_service_created_or_destroyed_(
264 base::WaitableEvent::ResetPolicy::AUTOMATIC,
265 base::WaitableEvent::InitialState::NOT_SIGNALED),
266 db_thread_(db_thread),
267 ui_thread_(ui_thread) {}
268
269 void SetDatabase(WebDatabase* web_database) {
270 web_database_ = web_database;
271 }
272
273 void StartSyncableService() {
274 // The |autofill_profile_syncable_service_| must be constructed on the DB
275 // thread.
276 const base::Closure& on_changed_callback = base::Bind(
277 &WebDataServiceFake::NotifyAutofillMultipleChangedOnUIThread,
278 AsWeakPtr());
279 const base::Callback<void(syncer::ModelType)> on_sync_started_callback =
280 base::Bind(&WebDataServiceFake::NotifySyncStartedOnUIThread,
281 AsWeakPtr());
282
283 db_thread_->PostTask(FROM_HERE,
284 base::Bind(&WebDataServiceFake::CreateSyncableService,
285 base::Unretained(this), on_changed_callback,
286 on_sync_started_callback));
287 syncable_service_created_or_destroyed_.Wait();
288 }
289
290 void ShutdownSyncableService() {
291 // The |autofill_profile_syncable_service_| must be destructed on the DB
292 // thread.
293 db_thread_->PostTask(FROM_HERE,
294 base::Bind(&WebDataServiceFake::DestroySyncableService,
295 base::Unretained(this)));
296 syncable_service_created_or_destroyed_.Wait();
297 }
298
299 bool IsDatabaseLoaded() override { return true; }
300
301 WebDatabase* GetDatabase() override { return web_database_; }
302
303 void OnAutofillEntriesChanged(const AutofillChangeList& changes) {
304 WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
305 base::WaitableEvent::InitialState::NOT_SIGNALED);
306
307 base::Closure notify_cb =
308 base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged,
309 base::Unretained(autocomplete_syncable_service_),
310 changes);
311 db_thread_->PostTask(FROM_HERE,
312 base::Bind(&RunAndSignal, notify_cb, &event));
313 event.Wait();
314 }
315
316 void OnAutofillProfileChanged(const AutofillProfileChange& changes) {
317 WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
318 base::WaitableEvent::InitialState::NOT_SIGNALED);
319
320 base::Closure notify_cb =
321 base::Bind(&AutocompleteSyncableService::AutofillProfileChanged,
322 base::Unretained(autofill_profile_syncable_service_),
323 changes);
324 db_thread_->PostTask(FROM_HERE,
325 base::Bind(&RunAndSignal, notify_cb, &event));
326 event.Wait();
327 }
328
329 private:
330 ~WebDataServiceFake() override {}
331
332 void CreateSyncableService(
333 const base::Closure& on_changed_callback,
334 const base::Callback<void(syncer::ModelType)>& on_sync_started) {
335 ASSERT_TRUE(db_thread_->RunsTasksOnCurrentThread());
336 // These services are deleted in DestroySyncableService().
337 backend_.reset(new MockAutofillBackend(GetDatabase(), on_changed_callback,
338 on_sync_started, ui_thread_.get()));
339 AutocompleteSyncableService::CreateForWebDataServiceAndBackend(
340 this, backend_.get());
341 AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
342 this, backend_.get(), "en-US");
343
344 autocomplete_syncable_service_ =
345 AutocompleteSyncableService::FromWebDataService(this);
346 autofill_profile_syncable_service_ =
347 AutofillProfileSyncableService::FromWebDataService(this);
348
349 syncable_service_created_or_destroyed_.Signal();
350 }
351
352 void DestroySyncableService() {
353 ASSERT_TRUE(db_thread_->RunsTasksOnCurrentThread());
354 autocomplete_syncable_service_ = NULL;
355 autofill_profile_syncable_service_ = NULL;
356 backend_.reset();
357 syncable_service_created_or_destroyed_.Signal();
358 }
359
360 WebDatabase* web_database_;
361 AutocompleteSyncableService* autocomplete_syncable_service_;
362 AutofillProfileSyncableService* autofill_profile_syncable_service_;
363 std::unique_ptr<autofill::AutofillWebDataBackend> backend_;
364
365 WaitableEvent syncable_service_created_or_destroyed_;
366
367 const scoped_refptr<base::SingleThreadTaskRunner> db_thread_;
368 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
369
370 DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake);
371 };
372
373 ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) {
374 return new sync_driver::DataTypeManagerImpl(
375 debug_listener,
376 arg1,
377 arg2,
378 arg3,
379 arg4);
380 }
381
382 class MockPersonalDataManager : public PersonalDataManager {
383 public:
384 MockPersonalDataManager() : PersonalDataManager("en-US") {}
385 MOCK_CONST_METHOD0(IsDataLoaded, bool());
386 MOCK_METHOD0(LoadProfiles, void());
387 MOCK_METHOD0(LoadCreditCards, void());
388 MOCK_METHOD0(Refresh, void());
389 };
390
391 template <class T> class AddAutofillHelper;
392
393 class ProfileSyncServiceAutofillTest
394 : public AbstractProfileSyncServiceTest,
395 public syncer::DataTypeDebugInfoListener {
396 public:
397 // DataTypeDebugInfoListener implementation.
398 void OnDataTypeConfigureComplete(const std::vector<
399 syncer::DataTypeConfigurationStats>& configuration_stats) override {
400 ASSERT_EQ(1u, configuration_stats.size());
401 association_stats_ = configuration_stats[0].association_stats;
402 }
403
404 protected:
405 ProfileSyncServiceAutofillTest() : debug_ptr_factory_(this) {
406 autofill::CountryNames::SetLocaleString("en-US");
407 RegisterAutofillPrefs(
408 profile_sync_service_bundle()->pref_service()->registry());
409
410 data_type_thread()->Start();
411 profile_sync_service_bundle()->set_db_thread(
412 data_type_thread()->task_runner());
413
414 web_database_.reset(new WebDatabaseFake(&autofill_table_));
415 web_data_wrapper_ = base::MakeUnique<MockWebDataServiceWrapper>(
416 new WebDataServiceFake(base::ThreadTaskRunnerHandle::Get(),
417 data_type_thread()->task_runner()),
418 new TokenWebDataServiceFake(base::ThreadTaskRunnerHandle::Get(),
419 data_type_thread()->task_runner()));
420 web_data_service_ = static_cast<WebDataServiceFake*>(
421 web_data_wrapper_->GetAutofillWebData().get());
422 web_data_service_->SetDatabase(web_database_.get());
423
424 personal_data_manager_ = base::MakeUnique<MockPersonalDataManager>();
425
426 EXPECT_CALL(personal_data_manager(), LoadProfiles());
427 EXPECT_CALL(personal_data_manager(), LoadCreditCards());
428
429 personal_data_manager_->Init(
430 web_data_service_, profile_sync_service_bundle()->pref_service(),
431 profile_sync_service_bundle()->account_tracker(),
432 profile_sync_service_bundle()->signin_manager(), false);
433
434 web_data_service_->StartSyncableService();
435
436 browser_sync::ProfileSyncServiceBundle::SyncClientBuilder builder(
437 profile_sync_service_bundle());
438 builder.SetPersonalDataManager(personal_data_manager_.get());
439 builder.SetSyncServiceCallback(GetSyncServiceCallback());
440 builder.SetSyncableServiceCallback(
441 base::Bind(&ProfileSyncServiceAutofillTest::GetSyncableServiceForType,
442 base::Unretained(this)));
443 builder.set_activate_model_creation();
444 sync_client_owned_ = builder.Build();
445 sync_client_ = sync_client_owned_.get();
446
447 // When UpdateAutofillEntries() is called with an empty list, the return
448 // value should be |true|, rather than the default of |false|.
449 std::vector<AutofillEntry> empty;
450 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(empty))
451 .WillRepeatedly(Return(true));
452 }
453
454 ~ProfileSyncServiceAutofillTest() override {
455 web_data_service_->ShutdownOnUIThread();
456 web_data_service_->ShutdownSyncableService();
457 web_data_wrapper_->Shutdown();
458 web_data_service_ = nullptr;
459 web_data_wrapper_.reset();
460 web_database_.reset();
461 // Shut down the service explicitly before some data members from this
462 // test it needs will be deleted.
463 sync_service()->Shutdown();
464 }
465
466 int GetSyncCount(syncer::ModelType type) {
467 syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare());
468 syncer::ReadNode node(&trans);
469 if (node.InitTypeRoot(type) != BaseNode::INIT_OK)
470 return 0;
471 return node.GetTotalNodeCount() - 1;
472 }
473
474 void StartSyncService(const base::Closure& callback,
475 bool will_fail_association,
476 syncer::ModelType type) {
477 SigninManagerBase* signin = profile_sync_service_bundle()->signin_manager();
478 signin->SetAuthenticatedAccountInfo("12345", "test_user@gmail.com");
479 CreateSyncService(std::move(sync_client_owned_), callback);
480
481 EXPECT_CALL(*profile_sync_service_bundle()->component_factory(),
482 CreateDataTypeManager(_, _, _, _, _))
483 .WillOnce(ReturnNewDataTypeManagerWithDebugListener(
484 syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr())));
485
486 EXPECT_CALL(personal_data_manager(), IsDataLoaded())
487 .WillRepeatedly(Return(true));
488
489 // We need tokens to get the tests going
490 profile_sync_service_bundle()->auth_service()->UpdateCredentials(
491 signin->GetAuthenticatedAccountId(), "oauth2_login_token");
492
493 sync_service()->RegisterDataTypeController(CreateDataTypeController(type));
494 sync_service()->Initialize();
495 base::RunLoop().Run();
496
497 // It's possible this test triggered an unrecoverable error, in which case
498 // we can't get the sync count.
499 if (sync_service()->IsSyncActive()) {
500 EXPECT_EQ(GetSyncCount(type),
501 association_stats_.num_sync_items_after_association);
502 }
503 EXPECT_EQ(association_stats_.num_sync_items_after_association,
504 association_stats_.num_sync_items_before_association +
505 association_stats_.num_sync_items_added -
506 association_stats_.num_sync_items_deleted);
507 }
508
509 bool AddAutofillSyncNode(const AutofillEntry& entry) {
510 syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare());
511 syncer::WriteNode node(&trans);
512 std::string tag = AutocompleteSyncableService::KeyToTag(
513 base::UTF16ToUTF8(entry.key().name()),
514 base::UTF16ToUTF8(entry.key().value()));
515 syncer::WriteNode::InitUniqueByCreationResult result =
516 node.InitUniqueByCreation(AUTOFILL, tag);
517 if (result != syncer::WriteNode::INIT_SUCCESS)
518 return false;
519
520 sync_pb::EntitySpecifics specifics;
521 AutocompleteSyncableService::WriteAutofillEntry(entry, &specifics);
522 node.SetEntitySpecifics(specifics);
523 return true;
524 }
525
526 bool AddAutofillSyncNode(const AutofillProfile& profile) {
527 syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare());
528 syncer::WriteNode node(&trans);
529 std::string tag = profile.guid();
530 syncer::WriteNode::InitUniqueByCreationResult result =
531 node.InitUniqueByCreation(AUTOFILL_PROFILE, tag);
532 if (result != syncer::WriteNode::INIT_SUCCESS)
533 return false;
534
535 sync_pb::EntitySpecifics specifics;
536 AutofillProfileSyncableService::WriteAutofillProfile(profile, &specifics);
537 node.SetEntitySpecifics(specifics);
538 return true;
539 }
540
541 bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries,
542 std::vector<AutofillProfile>* profiles) {
543 syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare());
544 syncer::ReadNode autofill_root(&trans);
545 if (autofill_root.InitTypeRoot(AUTOFILL) != BaseNode::INIT_OK) {
546 return false;
547 }
548
549 int64_t child_id = autofill_root.GetFirstChildId();
550 while (child_id != syncer::kInvalidId) {
551 syncer::ReadNode child_node(&trans);
552 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK)
553 return false;
554
555 const sync_pb::AutofillSpecifics& autofill(
556 child_node.GetEntitySpecifics().autofill());
557 if (autofill.has_value()) {
558 AutofillKey key(base::UTF8ToUTF16(autofill.name()),
559 base::UTF8ToUTF16(autofill.value()));
560 std::vector<Time> timestamps;
561 int timestamps_count = autofill.usage_timestamp_size();
562 for (int i = 0; i < timestamps_count; ++i) {
563 timestamps.push_back(Time::FromInternalValue(
564 autofill.usage_timestamp(i)));
565 }
566 entries->push_back(
567 AutofillEntry(key, timestamps.front(), timestamps.back()));
568 } else if (autofill.has_profile()) {
569 AutofillProfile p;
570 p.set_guid(autofill.profile().guid());
571 AutofillProfileSyncableService::OverwriteProfileWithServerData(
572 autofill.profile(), &p);
573 profiles->push_back(p);
574 }
575 child_id = child_node.GetSuccessorId();
576 }
577 return true;
578 }
579
580 bool GetAutofillProfilesFromSyncDBUnderProfileNode(
581 std::vector<AutofillProfile>* profiles) {
582 syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare());
583 syncer::ReadNode autofill_root(&trans);
584 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) {
585 return false;
586 }
587
588 int64_t child_id = autofill_root.GetFirstChildId();
589 while (child_id != syncer::kInvalidId) {
590 syncer::ReadNode child_node(&trans);
591 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK)
592 return false;
593
594 const sync_pb::AutofillProfileSpecifics& autofill(
595 child_node.GetEntitySpecifics().autofill_profile());
596 AutofillProfile p;
597 p.set_guid(autofill.guid());
598 AutofillProfileSyncableService::OverwriteProfileWithServerData(autofill,
599 &p);
600 profiles->push_back(p);
601 child_id = child_node.GetSuccessorId();
602 }
603 return true;
604 }
605
606 void SetIdleChangeProcessorExpectations() {
607 EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0);
608 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0);
609
610 // Only permit UpdateAutofillEntries() to be called with an empty list.
611 std::vector<AutofillEntry> empty;
612 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(Not(empty))).Times(0);
613 }
614
615 std::unique_ptr<sync_driver::DataTypeController> CreateDataTypeController(
616 syncer::ModelType type) {
617 DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE);
618 if (type == AUTOFILL) {
619 return base::MakeUnique<AutofillDataTypeController>(
620 data_type_thread()->task_runner(), base::Bind(&base::DoNothing),
621 sync_client_, web_data_service_);
622 } else {
623 return base::MakeUnique<AutofillProfileDataTypeController>(
624 data_type_thread()->task_runner(), base::Bind(&base::DoNothing),
625 sync_client_, web_data_service_);
626 }
627 }
628
629 AutofillTableMock& autofill_table() { return autofill_table_; }
630
631 MockPersonalDataManager& personal_data_manager() {
632 return *personal_data_manager_;
633 }
634
635 WebDataServiceFake* web_data_service() { return web_data_service_.get(); }
636
637 private:
638 friend class AddAutofillHelper<AutofillEntry>;
639 friend class AddAutofillHelper<AutofillProfile>;
640
641 base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
642 syncer::ModelType type) {
643 DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE);
644 if (type == AUTOFILL) {
645 return AutocompleteSyncableService::FromWebDataService(
646 web_data_service_.get())
647 ->AsWeakPtr();
648 } else {
649 return AutofillProfileSyncableService::FromWebDataService(
650 web_data_service_.get())
651 ->AsWeakPtr();
652 }
653 }
654
655 AutofillTableMock autofill_table_;
656 std::unique_ptr<WebDatabaseFake> web_database_;
657 std::unique_ptr<MockWebDataServiceWrapper> web_data_wrapper_;
658 scoped_refptr<WebDataServiceFake> web_data_service_;
659 std::unique_ptr<MockPersonalDataManager> personal_data_manager_;
660 syncer::DataTypeAssociationStats association_stats_;
661 base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_;
662 // |sync_client_owned_| keeps the created client until it is passed to the
663 // created ProfileSyncService. |sync_client_| just keeps a weak reference to
664 // the client the whole time.
665 std::unique_ptr<sync_driver::FakeSyncClient> sync_client_owned_;
666 sync_driver::FakeSyncClient* sync_client_;
667
668 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceAutofillTest);
669 };
670
671 template <class T>
672 class AddAutofillHelper {
673 public:
674 AddAutofillHelper(ProfileSyncServiceAutofillTest* test,
675 const std::vector<T>& entries)
676 : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback,
677 base::Unretained(this), test, entries)),
678 success_(false) {
679 }
680
681 const base::Closure& callback() const { return callback_; }
682 bool success() { return success_; }
683
684 private:
685 void AddAutofillCallback(ProfileSyncServiceAutofillTest* test,
686 const std::vector<T>& entries) {
687 if (!test->CreateRoot(GetModelType<T>()))
688 return;
689
690 for (size_t i = 0; i < entries.size(); ++i) {
691 if (!test->AddAutofillSyncNode(entries[i]))
692 return;
693 }
694 success_ = true;
695 }
696
697 base::Closure callback_;
698 bool success_;
699 };
700
701 // Overload write transaction to use custom NotifyTransactionComplete
702 class WriteTransactionTest: public WriteTransaction {
703 public:
704 WriteTransactionTest(const tracked_objects::Location& from_here,
705 WriterTag writer,
706 syncer::syncable::Directory* directory,
707 WaitableEvent* wait_for_syncapi)
708 : WriteTransaction(from_here, writer, directory),
709 wait_for_syncapi_(wait_for_syncapi) {}
710
711 void NotifyTransactionComplete(syncer::ModelTypeSet types) override {
712 // This is where we differ. Force a thread change here, giving another
713 // thread a chance to create a WriteTransaction
714 wait_for_syncapi_->Wait();
715
716 WriteTransaction::NotifyTransactionComplete(types);
717 }
718
719 private:
720 WaitableEvent* const wait_for_syncapi_;
721 };
722
723 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
724 // post tasks with it.
725 class FakeServerUpdater : public base::RefCountedThreadSafe<FakeServerUpdater> {
726 public:
727 FakeServerUpdater(TestProfileSyncService* service,
728 WaitableEvent* wait_for_start,
729 WaitableEvent* wait_for_syncapi,
730 scoped_refptr<base::SequencedTaskRunner> db_thread)
731 : entry_(MakeAutofillEntry("0", "0", 0)),
732 service_(service),
733 wait_for_start_(wait_for_start),
734 wait_for_syncapi_(wait_for_syncapi),
735 is_finished_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
736 base::WaitableEvent::InitialState::NOT_SIGNALED),
737 db_thread_(db_thread) {}
738
739 void Update() {
740 // This gets called in a modelsafeworker thread.
741 ASSERT_TRUE(db_thread_->RunsTasksOnCurrentThread());
742
743 syncer::UserShare* user_share = service_->GetUserShare();
744 syncer::syncable::Directory* directory = user_share->directory.get();
745
746 // Create autofill protobuf.
747 std::string tag = AutocompleteSyncableService::KeyToTag(
748 base::UTF16ToUTF8(entry_.key().name()),
749 base::UTF16ToUTF8(entry_.key().value()));
750 sync_pb::AutofillSpecifics new_autofill;
751 new_autofill.set_name(base::UTF16ToUTF8(entry_.key().name()));
752 new_autofill.set_value(base::UTF16ToUTF8(entry_.key().value()));
753 new_autofill.add_usage_timestamp(entry_.date_created().ToInternalValue());
754 if (entry_.date_created() != entry_.date_last_used()) {
755 new_autofill.add_usage_timestamp(
756 entry_.date_last_used().ToInternalValue());
757 }
758
759 sync_pb::EntitySpecifics entity_specifics;
760 entity_specifics.mutable_autofill()->CopyFrom(new_autofill);
761
762 {
763 // Tell main thread we've started
764 wait_for_start_->Signal();
765
766 // Create write transaction.
767 WriteTransactionTest trans(FROM_HERE, UNITTEST, directory,
768 wait_for_syncapi_);
769
770 // Create actual entry based on autofill protobuf information.
771 // Simulates effects of UpdateLocalDataFromServerData
772 MutableEntry parent(&trans, GET_TYPE_ROOT, AUTOFILL);
773 MutableEntry item(&trans, CREATE, AUTOFILL, parent.GetId(), tag);
774 ASSERT_TRUE(item.good());
775 item.PutSpecifics(entity_specifics);
776 item.PutServerSpecifics(entity_specifics);
777 item.PutBaseVersion(1);
778 syncer::syncable::Id server_item_id =
779 service_->id_factory()->NewServerId();
780 item.PutId(server_item_id);
781 syncer::syncable::Id new_predecessor;
782 ASSERT_TRUE(item.PutPredecessor(new_predecessor));
783 }
784 DVLOG(1) << "FakeServerUpdater finishing.";
785 is_finished_.Signal();
786 }
787
788 void CreateNewEntry(const AutofillEntry& entry) {
789 entry_ = entry;
790 ASSERT_FALSE(db_thread_->RunsTasksOnCurrentThread());
791 if (!db_thread_->PostTask(FROM_HERE,
792 base::Bind(&FakeServerUpdater::Update, this))) {
793 NOTREACHED() << "Failed to post task to the db thread.";
794 return;
795 }
796 }
797
798 void WaitForUpdateCompletion() {
799 is_finished_.Wait();
800 }
801
802 private:
803 friend class base::RefCountedThreadSafe<FakeServerUpdater>;
804 ~FakeServerUpdater() { }
805
806 AutofillEntry entry_;
807 TestProfileSyncService* service_;
808 WaitableEvent* const wait_for_start_;
809 WaitableEvent* const wait_for_syncapi_;
810 WaitableEvent is_finished_;
811 syncer::syncable::Id parent_id_;
812 scoped_refptr<base::SequencedTaskRunner> db_thread_;
813
814 DISALLOW_COPY_AND_ASSIGN(FakeServerUpdater);
815 };
816
817 // TODO(skrul): Test abort startup.
818 // TODO(skrul): Test processing of cloud changes.
819 // TODO(tim): Add autofill data type controller test, and a case to cover
820 // waiting for the PersonalDataManager.
821 TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) {
822 // Don't create the root autofill node so startup fails.
823 StartSyncService(base::Closure(), true, AUTOFILL);
824 EXPECT_TRUE(sync_service()->HasUnrecoverableError());
825 }
826
827 TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) {
828 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
829 .WillOnce(Return(true));
830 SetIdleChangeProcessorExpectations();
831 CreateRootHelper create_root(this, AUTOFILL);
832 EXPECT_CALL(personal_data_manager(), Refresh());
833 StartSyncService(create_root.callback(), false, AUTOFILL);
834 EXPECT_TRUE(create_root.success());
835 std::vector<AutofillEntry> sync_entries;
836 std::vector<AutofillProfile> sync_profiles;
837 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
838 EXPECT_EQ(0U, sync_entries.size());
839 EXPECT_EQ(0U, sync_profiles.size());
840 }
841
842 TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) {
843 std::vector<AutofillEntry> entries;
844 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
845 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
846 .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
847 SetIdleChangeProcessorExpectations();
848 CreateRootHelper create_root(this, AUTOFILL);
849 EXPECT_CALL(personal_data_manager(), Refresh());
850 StartSyncService(create_root.callback(), false, AUTOFILL);
851 ASSERT_TRUE(create_root.success());
852 std::vector<AutofillEntry> sync_entries;
853 std::vector<AutofillProfile> sync_profiles;
854 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
855 ASSERT_EQ(1U, entries.size());
856 EXPECT_TRUE(entries[0] == sync_entries[0]);
857 EXPECT_EQ(0U, sync_profiles.size());
858 }
859
860 TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) {
861 std::vector<AutofillProfile*> profiles;
862 std::vector<AutofillProfile> expected_profiles;
863 // Owned by GetAutofillProfiles caller.
864 AutofillProfile* profile0 = new AutofillProfile;
865 autofill::test::SetProfileInfoWithGuid(profile0,
866 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
867 "Mitchell", "Morrison",
868 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
869 "91601", "US", "12345678910");
870 profiles.push_back(profile0);
871 expected_profiles.push_back(*profile0);
872 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
873 .WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true)));
874 EXPECT_CALL(personal_data_manager(), Refresh());
875 SetIdleChangeProcessorExpectations();
876 CreateRootHelper create_root(this, AUTOFILL_PROFILE);
877 StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE);
878 ASSERT_TRUE(create_root.success());
879 std::vector<AutofillProfile> sync_profiles;
880 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles));
881 EXPECT_EQ(1U, sync_profiles.size());
882 EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0]));
883 }
884
885 TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
886 // There is buggy autofill code that allows duplicate name/value
887 // pairs to exist in the database with separate pair_ids.
888 std::vector<AutofillEntry> entries;
889 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
890 entries.push_back(MakeAutofillEntry("dup", "", 2));
891 entries.push_back(MakeAutofillEntry("dup", "", 3));
892 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
893 .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
894 SetIdleChangeProcessorExpectations();
895 CreateRootHelper create_root(this, AUTOFILL);
896 EXPECT_CALL(personal_data_manager(), Refresh());
897 StartSyncService(create_root.callback(), false, AUTOFILL);
898 ASSERT_TRUE(create_root.success());
899 std::vector<AutofillEntry> sync_entries;
900 std::vector<AutofillProfile> sync_profiles;
901 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
902 EXPECT_EQ(2U, sync_entries.size());
903 }
904
905 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) {
906 AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1));
907 AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2));
908
909 std::vector<AutofillEntry> native_entries;
910 native_entries.push_back(native_entry);
911
912 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
913 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
914
915 std::vector<AutofillEntry> sync_entries;
916 sync_entries.push_back(sync_entry);
917
918 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries);
919
920 EXPECT_CALL(autofill_table(), UpdateAutofillEntries(ElementsAre(sync_entry)))
921 .WillOnce(Return(true));
922
923 EXPECT_CALL(personal_data_manager(), Refresh());
924 StartSyncService(add_autofill.callback(), false, AUTOFILL);
925 ASSERT_TRUE(add_autofill.success());
926
927 std::set<AutofillEntry> expected_entries;
928 expected_entries.insert(native_entry);
929 expected_entries.insert(sync_entry);
930
931 std::vector<AutofillEntry> new_sync_entries;
932 std::vector<AutofillProfile> new_sync_profiles;
933 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
934 &new_sync_profiles));
935 std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(),
936 new_sync_entries.end());
937
938 EXPECT_TRUE(expected_entries == new_sync_entries_set);
939 }
940
941 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) {
942 AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1));
943 AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2));
944 AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
945
946 std::vector<AutofillEntry> native_entries;
947 native_entries.push_back(native_entry);
948 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
949 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
950
951 std::vector<AutofillEntry> sync_entries;
952 sync_entries.push_back(sync_entry);
953 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries);
954
955 EXPECT_CALL(autofill_table(),
956 UpdateAutofillEntries(ElementsAre(merged_entry)))
957 .WillOnce(Return(true));
958 EXPECT_CALL(personal_data_manager(), Refresh());
959 StartSyncService(add_autofill.callback(), false, AUTOFILL);
960 ASSERT_TRUE(add_autofill.success());
961
962 std::vector<AutofillEntry> new_sync_entries;
963 std::vector<AutofillProfile> new_sync_profiles;
964 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
965 &new_sync_profiles));
966 ASSERT_EQ(1U, new_sync_entries.size());
967 EXPECT_TRUE(merged_entry == new_sync_entries[0]);
968 }
969
970 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) {
971 AutofillProfile sync_profile;
972 autofill::test::SetProfileInfoWithGuid(&sync_profile,
973 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
974 "Mitchell", "Morrison",
975 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
976 "91601", "US", "12345678910");
977
978 AutofillProfile* native_profile = new AutofillProfile;
979 autofill::test::SetProfileInfoWithGuid(native_profile,
980 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
981 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
982 "32801", "US", "19482937549");
983
984 std::vector<AutofillProfile*> native_profiles;
985 native_profiles.push_back(native_profile);
986 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
987 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
988
989 std::vector<AutofillProfile> sync_profiles;
990 sync_profiles.push_back(sync_profile);
991 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
992
993 EXPECT_CALL(autofill_table(),
994 UpdateAutofillProfile(MatchProfiles(sync_profile)))
995 .WillOnce(Return(true));
996 EXPECT_CALL(personal_data_manager(), Refresh());
997 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE);
998 ASSERT_TRUE(add_autofill.success());
999
1000 std::vector<AutofillProfile> new_sync_profiles;
1001 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1002 &new_sync_profiles));
1003 ASSERT_EQ(1U, new_sync_profiles.size());
1004 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
1005 }
1006
1007 // Tests that a sync with a new native profile that matches a more recent new
1008 // sync profile but with less information results in the native profile being
1009 // deleted and replaced by the sync profile with merged usage stats.
1010 TEST_F(
1011 ProfileSyncServiceAutofillTest,
1012 HasNativeHasSyncMergeSimilarProfileCombine_SyncHasMoreInfoAndMoreRecent) {
1013 // Create two almost identical profiles. The GUIDs are different and the
1014 // native profile has no value for company name.
1015 AutofillProfile sync_profile;
1016 autofill::test::SetProfileInfoWithGuid(
1017 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1018 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
1019 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
1020 sync_profile.set_use_date(base::Time::FromTimeT(4321));
1021
1022 AutofillProfile* native_profile = new AutofillProfile;
1023 autofill::test::SetProfileInfoWithGuid(
1024 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing",
1025 "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5",
1026 "Hollywood", "CA", "91601", "US", "12345678910");
1027 native_profile->set_use_date(base::Time::FromTimeT(1234));
1028
1029 AutofillProfile expected_profile(sync_profile);
1030 expected_profile.SetRawInfo(NAME_FULL,
1031 ASCIIToUTF16("Billing Mitchell Morrison"));
1032 expected_profile.set_use_count(1);
1033
1034 std::vector<AutofillProfile*> native_profiles;
1035 native_profiles.push_back(native_profile);
1036 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
1037 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1038 EXPECT_CALL(autofill_table(),
1039 AddAutofillProfile(MatchProfiles(expected_profile)))
1040 .WillOnce(Return(true));
1041 EXPECT_CALL(autofill_table(),
1042 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF"))
1043 .WillOnce(Return(true));
1044 std::vector<AutofillProfile> sync_profiles;
1045 sync_profiles.push_back(sync_profile);
1046 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1047
1048 EXPECT_CALL(personal_data_manager(), Refresh());
1049 // Adds all entries in |sync_profiles| to sync.
1050 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE);
1051 ASSERT_TRUE(add_autofill.success());
1052
1053 std::vector<AutofillProfile> new_sync_profiles;
1054 ASSERT_TRUE(
1055 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
1056 ASSERT_EQ(1U, new_sync_profiles.size());
1057 // Check that key fields are the same.
1058 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US"));
1059 // Make sure the additional information from the sync profile was kept.
1060 EXPECT_EQ(ASCIIToUTF16("Fox"),
1061 new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME));
1062 // Check that the latest use date is saved.
1063 EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date());
1064 // Check that the use counts were added (default value is 1).
1065 EXPECT_EQ(1U, new_sync_profiles[0].use_count());
1066 }
1067
1068 // Tests that a sync with a new native profile that matches an older new sync
1069 // profile but with less information results in the native profile being deleted
1070 // and replaced by the sync profile with merged usage stats.
1071 TEST_F(ProfileSyncServiceAutofillTest,
1072 HasNativeHasSyncMergeSimilarProfileCombine_SyncHasMoreInfoAndOlder) {
1073 // Create two almost identical profiles. The GUIDs are different and the
1074 // native profile has no value for company name.
1075 AutofillProfile sync_profile;
1076 autofill::test::SetProfileInfoWithGuid(
1077 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1078 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
1079 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
1080 sync_profile.set_use_date(base::Time::FromTimeT(1234));
1081
1082 AutofillProfile* native_profile = new AutofillProfile;
1083 autofill::test::SetProfileInfoWithGuid(
1084 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing",
1085 "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5",
1086 "Hollywood", "CA", "91601", "US", "12345678910");
1087 native_profile->set_use_date(base::Time::FromTimeT(4321));
1088
1089 AutofillProfile expected_profile(sync_profile);
1090 expected_profile.SetRawInfo(NAME_FULL,
1091 ASCIIToUTF16("Billing Mitchell Morrison"));
1092 expected_profile.set_use_count(1);
1093 expected_profile.set_use_date(native_profile->use_date());
1094
1095 std::vector<AutofillProfile*> native_profiles;
1096 native_profiles.push_back(native_profile);
1097 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
1098 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1099 EXPECT_CALL(autofill_table(),
1100 AddAutofillProfile(MatchProfiles(expected_profile)))
1101 .WillOnce(Return(true));
1102 EXPECT_CALL(autofill_table(),
1103 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF"))
1104 .WillOnce(Return(true));
1105 std::vector<AutofillProfile> sync_profiles;
1106 sync_profiles.push_back(sync_profile);
1107 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1108
1109 EXPECT_CALL(personal_data_manager(), Refresh());
1110 // Adds all entries in |sync_profiles| to sync.
1111 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE);
1112 ASSERT_TRUE(add_autofill.success());
1113
1114 std::vector<AutofillProfile> new_sync_profiles;
1115 ASSERT_TRUE(
1116 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
1117 ASSERT_EQ(1U, new_sync_profiles.size());
1118 // Check that key fields are the same.
1119 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US"));
1120 // Make sure the additional information from the sync profile was kept.
1121 EXPECT_EQ(ASCIIToUTF16("Fox"),
1122 new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME));
1123 // Check that the latest use date is saved.
1124 EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date());
1125 // Check that the use counts were added (default value is 1).
1126 EXPECT_EQ(1U, new_sync_profiles[0].use_count());
1127 }
1128
1129 // Tests that a sync with a new native profile that matches an a new sync
1130 // profile but with more information results in the native profile being deleted
1131 // and replaced by the sync profile with the native profiles additional
1132 // information merged in. The merge should happen even if the sync profile is
1133 // more recent.
1134 TEST_F(ProfileSyncServiceAutofillTest,
1135 HasNativeHasSyncMergeSimilarProfileCombine_NativeHasMoreInfo) {
1136 // Create two almost identical profiles. The GUIDs are different and the
1137 // sync profile has no value for company name.
1138 AutofillProfile sync_profile;
1139 autofill::test::SetProfileInfoWithGuid(
1140 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1141 "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5",
1142 "Hollywood", "CA", "91601", "US", "12345678910");
1143 sync_profile.set_use_date(base::Time::FromTimeT(4321));
1144
1145 AutofillProfile* native_profile = new AutofillProfile;
1146 autofill::test::SetProfileInfoWithGuid(
1147 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing",
1148 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
1149 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
1150 native_profile->set_use_date(base::Time::FromTimeT(1234));
1151
1152 AutofillProfile expected_profile(*native_profile);
1153 expected_profile.SetRawInfo(NAME_FULL,
1154 ASCIIToUTF16("Billing Mitchell Morrison"));
1155 expected_profile.set_use_date(sync_profile.use_date());
1156 expected_profile.set_use_count(1);
1157
1158 std::vector<AutofillProfile*> native_profiles;
1159 native_profiles.push_back(native_profile);
1160 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
1161 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1162 EXPECT_CALL(autofill_table(),
1163 AddAutofillProfile(MatchProfiles(expected_profile)))
1164 .WillOnce(Return(true));
1165 EXPECT_CALL(autofill_table(),
1166 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF"))
1167 .WillOnce(Return(true));
1168 std::vector<AutofillProfile> sync_profiles;
1169 sync_profiles.push_back(sync_profile);
1170 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1171
1172 EXPECT_CALL(personal_data_manager(), Refresh());
1173 // Adds all entries in |sync_profiles| to sync.
1174 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE);
1175 ASSERT_TRUE(add_autofill.success());
1176
1177 std::vector<AutofillProfile> new_sync_profiles;
1178 ASSERT_TRUE(
1179 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
1180 ASSERT_EQ(1U, new_sync_profiles.size());
1181 // Check that key fields are the same.
1182 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(expected_profile, "en-US"));
1183 // Make sure the addtional information of the native profile was saved into
1184 // the sync profile.
1185 EXPECT_EQ(ASCIIToUTF16("Fox"),
1186 new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME));
1187 // Check that the latest use date is saved.
1188 EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date());
1189 // Check that the use counts were added (default value is 1).
1190 EXPECT_EQ(1U, new_sync_profiles[0].use_count());
1191 }
1192
1193 // Tests that a sync with a new native profile that differ only by name a new
1194 // sync profile results in keeping both profiles.
1195 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSync_DifferentPrimaryInfo) {
1196 AutofillProfile sync_profile;
1197 autofill::test::SetProfileInfoWithGuid(
1198 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1199 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
1200 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
1201 sync_profile.set_use_date(base::Time::FromTimeT(4321));
1202
1203 AutofillProfile* native_profile = new AutofillProfile;
1204 autofill::test::SetProfileInfoWithGuid(
1205 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "John",
1206 "Smith", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood",
1207 "CA", "91601", "US", "12345678910");
1208 native_profile->set_use_date(base::Time::FromTimeT(1234));
1209
1210 std::vector<AutofillProfile*> native_profiles;
1211 native_profiles.push_back(native_profile);
1212 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
1213 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1214 EXPECT_CALL(autofill_table(), AddAutofillProfile(MatchProfiles(sync_profile)))
1215 .WillOnce(Return(true));
1216 std::vector<AutofillProfile> sync_profiles;
1217 sync_profiles.push_back(sync_profile);
1218 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1219
1220 EXPECT_CALL(personal_data_manager(), Refresh());
1221 // Adds all entries in |sync_profiles| to sync.
1222 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE);
1223 ASSERT_TRUE(add_autofill.success());
1224
1225 std::vector<AutofillProfile> new_sync_profiles;
1226 ASSERT_TRUE(
1227 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
1228 // The two profiles should be kept.
1229 ASSERT_EQ(2U, new_sync_profiles.size());
1230 }
1231
1232 // Tests that a new native profile that is the same as a new sync profile except
1233 // with different GUIDs results in the native profile being deleted and replaced
1234 // by the sync profile.
1235 TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) {
1236 AutofillProfile sync_profile;
1237
1238 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1239 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1240 "Mitchell", "Morrison",
1241 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1242 "91601", "US", "12345678910");
1243 sync_profile.set_use_count(20);
1244 sync_profile.set_use_date(base::Time::FromTimeT(1234));
1245
1246 std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
1247 AutofillProfile* native_profile = new AutofillProfile;
1248 autofill::test::SetProfileInfoWithGuid(native_profile,
1249 native_guid.c_str(), "Billing",
1250 "Mitchell", "Morrison",
1251 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1252 "91601", "US", "12345678910");
1253 native_profile->set_use_count(5);
1254 native_profile->set_use_date(base::Time::FromTimeT(4321));
1255
1256 std::vector<AutofillProfile*> native_profiles;
1257 native_profiles.push_back(native_profile);
1258 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
1259 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1260
1261 std::vector<AutofillProfile> sync_profiles;
1262 sync_profiles.push_back(sync_profile);
1263 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1264
1265 EXPECT_CALL(autofill_table(), AddAutofillProfile(_)).WillOnce(Return(true));
1266 EXPECT_CALL(autofill_table(), RemoveAutofillProfile(native_guid))
1267 .WillOnce(Return(true));
1268 EXPECT_CALL(personal_data_manager(), Refresh());
1269 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE);
1270 ASSERT_TRUE(add_autofill.success());
1271
1272 std::vector<AutofillProfile> new_sync_profiles;
1273 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1274 &new_sync_profiles));
1275 // Check that the profiles were merged.
1276 ASSERT_EQ(1U, new_sync_profiles.size());
1277 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
1278 // Check that the sync guid was kept.
1279 EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid());
1280 // Check that the sync profile use count was kept.
1281 EXPECT_EQ(20U, new_sync_profiles[0].use_count());
1282 // Check that the sync profile use date was kept.
1283 EXPECT_EQ(base::Time::FromTimeT(1234), new_sync_profiles[0].use_date());
1284 }
1285
1286 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) {
1287 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
1288 .WillOnce(Return(true));
1289 EXPECT_CALL(personal_data_manager(), Refresh());
1290 SetIdleChangeProcessorExpectations();
1291 CreateRootHelper create_root(this, AUTOFILL);
1292 StartSyncService(create_root.callback(), false, AUTOFILL);
1293 ASSERT_TRUE(create_root.success());
1294
1295 AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1));
1296
1297 EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _))
1298 .WillOnce(DoAll(SetArgumentPointee<2>(added_entry.date_created()),
1299 SetArgumentPointee<3>(added_entry.date_last_used()),
1300 Return(true)));
1301
1302 AutofillChangeList changes;
1303 changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key()));
1304
1305 web_data_service()->OnAutofillEntriesChanged(changes);
1306
1307 std::vector<AutofillEntry> new_sync_entries;
1308 std::vector<AutofillProfile> new_sync_profiles;
1309 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1310 &new_sync_profiles));
1311 ASSERT_EQ(1U, new_sync_entries.size());
1312 EXPECT_TRUE(added_entry == new_sync_entries[0]);
1313 }
1314
1315 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
1316 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).WillOnce(Return(true));
1317 EXPECT_CALL(personal_data_manager(), Refresh());
1318 SetIdleChangeProcessorExpectations();
1319 CreateRootHelper create_root(this, AUTOFILL_PROFILE);
1320 StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE);
1321 ASSERT_TRUE(create_root.success());
1322
1323 AutofillProfile added_profile;
1324 autofill::test::SetProfileInfoWithGuid(&added_profile,
1325 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
1326 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1327 "32801", "US", "19482937549");
1328
1329 AutofillProfileChange change(
1330 AutofillProfileChange::ADD, added_profile.guid(), &added_profile);
1331 web_data_service()->OnAutofillProfileChanged(change);
1332
1333 std::vector<AutofillProfile> new_sync_profiles;
1334 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1335 &new_sync_profiles));
1336 ASSERT_EQ(1U, new_sync_profiles.size());
1337 EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0]));
1338 }
1339
1340 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
1341 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
1342 std::vector<AutofillEntry> original_entries;
1343 original_entries.push_back(original_entry);
1344
1345 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
1346 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
1347 EXPECT_CALL(personal_data_manager(), Refresh());
1348 CreateRootHelper create_root(this, AUTOFILL);
1349 StartSyncService(create_root.callback(), false, AUTOFILL);
1350 ASSERT_TRUE(create_root.success());
1351
1352 AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
1353
1354 EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _))
1355 .WillOnce(DoAll(SetArgumentPointee<2>(updated_entry.date_created()),
1356 SetArgumentPointee<3>(updated_entry.date_last_used()),
1357 Return(true)));
1358
1359 AutofillChangeList changes;
1360 changes.push_back(AutofillChange(AutofillChange::UPDATE,
1361 updated_entry.key()));
1362 web_data_service()->OnAutofillEntriesChanged(changes);
1363
1364 std::vector<AutofillEntry> new_sync_entries;
1365 std::vector<AutofillProfile> new_sync_profiles;
1366 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1367 &new_sync_profiles));
1368 ASSERT_EQ(1U, new_sync_entries.size());
1369 EXPECT_TRUE(updated_entry == new_sync_entries[0]);
1370 }
1371
1372
1373 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) {
1374 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
1375 std::vector<AutofillEntry> original_entries;
1376 original_entries.push_back(original_entry);
1377
1378 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
1379 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
1380 EXPECT_CALL(personal_data_manager(), Refresh());
1381 CreateRootHelper create_root(this, AUTOFILL);
1382 StartSyncService(create_root.callback(), false, AUTOFILL);
1383 ASSERT_TRUE(create_root.success());
1384
1385 AutofillChangeList changes;
1386 changes.push_back(AutofillChange(AutofillChange::REMOVE,
1387 original_entry.key()));
1388 web_data_service()->OnAutofillEntriesChanged(changes);
1389
1390 std::vector<AutofillEntry> new_sync_entries;
1391 std::vector<AutofillProfile> new_sync_profiles;
1392 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1393 &new_sync_profiles));
1394 ASSERT_EQ(0U, new_sync_entries.size());
1395 }
1396
1397 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) {
1398 AutofillProfile sync_profile;
1399 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1400 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1401 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1402 "32801", "US", "19482937549");
1403 AutofillProfile* native_profile = new AutofillProfile;
1404 autofill::test::SetProfileInfoWithGuid(native_profile,
1405 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1406 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1407 "32801", "US", "19482937549");
1408
1409 std::vector<AutofillProfile*> native_profiles;
1410 native_profiles.push_back(native_profile);
1411 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
1412 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1413
1414 std::vector<AutofillProfile> sync_profiles;
1415 sync_profiles.push_back(sync_profile);
1416 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1417 EXPECT_CALL(personal_data_manager(), Refresh());
1418 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE);
1419 ASSERT_TRUE(add_autofill.success());
1420
1421 AutofillProfileChange change(
1422 AutofillProfileChange::REMOVE, sync_profile.guid(), NULL);
1423 web_data_service()->OnAutofillProfileChanged(change);
1424
1425 std::vector<AutofillProfile> new_sync_profiles;
1426 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1427 &new_sync_profiles));
1428 ASSERT_EQ(0U, new_sync_profiles.size());
1429 }
1430
1431 TEST_F(ProfileSyncServiceAutofillTest, ServerChangeRace) {
1432 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via
1433 // LoadAutofillData().
1434 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
1435 .Times(3)
1436 .WillRepeatedly(Return(true));
1437 // On the other hand Autofill and Autocomplete are separated now, so
1438 // GetAutofillProfiles() should not be called.
1439 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).Times(0);
1440 EXPECT_CALL(autofill_table(), UpdateAutofillEntries(_))
1441 .WillRepeatedly(Return(true));
1442 EXPECT_CALL(personal_data_manager(), Refresh()).Times(3);
1443 CreateRootHelper create_root(this, AUTOFILL);
1444 StartSyncService(create_root.callback(), false, AUTOFILL);
1445 ASSERT_TRUE(create_root.success());
1446
1447 std::unique_ptr<WaitableEvent> wait_for_start(
1448 new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL,
1449 base::WaitableEvent::InitialState::NOT_SIGNALED));
1450 std::unique_ptr<WaitableEvent> wait_for_syncapi(
1451 new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL,
1452 base::WaitableEvent::InitialState::NOT_SIGNALED));
1453 scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater(
1454 sync_service(), wait_for_start.get(), wait_for_syncapi.get(),
1455 data_type_thread()->task_runner()));
1456
1457 // This server side update will stall waiting for CommitWaiter.
1458 updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
1459 wait_for_start->Wait();
1460
1461 AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
1462 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry));
1463 DVLOG(1) << "Syncapi update finished.";
1464
1465 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
1466 // Signal FakeServerUpdater that it can complete.
1467 wait_for_syncapi->Signal();
1468
1469 // Make another entry to ensure nothing broke afterwards and wait for finish
1470 // to clean up.
1471 updater->WaitForUpdateCompletion();
1472 updater->CreateNewEntry(MakeAutofillEntry("server2", "entry2", 3));
1473 updater->WaitForUpdateCompletion();
1474
1475 // Let callbacks posted on UI thread execute.
1476 base::RunLoop().RunUntilIdle();
1477
1478 std::vector<AutofillEntry> sync_entries;
1479 std::vector<AutofillProfile> sync_profiles;
1480 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
1481 EXPECT_EQ(3U, sync_entries.size());
1482 EXPECT_EQ(0U, sync_profiles.size());
1483 for (size_t i = 0; i < sync_entries.size(); i++) {
1484 DVLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name()
1485 << ", " << sync_entries[i].key().value();
1486 }
1487 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698