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

Side by Side Diff: chrome/browser/sync/profile_sync_service_autofill_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698