Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_service_autofill_unittest.cc
blob4931a98746514f2af1e23d2674d23b1d7f224900
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.
5 #include <set>
6 #include <string>
7 #include <utility>
8 #include <vector>
10 #include "testing/gtest/include/gtest/gtest.h"
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/callback.h"
15 #include "base/compiler_specific.h"
16 #include "base/location.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/message_loop/message_loop.h"
20 #include "base/strings/string16.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/synchronization/waitable_event.h"
23 #include "base/time/time.h"
24 #include "chrome/browser/autofill/personal_data_manager_factory.h"
25 #include "chrome/browser/prefs/pref_service_syncable.h"
26 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
27 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
28 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
29 #include "chrome/browser/signin/signin_manager_factory.h"
30 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
31 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
32 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
33 #include "chrome/browser/sync/profile_sync_components_factory.h"
34 #include "chrome/browser/sync/profile_sync_service.h"
35 #include "chrome/browser/sync/profile_sync_service_factory.h"
36 #include "chrome/browser/sync/profile_sync_test_util.h"
37 #include "chrome/browser/sync/test_profile_sync_service.h"
38 #include "chrome/browser/webdata/web_data_service_factory.h"
39 #include "chrome/test/base/testing_browser_process.h"
40 #include "chrome/test/base/testing_profile.h"
41 #include "chrome/test/base/testing_profile_manager.h"
42 #include "components/autofill/core/browser/autofill_test_utils.h"
43 #include "components/autofill/core/browser/personal_data_manager.h"
44 #include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h"
45 #include "components/autofill/core/browser/webdata/autofill_change.h"
46 #include "components/autofill/core/browser/webdata/autofill_entry.h"
47 #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
48 #include "components/autofill/core/browser/webdata/autofill_table.h"
49 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
50 #include "components/signin/core/browser/signin_manager.h"
51 #include "components/sync_driver/data_type_controller.h"
52 #include "components/webdata/common/web_database.h"
53 #include "components/webdata_services/web_data_service_test_util.h"
54 #include "content/public/test/test_browser_thread.h"
55 #include "google_apis/gaia/gaia_constants.h"
56 #include "sync/internal_api/public/base/model_type.h"
57 #include "sync/internal_api/public/data_type_debug_info_listener.h"
58 #include "sync/internal_api/public/read_node.h"
59 #include "sync/internal_api/public/read_transaction.h"
60 #include "sync/internal_api/public/write_node.h"
61 #include "sync/internal_api/public/write_transaction.h"
62 #include "sync/protocol/autofill_specifics.pb.h"
63 #include "sync/syncable/mutable_entry.h"
64 #include "sync/syncable/syncable_write_transaction.h"
65 #include "sync/test/engine/test_id_factory.h"
66 #include "testing/gmock/include/gmock/gmock.h"
68 using autofill::AutocompleteSyncableService;
69 using autofill::AutofillChange;
70 using autofill::AutofillChangeList;
71 using autofill::AutofillEntry;
72 using autofill::ServerFieldType;
73 using autofill::AutofillKey;
74 using autofill::AutofillProfile;
75 using autofill::AutofillProfileChange;
76 using autofill::AutofillProfileSyncableService;
77 using autofill::AutofillTable;
78 using autofill::AutofillWebDataService;
79 using autofill::PersonalDataManager;
80 using base::Time;
81 using base::TimeDelta;
82 using base::WaitableEvent;
83 using browser_sync::AutofillDataTypeController;
84 using browser_sync::AutofillProfileDataTypeController;
85 using content::BrowserThread;
86 using syncer::AUTOFILL;
87 using syncer::AUTOFILL_PROFILE;
88 using syncer::BaseNode;
89 using syncer::syncable::BASE_VERSION;
90 using syncer::syncable::CREATE;
91 using syncer::syncable::GET_TYPE_ROOT;
92 using syncer::syncable::MutableEntry;
93 using syncer::syncable::SERVER_SPECIFICS;
94 using syncer::syncable::SPECIFICS;
95 using syncer::syncable::UNITTEST;
96 using syncer::syncable::WriterTag;
97 using syncer::syncable::WriteTransaction;
98 using sync_driver::DataTypeController;
99 using testing::_;
100 using testing::DoAll;
101 using testing::ElementsAre;
102 using testing::Not;
103 using testing::SetArgumentPointee;
104 using testing::Return;
106 class HistoryService;
108 namespace syncable {
109 class Id;
112 namespace {
114 const char kTestProfileName[] = "test-profile";
116 void RunAndSignal(const base::Closure& cb, WaitableEvent* event) {
117 cb.Run();
118 event->Signal();
121 } // namespace
123 class AutofillTableMock : public AutofillTable {
124 public:
125 AutofillTableMock() : AutofillTable("en-US") {}
126 MOCK_METHOD2(RemoveFormElement,
127 bool(const base::string16& name,
128 const base::string16& value)); // NOLINT
129 MOCK_METHOD1(GetAllAutofillEntries,
130 bool(std::vector<AutofillEntry>* entries)); // NOLINT
131 MOCK_METHOD4(GetAutofillTimestamps,
132 bool(const base::string16& name, // NOLINT
133 const base::string16& value,
134 base::Time* date_created,
135 base::Time* date_last_used));
136 MOCK_METHOD1(UpdateAutofillEntries,
137 bool(const std::vector<AutofillEntry>&)); // NOLINT
138 MOCK_METHOD1(GetAutofillProfiles,
139 bool(std::vector<AutofillProfile*>*)); // NOLINT
140 MOCK_METHOD1(UpdateAutofillProfile,
141 bool(const AutofillProfile&)); // NOLINT
142 MOCK_METHOD1(AddAutofillProfile,
143 bool(const AutofillProfile&)); // NOLINT
144 MOCK_METHOD1(RemoveAutofillProfile,
145 bool(const std::string&)); // NOLINT
148 MATCHER_P(MatchProfiles, profile, "") {
149 return (profile.Compare(arg) == 0);
152 class WebDatabaseFake : public WebDatabase {
153 public:
154 explicit WebDatabaseFake(AutofillTable* autofill_table) {
155 AddTable(autofill_table);
159 class MockAutofillBackend : public autofill::AutofillWebDataBackend {
160 public:
161 MockAutofillBackend(
162 WebDatabase* web_database,
163 const base::Closure& on_changed)
164 : web_database_(web_database),
165 on_changed_(on_changed) {
168 ~MockAutofillBackend() override {}
169 WebDatabase* GetDatabase() override { return web_database_; }
170 void AddObserver(
171 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {}
172 void RemoveObserver(
173 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {}
174 void RemoveExpiredFormElements() override {}
175 void NotifyOfMultipleAutofillChanges() override {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
177 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_changed_);
180 private:
181 WebDatabase* web_database_;
182 base::Closure on_changed_;
185 class ProfileSyncServiceAutofillTest;
187 template<class AutofillProfile>
188 syncer::ModelType GetModelType() {
189 return syncer::UNSPECIFIED;
192 template<>
193 syncer::ModelType GetModelType<AutofillEntry>() {
194 return syncer::AUTOFILL;
197 template<>
198 syncer::ModelType GetModelType<AutofillProfile>() {
199 return syncer::AUTOFILL_PROFILE;
202 class TokenWebDataServiceFake : public TokenWebData {
203 public:
204 TokenWebDataServiceFake()
205 : TokenWebData(
206 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
207 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)) {
210 bool IsDatabaseLoaded() override { return true; }
212 AutofillWebDataService::Handle GetAllTokens(
213 WebDataServiceConsumer* consumer) override {
214 // TODO(tim): It would be nice if WebDataService was injected on
215 // construction of ProfileOAuth2TokenService rather than fetched by
216 // Initialize so that this isn't necessary (we could pass a NULL service).
217 // We currently do return it via EXPECT_CALLs, but without depending on
218 // order-of-initialization (which seems way more fragile) we can't tell
219 // which component is asking at what time, and some components in these
220 // Autofill tests require a WebDataService.
221 return 0;
224 private:
225 ~TokenWebDataServiceFake() override {}
227 DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake);
230 class WebDataServiceFake : public AutofillWebDataService {
231 public:
232 WebDataServiceFake()
233 : AutofillWebDataService(
234 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
235 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)),
236 web_database_(NULL),
237 autocomplete_syncable_service_(NULL),
238 autofill_profile_syncable_service_(NULL),
239 syncable_service_created_or_destroyed_(false, false) {
242 void SetDatabase(WebDatabase* web_database) {
243 web_database_ = web_database;
246 void StartSyncableService() {
247 // The |autofill_profile_syncable_service_| must be constructed on the DB
248 // thread.
249 const base::Closure& on_changed_callback = base::Bind(
250 &WebDataServiceFake::NotifyAutofillMultipleChangedOnUIThread,
251 AsWeakPtr());
253 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
254 base::Bind(&WebDataServiceFake::CreateSyncableService,
255 base::Unretained(this),
256 on_changed_callback));
257 syncable_service_created_or_destroyed_.Wait();
260 void ShutdownSyncableService() {
261 // The |autofill_profile_syncable_service_| must be destructed on the DB
262 // thread.
263 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
264 base::Bind(&WebDataServiceFake::DestroySyncableService,
265 base::Unretained(this)));
266 syncable_service_created_or_destroyed_.Wait();
269 bool IsDatabaseLoaded() override { return true; }
271 WebDatabase* GetDatabase() override { return web_database_; }
273 void OnAutofillEntriesChanged(const AutofillChangeList& changes) {
274 WaitableEvent event(true, false);
276 base::Closure notify_cb =
277 base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged,
278 base::Unretained(autocomplete_syncable_service_),
279 changes);
280 BrowserThread::PostTask(
281 BrowserThread::DB,
282 FROM_HERE,
283 base::Bind(&RunAndSignal, notify_cb, &event));
284 event.Wait();
287 void OnAutofillProfileChanged(const AutofillProfileChange& changes) {
288 WaitableEvent event(true, false);
290 base::Closure notify_cb =
291 base::Bind(&AutocompleteSyncableService::AutofillProfileChanged,
292 base::Unretained(autofill_profile_syncable_service_),
293 changes);
294 BrowserThread::PostTask(
295 BrowserThread::DB,
296 FROM_HERE,
297 base::Bind(&RunAndSignal, notify_cb, &event));
298 event.Wait();
301 private:
302 ~WebDataServiceFake() override {}
304 void CreateSyncableService(const base::Closure& on_changed_callback) {
305 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
306 // These services are deleted in DestroySyncableService().
307 backend_.reset(new MockAutofillBackend(
308 GetDatabase(), on_changed_callback));
309 AutocompleteSyncableService::CreateForWebDataServiceAndBackend(
310 this, backend_.get());
311 AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
312 this, backend_.get(), "en-US");
314 autocomplete_syncable_service_ =
315 AutocompleteSyncableService::FromWebDataService(this);
316 autofill_profile_syncable_service_ =
317 AutofillProfileSyncableService::FromWebDataService(this);
319 syncable_service_created_or_destroyed_.Signal();
322 void DestroySyncableService() {
323 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
324 autocomplete_syncable_service_ = NULL;
325 autofill_profile_syncable_service_ = NULL;
326 backend_.reset();
327 syncable_service_created_or_destroyed_.Signal();
330 WebDatabase* web_database_;
331 AutocompleteSyncableService* autocomplete_syncable_service_;
332 AutofillProfileSyncableService* autofill_profile_syncable_service_;
333 scoped_ptr<autofill::AutofillWebDataBackend> backend_;
335 WaitableEvent syncable_service_created_or_destroyed_;
337 DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake);
340 KeyedService* BuildMockWebDataServiceWrapper(content::BrowserContext* profile) {
341 return new MockWebDataServiceWrapper(
342 new WebDataServiceFake(),
343 new TokenWebDataServiceFake());
346 ACTION_P(MakeAutocompleteSyncComponents, wds) {
347 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
348 if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
349 return base::WeakPtr<syncer::SyncableService>();
350 return AutocompleteSyncableService::FromWebDataService(wds)->AsWeakPtr();
353 ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) {
354 return new sync_driver::DataTypeManagerImpl(
355 base::Closure(),
356 debug_listener,
357 arg1,
358 arg2,
359 arg3,
360 arg4);
363 ACTION_P(MakeAutofillProfileSyncComponents, wds) {
364 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
365 if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
366 return base::WeakPtr<syncer::SyncableService>();
367 return AutofillProfileSyncableService::FromWebDataService(wds)->AsWeakPtr();
370 class AbstractAutofillFactory {
371 public:
372 virtual DataTypeController* CreateDataTypeController(
373 ProfileSyncComponentsFactory* factory,
374 TestingProfile* profile,
375 ProfileSyncService* service) = 0;
376 virtual void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
377 ProfileSyncService* service,
378 AutofillWebDataService* wds,
379 DataTypeController* dtc) = 0;
380 virtual ~AbstractAutofillFactory() {}
383 class AutofillEntryFactory : public AbstractAutofillFactory {
384 public:
385 DataTypeController* CreateDataTypeController(
386 ProfileSyncComponentsFactory* factory,
387 TestingProfile* profile,
388 ProfileSyncService* service) override {
389 return new AutofillDataTypeController(factory, profile);
392 void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
393 ProfileSyncService* service,
394 AutofillWebDataService* wds,
395 DataTypeController* dtc) override {
396 EXPECT_CALL(*factory, GetSyncableServiceForType(syncer::AUTOFILL)).
397 WillOnce(MakeAutocompleteSyncComponents(wds));
401 class AutofillProfileFactory : public AbstractAutofillFactory {
402 public:
403 DataTypeController* CreateDataTypeController(
404 ProfileSyncComponentsFactory* factory,
405 TestingProfile* profile,
406 ProfileSyncService* service) override {
407 return new AutofillProfileDataTypeController(factory, profile);
410 void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
411 ProfileSyncService* service,
412 AutofillWebDataService* wds,
413 DataTypeController* dtc) override {
414 EXPECT_CALL(*factory,
415 GetSyncableServiceForType(syncer::AUTOFILL_PROFILE)).
416 WillOnce(MakeAutofillProfileSyncComponents(wds));
420 class MockPersonalDataManager : public PersonalDataManager {
421 public:
422 MockPersonalDataManager() : PersonalDataManager("en-US") {}
423 MOCK_CONST_METHOD0(IsDataLoaded, bool());
424 MOCK_METHOD0(LoadProfiles, void());
425 MOCK_METHOD0(LoadCreditCards, void());
426 MOCK_METHOD0(Refresh, void());
428 static KeyedService* Build(content::BrowserContext* profile) {
429 return new MockPersonalDataManager();
433 template <class T> class AddAutofillHelper;
435 class ProfileSyncServiceAutofillTest
436 : public AbstractProfileSyncServiceTest,
437 public syncer::DataTypeDebugInfoListener {
438 public:
439 // DataTypeDebugInfoListener implementation.
440 void OnDataTypeConfigureComplete(const std::vector<
441 syncer::DataTypeConfigurationStats>& configuration_stats) override {
442 ASSERT_EQ(1u, configuration_stats.size());
443 association_stats_ = configuration_stats[0].association_stats;
446 protected:
447 ProfileSyncServiceAutofillTest()
448 : profile_manager_(TestingBrowserProcess::GetGlobal()),
449 debug_ptr_factory_(this) {
451 ~ProfileSyncServiceAutofillTest() override {}
453 AutofillProfileFactory profile_factory_;
454 AutofillEntryFactory entry_factory_;
456 AbstractAutofillFactory* GetFactory(syncer::ModelType type) {
457 if (type == syncer::AUTOFILL) {
458 return &entry_factory_;
459 } else if (type == syncer::AUTOFILL_PROFILE) {
460 return &profile_factory_;
461 } else {
462 NOTREACHED();
463 return NULL;
467 void SetUp() override {
468 AbstractProfileSyncServiceTest::SetUp();
469 ASSERT_TRUE(profile_manager_.SetUp());
470 TestingProfile::TestingFactories testing_factories;
471 testing_factories.push_back(std::make_pair(
472 ProfileOAuth2TokenServiceFactory::GetInstance(),
473 BuildAutoIssuingFakeProfileOAuth2TokenService));
474 profile_ = profile_manager_.CreateTestingProfile(
475 kTestProfileName,
476 scoped_ptr<PrefServiceSyncable>(),
477 base::UTF8ToUTF16(kTestProfileName),
479 std::string(),
480 testing_factories);
481 web_database_.reset(new WebDatabaseFake(&autofill_table_));
482 MockWebDataServiceWrapper* wrapper =
483 static_cast<MockWebDataServiceWrapper*>(
484 WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse(
485 profile_, BuildMockWebDataServiceWrapper));
486 web_data_service_ =
487 static_cast<WebDataServiceFake*>(wrapper->GetAutofillWebData().get());
488 web_data_service_->SetDatabase(web_database_.get());
490 personal_data_manager_ = static_cast<MockPersonalDataManager*>(
491 autofill::PersonalDataManagerFactory::GetInstance()
492 ->SetTestingFactoryAndUse(profile_,
493 MockPersonalDataManager::Build));
495 EXPECT_CALL(*personal_data_manager_, LoadProfiles()).Times(1);
496 EXPECT_CALL(*personal_data_manager_, LoadCreditCards()).Times(1);
498 personal_data_manager_->Init(
499 WebDataServiceFactory::GetAutofillWebDataForProfile(
500 profile_, ServiceAccessType::EXPLICIT_ACCESS),
501 profile_->GetPrefs(),
502 profile_->IsOffTheRecord());
504 web_data_service_->StartSyncableService();
506 // When UpdateAutofillEntries() is called with an empty list, the return
507 // value should be |true|, rather than the default of |false|.
508 std::vector<AutofillEntry> empty;
509 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(empty))
510 .WillRepeatedly(Return(true));
513 void TearDown() override {
514 // Note: The tear down order is important.
515 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
516 web_data_service_->ShutdownOnUIThread();
517 web_data_service_->ShutdownSyncableService();
518 web_data_service_ = NULL;
519 // To prevent a leak, fully release TestURLRequestContext to ensure its
520 // destruction on the IO message loop.
521 profile_ = NULL;
522 profile_manager_.DeleteTestingProfile(kTestProfileName);
523 AbstractProfileSyncServiceTest::TearDown();
526 int GetSyncCount(syncer::ModelType type) {
527 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
528 syncer::ReadNode node(&trans);
529 if (node.InitTypeRoot(type) != syncer::BaseNode::INIT_OK)
530 return 0;
531 return node.GetTotalNodeCount() - 1;
534 void StartSyncService(const base::Closure& callback,
535 bool will_fail_association,
536 syncer::ModelType type) {
537 AbstractAutofillFactory* factory = GetFactory(type);
538 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile_);
539 signin->SetAuthenticatedUsername("test_user@gmail.com");
540 sync_service_ = TestProfileSyncService::BuildAutoStartAsyncInit(profile_,
541 callback);
543 ProfileSyncComponentsFactoryMock* components =
544 sync_service_->components_factory_mock();
545 DataTypeController* data_type_controller =
546 factory->CreateDataTypeController(components, profile_, sync_service_);
547 factory->SetExpectation(components,
548 sync_service_,
549 web_data_service_.get(),
550 data_type_controller);
552 EXPECT_CALL(*components, CreateDataTypeManager(_, _, _, _, _)).
553 WillOnce(ReturnNewDataTypeManagerWithDebugListener(
554 syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr())));
556 EXPECT_CALL(*personal_data_manager_, IsDataLoaded()).
557 WillRepeatedly(Return(true));
559 // We need tokens to get the tests going
560 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
561 ->UpdateCredentials("test_user@gmail.com", "oauth2_login_token");
563 sync_service_->RegisterDataTypeController(data_type_controller);
564 sync_service_->Initialize();
565 base::MessageLoop::current()->Run();
567 // It's possible this test triggered an unrecoverable error, in which case
568 // we can't get the sync count.
569 if (sync_service_->SyncActive()) {
570 EXPECT_EQ(GetSyncCount(type),
571 association_stats_.num_sync_items_after_association);
573 EXPECT_EQ(association_stats_.num_sync_items_after_association,
574 association_stats_.num_sync_items_before_association +
575 association_stats_.num_sync_items_added -
576 association_stats_.num_sync_items_deleted);
579 bool AddAutofillSyncNode(const AutofillEntry& entry) {
580 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
581 syncer::ReadNode autofill_root(&trans);
582 if (autofill_root.InitTypeRoot(syncer::AUTOFILL) != BaseNode::INIT_OK) {
583 return false;
586 syncer::WriteNode node(&trans);
587 std::string tag = AutocompleteSyncableService::KeyToTag(
588 base::UTF16ToUTF8(entry.key().name()),
589 base::UTF16ToUTF8(entry.key().value()));
590 syncer::WriteNode::InitUniqueByCreationResult result =
591 node.InitUniqueByCreation(syncer::AUTOFILL, autofill_root, tag);
592 if (result != syncer::WriteNode::INIT_SUCCESS)
593 return false;
595 sync_pb::EntitySpecifics specifics;
596 AutocompleteSyncableService::WriteAutofillEntry(entry, &specifics);
597 sync_pb::AutofillSpecifics* autofill_specifics =
598 specifics.mutable_autofill();
599 node.SetAutofillSpecifics(*autofill_specifics);
600 return true;
603 bool AddAutofillSyncNode(const AutofillProfile& profile) {
604 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
605 syncer::ReadNode autofill_root(&trans);
606 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) {
607 return false;
609 syncer::WriteNode node(&trans);
610 std::string tag = profile.guid();
611 syncer::WriteNode::InitUniqueByCreationResult result =
612 node.InitUniqueByCreation(syncer::AUTOFILL_PROFILE,
613 autofill_root, tag);
614 if (result != syncer::WriteNode::INIT_SUCCESS)
615 return false;
617 sync_pb::EntitySpecifics specifics;
618 AutofillProfileSyncableService::WriteAutofillProfile(profile, &specifics);
619 sync_pb::AutofillProfileSpecifics* profile_specifics =
620 specifics.mutable_autofill_profile();
621 node.SetAutofillProfileSpecifics(*profile_specifics);
622 return true;
625 bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries,
626 std::vector<AutofillProfile>* profiles) {
627 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
628 syncer::ReadNode autofill_root(&trans);
629 if (autofill_root.InitTypeRoot(syncer::AUTOFILL) != BaseNode::INIT_OK) {
630 return false;
633 int64 child_id = autofill_root.GetFirstChildId();
634 while (child_id != syncer::kInvalidId) {
635 syncer::ReadNode child_node(&trans);
636 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK)
637 return false;
639 const sync_pb::AutofillSpecifics& autofill(
640 child_node.GetAutofillSpecifics());
641 if (autofill.has_value()) {
642 AutofillKey key(base::UTF8ToUTF16(autofill.name()),
643 base::UTF8ToUTF16(autofill.value()));
644 std::vector<base::Time> timestamps;
645 int timestamps_count = autofill.usage_timestamp_size();
646 for (int i = 0; i < timestamps_count; ++i) {
647 timestamps.push_back(Time::FromInternalValue(
648 autofill.usage_timestamp(i)));
650 entries->push_back(
651 AutofillEntry(key, timestamps.front(), timestamps.back()));
652 } else if (autofill.has_profile()) {
653 AutofillProfile p;
654 p.set_guid(autofill.profile().guid());
655 AutofillProfileSyncableService::OverwriteProfileWithServerData(
656 autofill.profile(), &p, "en-US");
657 profiles->push_back(p);
659 child_id = child_node.GetSuccessorId();
661 return true;
664 bool GetAutofillProfilesFromSyncDBUnderProfileNode(
665 std::vector<AutofillProfile>* profiles) {
666 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
667 syncer::ReadNode autofill_root(&trans);
668 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) {
669 return false;
672 int64 child_id = autofill_root.GetFirstChildId();
673 while (child_id != syncer::kInvalidId) {
674 syncer::ReadNode child_node(&trans);
675 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK)
676 return false;
678 const sync_pb::AutofillProfileSpecifics& autofill(
679 child_node.GetAutofillProfileSpecifics());
680 AutofillProfile p;
681 p.set_guid(autofill.guid());
682 AutofillProfileSyncableService::OverwriteProfileWithServerData(
683 autofill, &p, "en-US");
684 profiles->push_back(p);
685 child_id = child_node.GetSuccessorId();
687 return true;
690 void SetIdleChangeProcessorExpectations() {
691 EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0);
692 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0);
694 // Only permit UpdateAutofillEntries() to be called with an empty list.
695 std::vector<AutofillEntry> empty;
696 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(Not(empty))).Times(0);
699 static AutofillEntry MakeAutofillEntry(const char* name,
700 const char* value,
701 int time_shift0,
702 int time_shift1) {
703 // Time deep in the past would cause Autocomplete sync to discard the
704 // entries.
705 static Time base_time = Time::Now().LocalMidnight();
707 base::Time date_created = base_time + TimeDelta::FromSeconds(time_shift0);
708 base::Time date_last_used = date_created;
709 if (time_shift1 >= 0)
710 date_last_used = base_time + TimeDelta::FromSeconds(time_shift1);
711 return AutofillEntry(
712 AutofillKey(base::ASCIIToUTF16(name), base::ASCIIToUTF16(value)),
713 date_created, date_last_used);
716 static AutofillEntry MakeAutofillEntry(const char* name,
717 const char* value,
718 int time_shift) {
719 return MakeAutofillEntry(name, value, time_shift, -1);
722 friend class AddAutofillHelper<AutofillEntry>;
723 friend class AddAutofillHelper<AutofillProfile>;
724 friend class FakeServerUpdater;
726 TestingProfileManager profile_manager_;
727 TestingProfile* profile_;
728 AutofillTableMock autofill_table_;
729 scoped_ptr<WebDatabaseFake> web_database_;
730 scoped_refptr<WebDataServiceFake> web_data_service_;
731 MockPersonalDataManager* personal_data_manager_;
732 syncer::DataTypeAssociationStats association_stats_;
733 base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_;
736 template <class T>
737 class AddAutofillHelper {
738 public:
739 AddAutofillHelper(ProfileSyncServiceAutofillTest* test,
740 const std::vector<T>& entries)
741 : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback,
742 base::Unretained(this), test, entries)),
743 success_(false) {
746 const base::Closure& callback() const { return callback_; }
747 bool success() { return success_; }
749 private:
750 void AddAutofillCallback(ProfileSyncServiceAutofillTest* test,
751 const std::vector<T>& entries) {
752 if (!test->CreateRoot(GetModelType<T>()))
753 return;
755 for (size_t i = 0; i < entries.size(); ++i) {
756 if (!test->AddAutofillSyncNode(entries[i]))
757 return;
759 success_ = true;
762 base::Closure callback_;
763 bool success_;
766 // Overload write transaction to use custom NotifyTransactionComplete
767 class WriteTransactionTest: public WriteTransaction {
768 public:
769 WriteTransactionTest(const tracked_objects::Location& from_here,
770 WriterTag writer,
771 syncer::syncable::Directory* directory,
772 scoped_ptr<WaitableEvent>* wait_for_syncapi)
773 : WriteTransaction(from_here, writer, directory),
774 wait_for_syncapi_(wait_for_syncapi) { }
776 void NotifyTransactionComplete(syncer::ModelTypeSet types) override {
777 // This is where we differ. Force a thread change here, giving another
778 // thread a chance to create a WriteTransaction
779 (*wait_for_syncapi_)->Wait();
781 WriteTransaction::NotifyTransactionComplete(types);
784 private:
785 scoped_ptr<WaitableEvent>* wait_for_syncapi_;
788 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
789 // post tasks with it.
790 class FakeServerUpdater : public base::RefCountedThreadSafe<FakeServerUpdater> {
791 public:
792 FakeServerUpdater(TestProfileSyncService* service,
793 scoped_ptr<WaitableEvent>* wait_for_start,
794 scoped_ptr<WaitableEvent>* wait_for_syncapi)
795 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)),
796 service_(service),
797 wait_for_start_(wait_for_start),
798 wait_for_syncapi_(wait_for_syncapi),
799 is_finished_(false, false) { }
801 void Update() {
802 // This gets called in a modelsafeworker thread.
803 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
805 syncer::UserShare* user_share = service_->GetUserShare();
806 syncer::syncable::Directory* directory = user_share->directory.get();
808 // Create autofill protobuf.
809 std::string tag = AutocompleteSyncableService::KeyToTag(
810 base::UTF16ToUTF8(entry_.key().name()),
811 base::UTF16ToUTF8(entry_.key().value()));
812 sync_pb::AutofillSpecifics new_autofill;
813 new_autofill.set_name(base::UTF16ToUTF8(entry_.key().name()));
814 new_autofill.set_value(base::UTF16ToUTF8(entry_.key().value()));
815 new_autofill.add_usage_timestamp(entry_.date_created().ToInternalValue());
816 if (entry_.date_created() != entry_.date_last_used()) {
817 new_autofill.add_usage_timestamp(
818 entry_.date_last_used().ToInternalValue());
821 sync_pb::EntitySpecifics entity_specifics;
822 entity_specifics.mutable_autofill()->CopyFrom(new_autofill);
825 // Tell main thread we've started
826 (*wait_for_start_)->Signal();
828 // Create write transaction.
829 WriteTransactionTest trans(FROM_HERE, UNITTEST, directory,
830 wait_for_syncapi_);
832 // Create actual entry based on autofill protobuf information.
833 // Simulates effects of UpdateLocalDataFromServerData
834 MutableEntry parent(&trans, GET_TYPE_ROOT, syncer::AUTOFILL);
835 MutableEntry item(&trans, CREATE, syncer::AUTOFILL, parent.GetId(), tag);
836 ASSERT_TRUE(item.good());
837 item.PutSpecifics(entity_specifics);
838 item.PutServerSpecifics(entity_specifics);
839 item.PutBaseVersion(1);
840 syncer::syncable::Id server_item_id =
841 service_->id_factory()->NewServerId();
842 item.PutId(server_item_id);
843 syncer::syncable::Id new_predecessor;
844 ASSERT_TRUE(item.PutPredecessor(new_predecessor));
846 DVLOG(1) << "FakeServerUpdater finishing.";
847 is_finished_.Signal();
850 void CreateNewEntry(const AutofillEntry& entry) {
851 entry_ = entry;
852 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
853 if (!BrowserThread::PostTask(
854 BrowserThread::DB, FROM_HERE,
855 base::Bind(&FakeServerUpdater::Update, this))) {
856 NOTREACHED() << "Failed to post task to the db thread.";
857 return;
861 void CreateNewEntryAndWait(const AutofillEntry& entry) {
862 entry_ = entry;
863 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
864 is_finished_.Reset();
865 if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
866 base::Bind(&FakeServerUpdater::Update, this))) {
867 NOTREACHED() << "Failed to post task to the db thread.";
868 return;
870 is_finished_.Wait();
873 private:
874 friend class base::RefCountedThreadSafe<FakeServerUpdater>;
875 ~FakeServerUpdater() { }
877 AutofillEntry entry_;
878 TestProfileSyncService* service_;
879 scoped_ptr<WaitableEvent>* wait_for_start_;
880 scoped_ptr<WaitableEvent>* wait_for_syncapi_;
881 WaitableEvent is_finished_;
882 syncer::syncable::Id parent_id_;
885 namespace {
887 // Checks if the field of type |field_type| in |profile1| includes all values
888 // of the field in |profile2|.
889 bool IncludesField(const AutofillProfile& profile1,
890 const AutofillProfile& profile2,
891 ServerFieldType field_type) {
892 std::vector<base::string16> values1;
893 profile1.GetRawMultiInfo(field_type, &values1);
894 std::vector<base::string16> values2;
895 profile2.GetRawMultiInfo(field_type, &values2);
897 std::set<base::string16> values_set;
898 for (size_t i = 0; i < values1.size(); ++i)
899 values_set.insert(values1[i]);
900 for (size_t i = 0; i < values2.size(); ++i)
901 if (values_set.find(values2[i]) == values_set.end())
902 return false;
903 return true;
906 } // namespace
908 // TODO(skrul): Test abort startup.
909 // TODO(skrul): Test processing of cloud changes.
910 // TODO(tim): Add autofill data type controller test, and a case to cover
911 // waiting for the PersonalDataManager.
912 TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) {
913 // Don't create the root autofill node so startup fails.
914 StartSyncService(base::Closure(), true, syncer::AUTOFILL);
915 EXPECT_TRUE(sync_service_->HasUnrecoverableError());
918 TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) {
919 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
920 SetIdleChangeProcessorExpectations();
921 CreateRootHelper create_root(this, syncer::AUTOFILL);
922 EXPECT_CALL(*personal_data_manager_, Refresh());
923 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
924 EXPECT_TRUE(create_root.success());
925 std::vector<AutofillEntry> sync_entries;
926 std::vector<AutofillProfile> sync_profiles;
927 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
928 EXPECT_EQ(0U, sync_entries.size());
929 EXPECT_EQ(0U, sync_profiles.size());
932 TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) {
933 std::vector<AutofillEntry> entries;
934 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
935 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
936 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
937 SetIdleChangeProcessorExpectations();
938 CreateRootHelper create_root(this, syncer::AUTOFILL);
939 EXPECT_CALL(*personal_data_manager_, Refresh());
940 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
941 ASSERT_TRUE(create_root.success());
942 std::vector<AutofillEntry> sync_entries;
943 std::vector<AutofillProfile> sync_profiles;
944 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
945 ASSERT_EQ(1U, entries.size());
946 EXPECT_TRUE(entries[0] == sync_entries[0]);
947 EXPECT_EQ(0U, sync_profiles.size());
950 TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) {
951 std::vector<AutofillProfile*> profiles;
952 std::vector<AutofillProfile> expected_profiles;
953 // Owned by GetAutofillProfiles caller.
954 AutofillProfile* profile0 = new AutofillProfile;
955 autofill::test::SetProfileInfoWithGuid(profile0,
956 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
957 "Mitchell", "Morrison",
958 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
959 "91601", "US", "12345678910");
960 profiles.push_back(profile0);
961 expected_profiles.push_back(*profile0);
962 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
963 WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true)));
964 EXPECT_CALL(*personal_data_manager_, Refresh());
965 SetIdleChangeProcessorExpectations();
966 CreateRootHelper create_root(this, syncer::AUTOFILL_PROFILE);
967 StartSyncService(create_root.callback(), false, syncer::AUTOFILL_PROFILE);
968 ASSERT_TRUE(create_root.success());
969 std::vector<AutofillProfile> sync_profiles;
970 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles));
971 EXPECT_EQ(1U, sync_profiles.size());
972 EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0]));
975 TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
976 // There is buggy autofill code that allows duplicate name/value
977 // pairs to exist in the database with separate pair_ids.
978 std::vector<AutofillEntry> entries;
979 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
980 entries.push_back(MakeAutofillEntry("dup", "", 2));
981 entries.push_back(MakeAutofillEntry("dup", "", 3));
982 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
983 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
984 SetIdleChangeProcessorExpectations();
985 CreateRootHelper create_root(this, syncer::AUTOFILL);
986 EXPECT_CALL(*personal_data_manager_, Refresh());
987 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
988 ASSERT_TRUE(create_root.success());
989 std::vector<AutofillEntry> sync_entries;
990 std::vector<AutofillProfile> sync_profiles;
991 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
992 EXPECT_EQ(2U, sync_entries.size());
995 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) {
996 AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1));
997 AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2));
999 std::vector<AutofillEntry> native_entries;
1000 native_entries.push_back(native_entry);
1002 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1003 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
1005 std::vector<AutofillEntry> sync_entries;
1006 sync_entries.push_back(sync_entry);
1008 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries);
1010 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(ElementsAre(sync_entry))).
1011 WillOnce(Return(true));
1013 EXPECT_CALL(*personal_data_manager_, Refresh());
1014 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL);
1015 ASSERT_TRUE(add_autofill.success());
1017 std::set<AutofillEntry> expected_entries;
1018 expected_entries.insert(native_entry);
1019 expected_entries.insert(sync_entry);
1021 std::vector<AutofillEntry> new_sync_entries;
1022 std::vector<AutofillProfile> new_sync_profiles;
1023 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1024 &new_sync_profiles));
1025 std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(),
1026 new_sync_entries.end());
1028 EXPECT_TRUE(expected_entries == new_sync_entries_set);
1031 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) {
1032 AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1));
1033 AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2));
1034 AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
1036 std::vector<AutofillEntry> native_entries;
1037 native_entries.push_back(native_entry);
1038 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1039 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
1041 std::vector<AutofillEntry> sync_entries;
1042 sync_entries.push_back(sync_entry);
1043 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries);
1045 EXPECT_CALL(autofill_table_,
1046 UpdateAutofillEntries(ElementsAre(merged_entry))).WillOnce(Return(true));
1047 EXPECT_CALL(*personal_data_manager_, Refresh());
1048 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL);
1049 ASSERT_TRUE(add_autofill.success());
1051 std::vector<AutofillEntry> new_sync_entries;
1052 std::vector<AutofillProfile> new_sync_profiles;
1053 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1054 &new_sync_profiles));
1055 ASSERT_EQ(1U, new_sync_entries.size());
1056 EXPECT_TRUE(merged_entry == new_sync_entries[0]);
1059 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) {
1060 AutofillProfile sync_profile;
1061 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1062 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1063 "Mitchell", "Morrison",
1064 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1065 "91601", "US", "12345678910");
1067 AutofillProfile* native_profile = new AutofillProfile;
1068 autofill::test::SetProfileInfoWithGuid(native_profile,
1069 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
1070 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1071 "32801", "US", "19482937549");
1073 std::vector<AutofillProfile*> native_profiles;
1074 native_profiles.push_back(native_profile);
1075 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1076 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1078 std::vector<AutofillProfile> sync_profiles;
1079 sync_profiles.push_back(sync_profile);
1080 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1082 EXPECT_CALL(autofill_table_,
1083 UpdateAutofillProfile(MatchProfiles(sync_profile))).
1084 WillOnce(Return(true));
1085 EXPECT_CALL(*personal_data_manager_, Refresh());
1086 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1087 ASSERT_TRUE(add_autofill.success());
1089 std::vector<AutofillProfile> new_sync_profiles;
1090 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1091 &new_sync_profiles));
1092 ASSERT_EQ(1U, new_sync_profiles.size());
1093 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
1096 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfileCombine) {
1097 AutofillProfile sync_profile;
1098 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1099 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1100 "Mitchell", "Morrison",
1101 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1102 "91601", "US", "12345678910");
1104 AutofillProfile* native_profile = new AutofillProfile;
1105 // Same address, but different names, phones and e-mails.
1106 autofill::test::SetProfileInfoWithGuid(native_profile,
1107 "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "Alicia", "Saenz",
1108 "joewayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1109 "91601", "US", "19482937549");
1111 AutofillProfile expected_profile(sync_profile);
1112 expected_profile.OverwriteWithOrAddTo(*native_profile, "en-US");
1114 std::vector<AutofillProfile*> native_profiles;
1115 native_profiles.push_back(native_profile);
1116 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1117 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1118 EXPECT_CALL(autofill_table_,
1119 AddAutofillProfile(MatchProfiles(expected_profile))).
1120 WillOnce(Return(true));
1121 EXPECT_CALL(autofill_table_,
1122 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")).
1123 WillOnce(Return(true));
1124 std::vector<AutofillProfile> sync_profiles;
1125 sync_profiles.push_back(sync_profile);
1126 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1128 EXPECT_CALL(*personal_data_manager_, Refresh());
1129 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1130 ASSERT_TRUE(add_autofill.success());
1132 std::vector<AutofillProfile> new_sync_profiles;
1133 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1134 &new_sync_profiles));
1135 ASSERT_EQ(1U, new_sync_profiles.size());
1136 // Check that key fields are the same.
1137 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US"));
1138 // Check that multivalued fields of the synced back data include original
1139 // data.
1140 EXPECT_TRUE(
1141 IncludesField(new_sync_profiles[0], sync_profile, autofill::NAME_FULL));
1142 EXPECT_TRUE(IncludesField(
1143 new_sync_profiles[0], sync_profile, autofill::EMAIL_ADDRESS));
1144 EXPECT_TRUE(IncludesField(
1145 new_sync_profiles[0], sync_profile, autofill::PHONE_HOME_WHOLE_NUMBER));
1148 TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) {
1149 AutofillProfile sync_profile;
1151 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1152 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1153 "Mitchell", "Morrison",
1154 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1155 "91601", "US", "12345678910");
1157 std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
1158 AutofillProfile* native_profile = new AutofillProfile;
1159 autofill::test::SetProfileInfoWithGuid(native_profile,
1160 native_guid.c_str(), "Billing",
1161 "Mitchell", "Morrison",
1162 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1163 "91601", "US", "12345678910");
1165 std::vector<AutofillProfile*> native_profiles;
1166 native_profiles.push_back(native_profile);
1167 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1168 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1170 std::vector<AutofillProfile> sync_profiles;
1171 sync_profiles.push_back(sync_profile);
1172 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1174 EXPECT_CALL(autofill_table_, AddAutofillProfile(_)).
1175 WillOnce(Return(true));
1176 EXPECT_CALL(autofill_table_, RemoveAutofillProfile(native_guid)).
1177 WillOnce(Return(true));
1178 EXPECT_CALL(*personal_data_manager_, Refresh());
1179 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1180 ASSERT_TRUE(add_autofill.success());
1182 std::vector<AutofillProfile> new_sync_profiles;
1183 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1184 &new_sync_profiles));
1185 ASSERT_EQ(1U, new_sync_profiles.size());
1186 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
1187 EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid());
1190 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) {
1191 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
1192 EXPECT_CALL(*personal_data_manager_, Refresh());
1193 SetIdleChangeProcessorExpectations();
1194 CreateRootHelper create_root(this, syncer::AUTOFILL);
1195 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1196 ASSERT_TRUE(create_root.success());
1198 AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1));
1200 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).
1201 WillOnce(DoAll(SetArgumentPointee<2>(added_entry.date_created()),
1202 SetArgumentPointee<3>(added_entry.date_last_used()),
1203 Return(true)));
1205 AutofillChangeList changes;
1206 changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key()));
1208 web_data_service_->OnAutofillEntriesChanged(changes);
1210 std::vector<AutofillEntry> new_sync_entries;
1211 std::vector<AutofillProfile> new_sync_profiles;
1212 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1213 &new_sync_profiles));
1214 ASSERT_EQ(1U, new_sync_entries.size());
1215 EXPECT_TRUE(added_entry == new_sync_entries[0]);
1218 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
1219 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
1220 EXPECT_CALL(*personal_data_manager_, Refresh());
1221 SetIdleChangeProcessorExpectations();
1222 CreateRootHelper create_root(this, syncer::AUTOFILL_PROFILE);
1223 StartSyncService(create_root.callback(), false, syncer::AUTOFILL_PROFILE);
1224 ASSERT_TRUE(create_root.success());
1226 AutofillProfile added_profile;
1227 autofill::test::SetProfileInfoWithGuid(&added_profile,
1228 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
1229 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1230 "32801", "US", "19482937549");
1232 AutofillProfileChange change(
1233 AutofillProfileChange::ADD, added_profile.guid(), &added_profile);
1234 web_data_service_->OnAutofillProfileChanged(change);
1236 std::vector<AutofillProfile> new_sync_profiles;
1237 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1238 &new_sync_profiles));
1239 ASSERT_EQ(1U, new_sync_profiles.size());
1240 EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0]));
1243 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
1244 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
1245 std::vector<AutofillEntry> original_entries;
1246 original_entries.push_back(original_entry);
1248 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1249 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
1250 EXPECT_CALL(*personal_data_manager_, Refresh());
1251 CreateRootHelper create_root(this, syncer::AUTOFILL);
1252 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1253 ASSERT_TRUE(create_root.success());
1255 AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
1257 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).
1258 WillOnce(DoAll(SetArgumentPointee<2>(updated_entry.date_created()),
1259 SetArgumentPointee<3>(updated_entry.date_last_used()),
1260 Return(true)));
1262 AutofillChangeList changes;
1263 changes.push_back(AutofillChange(AutofillChange::UPDATE,
1264 updated_entry.key()));
1265 web_data_service_->OnAutofillEntriesChanged(changes);
1267 std::vector<AutofillEntry> new_sync_entries;
1268 std::vector<AutofillProfile> new_sync_profiles;
1269 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1270 &new_sync_profiles));
1271 ASSERT_EQ(1U, new_sync_entries.size());
1272 EXPECT_TRUE(updated_entry == new_sync_entries[0]);
1276 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) {
1277 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
1278 std::vector<AutofillEntry> original_entries;
1279 original_entries.push_back(original_entry);
1281 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1282 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
1283 EXPECT_CALL(*personal_data_manager_, Refresh());
1284 CreateRootHelper create_root(this, syncer::AUTOFILL);
1285 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1286 ASSERT_TRUE(create_root.success());
1288 AutofillChangeList changes;
1289 changes.push_back(AutofillChange(AutofillChange::REMOVE,
1290 original_entry.key()));
1291 web_data_service_->OnAutofillEntriesChanged(changes);
1293 std::vector<AutofillEntry> new_sync_entries;
1294 std::vector<AutofillProfile> new_sync_profiles;
1295 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1296 &new_sync_profiles));
1297 ASSERT_EQ(0U, new_sync_entries.size());
1300 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) {
1301 AutofillProfile sync_profile;
1302 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1303 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1304 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1305 "32801", "US", "19482937549");
1306 AutofillProfile* native_profile = new AutofillProfile;
1307 autofill::test::SetProfileInfoWithGuid(native_profile,
1308 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1309 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1310 "32801", "US", "19482937549");
1312 std::vector<AutofillProfile*> native_profiles;
1313 native_profiles.push_back(native_profile);
1314 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1315 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1317 std::vector<AutofillProfile> sync_profiles;
1318 sync_profiles.push_back(sync_profile);
1319 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1320 EXPECT_CALL(*personal_data_manager_, Refresh());
1321 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1322 ASSERT_TRUE(add_autofill.success());
1324 AutofillProfileChange change(
1325 AutofillProfileChange::REMOVE, sync_profile.guid(), NULL);
1326 web_data_service_->OnAutofillProfileChanged(change);
1328 std::vector<AutofillProfile> new_sync_profiles;
1329 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1330 &new_sync_profiles));
1331 ASSERT_EQ(0U, new_sync_profiles.size());
1334 // http://crbug.com/57884
1335 TEST_F(ProfileSyncServiceAutofillTest, DISABLED_ServerChangeRace) {
1336 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via
1337 // LoadAutofillData().
1338 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1339 Times(3).WillRepeatedly(Return(true));
1340 // On the other hand Autofill and Autocomplete are separated now, so
1341 // GetAutofillProfiles() should not be called.
1342 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).Times(0);
1343 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).
1344 WillRepeatedly(Return(true));
1345 EXPECT_CALL(*personal_data_manager_, Refresh()).Times(3);
1346 CreateRootHelper create_root(this, syncer::AUTOFILL);
1347 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1348 ASSERT_TRUE(create_root.success());
1350 // (true, false) means we have to reset after |Signal|, init to unsignaled.
1351 scoped_ptr<WaitableEvent> wait_for_start(new WaitableEvent(true, false));
1352 scoped_ptr<WaitableEvent> wait_for_syncapi(new WaitableEvent(true, false));
1353 scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater(
1354 sync_service_, &wait_for_start, &wait_for_syncapi));
1356 // This server side update will stall waiting for CommitWaiter.
1357 updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
1358 wait_for_start->Wait();
1360 AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
1361 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry));
1362 DVLOG(1) << "Syncapi update finished.";
1364 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
1365 // Signal FakeServerUpdater that it can complete.
1366 wait_for_syncapi->Signal();
1368 // Make another entry to ensure nothing broke afterwards and wait for finish
1369 // to clean up.
1370 updater->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3));
1372 std::vector<AutofillEntry> sync_entries;
1373 std::vector<AutofillProfile> sync_profiles;
1374 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
1375 EXPECT_EQ(3U, sync_entries.size());
1376 EXPECT_EQ(0U, sync_profiles.size());
1377 for (size_t i = 0; i < sync_entries.size(); i++) {
1378 DVLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name()
1379 << ", " << sync_entries[i].key().value();