[Cronet] Delay StartNetLog and StopNetLog until native request context is initialized
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_service_autofill_unittest.cc
blob758db1bd7be4e2ebcec5b53ff1b85a4a9b7cb804
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 namespace syncable {
107 class Id;
110 namespace {
112 const char kTestProfileName[] = "test-profile";
114 void RunAndSignal(const base::Closure& cb, WaitableEvent* event) {
115 cb.Run();
116 event->Signal();
119 } // namespace
121 class AutofillTableMock : public AutofillTable {
122 public:
123 AutofillTableMock() : AutofillTable("en-US") {}
124 MOCK_METHOD2(RemoveFormElement,
125 bool(const base::string16& name,
126 const base::string16& value)); // NOLINT
127 MOCK_METHOD1(GetAllAutofillEntries,
128 bool(std::vector<AutofillEntry>* entries)); // NOLINT
129 MOCK_METHOD4(GetAutofillTimestamps,
130 bool(const base::string16& name, // NOLINT
131 const base::string16& value,
132 base::Time* date_created,
133 base::Time* date_last_used));
134 MOCK_METHOD1(UpdateAutofillEntries,
135 bool(const std::vector<AutofillEntry>&)); // NOLINT
136 MOCK_METHOD1(GetAutofillProfiles,
137 bool(std::vector<AutofillProfile*>*)); // NOLINT
138 MOCK_METHOD1(UpdateAutofillProfile,
139 bool(const AutofillProfile&)); // NOLINT
140 MOCK_METHOD1(AddAutofillProfile,
141 bool(const AutofillProfile&)); // NOLINT
142 MOCK_METHOD1(RemoveAutofillProfile,
143 bool(const std::string&)); // NOLINT
146 MATCHER_P(MatchProfiles, profile, "") {
147 return (profile.Compare(arg) == 0);
150 class WebDatabaseFake : public WebDatabase {
151 public:
152 explicit WebDatabaseFake(AutofillTable* autofill_table) {
153 AddTable(autofill_table);
157 class MockAutofillBackend : public autofill::AutofillWebDataBackend {
158 public:
159 MockAutofillBackend(
160 WebDatabase* web_database,
161 const base::Closure& on_changed)
162 : web_database_(web_database),
163 on_changed_(on_changed) {
166 ~MockAutofillBackend() override {}
167 WebDatabase* GetDatabase() override { return web_database_; }
168 void AddObserver(
169 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {}
170 void RemoveObserver(
171 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {}
172 void RemoveExpiredFormElements() override {}
173 void NotifyOfMultipleAutofillChanges() override {
174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
175 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_changed_);
178 private:
179 WebDatabase* web_database_;
180 base::Closure on_changed_;
183 class ProfileSyncServiceAutofillTest;
185 template<class AutofillProfile>
186 syncer::ModelType GetModelType() {
187 return syncer::UNSPECIFIED;
190 template<>
191 syncer::ModelType GetModelType<AutofillEntry>() {
192 return syncer::AUTOFILL;
195 template<>
196 syncer::ModelType GetModelType<AutofillProfile>() {
197 return syncer::AUTOFILL_PROFILE;
200 class TokenWebDataServiceFake : public TokenWebData {
201 public:
202 TokenWebDataServiceFake()
203 : TokenWebData(
204 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
205 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)) {
208 bool IsDatabaseLoaded() override { return true; }
210 AutofillWebDataService::Handle GetAllTokens(
211 WebDataServiceConsumer* consumer) override {
212 // TODO(tim): It would be nice if WebDataService was injected on
213 // construction of ProfileOAuth2TokenService rather than fetched by
214 // Initialize so that this isn't necessary (we could pass a NULL service).
215 // We currently do return it via EXPECT_CALLs, but without depending on
216 // order-of-initialization (which seems way more fragile) we can't tell
217 // which component is asking at what time, and some components in these
218 // Autofill tests require a WebDataService.
219 return 0;
222 private:
223 ~TokenWebDataServiceFake() override {}
225 DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake);
228 class WebDataServiceFake : public AutofillWebDataService {
229 public:
230 WebDataServiceFake()
231 : AutofillWebDataService(
232 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
233 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)),
234 web_database_(NULL),
235 autocomplete_syncable_service_(NULL),
236 autofill_profile_syncable_service_(NULL),
237 syncable_service_created_or_destroyed_(false, false) {
240 void SetDatabase(WebDatabase* web_database) {
241 web_database_ = web_database;
244 void StartSyncableService() {
245 // The |autofill_profile_syncable_service_| must be constructed on the DB
246 // thread.
247 const base::Closure& on_changed_callback = base::Bind(
248 &WebDataServiceFake::NotifyAutofillMultipleChangedOnUIThread,
249 AsWeakPtr());
251 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
252 base::Bind(&WebDataServiceFake::CreateSyncableService,
253 base::Unretained(this),
254 on_changed_callback));
255 syncable_service_created_or_destroyed_.Wait();
258 void ShutdownSyncableService() {
259 // The |autofill_profile_syncable_service_| must be destructed on the DB
260 // thread.
261 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
262 base::Bind(&WebDataServiceFake::DestroySyncableService,
263 base::Unretained(this)));
264 syncable_service_created_or_destroyed_.Wait();
267 bool IsDatabaseLoaded() override { return true; }
269 WebDatabase* GetDatabase() override { return web_database_; }
271 void OnAutofillEntriesChanged(const AutofillChangeList& changes) {
272 WaitableEvent event(true, false);
274 base::Closure notify_cb =
275 base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged,
276 base::Unretained(autocomplete_syncable_service_),
277 changes);
278 BrowserThread::PostTask(
279 BrowserThread::DB,
280 FROM_HERE,
281 base::Bind(&RunAndSignal, notify_cb, &event));
282 event.Wait();
285 void OnAutofillProfileChanged(const AutofillProfileChange& changes) {
286 WaitableEvent event(true, false);
288 base::Closure notify_cb =
289 base::Bind(&AutocompleteSyncableService::AutofillProfileChanged,
290 base::Unretained(autofill_profile_syncable_service_),
291 changes);
292 BrowserThread::PostTask(
293 BrowserThread::DB,
294 FROM_HERE,
295 base::Bind(&RunAndSignal, notify_cb, &event));
296 event.Wait();
299 private:
300 ~WebDataServiceFake() override {}
302 void CreateSyncableService(const base::Closure& on_changed_callback) {
303 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
304 // These services are deleted in DestroySyncableService().
305 backend_.reset(new MockAutofillBackend(
306 GetDatabase(), on_changed_callback));
307 AutocompleteSyncableService::CreateForWebDataServiceAndBackend(
308 this, backend_.get());
309 AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
310 this, backend_.get(), "en-US");
312 autocomplete_syncable_service_ =
313 AutocompleteSyncableService::FromWebDataService(this);
314 autofill_profile_syncable_service_ =
315 AutofillProfileSyncableService::FromWebDataService(this);
317 syncable_service_created_or_destroyed_.Signal();
320 void DestroySyncableService() {
321 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
322 autocomplete_syncable_service_ = NULL;
323 autofill_profile_syncable_service_ = NULL;
324 backend_.reset();
325 syncable_service_created_or_destroyed_.Signal();
328 WebDatabase* web_database_;
329 AutocompleteSyncableService* autocomplete_syncable_service_;
330 AutofillProfileSyncableService* autofill_profile_syncable_service_;
331 scoped_ptr<autofill::AutofillWebDataBackend> backend_;
333 WaitableEvent syncable_service_created_or_destroyed_;
335 DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake);
338 KeyedService* BuildMockWebDataServiceWrapper(content::BrowserContext* profile) {
339 return new MockWebDataServiceWrapper(
340 new WebDataServiceFake(),
341 new TokenWebDataServiceFake());
344 ACTION_P(MakeAutocompleteSyncComponents, wds) {
345 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
346 if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
347 return base::WeakPtr<syncer::SyncableService>();
348 return AutocompleteSyncableService::FromWebDataService(wds)->AsWeakPtr();
351 ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) {
352 return new sync_driver::DataTypeManagerImpl(
353 base::Closure(),
354 debug_listener,
355 arg1,
356 arg2,
357 arg3,
358 arg4);
361 ACTION_P(MakeAutofillProfileSyncComponents, wds) {
362 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
363 if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
364 return base::WeakPtr<syncer::SyncableService>();
365 return AutofillProfileSyncableService::FromWebDataService(wds)->AsWeakPtr();
368 class AbstractAutofillFactory {
369 public:
370 virtual DataTypeController* CreateDataTypeController(
371 ProfileSyncComponentsFactory* factory,
372 TestingProfile* profile,
373 ProfileSyncService* service) = 0;
374 virtual void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
375 ProfileSyncService* service,
376 AutofillWebDataService* wds,
377 DataTypeController* dtc) = 0;
378 virtual ~AbstractAutofillFactory() {}
381 class AutofillEntryFactory : public AbstractAutofillFactory {
382 public:
383 DataTypeController* CreateDataTypeController(
384 ProfileSyncComponentsFactory* factory,
385 TestingProfile* profile,
386 ProfileSyncService* service) override {
387 return new AutofillDataTypeController(factory, profile);
390 void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
391 ProfileSyncService* service,
392 AutofillWebDataService* wds,
393 DataTypeController* dtc) override {
394 EXPECT_CALL(*factory, GetSyncableServiceForType(syncer::AUTOFILL)).
395 WillOnce(MakeAutocompleteSyncComponents(wds));
399 class AutofillProfileFactory : public AbstractAutofillFactory {
400 public:
401 DataTypeController* CreateDataTypeController(
402 ProfileSyncComponentsFactory* factory,
403 TestingProfile* profile,
404 ProfileSyncService* service) override {
405 return new AutofillProfileDataTypeController(factory, profile);
408 void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
409 ProfileSyncService* service,
410 AutofillWebDataService* wds,
411 DataTypeController* dtc) override {
412 EXPECT_CALL(*factory,
413 GetSyncableServiceForType(syncer::AUTOFILL_PROFILE)).
414 WillOnce(MakeAutofillProfileSyncComponents(wds));
418 class MockPersonalDataManager : public PersonalDataManager {
419 public:
420 MockPersonalDataManager() : PersonalDataManager("en-US") {}
421 MOCK_CONST_METHOD0(IsDataLoaded, bool());
422 MOCK_METHOD0(LoadProfiles, void());
423 MOCK_METHOD0(LoadCreditCards, void());
424 MOCK_METHOD0(Refresh, void());
426 static KeyedService* Build(content::BrowserContext* profile) {
427 return new MockPersonalDataManager();
431 template <class T> class AddAutofillHelper;
433 class ProfileSyncServiceAutofillTest
434 : public AbstractProfileSyncServiceTest,
435 public syncer::DataTypeDebugInfoListener {
436 public:
437 // DataTypeDebugInfoListener implementation.
438 void OnDataTypeConfigureComplete(const std::vector<
439 syncer::DataTypeConfigurationStats>& configuration_stats) override {
440 ASSERT_EQ(1u, configuration_stats.size());
441 association_stats_ = configuration_stats[0].association_stats;
444 protected:
445 ProfileSyncServiceAutofillTest()
446 : profile_manager_(TestingBrowserProcess::GetGlobal()),
447 debug_ptr_factory_(this) {
449 ~ProfileSyncServiceAutofillTest() override {}
451 AutofillProfileFactory profile_factory_;
452 AutofillEntryFactory entry_factory_;
454 AbstractAutofillFactory* GetFactory(syncer::ModelType type) {
455 if (type == syncer::AUTOFILL) {
456 return &entry_factory_;
457 } else if (type == syncer::AUTOFILL_PROFILE) {
458 return &profile_factory_;
459 } else {
460 NOTREACHED();
461 return NULL;
465 void SetUp() override {
466 AbstractProfileSyncServiceTest::SetUp();
467 ASSERT_TRUE(profile_manager_.SetUp());
468 TestingProfile::TestingFactories testing_factories;
469 testing_factories.push_back(std::make_pair(
470 ProfileOAuth2TokenServiceFactory::GetInstance(),
471 BuildAutoIssuingFakeProfileOAuth2TokenService));
472 profile_ = profile_manager_.CreateTestingProfile(
473 kTestProfileName,
474 scoped_ptr<PrefServiceSyncable>(),
475 base::UTF8ToUTF16(kTestProfileName),
477 std::string(),
478 testing_factories);
479 web_database_.reset(new WebDatabaseFake(&autofill_table_));
480 MockWebDataServiceWrapper* wrapper =
481 static_cast<MockWebDataServiceWrapper*>(
482 WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse(
483 profile_, BuildMockWebDataServiceWrapper));
484 web_data_service_ =
485 static_cast<WebDataServiceFake*>(wrapper->GetAutofillWebData().get());
486 web_data_service_->SetDatabase(web_database_.get());
488 personal_data_manager_ = static_cast<MockPersonalDataManager*>(
489 autofill::PersonalDataManagerFactory::GetInstance()
490 ->SetTestingFactoryAndUse(profile_,
491 MockPersonalDataManager::Build));
493 EXPECT_CALL(*personal_data_manager_, LoadProfiles()).Times(1);
494 EXPECT_CALL(*personal_data_manager_, LoadCreditCards()).Times(1);
496 personal_data_manager_->Init(
497 WebDataServiceFactory::GetAutofillWebDataForProfile(
498 profile_, ServiceAccessType::EXPLICIT_ACCESS),
499 profile_->GetPrefs(),
500 profile_->IsOffTheRecord());
502 web_data_service_->StartSyncableService();
504 // When UpdateAutofillEntries() is called with an empty list, the return
505 // value should be |true|, rather than the default of |false|.
506 std::vector<AutofillEntry> empty;
507 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(empty))
508 .WillRepeatedly(Return(true));
511 void TearDown() override {
512 // Note: The tear down order is important.
513 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
514 web_data_service_->ShutdownOnUIThread();
515 web_data_service_->ShutdownSyncableService();
516 web_data_service_ = NULL;
517 // To prevent a leak, fully release TestURLRequestContext to ensure its
518 // destruction on the IO message loop.
519 profile_ = NULL;
520 profile_manager_.DeleteTestingProfile(kTestProfileName);
521 AbstractProfileSyncServiceTest::TearDown();
524 int GetSyncCount(syncer::ModelType type) {
525 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
526 syncer::ReadNode node(&trans);
527 if (node.InitTypeRoot(type) != syncer::BaseNode::INIT_OK)
528 return 0;
529 return node.GetTotalNodeCount() - 1;
532 void StartSyncService(const base::Closure& callback,
533 bool will_fail_association,
534 syncer::ModelType type) {
535 AbstractAutofillFactory* factory = GetFactory(type);
536 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile_);
537 signin->SetAuthenticatedUsername("test_user@gmail.com");
538 sync_service_ = TestProfileSyncService::BuildAutoStartAsyncInit(profile_,
539 callback);
541 ProfileSyncComponentsFactoryMock* components =
542 sync_service_->components_factory_mock();
543 DataTypeController* data_type_controller =
544 factory->CreateDataTypeController(components, profile_, sync_service_);
545 factory->SetExpectation(components,
546 sync_service_,
547 web_data_service_.get(),
548 data_type_controller);
550 EXPECT_CALL(*components, CreateDataTypeManager(_, _, _, _, _)).
551 WillOnce(ReturnNewDataTypeManagerWithDebugListener(
552 syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr())));
554 EXPECT_CALL(*personal_data_manager_, IsDataLoaded()).
555 WillRepeatedly(Return(true));
557 // We need tokens to get the tests going
558 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
559 ->UpdateCredentials("test_user@gmail.com", "oauth2_login_token");
561 sync_service_->RegisterDataTypeController(data_type_controller);
562 sync_service_->Initialize();
563 base::MessageLoop::current()->Run();
565 // It's possible this test triggered an unrecoverable error, in which case
566 // we can't get the sync count.
567 if (sync_service_->SyncActive()) {
568 EXPECT_EQ(GetSyncCount(type),
569 association_stats_.num_sync_items_after_association);
571 EXPECT_EQ(association_stats_.num_sync_items_after_association,
572 association_stats_.num_sync_items_before_association +
573 association_stats_.num_sync_items_added -
574 association_stats_.num_sync_items_deleted);
577 bool AddAutofillSyncNode(const AutofillEntry& entry) {
578 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
579 syncer::ReadNode autofill_root(&trans);
580 if (autofill_root.InitTypeRoot(syncer::AUTOFILL) != BaseNode::INIT_OK) {
581 return false;
584 syncer::WriteNode node(&trans);
585 std::string tag = AutocompleteSyncableService::KeyToTag(
586 base::UTF16ToUTF8(entry.key().name()),
587 base::UTF16ToUTF8(entry.key().value()));
588 syncer::WriteNode::InitUniqueByCreationResult result =
589 node.InitUniqueByCreation(syncer::AUTOFILL, autofill_root, tag);
590 if (result != syncer::WriteNode::INIT_SUCCESS)
591 return false;
593 sync_pb::EntitySpecifics specifics;
594 AutocompleteSyncableService::WriteAutofillEntry(entry, &specifics);
595 sync_pb::AutofillSpecifics* autofill_specifics =
596 specifics.mutable_autofill();
597 node.SetAutofillSpecifics(*autofill_specifics);
598 return true;
601 bool AddAutofillSyncNode(const AutofillProfile& profile) {
602 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
603 syncer::ReadNode autofill_root(&trans);
604 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) {
605 return false;
607 syncer::WriteNode node(&trans);
608 std::string tag = profile.guid();
609 syncer::WriteNode::InitUniqueByCreationResult result =
610 node.InitUniqueByCreation(syncer::AUTOFILL_PROFILE,
611 autofill_root, tag);
612 if (result != syncer::WriteNode::INIT_SUCCESS)
613 return false;
615 sync_pb::EntitySpecifics specifics;
616 AutofillProfileSyncableService::WriteAutofillProfile(profile, &specifics);
617 sync_pb::AutofillProfileSpecifics* profile_specifics =
618 specifics.mutable_autofill_profile();
619 node.SetAutofillProfileSpecifics(*profile_specifics);
620 return true;
623 bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries,
624 std::vector<AutofillProfile>* profiles) {
625 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
626 syncer::ReadNode autofill_root(&trans);
627 if (autofill_root.InitTypeRoot(syncer::AUTOFILL) != BaseNode::INIT_OK) {
628 return false;
631 int64 child_id = autofill_root.GetFirstChildId();
632 while (child_id != syncer::kInvalidId) {
633 syncer::ReadNode child_node(&trans);
634 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK)
635 return false;
637 const sync_pb::AutofillSpecifics& autofill(
638 child_node.GetAutofillSpecifics());
639 if (autofill.has_value()) {
640 AutofillKey key(base::UTF8ToUTF16(autofill.name()),
641 base::UTF8ToUTF16(autofill.value()));
642 std::vector<base::Time> timestamps;
643 int timestamps_count = autofill.usage_timestamp_size();
644 for (int i = 0; i < timestamps_count; ++i) {
645 timestamps.push_back(Time::FromInternalValue(
646 autofill.usage_timestamp(i)));
648 entries->push_back(
649 AutofillEntry(key, timestamps.front(), timestamps.back()));
650 } else if (autofill.has_profile()) {
651 AutofillProfile p;
652 p.set_guid(autofill.profile().guid());
653 AutofillProfileSyncableService::OverwriteProfileWithServerData(
654 autofill.profile(), &p, "en-US");
655 profiles->push_back(p);
657 child_id = child_node.GetSuccessorId();
659 return true;
662 bool GetAutofillProfilesFromSyncDBUnderProfileNode(
663 std::vector<AutofillProfile>* profiles) {
664 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
665 syncer::ReadNode autofill_root(&trans);
666 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) {
667 return false;
670 int64 child_id = autofill_root.GetFirstChildId();
671 while (child_id != syncer::kInvalidId) {
672 syncer::ReadNode child_node(&trans);
673 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK)
674 return false;
676 const sync_pb::AutofillProfileSpecifics& autofill(
677 child_node.GetAutofillProfileSpecifics());
678 AutofillProfile p;
679 p.set_guid(autofill.guid());
680 AutofillProfileSyncableService::OverwriteProfileWithServerData(
681 autofill, &p, "en-US");
682 profiles->push_back(p);
683 child_id = child_node.GetSuccessorId();
685 return true;
688 void SetIdleChangeProcessorExpectations() {
689 EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0);
690 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0);
692 // Only permit UpdateAutofillEntries() to be called with an empty list.
693 std::vector<AutofillEntry> empty;
694 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(Not(empty))).Times(0);
697 static AutofillEntry MakeAutofillEntry(const char* name,
698 const char* value,
699 int time_shift0,
700 int time_shift1) {
701 // Time deep in the past would cause Autocomplete sync to discard the
702 // entries.
703 static Time base_time = Time::Now().LocalMidnight();
705 base::Time date_created = base_time + TimeDelta::FromSeconds(time_shift0);
706 base::Time date_last_used = date_created;
707 if (time_shift1 >= 0)
708 date_last_used = base_time + TimeDelta::FromSeconds(time_shift1);
709 return AutofillEntry(
710 AutofillKey(base::ASCIIToUTF16(name), base::ASCIIToUTF16(value)),
711 date_created, date_last_used);
714 static AutofillEntry MakeAutofillEntry(const char* name,
715 const char* value,
716 int time_shift) {
717 return MakeAutofillEntry(name, value, time_shift, -1);
720 friend class AddAutofillHelper<AutofillEntry>;
721 friend class AddAutofillHelper<AutofillProfile>;
722 friend class FakeServerUpdater;
724 TestingProfileManager profile_manager_;
725 TestingProfile* profile_;
726 AutofillTableMock autofill_table_;
727 scoped_ptr<WebDatabaseFake> web_database_;
728 scoped_refptr<WebDataServiceFake> web_data_service_;
729 MockPersonalDataManager* personal_data_manager_;
730 syncer::DataTypeAssociationStats association_stats_;
731 base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_;
734 template <class T>
735 class AddAutofillHelper {
736 public:
737 AddAutofillHelper(ProfileSyncServiceAutofillTest* test,
738 const std::vector<T>& entries)
739 : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback,
740 base::Unretained(this), test, entries)),
741 success_(false) {
744 const base::Closure& callback() const { return callback_; }
745 bool success() { return success_; }
747 private:
748 void AddAutofillCallback(ProfileSyncServiceAutofillTest* test,
749 const std::vector<T>& entries) {
750 if (!test->CreateRoot(GetModelType<T>()))
751 return;
753 for (size_t i = 0; i < entries.size(); ++i) {
754 if (!test->AddAutofillSyncNode(entries[i]))
755 return;
757 success_ = true;
760 base::Closure callback_;
761 bool success_;
764 // Overload write transaction to use custom NotifyTransactionComplete
765 class WriteTransactionTest: public WriteTransaction {
766 public:
767 WriteTransactionTest(const tracked_objects::Location& from_here,
768 WriterTag writer,
769 syncer::syncable::Directory* directory,
770 scoped_ptr<WaitableEvent>* wait_for_syncapi)
771 : WriteTransaction(from_here, writer, directory),
772 wait_for_syncapi_(wait_for_syncapi) { }
774 void NotifyTransactionComplete(syncer::ModelTypeSet types) override {
775 // This is where we differ. Force a thread change here, giving another
776 // thread a chance to create a WriteTransaction
777 (*wait_for_syncapi_)->Wait();
779 WriteTransaction::NotifyTransactionComplete(types);
782 private:
783 scoped_ptr<WaitableEvent>* wait_for_syncapi_;
786 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
787 // post tasks with it.
788 class FakeServerUpdater : public base::RefCountedThreadSafe<FakeServerUpdater> {
789 public:
790 FakeServerUpdater(TestProfileSyncService* service,
791 scoped_ptr<WaitableEvent>* wait_for_start,
792 scoped_ptr<WaitableEvent>* wait_for_syncapi)
793 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)),
794 service_(service),
795 wait_for_start_(wait_for_start),
796 wait_for_syncapi_(wait_for_syncapi),
797 is_finished_(false, false) { }
799 void Update() {
800 // This gets called in a modelsafeworker thread.
801 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
803 syncer::UserShare* user_share = service_->GetUserShare();
804 syncer::syncable::Directory* directory = user_share->directory.get();
806 // Create autofill protobuf.
807 std::string tag = AutocompleteSyncableService::KeyToTag(
808 base::UTF16ToUTF8(entry_.key().name()),
809 base::UTF16ToUTF8(entry_.key().value()));
810 sync_pb::AutofillSpecifics new_autofill;
811 new_autofill.set_name(base::UTF16ToUTF8(entry_.key().name()));
812 new_autofill.set_value(base::UTF16ToUTF8(entry_.key().value()));
813 new_autofill.add_usage_timestamp(entry_.date_created().ToInternalValue());
814 if (entry_.date_created() != entry_.date_last_used()) {
815 new_autofill.add_usage_timestamp(
816 entry_.date_last_used().ToInternalValue());
819 sync_pb::EntitySpecifics entity_specifics;
820 entity_specifics.mutable_autofill()->CopyFrom(new_autofill);
823 // Tell main thread we've started
824 (*wait_for_start_)->Signal();
826 // Create write transaction.
827 WriteTransactionTest trans(FROM_HERE, UNITTEST, directory,
828 wait_for_syncapi_);
830 // Create actual entry based on autofill protobuf information.
831 // Simulates effects of UpdateLocalDataFromServerData
832 MutableEntry parent(&trans, GET_TYPE_ROOT, syncer::AUTOFILL);
833 MutableEntry item(&trans, CREATE, syncer::AUTOFILL, parent.GetId(), tag);
834 ASSERT_TRUE(item.good());
835 item.PutSpecifics(entity_specifics);
836 item.PutServerSpecifics(entity_specifics);
837 item.PutBaseVersion(1);
838 syncer::syncable::Id server_item_id =
839 service_->id_factory()->NewServerId();
840 item.PutId(server_item_id);
841 syncer::syncable::Id new_predecessor;
842 ASSERT_TRUE(item.PutPredecessor(new_predecessor));
844 DVLOG(1) << "FakeServerUpdater finishing.";
845 is_finished_.Signal();
848 void CreateNewEntry(const AutofillEntry& entry) {
849 entry_ = entry;
850 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
851 if (!BrowserThread::PostTask(
852 BrowserThread::DB, FROM_HERE,
853 base::Bind(&FakeServerUpdater::Update, this))) {
854 NOTREACHED() << "Failed to post task to the db thread.";
855 return;
859 void CreateNewEntryAndWait(const AutofillEntry& entry) {
860 entry_ = entry;
861 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
862 is_finished_.Reset();
863 if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
864 base::Bind(&FakeServerUpdater::Update, this))) {
865 NOTREACHED() << "Failed to post task to the db thread.";
866 return;
868 is_finished_.Wait();
871 private:
872 friend class base::RefCountedThreadSafe<FakeServerUpdater>;
873 ~FakeServerUpdater() { }
875 AutofillEntry entry_;
876 TestProfileSyncService* service_;
877 scoped_ptr<WaitableEvent>* wait_for_start_;
878 scoped_ptr<WaitableEvent>* wait_for_syncapi_;
879 WaitableEvent is_finished_;
880 syncer::syncable::Id parent_id_;
883 namespace {
885 // Checks if the field of type |field_type| in |profile1| includes all values
886 // of the field in |profile2|.
887 bool IncludesField(const AutofillProfile& profile1,
888 const AutofillProfile& profile2,
889 ServerFieldType field_type) {
890 std::vector<base::string16> values1;
891 profile1.GetRawMultiInfo(field_type, &values1);
892 std::vector<base::string16> values2;
893 profile2.GetRawMultiInfo(field_type, &values2);
895 std::set<base::string16> values_set;
896 for (size_t i = 0; i < values1.size(); ++i)
897 values_set.insert(values1[i]);
898 for (size_t i = 0; i < values2.size(); ++i)
899 if (values_set.find(values2[i]) == values_set.end())
900 return false;
901 return true;
904 } // namespace
906 // TODO(skrul): Test abort startup.
907 // TODO(skrul): Test processing of cloud changes.
908 // TODO(tim): Add autofill data type controller test, and a case to cover
909 // waiting for the PersonalDataManager.
910 TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) {
911 // Don't create the root autofill node so startup fails.
912 StartSyncService(base::Closure(), true, syncer::AUTOFILL);
913 EXPECT_TRUE(sync_service_->HasUnrecoverableError());
916 TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) {
917 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
918 SetIdleChangeProcessorExpectations();
919 CreateRootHelper create_root(this, syncer::AUTOFILL);
920 EXPECT_CALL(*personal_data_manager_, Refresh());
921 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
922 EXPECT_TRUE(create_root.success());
923 std::vector<AutofillEntry> sync_entries;
924 std::vector<AutofillProfile> sync_profiles;
925 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
926 EXPECT_EQ(0U, sync_entries.size());
927 EXPECT_EQ(0U, sync_profiles.size());
930 TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) {
931 std::vector<AutofillEntry> entries;
932 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
933 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
934 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
935 SetIdleChangeProcessorExpectations();
936 CreateRootHelper create_root(this, syncer::AUTOFILL);
937 EXPECT_CALL(*personal_data_manager_, Refresh());
938 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
939 ASSERT_TRUE(create_root.success());
940 std::vector<AutofillEntry> sync_entries;
941 std::vector<AutofillProfile> sync_profiles;
942 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
943 ASSERT_EQ(1U, entries.size());
944 EXPECT_TRUE(entries[0] == sync_entries[0]);
945 EXPECT_EQ(0U, sync_profiles.size());
948 TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) {
949 std::vector<AutofillProfile*> profiles;
950 std::vector<AutofillProfile> expected_profiles;
951 // Owned by GetAutofillProfiles caller.
952 AutofillProfile* profile0 = new AutofillProfile;
953 autofill::test::SetProfileInfoWithGuid(profile0,
954 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
955 "Mitchell", "Morrison",
956 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
957 "91601", "US", "12345678910");
958 profiles.push_back(profile0);
959 expected_profiles.push_back(*profile0);
960 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
961 WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true)));
962 EXPECT_CALL(*personal_data_manager_, Refresh());
963 SetIdleChangeProcessorExpectations();
964 CreateRootHelper create_root(this, syncer::AUTOFILL_PROFILE);
965 StartSyncService(create_root.callback(), false, syncer::AUTOFILL_PROFILE);
966 ASSERT_TRUE(create_root.success());
967 std::vector<AutofillProfile> sync_profiles;
968 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles));
969 EXPECT_EQ(1U, sync_profiles.size());
970 EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0]));
973 TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
974 // There is buggy autofill code that allows duplicate name/value
975 // pairs to exist in the database with separate pair_ids.
976 std::vector<AutofillEntry> entries;
977 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
978 entries.push_back(MakeAutofillEntry("dup", "", 2));
979 entries.push_back(MakeAutofillEntry("dup", "", 3));
980 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
981 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
982 SetIdleChangeProcessorExpectations();
983 CreateRootHelper create_root(this, syncer::AUTOFILL);
984 EXPECT_CALL(*personal_data_manager_, Refresh());
985 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
986 ASSERT_TRUE(create_root.success());
987 std::vector<AutofillEntry> sync_entries;
988 std::vector<AutofillProfile> sync_profiles;
989 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
990 EXPECT_EQ(2U, sync_entries.size());
993 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) {
994 AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1));
995 AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2));
997 std::vector<AutofillEntry> native_entries;
998 native_entries.push_back(native_entry);
1000 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1001 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
1003 std::vector<AutofillEntry> sync_entries;
1004 sync_entries.push_back(sync_entry);
1006 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries);
1008 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(ElementsAre(sync_entry))).
1009 WillOnce(Return(true));
1011 EXPECT_CALL(*personal_data_manager_, Refresh());
1012 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL);
1013 ASSERT_TRUE(add_autofill.success());
1015 std::set<AutofillEntry> expected_entries;
1016 expected_entries.insert(native_entry);
1017 expected_entries.insert(sync_entry);
1019 std::vector<AutofillEntry> new_sync_entries;
1020 std::vector<AutofillProfile> new_sync_profiles;
1021 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1022 &new_sync_profiles));
1023 std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(),
1024 new_sync_entries.end());
1026 EXPECT_TRUE(expected_entries == new_sync_entries_set);
1029 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) {
1030 AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1));
1031 AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2));
1032 AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
1034 std::vector<AutofillEntry> native_entries;
1035 native_entries.push_back(native_entry);
1036 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1037 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
1039 std::vector<AutofillEntry> sync_entries;
1040 sync_entries.push_back(sync_entry);
1041 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries);
1043 EXPECT_CALL(autofill_table_,
1044 UpdateAutofillEntries(ElementsAre(merged_entry))).WillOnce(Return(true));
1045 EXPECT_CALL(*personal_data_manager_, Refresh());
1046 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL);
1047 ASSERT_TRUE(add_autofill.success());
1049 std::vector<AutofillEntry> new_sync_entries;
1050 std::vector<AutofillProfile> new_sync_profiles;
1051 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1052 &new_sync_profiles));
1053 ASSERT_EQ(1U, new_sync_entries.size());
1054 EXPECT_TRUE(merged_entry == new_sync_entries[0]);
1057 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) {
1058 AutofillProfile sync_profile;
1059 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1060 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1061 "Mitchell", "Morrison",
1062 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1063 "91601", "US", "12345678910");
1065 AutofillProfile* native_profile = new AutofillProfile;
1066 autofill::test::SetProfileInfoWithGuid(native_profile,
1067 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
1068 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1069 "32801", "US", "19482937549");
1071 std::vector<AutofillProfile*> native_profiles;
1072 native_profiles.push_back(native_profile);
1073 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1074 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1076 std::vector<AutofillProfile> sync_profiles;
1077 sync_profiles.push_back(sync_profile);
1078 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1080 EXPECT_CALL(autofill_table_,
1081 UpdateAutofillProfile(MatchProfiles(sync_profile))).
1082 WillOnce(Return(true));
1083 EXPECT_CALL(*personal_data_manager_, Refresh());
1084 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1085 ASSERT_TRUE(add_autofill.success());
1087 std::vector<AutofillProfile> new_sync_profiles;
1088 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1089 &new_sync_profiles));
1090 ASSERT_EQ(1U, new_sync_profiles.size());
1091 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
1094 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfileCombine) {
1095 AutofillProfile sync_profile;
1096 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1097 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1098 "Mitchell", "Morrison",
1099 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1100 "91601", "US", "12345678910");
1102 AutofillProfile* native_profile = new AutofillProfile;
1103 // Same address, but different names, phones and e-mails.
1104 autofill::test::SetProfileInfoWithGuid(native_profile,
1105 "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "Alicia", "Saenz",
1106 "joewayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1107 "91601", "US", "19482937549");
1109 AutofillProfile expected_profile(sync_profile);
1110 expected_profile.OverwriteWithOrAddTo(*native_profile, "en-US");
1112 std::vector<AutofillProfile*> native_profiles;
1113 native_profiles.push_back(native_profile);
1114 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1115 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1116 EXPECT_CALL(autofill_table_,
1117 AddAutofillProfile(MatchProfiles(expected_profile))).
1118 WillOnce(Return(true));
1119 EXPECT_CALL(autofill_table_,
1120 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")).
1121 WillOnce(Return(true));
1122 std::vector<AutofillProfile> sync_profiles;
1123 sync_profiles.push_back(sync_profile);
1124 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1126 EXPECT_CALL(*personal_data_manager_, Refresh());
1127 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1128 ASSERT_TRUE(add_autofill.success());
1130 std::vector<AutofillProfile> new_sync_profiles;
1131 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1132 &new_sync_profiles));
1133 ASSERT_EQ(1U, new_sync_profiles.size());
1134 // Check that key fields are the same.
1135 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US"));
1136 // Check that multivalued fields of the synced back data include original
1137 // data.
1138 EXPECT_TRUE(
1139 IncludesField(new_sync_profiles[0], sync_profile, autofill::NAME_FULL));
1140 EXPECT_TRUE(IncludesField(
1141 new_sync_profiles[0], sync_profile, autofill::EMAIL_ADDRESS));
1142 EXPECT_TRUE(IncludesField(
1143 new_sync_profiles[0], sync_profile, autofill::PHONE_HOME_WHOLE_NUMBER));
1146 TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) {
1147 AutofillProfile sync_profile;
1149 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1150 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1151 "Mitchell", "Morrison",
1152 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1153 "91601", "US", "12345678910");
1155 std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
1156 AutofillProfile* native_profile = new AutofillProfile;
1157 autofill::test::SetProfileInfoWithGuid(native_profile,
1158 native_guid.c_str(), "Billing",
1159 "Mitchell", "Morrison",
1160 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1161 "91601", "US", "12345678910");
1163 std::vector<AutofillProfile*> native_profiles;
1164 native_profiles.push_back(native_profile);
1165 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1166 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1168 std::vector<AutofillProfile> sync_profiles;
1169 sync_profiles.push_back(sync_profile);
1170 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1172 EXPECT_CALL(autofill_table_, AddAutofillProfile(_)).
1173 WillOnce(Return(true));
1174 EXPECT_CALL(autofill_table_, RemoveAutofillProfile(native_guid)).
1175 WillOnce(Return(true));
1176 EXPECT_CALL(*personal_data_manager_, Refresh());
1177 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1178 ASSERT_TRUE(add_autofill.success());
1180 std::vector<AutofillProfile> new_sync_profiles;
1181 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1182 &new_sync_profiles));
1183 ASSERT_EQ(1U, new_sync_profiles.size());
1184 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
1185 EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid());
1188 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) {
1189 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
1190 EXPECT_CALL(*personal_data_manager_, Refresh());
1191 SetIdleChangeProcessorExpectations();
1192 CreateRootHelper create_root(this, syncer::AUTOFILL);
1193 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1194 ASSERT_TRUE(create_root.success());
1196 AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1));
1198 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).
1199 WillOnce(DoAll(SetArgumentPointee<2>(added_entry.date_created()),
1200 SetArgumentPointee<3>(added_entry.date_last_used()),
1201 Return(true)));
1203 AutofillChangeList changes;
1204 changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key()));
1206 web_data_service_->OnAutofillEntriesChanged(changes);
1208 std::vector<AutofillEntry> new_sync_entries;
1209 std::vector<AutofillProfile> new_sync_profiles;
1210 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1211 &new_sync_profiles));
1212 ASSERT_EQ(1U, new_sync_entries.size());
1213 EXPECT_TRUE(added_entry == new_sync_entries[0]);
1216 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
1217 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
1218 EXPECT_CALL(*personal_data_manager_, Refresh());
1219 SetIdleChangeProcessorExpectations();
1220 CreateRootHelper create_root(this, syncer::AUTOFILL_PROFILE);
1221 StartSyncService(create_root.callback(), false, syncer::AUTOFILL_PROFILE);
1222 ASSERT_TRUE(create_root.success());
1224 AutofillProfile added_profile;
1225 autofill::test::SetProfileInfoWithGuid(&added_profile,
1226 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
1227 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1228 "32801", "US", "19482937549");
1230 AutofillProfileChange change(
1231 AutofillProfileChange::ADD, added_profile.guid(), &added_profile);
1232 web_data_service_->OnAutofillProfileChanged(change);
1234 std::vector<AutofillProfile> new_sync_profiles;
1235 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1236 &new_sync_profiles));
1237 ASSERT_EQ(1U, new_sync_profiles.size());
1238 EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0]));
1241 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
1242 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
1243 std::vector<AutofillEntry> original_entries;
1244 original_entries.push_back(original_entry);
1246 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1247 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
1248 EXPECT_CALL(*personal_data_manager_, Refresh());
1249 CreateRootHelper create_root(this, syncer::AUTOFILL);
1250 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1251 ASSERT_TRUE(create_root.success());
1253 AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
1255 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).
1256 WillOnce(DoAll(SetArgumentPointee<2>(updated_entry.date_created()),
1257 SetArgumentPointee<3>(updated_entry.date_last_used()),
1258 Return(true)));
1260 AutofillChangeList changes;
1261 changes.push_back(AutofillChange(AutofillChange::UPDATE,
1262 updated_entry.key()));
1263 web_data_service_->OnAutofillEntriesChanged(changes);
1265 std::vector<AutofillEntry> new_sync_entries;
1266 std::vector<AutofillProfile> new_sync_profiles;
1267 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1268 &new_sync_profiles));
1269 ASSERT_EQ(1U, new_sync_entries.size());
1270 EXPECT_TRUE(updated_entry == new_sync_entries[0]);
1274 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) {
1275 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
1276 std::vector<AutofillEntry> original_entries;
1277 original_entries.push_back(original_entry);
1279 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1280 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
1281 EXPECT_CALL(*personal_data_manager_, Refresh());
1282 CreateRootHelper create_root(this, syncer::AUTOFILL);
1283 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1284 ASSERT_TRUE(create_root.success());
1286 AutofillChangeList changes;
1287 changes.push_back(AutofillChange(AutofillChange::REMOVE,
1288 original_entry.key()));
1289 web_data_service_->OnAutofillEntriesChanged(changes);
1291 std::vector<AutofillEntry> new_sync_entries;
1292 std::vector<AutofillProfile> new_sync_profiles;
1293 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
1294 &new_sync_profiles));
1295 ASSERT_EQ(0U, new_sync_entries.size());
1298 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) {
1299 AutofillProfile sync_profile;
1300 autofill::test::SetProfileInfoWithGuid(&sync_profile,
1301 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1302 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1303 "32801", "US", "19482937549");
1304 AutofillProfile* native_profile = new AutofillProfile;
1305 autofill::test::SetProfileInfoWithGuid(native_profile,
1306 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1307 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1308 "32801", "US", "19482937549");
1310 std::vector<AutofillProfile*> native_profiles;
1311 native_profiles.push_back(native_profile);
1312 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1313 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1315 std::vector<AutofillProfile> sync_profiles;
1316 sync_profiles.push_back(sync_profile);
1317 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles);
1318 EXPECT_CALL(*personal_data_manager_, Refresh());
1319 StartSyncService(add_autofill.callback(), false, syncer::AUTOFILL_PROFILE);
1320 ASSERT_TRUE(add_autofill.success());
1322 AutofillProfileChange change(
1323 AutofillProfileChange::REMOVE, sync_profile.guid(), NULL);
1324 web_data_service_->OnAutofillProfileChanged(change);
1326 std::vector<AutofillProfile> new_sync_profiles;
1327 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1328 &new_sync_profiles));
1329 ASSERT_EQ(0U, new_sync_profiles.size());
1332 // http://crbug.com/57884
1333 TEST_F(ProfileSyncServiceAutofillTest, DISABLED_ServerChangeRace) {
1334 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via
1335 // LoadAutofillData().
1336 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
1337 Times(3).WillRepeatedly(Return(true));
1338 // On the other hand Autofill and Autocomplete are separated now, so
1339 // GetAutofillProfiles() should not be called.
1340 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).Times(0);
1341 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).
1342 WillRepeatedly(Return(true));
1343 EXPECT_CALL(*personal_data_manager_, Refresh()).Times(3);
1344 CreateRootHelper create_root(this, syncer::AUTOFILL);
1345 StartSyncService(create_root.callback(), false, syncer::AUTOFILL);
1346 ASSERT_TRUE(create_root.success());
1348 // (true, false) means we have to reset after |Signal|, init to unsignaled.
1349 scoped_ptr<WaitableEvent> wait_for_start(new WaitableEvent(true, false));
1350 scoped_ptr<WaitableEvent> wait_for_syncapi(new WaitableEvent(true, false));
1351 scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater(
1352 sync_service_, &wait_for_start, &wait_for_syncapi));
1354 // This server side update will stall waiting for CommitWaiter.
1355 updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
1356 wait_for_start->Wait();
1358 AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
1359 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry));
1360 DVLOG(1) << "Syncapi update finished.";
1362 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
1363 // Signal FakeServerUpdater that it can complete.
1364 wait_for_syncapi->Signal();
1366 // Make another entry to ensure nothing broke afterwards and wait for finish
1367 // to clean up.
1368 updater->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3));
1370 std::vector<AutofillEntry> sync_entries;
1371 std::vector<AutofillProfile> sync_profiles;
1372 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
1373 EXPECT_EQ(3U, sync_entries.size());
1374 EXPECT_EQ(0U, sync_profiles.size());
1375 for (size_t i = 0; i < sync_entries.size(); i++) {
1376 DVLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name()
1377 << ", " << sync_entries[i].key().value();