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.
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/account_tracker_service_factory.h"
27 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
28 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
29 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
30 #include "chrome/browser/signin/signin_manager_factory.h"
31 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
32 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
33 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
34 #include "chrome/browser/sync/profile_sync_components_factory.h"
35 #include "chrome/browser/sync/profile_sync_service.h"
36 #include "chrome/browser/sync/profile_sync_service_factory.h"
37 #include "chrome/browser/sync/profile_sync_test_util.h"
38 #include "chrome/browser/sync/test_profile_sync_service.h"
39 #include "chrome/browser/webdata/web_data_service_factory.h"
40 #include "chrome/test/base/testing_browser_process.h"
41 #include "chrome/test/base/testing_profile.h"
42 #include "chrome/test/base/testing_profile_manager.h"
43 #include "components/autofill/core/browser/autofill_test_utils.h"
44 #include "components/autofill/core/browser/personal_data_manager.h"
45 #include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h"
46 #include "components/autofill/core/browser/webdata/autofill_change.h"
47 #include "components/autofill/core/browser/webdata/autofill_entry.h"
48 #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
49 #include "components/autofill/core/browser/webdata/autofill_table.h"
50 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
51 #include "components/signin/core/browser/account_tracker_service.h"
52 #include "components/signin/core/browser/signin_manager.h"
53 #include "components/sync_driver/data_type_controller.h"
54 #include "components/webdata/common/web_database.h"
55 #include "components/webdata_services/web_data_service_test_util.h"
56 #include "content/public/test/test_browser_thread.h"
57 #include "google_apis/gaia/gaia_constants.h"
58 #include "sync/internal_api/public/base/model_type.h"
59 #include "sync/internal_api/public/data_type_debug_info_listener.h"
60 #include "sync/internal_api/public/read_node.h"
61 #include "sync/internal_api/public/read_transaction.h"
62 #include "sync/internal_api/public/write_node.h"
63 #include "sync/internal_api/public/write_transaction.h"
64 #include "sync/protocol/autofill_specifics.pb.h"
65 #include "sync/syncable/mutable_entry.h"
66 #include "sync/syncable/syncable_write_transaction.h"
67 #include "sync/test/engine/test_id_factory.h"
68 #include "testing/gmock/include/gmock/gmock.h"
70 using autofill::AutocompleteSyncableService
;
71 using autofill::AutofillChange
;
72 using autofill::AutofillChangeList
;
73 using autofill::AutofillEntry
;
74 using autofill::ServerFieldType
;
75 using autofill::AutofillKey
;
76 using autofill::AutofillProfile
;
77 using autofill::AutofillProfileChange
;
78 using autofill::AutofillProfileSyncableService
;
79 using autofill::AutofillTable
;
80 using autofill::AutofillWebDataService
;
81 using autofill::PersonalDataManager
;
83 using base::TimeDelta
;
84 using base::WaitableEvent
;
85 using browser_sync::AutofillDataTypeController
;
86 using browser_sync::AutofillProfileDataTypeController
;
87 using content::BrowserThread
;
88 using syncer::AUTOFILL
;
89 using syncer::AUTOFILL_PROFILE
;
90 using syncer::BaseNode
;
91 using syncer::syncable::BASE_VERSION
;
92 using syncer::syncable::CREATE
;
93 using syncer::syncable::GET_TYPE_ROOT
;
94 using syncer::syncable::MutableEntry
;
95 using syncer::syncable::SERVER_SPECIFICS
;
96 using syncer::syncable::SPECIFICS
;
97 using syncer::syncable::UNITTEST
;
98 using syncer::syncable::WriterTag
;
99 using syncer::syncable::WriteTransaction
;
100 using sync_driver::DataTypeController
;
102 using testing::DoAll
;
103 using testing::ElementsAre
;
105 using testing::SetArgumentPointee
;
106 using testing::Return
;
114 const char kTestProfileName
[] = "test-profile";
116 void RunAndSignal(const base::Closure
& cb
, WaitableEvent
* event
) {
123 class AutofillTableMock
: public AutofillTable
{
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
{
154 explicit WebDatabaseFake(AutofillTable
* autofill_table
) {
155 AddTable(autofill_table
);
159 class MockAutofillBackend
: public autofill::AutofillWebDataBackend
{
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_
; }
171 autofill::AutofillWebDataServiceObserverOnDBThread
* observer
) override
{}
173 autofill::AutofillWebDataServiceObserverOnDBThread
* observer
) override
{}
174 void RemoveExpiredFormElements() override
{}
175 void NotifyOfMultipleAutofillChanges() override
{
176 DCHECK_CURRENTLY_ON(BrowserThread::DB
);
177 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, on_changed_
);
181 WebDatabase
* web_database_
;
182 base::Closure on_changed_
;
185 class ProfileSyncServiceAutofillTest
;
187 template<class AutofillProfile
>
188 syncer::ModelType
GetModelType() {
189 return syncer::UNSPECIFIED
;
193 syncer::ModelType GetModelType
<AutofillEntry
>() {
194 return syncer::AUTOFILL
;
198 syncer::ModelType GetModelType
<AutofillProfile
>() {
199 return syncer::AUTOFILL_PROFILE
;
202 class TokenWebDataServiceFake
: public TokenWebData
{
204 TokenWebDataServiceFake()
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.
225 ~TokenWebDataServiceFake() override
{}
227 DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake
);
230 class WebDataServiceFake
: public AutofillWebDataService
{
233 : AutofillWebDataService(
234 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI
),
235 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB
)),
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
249 const base::Closure
& on_changed_callback
= base::Bind(
250 &WebDataServiceFake::NotifyAutofillMultipleChangedOnUIThread
,
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
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_
),
280 BrowserThread::PostTask(
283 base::Bind(&RunAndSignal
, notify_cb
, &event
));
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_
),
294 BrowserThread::PostTask(
297 base::Bind(&RunAndSignal
, notify_cb
, &event
));
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
;
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(
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
{
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
{
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
{
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
{
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
{
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
;
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_
;
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(
476 scoped_ptr
<PrefServiceSyncable
>(),
477 base::UTF8ToUTF16(kTestProfileName
),
481 web_database_
.reset(new WebDatabaseFake(&autofill_table_
));
482 MockWebDataServiceWrapper
* wrapper
=
483 static_cast<MockWebDataServiceWrapper
*>(
484 WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse(
485 profile_
, BuildMockWebDataServiceWrapper
));
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 AccountTrackerServiceFactory::GetForProfile(profile_
),
503 profile_
->IsOffTheRecord());
505 web_data_service_
->StartSyncableService();
507 // When UpdateAutofillEntries() is called with an empty list, the return
508 // value should be |true|, rather than the default of |false|.
509 std::vector
<AutofillEntry
> empty
;
510 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(empty
))
511 .WillRepeatedly(Return(true));
514 void TearDown() override
{
515 // Note: The tear down order is important.
516 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(profile_
, NULL
);
517 web_data_service_
->ShutdownOnUIThread();
518 web_data_service_
->ShutdownSyncableService();
519 web_data_service_
= NULL
;
520 // To prevent a leak, fully release TestURLRequestContext to ensure its
521 // destruction on the IO message loop.
523 profile_manager_
.DeleteTestingProfile(kTestProfileName
);
524 AbstractProfileSyncServiceTest::TearDown();
527 int GetSyncCount(syncer::ModelType type
) {
528 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
529 syncer::ReadNode
node(&trans
);
530 if (node
.InitTypeRoot(type
) != syncer::BaseNode::INIT_OK
)
532 return node
.GetTotalNodeCount() - 1;
535 void StartSyncService(const base::Closure
& callback
,
536 bool will_fail_association
,
537 syncer::ModelType type
) {
538 AbstractAutofillFactory
* factory
= GetFactory(type
);
539 SigninManagerBase
* signin
= SigninManagerFactory::GetForProfile(profile_
);
540 signin
->SetAuthenticatedAccountInfo("12345", "test_user@gmail.com");
541 sync_service_
= TestProfileSyncService::BuildAutoStartAsyncInit(profile_
,
544 ProfileSyncComponentsFactoryMock
* components
=
545 sync_service_
->components_factory_mock();
546 DataTypeController
* data_type_controller
=
547 factory
->CreateDataTypeController(components
, profile_
, sync_service_
);
548 factory
->SetExpectation(components
,
550 web_data_service_
.get(),
551 data_type_controller
);
553 EXPECT_CALL(*components
, CreateDataTypeManager(_
, _
, _
, _
, _
)).
554 WillOnce(ReturnNewDataTypeManagerWithDebugListener(
555 syncer::MakeWeakHandle(debug_ptr_factory_
.GetWeakPtr())));
557 EXPECT_CALL(*personal_data_manager_
, IsDataLoaded()).
558 WillRepeatedly(Return(true));
560 // We need tokens to get the tests going
561 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
)
562 ->UpdateCredentials(signin
->GetAuthenticatedAccountId(),
563 "oauth2_login_token");
565 sync_service_
->RegisterDataTypeController(data_type_controller
);
566 sync_service_
->Initialize();
567 base::MessageLoop::current()->Run();
569 // It's possible this test triggered an unrecoverable error, in which case
570 // we can't get the sync count.
571 if (sync_service_
->SyncActive()) {
572 EXPECT_EQ(GetSyncCount(type
),
573 association_stats_
.num_sync_items_after_association
);
575 EXPECT_EQ(association_stats_
.num_sync_items_after_association
,
576 association_stats_
.num_sync_items_before_association
+
577 association_stats_
.num_sync_items_added
-
578 association_stats_
.num_sync_items_deleted
);
581 bool AddAutofillSyncNode(const AutofillEntry
& entry
) {
582 syncer::WriteTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
583 syncer::ReadNode
autofill_root(&trans
);
584 if (autofill_root
.InitTypeRoot(syncer::AUTOFILL
) != BaseNode::INIT_OK
) {
588 syncer::WriteNode
node(&trans
);
589 std::string tag
= AutocompleteSyncableService::KeyToTag(
590 base::UTF16ToUTF8(entry
.key().name()),
591 base::UTF16ToUTF8(entry
.key().value()));
592 syncer::WriteNode::InitUniqueByCreationResult result
=
593 node
.InitUniqueByCreation(syncer::AUTOFILL
, autofill_root
, tag
);
594 if (result
!= syncer::WriteNode::INIT_SUCCESS
)
597 sync_pb::EntitySpecifics specifics
;
598 AutocompleteSyncableService::WriteAutofillEntry(entry
, &specifics
);
599 sync_pb::AutofillSpecifics
* autofill_specifics
=
600 specifics
.mutable_autofill();
601 node
.SetAutofillSpecifics(*autofill_specifics
);
605 bool AddAutofillSyncNode(const AutofillProfile
& profile
) {
606 syncer::WriteTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
607 syncer::ReadNode
autofill_root(&trans
);
608 if (autofill_root
.InitTypeRoot(AUTOFILL_PROFILE
) != BaseNode::INIT_OK
) {
611 syncer::WriteNode
node(&trans
);
612 std::string tag
= profile
.guid();
613 syncer::WriteNode::InitUniqueByCreationResult result
=
614 node
.InitUniqueByCreation(syncer::AUTOFILL_PROFILE
,
616 if (result
!= syncer::WriteNode::INIT_SUCCESS
)
619 sync_pb::EntitySpecifics specifics
;
620 AutofillProfileSyncableService::WriteAutofillProfile(profile
, &specifics
);
621 sync_pb::AutofillProfileSpecifics
* profile_specifics
=
622 specifics
.mutable_autofill_profile();
623 node
.SetAutofillProfileSpecifics(*profile_specifics
);
627 bool GetAutofillEntriesFromSyncDB(std::vector
<AutofillEntry
>* entries
,
628 std::vector
<AutofillProfile
>* profiles
) {
629 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
630 syncer::ReadNode
autofill_root(&trans
);
631 if (autofill_root
.InitTypeRoot(syncer::AUTOFILL
) != BaseNode::INIT_OK
) {
635 int64 child_id
= autofill_root
.GetFirstChildId();
636 while (child_id
!= syncer::kInvalidId
) {
637 syncer::ReadNode
child_node(&trans
);
638 if (child_node
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
641 const sync_pb::AutofillSpecifics
& autofill(
642 child_node
.GetAutofillSpecifics());
643 if (autofill
.has_value()) {
644 AutofillKey
key(base::UTF8ToUTF16(autofill
.name()),
645 base::UTF8ToUTF16(autofill
.value()));
646 std::vector
<base::Time
> timestamps
;
647 int timestamps_count
= autofill
.usage_timestamp_size();
648 for (int i
= 0; i
< timestamps_count
; ++i
) {
649 timestamps
.push_back(Time::FromInternalValue(
650 autofill
.usage_timestamp(i
)));
653 AutofillEntry(key
, timestamps
.front(), timestamps
.back()));
654 } else if (autofill
.has_profile()) {
656 p
.set_guid(autofill
.profile().guid());
657 AutofillProfileSyncableService::OverwriteProfileWithServerData(
658 autofill
.profile(), &p
, "en-US");
659 profiles
->push_back(p
);
661 child_id
= child_node
.GetSuccessorId();
666 bool GetAutofillProfilesFromSyncDBUnderProfileNode(
667 std::vector
<AutofillProfile
>* profiles
) {
668 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
669 syncer::ReadNode
autofill_root(&trans
);
670 if (autofill_root
.InitTypeRoot(AUTOFILL_PROFILE
) != BaseNode::INIT_OK
) {
674 int64 child_id
= autofill_root
.GetFirstChildId();
675 while (child_id
!= syncer::kInvalidId
) {
676 syncer::ReadNode
child_node(&trans
);
677 if (child_node
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
680 const sync_pb::AutofillProfileSpecifics
& autofill(
681 child_node
.GetAutofillProfileSpecifics());
683 p
.set_guid(autofill
.guid());
684 AutofillProfileSyncableService::OverwriteProfileWithServerData(
685 autofill
, &p
, "en-US");
686 profiles
->push_back(p
);
687 child_id
= child_node
.GetSuccessorId();
692 void SetIdleChangeProcessorExpectations() {
693 EXPECT_CALL(autofill_table_
, RemoveFormElement(_
, _
)).Times(0);
694 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
, _
)).Times(0);
696 // Only permit UpdateAutofillEntries() to be called with an empty list.
697 std::vector
<AutofillEntry
> empty
;
698 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(Not(empty
))).Times(0);
701 static AutofillEntry
MakeAutofillEntry(const char* name
,
705 // Time deep in the past would cause Autocomplete sync to discard the
707 static Time base_time
= Time::Now().LocalMidnight();
709 base::Time date_created
= base_time
+ TimeDelta::FromSeconds(time_shift0
);
710 base::Time date_last_used
= date_created
;
711 if (time_shift1
>= 0)
712 date_last_used
= base_time
+ TimeDelta::FromSeconds(time_shift1
);
713 return AutofillEntry(
714 AutofillKey(base::ASCIIToUTF16(name
), base::ASCIIToUTF16(value
)),
715 date_created
, date_last_used
);
718 static AutofillEntry
MakeAutofillEntry(const char* name
,
721 return MakeAutofillEntry(name
, value
, time_shift
, -1);
724 friend class AddAutofillHelper
<AutofillEntry
>;
725 friend class AddAutofillHelper
<AutofillProfile
>;
726 friend class FakeServerUpdater
;
728 TestingProfileManager profile_manager_
;
729 TestingProfile
* profile_
;
730 AutofillTableMock autofill_table_
;
731 scoped_ptr
<WebDatabaseFake
> web_database_
;
732 scoped_refptr
<WebDataServiceFake
> web_data_service_
;
733 MockPersonalDataManager
* personal_data_manager_
;
734 syncer::DataTypeAssociationStats association_stats_
;
735 base::WeakPtrFactory
<DataTypeDebugInfoListener
> debug_ptr_factory_
;
739 class AddAutofillHelper
{
741 AddAutofillHelper(ProfileSyncServiceAutofillTest
* test
,
742 const std::vector
<T
>& entries
)
743 : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback
,
744 base::Unretained(this), test
, entries
)),
748 const base::Closure
& callback() const { return callback_
; }
749 bool success() { return success_
; }
752 void AddAutofillCallback(ProfileSyncServiceAutofillTest
* test
,
753 const std::vector
<T
>& entries
) {
754 if (!test
->CreateRoot(GetModelType
<T
>()))
757 for (size_t i
= 0; i
< entries
.size(); ++i
) {
758 if (!test
->AddAutofillSyncNode(entries
[i
]))
764 base::Closure callback_
;
768 // Overload write transaction to use custom NotifyTransactionComplete
769 class WriteTransactionTest
: public WriteTransaction
{
771 WriteTransactionTest(const tracked_objects::Location
& from_here
,
773 syncer::syncable::Directory
* directory
,
774 scoped_ptr
<WaitableEvent
>* wait_for_syncapi
)
775 : WriteTransaction(from_here
, writer
, directory
),
776 wait_for_syncapi_(wait_for_syncapi
) { }
778 void NotifyTransactionComplete(syncer::ModelTypeSet types
) override
{
779 // This is where we differ. Force a thread change here, giving another
780 // thread a chance to create a WriteTransaction
781 (*wait_for_syncapi_
)->Wait();
783 WriteTransaction::NotifyTransactionComplete(types
);
787 scoped_ptr
<WaitableEvent
>* wait_for_syncapi_
;
790 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
791 // post tasks with it.
792 class FakeServerUpdater
: public base::RefCountedThreadSafe
<FakeServerUpdater
> {
794 FakeServerUpdater(TestProfileSyncService
* service
,
795 scoped_ptr
<WaitableEvent
>* wait_for_start
,
796 scoped_ptr
<WaitableEvent
>* wait_for_syncapi
)
797 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)),
799 wait_for_start_(wait_for_start
),
800 wait_for_syncapi_(wait_for_syncapi
),
801 is_finished_(false, false) { }
804 // This gets called in a modelsafeworker thread.
805 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
807 syncer::UserShare
* user_share
= service_
->GetUserShare();
808 syncer::syncable::Directory
* directory
= user_share
->directory
.get();
810 // Create autofill protobuf.
811 std::string tag
= AutocompleteSyncableService::KeyToTag(
812 base::UTF16ToUTF8(entry_
.key().name()),
813 base::UTF16ToUTF8(entry_
.key().value()));
814 sync_pb::AutofillSpecifics new_autofill
;
815 new_autofill
.set_name(base::UTF16ToUTF8(entry_
.key().name()));
816 new_autofill
.set_value(base::UTF16ToUTF8(entry_
.key().value()));
817 new_autofill
.add_usage_timestamp(entry_
.date_created().ToInternalValue());
818 if (entry_
.date_created() != entry_
.date_last_used()) {
819 new_autofill
.add_usage_timestamp(
820 entry_
.date_last_used().ToInternalValue());
823 sync_pb::EntitySpecifics entity_specifics
;
824 entity_specifics
.mutable_autofill()->CopyFrom(new_autofill
);
827 // Tell main thread we've started
828 (*wait_for_start_
)->Signal();
830 // Create write transaction.
831 WriteTransactionTest
trans(FROM_HERE
, UNITTEST
, directory
,
834 // Create actual entry based on autofill protobuf information.
835 // Simulates effects of UpdateLocalDataFromServerData
836 MutableEntry
parent(&trans
, GET_TYPE_ROOT
, syncer::AUTOFILL
);
837 MutableEntry
item(&trans
, CREATE
, syncer::AUTOFILL
, parent
.GetId(), tag
);
838 ASSERT_TRUE(item
.good());
839 item
.PutSpecifics(entity_specifics
);
840 item
.PutServerSpecifics(entity_specifics
);
841 item
.PutBaseVersion(1);
842 syncer::syncable::Id server_item_id
=
843 service_
->id_factory()->NewServerId();
844 item
.PutId(server_item_id
);
845 syncer::syncable::Id new_predecessor
;
846 ASSERT_TRUE(item
.PutPredecessor(new_predecessor
));
848 DVLOG(1) << "FakeServerUpdater finishing.";
849 is_finished_
.Signal();
852 void CreateNewEntry(const AutofillEntry
& entry
) {
854 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
855 if (!BrowserThread::PostTask(
856 BrowserThread::DB
, FROM_HERE
,
857 base::Bind(&FakeServerUpdater::Update
, this))) {
858 NOTREACHED() << "Failed to post task to the db thread.";
863 void CreateNewEntryAndWait(const AutofillEntry
& entry
) {
865 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
866 is_finished_
.Reset();
867 if (!BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
868 base::Bind(&FakeServerUpdater::Update
, this))) {
869 NOTREACHED() << "Failed to post task to the db thread.";
876 friend class base::RefCountedThreadSafe
<FakeServerUpdater
>;
877 ~FakeServerUpdater() { }
879 AutofillEntry entry_
;
880 TestProfileSyncService
* service_
;
881 scoped_ptr
<WaitableEvent
>* wait_for_start_
;
882 scoped_ptr
<WaitableEvent
>* wait_for_syncapi_
;
883 WaitableEvent is_finished_
;
884 syncer::syncable::Id parent_id_
;
887 // TODO(skrul): Test abort startup.
888 // TODO(skrul): Test processing of cloud changes.
889 // TODO(tim): Add autofill data type controller test, and a case to cover
890 // waiting for the PersonalDataManager.
891 TEST_F(ProfileSyncServiceAutofillTest
, FailModelAssociation
) {
892 // Don't create the root autofill node so startup fails.
893 StartSyncService(base::Closure(), true, syncer::AUTOFILL
);
894 EXPECT_TRUE(sync_service_
->HasUnrecoverableError());
897 TEST_F(ProfileSyncServiceAutofillTest
, EmptyNativeEmptySync
) {
898 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).WillOnce(Return(true));
899 SetIdleChangeProcessorExpectations();
900 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
901 EXPECT_CALL(*personal_data_manager_
, Refresh());
902 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
903 EXPECT_TRUE(create_root
.success());
904 std::vector
<AutofillEntry
> sync_entries
;
905 std::vector
<AutofillProfile
> sync_profiles
;
906 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
907 EXPECT_EQ(0U, sync_entries
.size());
908 EXPECT_EQ(0U, sync_profiles
.size());
911 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeEntriesEmptySync
) {
912 std::vector
<AutofillEntry
> entries
;
913 entries
.push_back(MakeAutofillEntry("foo", "bar", 1));
914 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
915 WillOnce(DoAll(SetArgumentPointee
<0>(entries
), Return(true)));
916 SetIdleChangeProcessorExpectations();
917 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
918 EXPECT_CALL(*personal_data_manager_
, Refresh());
919 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
920 ASSERT_TRUE(create_root
.success());
921 std::vector
<AutofillEntry
> sync_entries
;
922 std::vector
<AutofillProfile
> sync_profiles
;
923 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
924 ASSERT_EQ(1U, entries
.size());
925 EXPECT_TRUE(entries
[0] == sync_entries
[0]);
926 EXPECT_EQ(0U, sync_profiles
.size());
929 TEST_F(ProfileSyncServiceAutofillTest
, HasProfileEmptySync
) {
930 std::vector
<AutofillProfile
*> profiles
;
931 std::vector
<AutofillProfile
> expected_profiles
;
932 // Owned by GetAutofillProfiles caller.
933 AutofillProfile
* profile0
= new AutofillProfile
;
934 autofill::test::SetProfileInfoWithGuid(profile0
,
935 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
936 "Mitchell", "Morrison",
937 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
938 "91601", "US", "12345678910");
939 profiles
.push_back(profile0
);
940 expected_profiles
.push_back(*profile0
);
941 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
942 WillOnce(DoAll(SetArgumentPointee
<0>(profiles
), Return(true)));
943 EXPECT_CALL(*personal_data_manager_
, Refresh());
944 SetIdleChangeProcessorExpectations();
945 CreateRootHelper
create_root(this, syncer::AUTOFILL_PROFILE
);
946 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL_PROFILE
);
947 ASSERT_TRUE(create_root
.success());
948 std::vector
<AutofillProfile
> sync_profiles
;
949 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles
));
950 EXPECT_EQ(1U, sync_profiles
.size());
951 EXPECT_EQ(0, expected_profiles
[0].Compare(sync_profiles
[0]));
954 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeWithDuplicatesEmptySync
) {
955 // There is buggy autofill code that allows duplicate name/value
956 // pairs to exist in the database with separate pair_ids.
957 std::vector
<AutofillEntry
> entries
;
958 entries
.push_back(MakeAutofillEntry("foo", "bar", 1));
959 entries
.push_back(MakeAutofillEntry("dup", "", 2));
960 entries
.push_back(MakeAutofillEntry("dup", "", 3));
961 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
962 WillOnce(DoAll(SetArgumentPointee
<0>(entries
), Return(true)));
963 SetIdleChangeProcessorExpectations();
964 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
965 EXPECT_CALL(*personal_data_manager_
, Refresh());
966 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
967 ASSERT_TRUE(create_root
.success());
968 std::vector
<AutofillEntry
> sync_entries
;
969 std::vector
<AutofillProfile
> sync_profiles
;
970 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
971 EXPECT_EQ(2U, sync_entries
.size());
974 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncNoMerge
) {
975 AutofillEntry
native_entry(MakeAutofillEntry("native", "entry", 1));
976 AutofillEntry
sync_entry(MakeAutofillEntry("sync", "entry", 2));
978 std::vector
<AutofillEntry
> native_entries
;
979 native_entries
.push_back(native_entry
);
981 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
982 WillOnce(DoAll(SetArgumentPointee
<0>(native_entries
), Return(true)));
984 std::vector
<AutofillEntry
> sync_entries
;
985 sync_entries
.push_back(sync_entry
);
987 AddAutofillHelper
<AutofillEntry
> add_autofill(this, sync_entries
);
989 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(ElementsAre(sync_entry
))).
990 WillOnce(Return(true));
992 EXPECT_CALL(*personal_data_manager_
, Refresh());
993 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL
);
994 ASSERT_TRUE(add_autofill
.success());
996 std::set
<AutofillEntry
> expected_entries
;
997 expected_entries
.insert(native_entry
);
998 expected_entries
.insert(sync_entry
);
1000 std::vector
<AutofillEntry
> new_sync_entries
;
1001 std::vector
<AutofillProfile
> new_sync_profiles
;
1002 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1003 &new_sync_profiles
));
1004 std::set
<AutofillEntry
> new_sync_entries_set(new_sync_entries
.begin(),
1005 new_sync_entries
.end());
1007 EXPECT_TRUE(expected_entries
== new_sync_entries_set
);
1010 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeEntry
) {
1011 AutofillEntry
native_entry(MakeAutofillEntry("merge", "entry", 1));
1012 AutofillEntry
sync_entry(MakeAutofillEntry("merge", "entry", 2));
1013 AutofillEntry
merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
1015 std::vector
<AutofillEntry
> native_entries
;
1016 native_entries
.push_back(native_entry
);
1017 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1018 WillOnce(DoAll(SetArgumentPointee
<0>(native_entries
), Return(true)));
1020 std::vector
<AutofillEntry
> sync_entries
;
1021 sync_entries
.push_back(sync_entry
);
1022 AddAutofillHelper
<AutofillEntry
> add_autofill(this, sync_entries
);
1024 EXPECT_CALL(autofill_table_
,
1025 UpdateAutofillEntries(ElementsAre(merged_entry
))).WillOnce(Return(true));
1026 EXPECT_CALL(*personal_data_manager_
, Refresh());
1027 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL
);
1028 ASSERT_TRUE(add_autofill
.success());
1030 std::vector
<AutofillEntry
> new_sync_entries
;
1031 std::vector
<AutofillProfile
> new_sync_profiles
;
1032 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1033 &new_sync_profiles
));
1034 ASSERT_EQ(1U, new_sync_entries
.size());
1035 EXPECT_TRUE(merged_entry
== new_sync_entries
[0]);
1038 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeProfile
) {
1039 AutofillProfile sync_profile
;
1040 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1041 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1042 "Mitchell", "Morrison",
1043 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1044 "91601", "US", "12345678910");
1046 AutofillProfile
* native_profile
= new AutofillProfile
;
1047 autofill::test::SetProfileInfoWithGuid(native_profile
,
1048 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
1049 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1050 "32801", "US", "19482937549");
1052 std::vector
<AutofillProfile
*> native_profiles
;
1053 native_profiles
.push_back(native_profile
);
1054 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1055 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1057 std::vector
<AutofillProfile
> sync_profiles
;
1058 sync_profiles
.push_back(sync_profile
);
1059 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1061 EXPECT_CALL(autofill_table_
,
1062 UpdateAutofillProfile(MatchProfiles(sync_profile
))).
1063 WillOnce(Return(true));
1064 EXPECT_CALL(*personal_data_manager_
, Refresh());
1065 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1066 ASSERT_TRUE(add_autofill
.success());
1068 std::vector
<AutofillProfile
> new_sync_profiles
;
1069 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1070 &new_sync_profiles
));
1071 ASSERT_EQ(1U, new_sync_profiles
.size());
1072 EXPECT_EQ(0, sync_profile
.Compare(new_sync_profiles
[0]));
1075 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeProfileCombine
) {
1076 AutofillProfile sync_profile
;
1077 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1078 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1079 "Mitchell", "Morrison",
1080 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1081 "91601", "US", "12345678910");
1083 AutofillProfile
* native_profile
= new AutofillProfile
;
1084 // Same address, but different names, phones and e-mails.
1085 autofill::test::SetProfileInfoWithGuid(native_profile
,
1086 "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "Alicia", "Saenz",
1087 "joewayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1088 "91601", "US", "19482937549");
1090 AutofillProfile
expected_profile(sync_profile
);
1091 expected_profile
.OverwriteWithOrAddTo(*native_profile
, "en-US");
1093 std::vector
<AutofillProfile
*> native_profiles
;
1094 native_profiles
.push_back(native_profile
);
1095 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1096 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1097 EXPECT_CALL(autofill_table_
,
1098 AddAutofillProfile(MatchProfiles(expected_profile
))).
1099 WillOnce(Return(true));
1100 EXPECT_CALL(autofill_table_
,
1101 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")).
1102 WillOnce(Return(true));
1103 std::vector
<AutofillProfile
> sync_profiles
;
1104 sync_profiles
.push_back(sync_profile
);
1105 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1107 EXPECT_CALL(*personal_data_manager_
, Refresh());
1108 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1109 ASSERT_TRUE(add_autofill
.success());
1111 std::vector
<AutofillProfile
> new_sync_profiles
;
1112 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1113 &new_sync_profiles
));
1114 ASSERT_EQ(1U, new_sync_profiles
.size());
1115 // Check that key fields are the same.
1116 EXPECT_TRUE(new_sync_profiles
[0].IsSubsetOf(sync_profile
, "en-US"));
1119 TEST_F(ProfileSyncServiceAutofillTest
, MergeProfileWithDifferentGuid
) {
1120 AutofillProfile sync_profile
;
1122 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1123 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1124 "Mitchell", "Morrison",
1125 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1126 "91601", "US", "12345678910");
1128 std::string native_guid
= "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
1129 AutofillProfile
* native_profile
= new AutofillProfile
;
1130 autofill::test::SetProfileInfoWithGuid(native_profile
,
1131 native_guid
.c_str(), "Billing",
1132 "Mitchell", "Morrison",
1133 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1134 "91601", "US", "12345678910");
1136 std::vector
<AutofillProfile
*> native_profiles
;
1137 native_profiles
.push_back(native_profile
);
1138 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1139 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1141 std::vector
<AutofillProfile
> sync_profiles
;
1142 sync_profiles
.push_back(sync_profile
);
1143 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1145 EXPECT_CALL(autofill_table_
, AddAutofillProfile(_
)).
1146 WillOnce(Return(true));
1147 EXPECT_CALL(autofill_table_
, RemoveAutofillProfile(native_guid
)).
1148 WillOnce(Return(true));
1149 EXPECT_CALL(*personal_data_manager_
, Refresh());
1150 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1151 ASSERT_TRUE(add_autofill
.success());
1153 std::vector
<AutofillProfile
> new_sync_profiles
;
1154 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1155 &new_sync_profiles
));
1156 ASSERT_EQ(1U, new_sync_profiles
.size());
1157 EXPECT_EQ(0, sync_profile
.Compare(new_sync_profiles
[0]));
1158 EXPECT_EQ(sync_profile
.guid(), new_sync_profiles
[0].guid());
1161 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeAddEntry
) {
1162 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).WillOnce(Return(true));
1163 EXPECT_CALL(*personal_data_manager_
, Refresh());
1164 SetIdleChangeProcessorExpectations();
1165 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1166 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1167 ASSERT_TRUE(create_root
.success());
1169 AutofillEntry
added_entry(MakeAutofillEntry("added", "entry", 1));
1171 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
, _
)).
1172 WillOnce(DoAll(SetArgumentPointee
<2>(added_entry
.date_created()),
1173 SetArgumentPointee
<3>(added_entry
.date_last_used()),
1176 AutofillChangeList changes
;
1177 changes
.push_back(AutofillChange(AutofillChange::ADD
, added_entry
.key()));
1179 web_data_service_
->OnAutofillEntriesChanged(changes
);
1181 std::vector
<AutofillEntry
> new_sync_entries
;
1182 std::vector
<AutofillProfile
> new_sync_profiles
;
1183 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1184 &new_sync_profiles
));
1185 ASSERT_EQ(1U, new_sync_entries
.size());
1186 EXPECT_TRUE(added_entry
== new_sync_entries
[0]);
1189 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeAddProfile
) {
1190 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).WillOnce(Return(true));
1191 EXPECT_CALL(*personal_data_manager_
, Refresh());
1192 SetIdleChangeProcessorExpectations();
1193 CreateRootHelper
create_root(this, syncer::AUTOFILL_PROFILE
);
1194 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL_PROFILE
);
1195 ASSERT_TRUE(create_root
.success());
1197 AutofillProfile added_profile
;
1198 autofill::test::SetProfileInfoWithGuid(&added_profile
,
1199 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
1200 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1201 "32801", "US", "19482937549");
1203 AutofillProfileChange
change(
1204 AutofillProfileChange::ADD
, added_profile
.guid(), &added_profile
);
1205 web_data_service_
->OnAutofillProfileChanged(change
);
1207 std::vector
<AutofillProfile
> new_sync_profiles
;
1208 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1209 &new_sync_profiles
));
1210 ASSERT_EQ(1U, new_sync_profiles
.size());
1211 EXPECT_EQ(0, added_profile
.Compare(new_sync_profiles
[0]));
1214 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeUpdateEntry
) {
1215 AutofillEntry
original_entry(MakeAutofillEntry("my", "entry", 1));
1216 std::vector
<AutofillEntry
> original_entries
;
1217 original_entries
.push_back(original_entry
);
1219 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1220 WillOnce(DoAll(SetArgumentPointee
<0>(original_entries
), Return(true)));
1221 EXPECT_CALL(*personal_data_manager_
, Refresh());
1222 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1223 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1224 ASSERT_TRUE(create_root
.success());
1226 AutofillEntry
updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
1228 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
, _
)).
1229 WillOnce(DoAll(SetArgumentPointee
<2>(updated_entry
.date_created()),
1230 SetArgumentPointee
<3>(updated_entry
.date_last_used()),
1233 AutofillChangeList changes
;
1234 changes
.push_back(AutofillChange(AutofillChange::UPDATE
,
1235 updated_entry
.key()));
1236 web_data_service_
->OnAutofillEntriesChanged(changes
);
1238 std::vector
<AutofillEntry
> new_sync_entries
;
1239 std::vector
<AutofillProfile
> new_sync_profiles
;
1240 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1241 &new_sync_profiles
));
1242 ASSERT_EQ(1U, new_sync_entries
.size());
1243 EXPECT_TRUE(updated_entry
== new_sync_entries
[0]);
1247 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeRemoveEntry
) {
1248 AutofillEntry
original_entry(MakeAutofillEntry("my", "entry", 1));
1249 std::vector
<AutofillEntry
> original_entries
;
1250 original_entries
.push_back(original_entry
);
1252 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1253 WillOnce(DoAll(SetArgumentPointee
<0>(original_entries
), Return(true)));
1254 EXPECT_CALL(*personal_data_manager_
, Refresh());
1255 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1256 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1257 ASSERT_TRUE(create_root
.success());
1259 AutofillChangeList changes
;
1260 changes
.push_back(AutofillChange(AutofillChange::REMOVE
,
1261 original_entry
.key()));
1262 web_data_service_
->OnAutofillEntriesChanged(changes
);
1264 std::vector
<AutofillEntry
> new_sync_entries
;
1265 std::vector
<AutofillProfile
> new_sync_profiles
;
1266 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1267 &new_sync_profiles
));
1268 ASSERT_EQ(0U, new_sync_entries
.size());
1271 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeRemoveProfile
) {
1272 AutofillProfile sync_profile
;
1273 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1274 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1275 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1276 "32801", "US", "19482937549");
1277 AutofillProfile
* native_profile
= new AutofillProfile
;
1278 autofill::test::SetProfileInfoWithGuid(native_profile
,
1279 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1280 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1281 "32801", "US", "19482937549");
1283 std::vector
<AutofillProfile
*> native_profiles
;
1284 native_profiles
.push_back(native_profile
);
1285 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1286 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1288 std::vector
<AutofillProfile
> sync_profiles
;
1289 sync_profiles
.push_back(sync_profile
);
1290 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1291 EXPECT_CALL(*personal_data_manager_
, Refresh());
1292 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1293 ASSERT_TRUE(add_autofill
.success());
1295 AutofillProfileChange
change(
1296 AutofillProfileChange::REMOVE
, sync_profile
.guid(), NULL
);
1297 web_data_service_
->OnAutofillProfileChanged(change
);
1299 std::vector
<AutofillProfile
> new_sync_profiles
;
1300 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1301 &new_sync_profiles
));
1302 ASSERT_EQ(0U, new_sync_profiles
.size());
1305 // http://crbug.com/57884
1306 TEST_F(ProfileSyncServiceAutofillTest
, DISABLED_ServerChangeRace
) {
1307 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via
1308 // LoadAutofillData().
1309 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1310 Times(3).WillRepeatedly(Return(true));
1311 // On the other hand Autofill and Autocomplete are separated now, so
1312 // GetAutofillProfiles() should not be called.
1313 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).Times(0);
1314 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(_
)).
1315 WillRepeatedly(Return(true));
1316 EXPECT_CALL(*personal_data_manager_
, Refresh()).Times(3);
1317 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1318 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1319 ASSERT_TRUE(create_root
.success());
1321 // (true, false) means we have to reset after |Signal|, init to unsignaled.
1322 scoped_ptr
<WaitableEvent
> wait_for_start(new WaitableEvent(true, false));
1323 scoped_ptr
<WaitableEvent
> wait_for_syncapi(new WaitableEvent(true, false));
1324 scoped_refptr
<FakeServerUpdater
> updater(new FakeServerUpdater(
1325 sync_service_
, &wait_for_start
, &wait_for_syncapi
));
1327 // This server side update will stall waiting for CommitWaiter.
1328 updater
->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
1329 wait_for_start
->Wait();
1331 AutofillEntry
syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
1332 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry
));
1333 DVLOG(1) << "Syncapi update finished.";
1335 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
1336 // Signal FakeServerUpdater that it can complete.
1337 wait_for_syncapi
->Signal();
1339 // Make another entry to ensure nothing broke afterwards and wait for finish
1341 updater
->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3));
1343 std::vector
<AutofillEntry
> sync_entries
;
1344 std::vector
<AutofillProfile
> sync_profiles
;
1345 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
1346 EXPECT_EQ(3U, sync_entries
.size());
1347 EXPECT_EQ(0U, sync_profiles
.size());
1348 for (size_t i
= 0; i
< sync_entries
.size(); i
++) {
1349 DVLOG(1) << "Entry " << i
<< ": " << sync_entries
[i
].key().name()
1350 << ", " << sync_entries
[i
].key().value();