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

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

Powered by Google App Engine
This is Rietveld 408576698