1 // Copyright (c) 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.
9 #include "testing/gtest/include/gtest/gtest.h"
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/callback.h"
14 #include "base/compiler_specific.h"
15 #include "base/location.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop.h"
19 #include "base/string16.h"
20 #include "base/synchronization/waitable_event.h"
21 #include "base/time.h"
22 #include "base/utf_string_conversions.h"
23 #include "chrome/browser/autofill/autofill_common_test.h"
24 #include "chrome/browser/autofill/personal_data_manager.h"
25 #include "chrome/browser/autofill/personal_data_manager_factory.h"
26 #include "chrome/browser/signin/signin_manager.h"
27 #include "chrome/browser/signin/signin_manager_factory.h"
28 #include "chrome/browser/signin/token_service_factory.h"
29 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
30 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
31 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
32 #include "chrome/browser/sync/glue/data_type_controller.h"
33 #include "chrome/browser/sync/glue/generic_change_processor.h"
34 #include "chrome/browser/sync/glue/shared_change_processor.h"
35 #include "chrome/browser/sync/profile_sync_components_factory.h"
36 #include "chrome/browser/sync/profile_sync_service.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/autocomplete_syncable_service.h"
40 #include "chrome/browser/webdata/autofill_change.h"
41 #include "chrome/browser/webdata/autofill_entry.h"
42 #include "chrome/browser/webdata/autofill_profile_syncable_service.h"
43 #include "chrome/browser/webdata/autofill_table.h"
44 #include "chrome/browser/webdata/web_data_service.h"
45 #include "chrome/browser/webdata/web_data_service_factory.h"
46 #include "chrome/browser/webdata/web_database.h"
47 #include "chrome/common/chrome_notification_types.h"
48 #include "content/public/browser/notification_source.h"
49 #include "content/public/test/test_browser_thread.h"
50 #include "google_apis/gaia/gaia_constants.h"
51 #include "sync/internal_api/public/base/model_type.h"
52 #include "sync/internal_api/public/read_node.h"
53 #include "sync/internal_api/public/read_transaction.h"
54 #include "sync/internal_api/public/write_node.h"
55 #include "sync/internal_api/public/write_transaction.h"
56 #include "sync/protocol/autofill_specifics.pb.h"
57 #include "sync/syncable/mutable_entry.h"
58 #include "sync/syncable/write_transaction.h"
59 #include "sync/test/engine/test_id_factory.h"
60 #include "testing/gmock/include/gmock/gmock.h"
63 using base::TimeDelta
;
64 using base::WaitableEvent
;
65 using browser_sync::AutofillDataTypeController
;
66 using browser_sync::AutofillProfileDataTypeController
;
67 using browser_sync::DataTypeController
;
68 using browser_sync::GenericChangeProcessor
;
69 using browser_sync::SharedChangeProcessor
;
70 using content::BrowserThread
;
71 using syncer::AUTOFILL
;
72 using syncer::BaseNode
;
73 using syncer::syncable::BASE_VERSION
;
74 using syncer::syncable::CREATE
;
75 using syncer::syncable::GET_BY_SERVER_TAG
;
76 using syncer::syncable::MutableEntry
;
77 using syncer::syncable::SERVER_SPECIFICS
;
78 using syncer::syncable::SPECIFICS
;
79 using syncer::syncable::UNITTEST
;
80 using syncer::syncable::WriterTag
;
81 using syncer::syncable::WriteTransaction
;
84 using testing::ElementsAre
;
85 using testing::SetArgumentPointee
;
86 using testing::Return
;
94 class AutofillTableMock
: public AutofillTable
{
96 AutofillTableMock() : AutofillTable(NULL
, NULL
) {}
97 MOCK_METHOD2(RemoveFormElement
,
98 bool(const string16
& name
, const string16
& value
)); // NOLINT
99 MOCK_METHOD1(GetAllAutofillEntries
,
100 bool(std::vector
<AutofillEntry
>* entries
)); // NOLINT
101 MOCK_METHOD3(GetAutofillTimestamps
,
102 bool(const string16
& name
, // NOLINT
103 const string16
& value
,
104 std::vector
<base::Time
>* timestamps
));
105 MOCK_METHOD1(UpdateAutofillEntries
,
106 bool(const std::vector
<AutofillEntry
>&)); // NOLINT
107 MOCK_METHOD1(GetAutofillProfiles
,
108 bool(std::vector
<AutofillProfile
*>*)); // NOLINT
109 MOCK_METHOD1(UpdateAutofillProfileMulti
,
110 bool(const AutofillProfile
&)); // NOLINT
111 MOCK_METHOD1(AddAutofillProfile
,
112 bool(const AutofillProfile
&)); // NOLINT
113 MOCK_METHOD1(RemoveAutofillProfile
,
114 bool(const std::string
&)); // NOLINT
117 MATCHER_P(MatchProfiles
, profile
, "") {
118 return (profile
.Compare(arg
) == 0);
122 class WebDatabaseFake
: public WebDatabase
{
124 explicit WebDatabaseFake(AutofillTable
* autofill_table
)
125 : autofill_table_(autofill_table
) {}
127 virtual AutofillTable
* GetAutofillTable() OVERRIDE
{
128 return autofill_table_
;
132 AutofillTable
* autofill_table_
;
135 class ProfileSyncServiceAutofillTest
;
137 template<class AutofillProfile
>
138 syncer::ModelType
GetModelType() {
139 return syncer::UNSPECIFIED
;
143 syncer::ModelType GetModelType
<AutofillEntry
>() {
144 return syncer::AUTOFILL
;
148 syncer::ModelType GetModelType
<AutofillProfile
>() {
149 return syncer::AUTOFILL_PROFILE
;
152 class WebDataServiceFake
: public WebDataService
{
155 : web_database_(NULL
),
156 syncable_service_created_or_destroyed_(false, false) {
159 static scoped_refptr
<RefcountedProfileKeyedService
> Build(Profile
* profile
) {
160 return new WebDataServiceFake
;
163 void SetDatabase(WebDatabase
* web_database
) {
164 web_database_
= web_database
;
167 void StartSyncableService() {
168 // The |autofill_profile_syncable_service_| must be constructed on the DB
170 BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
171 base::Bind(&WebDataServiceFake::CreateSyncableService
,
172 base::Unretained(this)));
173 syncable_service_created_or_destroyed_
.Wait();
176 void ShutdownSyncableService() {
177 // The |autofill_profile_syncable_service_| must be destructed on the DB
179 BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
180 base::Bind(&WebDataServiceFake::DestroySyncableService
,
181 base::Unretained(this)));
182 syncable_service_created_or_destroyed_
.Wait();
185 virtual bool IsDatabaseLoaded() OVERRIDE
{
189 virtual WebDatabase
* GetDatabase() OVERRIDE
{
190 return web_database_
;
193 virtual WebDataService::Handle
GetAllTokens(
194 WebDataServiceConsumer
* consumer
) OVERRIDE
{
195 // TODO(tim): It would be nice if WebDataService was injected on
196 // construction of TokenService rather than fetched by Initialize so that
197 // this isn't necessary (we could pass a NULL service). We currently do
198 // return it via EXPECT_CALLs, but without depending on order-of-
199 // initialization (which seems way more fragile) we can't tell which
200 // component is asking at what time, and some components in these Autofill
201 // tests require a WebDataService.
205 virtual AutocompleteSyncableService
*
206 GetAutocompleteSyncableService() const OVERRIDE
{
207 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
208 EXPECT_TRUE(autocomplete_syncable_service_
);
210 return autocomplete_syncable_service_
;
213 virtual AutofillProfileSyncableService
*
214 GetAutofillProfileSyncableService() const OVERRIDE
{
215 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
216 EXPECT_TRUE(autofill_profile_syncable_service_
);
218 return autofill_profile_syncable_service_
;
221 virtual void ShutdownOnUIThread() OVERRIDE
{}
224 virtual ~WebDataServiceFake() {}
226 void CreateSyncableService() {
227 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
228 // These services are deleted in DestroySyncableService().
229 autocomplete_syncable_service_
= new AutocompleteSyncableService(this);
230 autofill_profile_syncable_service_
=
231 new AutofillProfileSyncableService(this);
232 syncable_service_created_or_destroyed_
.Signal();
235 void DestroySyncableService() {
236 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
237 delete autofill_profile_syncable_service_
;
238 delete autocomplete_syncable_service_
;
239 syncable_service_created_or_destroyed_
.Signal();
242 WebDatabase
* web_database_
;
244 // We own the syncable services, but don't use a |scoped_ptr| because the
245 // lifetime must be managed on the DB thread.
246 AutocompleteSyncableService
* autocomplete_syncable_service_
;
247 AutofillProfileSyncableService
* autofill_profile_syncable_service_
;
248 WaitableEvent syncable_service_created_or_destroyed_
;
251 ACTION_P(MakeAutocompleteSyncComponents
, wds
) {
252 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
253 if (!BrowserThread::CurrentlyOn(BrowserThread::DB
))
254 return base::WeakPtr
<syncer::SyncableService
>();
255 return wds
->GetAutocompleteSyncableService()->AsWeakPtr();
258 ACTION(MakeGenericChangeProcessor
) {
259 syncer::UserShare
* user_share
= arg0
->GetUserShare();
260 return new GenericChangeProcessor(arg1
, arg2
, user_share
);
263 ACTION(MakeSharedChangeProcessor
) {
264 return new SharedChangeProcessor();
267 ACTION_P(MakeAutofillProfileSyncComponents
, wds
) {
268 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
269 if (!BrowserThread::CurrentlyOn(BrowserThread::DB
))
270 return base::WeakPtr
<syncer::SyncableService
>();;
271 return wds
->GetAutofillProfileSyncableService()->AsWeakPtr();
274 class AbstractAutofillFactory
{
276 virtual DataTypeController
* CreateDataTypeController(
277 ProfileSyncComponentsFactory
* factory
,
278 ProfileMock
* profile
,
279 ProfileSyncService
* service
) = 0;
280 virtual void SetExpectation(ProfileSyncComponentsFactoryMock
* factory
,
281 ProfileSyncService
* service
,
283 DataTypeController
* dtc
) = 0;
284 virtual ~AbstractAutofillFactory() {}
287 class AutofillEntryFactory
: public AbstractAutofillFactory
{
289 virtual browser_sync::DataTypeController
* CreateDataTypeController(
290 ProfileSyncComponentsFactory
* factory
,
291 ProfileMock
* profile
,
292 ProfileSyncService
* service
) OVERRIDE
{
293 return new AutofillDataTypeController(factory
, profile
, service
);
296 virtual void SetExpectation(ProfileSyncComponentsFactoryMock
* factory
,
297 ProfileSyncService
* service
,
299 DataTypeController
* dtc
) OVERRIDE
{
300 EXPECT_CALL(*factory
, CreateGenericChangeProcessor(_
,_
,_
)).
301 WillOnce(MakeGenericChangeProcessor());
302 EXPECT_CALL(*factory
, CreateSharedChangeProcessor()).
303 WillOnce(MakeSharedChangeProcessor());
304 EXPECT_CALL(*factory
, GetSyncableServiceForType(syncer::AUTOFILL
)).
305 WillOnce(MakeAutocompleteSyncComponents(wds
));
309 class AutofillProfileFactory
: public AbstractAutofillFactory
{
311 virtual browser_sync::DataTypeController
* CreateDataTypeController(
312 ProfileSyncComponentsFactory
* factory
,
313 ProfileMock
* profile
,
314 ProfileSyncService
* service
) OVERRIDE
{
315 return new AutofillProfileDataTypeController(factory
, profile
, service
);
318 virtual void SetExpectation(ProfileSyncComponentsFactoryMock
* factory
,
319 ProfileSyncService
* service
,
321 DataTypeController
* dtc
) OVERRIDE
{
322 EXPECT_CALL(*factory
, CreateGenericChangeProcessor(_
,_
,_
)).
323 WillOnce(MakeGenericChangeProcessor());
324 EXPECT_CALL(*factory
, CreateSharedChangeProcessor()).
325 WillOnce(MakeSharedChangeProcessor());
326 EXPECT_CALL(*factory
,
327 GetSyncableServiceForType(syncer::AUTOFILL_PROFILE
)).
328 WillOnce(MakeAutofillProfileSyncComponents(wds
));
332 class PersonalDataManagerMock
: public PersonalDataManager
{
334 static ProfileKeyedService
* Build(Profile
* profile
) {
335 return new PersonalDataManagerMock
;
338 MOCK_CONST_METHOD0(IsDataLoaded
, bool());
339 MOCK_METHOD0(LoadProfiles
, void());
340 MOCK_METHOD0(LoadCreditCards
, void());
341 MOCK_METHOD0(Refresh
, void());
343 template <class T
> class AddAutofillHelper
;
345 class ProfileSyncServiceAutofillTest
: public AbstractProfileSyncServiceTest
{
347 ProfileSyncServiceAutofillTest() {
349 virtual ~ProfileSyncServiceAutofillTest() {
352 AutofillProfileFactory profile_factory_
;
353 AutofillEntryFactory entry_factory_
;
355 AbstractAutofillFactory
* GetFactory(syncer::ModelType type
) {
356 if (type
== syncer::AUTOFILL
) {
357 return &entry_factory_
;
358 } else if (type
== syncer::AUTOFILL_PROFILE
) {
359 return &profile_factory_
;
366 virtual void SetUp() OVERRIDE
{
367 AbstractProfileSyncServiceTest::SetUp();
368 profile_
.reset(new ProfileMock());
369 profile_
->CreateRequestContext();
370 web_database_
.reset(new WebDatabaseFake(&autofill_table_
));
371 web_data_service_
= static_cast<WebDataServiceFake
*>(
372 WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse(
373 profile_
.get(), WebDataServiceFake::Build
).get());
374 web_data_service_
->SetDatabase(web_database_
.get());
375 personal_data_manager_
= static_cast<PersonalDataManagerMock
*>(
376 PersonalDataManagerFactory::GetInstance()->SetTestingFactoryAndUse(
377 profile_
.get(), PersonalDataManagerMock::Build
));
378 token_service_
= static_cast<TokenService
*>(
379 TokenServiceFactory::GetInstance()->SetTestingFactoryAndUse(
380 profile_
.get(), BuildTokenService
));
381 EXPECT_CALL(*personal_data_manager_
, LoadProfiles()).Times(1);
382 EXPECT_CALL(*personal_data_manager_
, LoadCreditCards()).Times(1);
384 personal_data_manager_
->Init(profile_
.get());
386 // Note: This must be called *after* the notification service is created.
387 web_data_service_
->StartSyncableService();
390 virtual void TearDown() OVERRIDE
{
391 // Note: The tear down order is important.
392 service_
->Shutdown();
394 web_data_service_
->ShutdownSyncableService();
395 profile_
->ResetRequestContext();
396 // To prevent a leak, fully release TestURLRequestContext to ensure its
397 // destruction on the IO message loop.
399 AbstractProfileSyncServiceTest::TearDown();
402 void StartSyncService(const base::Closure
& callback
,
403 bool will_fail_association
,
404 syncer::ModelType type
) {
405 AbstractAutofillFactory
* factory
= GetFactory(type
);
406 SigninManager
* signin
= SigninManagerFactory::GetForProfile(profile_
.get());
407 signin
->SetAuthenticatedUsername("test_user");
408 ProfileSyncComponentsFactoryMock
* components_factory
=
409 new ProfileSyncComponentsFactoryMock();
411 new TestProfileSyncService(components_factory
,
414 ProfileSyncService::AUTO_START
,
417 DataTypeController
* data_type_controller
=
418 factory
->CreateDataTypeController(components_factory
,
422 factory
->SetExpectation(components_factory
,
424 web_data_service_
.get(),
425 data_type_controller
);
427 EXPECT_CALL(*components_factory
, CreateDataTypeManager(_
, _
, _
, _
)).
428 WillOnce(ReturnNewDataTypeManager());
430 EXPECT_CALL(*personal_data_manager_
, IsDataLoaded()).
431 WillRepeatedly(Return(true));
433 // We need tokens to get the tests going
434 token_service_
->IssueAuthTokenForTest(GaiaConstants::kSyncService
, "token");
436 service_
->RegisterDataTypeController(data_type_controller
);
437 service_
->Initialize();
438 MessageLoop::current()->Run();
441 bool AddAutofillSyncNode(const AutofillEntry
& entry
) {
442 syncer::WriteTransaction
trans(FROM_HERE
, service_
->GetUserShare());
443 syncer::ReadNode
autofill_root(&trans
);
444 if (autofill_root
.InitByTagLookup(
445 syncer::ModelTypeToRootTag(syncer::AUTOFILL
)) !=
450 syncer::WriteNode
node(&trans
);
451 std::string tag
= AutocompleteSyncableService::KeyToTag(
452 UTF16ToUTF8(entry
.key().name()), UTF16ToUTF8(entry
.key().value()));
453 syncer::WriteNode::InitUniqueByCreationResult result
=
454 node
.InitUniqueByCreation(syncer::AUTOFILL
, autofill_root
, tag
);
455 if (result
!= syncer::WriteNode::INIT_SUCCESS
)
458 sync_pb::EntitySpecifics specifics
;
459 AutocompleteSyncableService::WriteAutofillEntry(entry
, &specifics
);
460 sync_pb::AutofillSpecifics
* autofill_specifics
=
461 specifics
.mutable_autofill();
462 node
.SetAutofillSpecifics(*autofill_specifics
);
466 bool AddAutofillSyncNode(const AutofillProfile
& profile
) {
467 syncer::WriteTransaction
trans(FROM_HERE
, service_
->GetUserShare());
468 syncer::ReadNode
autofill_root(&trans
);
469 if (autofill_root
.InitByTagLookup(kAutofillProfileTag
) !=
473 syncer::WriteNode
node(&trans
);
474 std::string tag
= profile
.guid();
475 syncer::WriteNode::InitUniqueByCreationResult result
=
476 node
.InitUniqueByCreation(syncer::AUTOFILL_PROFILE
,
478 if (result
!= syncer::WriteNode::INIT_SUCCESS
)
481 sync_pb::EntitySpecifics specifics
;
482 AutofillProfileSyncableService::WriteAutofillProfile(profile
, &specifics
);
483 sync_pb::AutofillProfileSpecifics
* profile_specifics
=
484 specifics
.mutable_autofill_profile();
485 node
.SetAutofillProfileSpecifics(*profile_specifics
);
489 bool GetAutofillEntriesFromSyncDB(std::vector
<AutofillEntry
>* entries
,
490 std::vector
<AutofillProfile
>* profiles
) {
491 syncer::ReadTransaction
trans(FROM_HERE
, service_
->GetUserShare());
492 syncer::ReadNode
autofill_root(&trans
);
493 if (autofill_root
.InitByTagLookup(
494 syncer::ModelTypeToRootTag(syncer::AUTOFILL
)) !=
499 int64 child_id
= autofill_root
.GetFirstChildId();
500 while (child_id
!= syncer::kInvalidId
) {
501 syncer::ReadNode
child_node(&trans
);
502 if (child_node
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
505 const sync_pb::AutofillSpecifics
& autofill(
506 child_node
.GetAutofillSpecifics());
507 if (autofill
.has_value()) {
508 AutofillKey
key(UTF8ToUTF16(autofill
.name()),
509 UTF8ToUTF16(autofill
.value()));
510 std::vector
<base::Time
> timestamps
;
511 int timestamps_count
= autofill
.usage_timestamp_size();
512 for (int i
= 0; i
< timestamps_count
; ++i
) {
513 timestamps
.push_back(Time::FromInternalValue(
514 autofill
.usage_timestamp(i
)));
516 entries
->push_back(AutofillEntry(key
, timestamps
));
517 } else if (autofill
.has_profile()) {
519 p
.set_guid(autofill
.profile().guid());
520 AutofillProfileSyncableService::OverwriteProfileWithServerData(
521 autofill
.profile(), &p
);
522 profiles
->push_back(p
);
524 child_id
= child_node
.GetSuccessorId();
529 bool GetAutofillProfilesFromSyncDBUnderProfileNode(
530 std::vector
<AutofillProfile
>* profiles
) {
531 syncer::ReadTransaction
trans(FROM_HERE
, service_
->GetUserShare());
532 syncer::ReadNode
autofill_root(&trans
);
533 if (autofill_root
.InitByTagLookup(kAutofillProfileTag
) !=
538 int64 child_id
= autofill_root
.GetFirstChildId();
539 while (child_id
!= syncer::kInvalidId
) {
540 syncer::ReadNode
child_node(&trans
);
541 if (child_node
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
544 const sync_pb::AutofillProfileSpecifics
& autofill(
545 child_node
.GetAutofillProfileSpecifics());
547 p
.set_guid(autofill
.guid());
548 AutofillProfileSyncableService::OverwriteProfileWithServerData(
550 profiles
->push_back(p
);
551 child_id
= child_node
.GetSuccessorId();
556 void SetIdleChangeProcessorExpectations() {
557 EXPECT_CALL(autofill_table_
, RemoveFormElement(_
, _
)).Times(0);
558 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
)).Times(0);
559 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(_
)).Times(0);
562 static AutofillEntry
MakeAutofillEntry(const char* name
,
566 // Time deep in the past would cause Autocomplete sync to discard the
568 static Time base_time
= Time::Now().LocalMidnight();
570 std::vector
<Time
> timestamps
;
572 timestamps
.push_back(base_time
+ TimeDelta::FromSeconds(time_shift0
));
574 timestamps
.push_back(base_time
+ TimeDelta::FromSeconds(time_shift1
));
575 return AutofillEntry(
576 AutofillKey(ASCIIToUTF16(name
), ASCIIToUTF16(value
)), timestamps
);
579 static AutofillEntry
MakeAutofillEntry(const char* name
,
582 return MakeAutofillEntry(name
, value
, time_shift
, -1);
585 friend class AddAutofillHelper
<AutofillEntry
>;
586 friend class AddAutofillHelper
<AutofillProfile
>;
587 friend class FakeServerUpdater
;
589 scoped_ptr
<ProfileMock
> profile_
;
590 AutofillTableMock autofill_table_
;
591 scoped_ptr
<WebDatabaseFake
> web_database_
;
592 scoped_refptr
<WebDataServiceFake
> web_data_service_
;
593 PersonalDataManagerMock
* personal_data_manager_
;
597 class AddAutofillHelper
{
599 AddAutofillHelper(ProfileSyncServiceAutofillTest
* test
,
600 const std::vector
<T
>& entries
)
601 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
602 base::Bind(&AddAutofillHelper::AddAutofillCallback
,
603 base::Unretained(this), test
, entries
))),
607 const base::Closure
& callback() const { return callback_
; }
608 bool success() { return success_
; }
611 void AddAutofillCallback(ProfileSyncServiceAutofillTest
* test
,
612 const std::vector
<T
>& entries
) {
613 if (!test
->CreateRoot(GetModelType
<T
>()))
616 for (size_t i
= 0; i
< entries
.size(); ++i
) {
617 if (!test
->AddAutofillSyncNode(entries
[i
]))
623 base::Closure callback_
;
627 // Overload write transaction to use custom NotifyTransactionComplete
628 class WriteTransactionTest
: public WriteTransaction
{
630 WriteTransactionTest(const tracked_objects::Location
& from_here
,
632 syncer::syncable::Directory
* directory
,
633 scoped_ptr
<WaitableEvent
>* wait_for_syncapi
)
634 : WriteTransaction(from_here
, writer
, directory
),
635 wait_for_syncapi_(wait_for_syncapi
) { }
637 virtual void NotifyTransactionComplete(
638 syncer::ModelTypeSet types
) OVERRIDE
{
639 // This is where we differ. Force a thread change here, giving another
640 // thread a chance to create a WriteTransaction
641 (*wait_for_syncapi_
)->Wait();
643 WriteTransaction::NotifyTransactionComplete(types
);
647 scoped_ptr
<WaitableEvent
>* wait_for_syncapi_
;
650 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
651 // post tasks with it.
652 class FakeServerUpdater
: public base::RefCountedThreadSafe
<FakeServerUpdater
> {
654 FakeServerUpdater(TestProfileSyncService
* service
,
655 scoped_ptr
<WaitableEvent
>* wait_for_start
,
656 scoped_ptr
<WaitableEvent
>* wait_for_syncapi
)
657 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)),
659 wait_for_start_(wait_for_start
),
660 wait_for_syncapi_(wait_for_syncapi
),
661 is_finished_(false, false) { }
664 // This gets called in a modelsafeworker thread.
665 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
667 syncer::UserShare
* user_share
= service_
->GetUserShare();
668 syncer::syncable::Directory
* directory
= user_share
->directory
.get();
670 // Create autofill protobuf.
671 std::string tag
= AutocompleteSyncableService::KeyToTag(
672 UTF16ToUTF8(entry_
.key().name()), UTF16ToUTF8(entry_
.key().value()));
673 sync_pb::AutofillSpecifics new_autofill
;
674 new_autofill
.set_name(UTF16ToUTF8(entry_
.key().name()));
675 new_autofill
.set_value(UTF16ToUTF8(entry_
.key().value()));
676 const std::vector
<base::Time
>& ts(entry_
.timestamps());
677 for (std::vector
<base::Time
>::const_iterator timestamp
= ts
.begin();
678 timestamp
!= ts
.end(); ++timestamp
) {
679 new_autofill
.add_usage_timestamp(timestamp
->ToInternalValue());
682 sync_pb::EntitySpecifics entity_specifics
;
683 entity_specifics
.mutable_autofill()->CopyFrom(new_autofill
);
686 // Tell main thread we've started
687 (*wait_for_start_
)->Signal();
689 // Create write transaction.
690 WriteTransactionTest
trans(FROM_HERE
, UNITTEST
, directory
,
693 // Create actual entry based on autofill protobuf information.
694 // Simulates effects of UpdateLocalDataFromServerData
695 MutableEntry
parent(&trans
, GET_BY_SERVER_TAG
,
696 syncer::ModelTypeToRootTag(syncer::AUTOFILL
));
697 MutableEntry
item(&trans
, CREATE
, parent
.Get(syncer::syncable::ID
), tag
);
698 ASSERT_TRUE(item
.good());
699 item
.Put(SPECIFICS
, entity_specifics
);
700 item
.Put(SERVER_SPECIFICS
, entity_specifics
);
701 item
.Put(BASE_VERSION
, 1);
702 syncer::syncable::Id server_item_id
=
703 service_
->id_factory()->NewServerId();
704 item
.Put(syncer::syncable::ID
, server_item_id
);
705 syncer::syncable::Id new_predecessor
;
706 ASSERT_TRUE(item
.PutPredecessor(new_predecessor
));
708 DVLOG(1) << "FakeServerUpdater finishing.";
709 is_finished_
.Signal();
712 void CreateNewEntry(const AutofillEntry
& entry
) {
714 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
715 if (!BrowserThread::PostTask(
716 BrowserThread::DB
, FROM_HERE
,
717 base::Bind(&FakeServerUpdater::Update
, this))) {
718 NOTREACHED() << "Failed to post task to the db thread.";
723 void CreateNewEntryAndWait(const AutofillEntry
& entry
) {
725 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
726 is_finished_
.Reset();
727 if (!BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
728 base::Bind(&FakeServerUpdater::Update
, this))) {
729 NOTREACHED() << "Failed to post task to the db thread.";
736 friend class base::RefCountedThreadSafe
<FakeServerUpdater
>;
737 ~FakeServerUpdater() { }
739 AutofillEntry entry_
;
740 TestProfileSyncService
* service_
;
741 scoped_ptr
<WaitableEvent
>* wait_for_start_
;
742 scoped_ptr
<WaitableEvent
>* wait_for_syncapi_
;
743 WaitableEvent is_finished_
;
744 syncer::syncable::Id parent_id_
;
749 // Checks if the field of type |field_type| in |profile1| includes all values
750 // of the field in |profile2|.
751 bool IncludesField(const AutofillProfile
& profile1
,
752 const AutofillProfile
& profile2
,
753 AutofillFieldType field_type
) {
754 std::vector
<string16
> values1
;
755 profile1
.GetMultiInfo(field_type
, &values1
);
756 std::vector
<string16
> values2
;
757 profile2
.GetMultiInfo(field_type
, &values2
);
759 std::set
<string16
> values_set
;
760 for (size_t i
= 0; i
< values1
.size(); ++i
)
761 values_set
.insert(values1
[i
]);
762 for (size_t i
= 0; i
< values2
.size(); ++i
)
763 if (values_set
.find(values2
[i
]) == values_set
.end())
770 // TODO(skrul): Test abort startup.
771 // TODO(skrul): Test processing of cloud changes.
772 // TODO(tim): Add autofill data type controller test, and a case to cover
773 // waiting for the PersonalDataManager.
774 TEST_F(ProfileSyncServiceAutofillTest
, FailModelAssociation
) {
775 // Don't create the root autofill node so startup fails.
776 StartSyncService(base::Closure(), true, syncer::AUTOFILL
);
777 EXPECT_TRUE(service_
->HasUnrecoverableError());
780 TEST_F(ProfileSyncServiceAutofillTest
, EmptyNativeEmptySync
) {
781 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).WillOnce(Return(true));
782 SetIdleChangeProcessorExpectations();
783 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
784 EXPECT_CALL(*personal_data_manager_
, Refresh());
785 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
786 EXPECT_TRUE(create_root
.success());
787 std::vector
<AutofillEntry
> sync_entries
;
788 std::vector
<AutofillProfile
> sync_profiles
;
789 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
790 EXPECT_EQ(0U, sync_entries
.size());
791 EXPECT_EQ(0U, sync_profiles
.size());
794 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeEntriesEmptySync
) {
795 std::vector
<AutofillEntry
> entries
;
796 entries
.push_back(MakeAutofillEntry("foo", "bar", 1));
797 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
798 WillOnce(DoAll(SetArgumentPointee
<0>(entries
), Return(true)));
799 SetIdleChangeProcessorExpectations();
800 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
801 EXPECT_CALL(*personal_data_manager_
, Refresh());
802 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
803 ASSERT_TRUE(create_root
.success());
804 std::vector
<AutofillEntry
> sync_entries
;
805 std::vector
<AutofillProfile
> sync_profiles
;
806 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
807 ASSERT_EQ(1U, entries
.size());
808 EXPECT_TRUE(entries
[0] == sync_entries
[0]);
809 EXPECT_EQ(0U, sync_profiles
.size());
812 TEST_F(ProfileSyncServiceAutofillTest
, HasProfileEmptySync
) {
813 std::vector
<AutofillProfile
*> profiles
;
814 std::vector
<AutofillProfile
> expected_profiles
;
815 // Owned by GetAutofillProfiles caller.
816 AutofillProfile
* profile0
= new AutofillProfile
;
817 autofill_test::SetProfileInfoWithGuid(profile0
,
818 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
819 "Mitchell", "Morrison",
820 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
821 "91601", "US", "12345678910");
822 profiles
.push_back(profile0
);
823 expected_profiles
.push_back(*profile0
);
824 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
825 WillOnce(DoAll(SetArgumentPointee
<0>(profiles
), Return(true)));
826 EXPECT_CALL(*personal_data_manager_
, Refresh());
827 SetIdleChangeProcessorExpectations();
828 CreateRootHelper
create_root(this, syncer::AUTOFILL_PROFILE
);
829 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL_PROFILE
);
830 ASSERT_TRUE(create_root
.success());
831 std::vector
<AutofillProfile
> sync_profiles
;
832 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles
));
833 EXPECT_EQ(1U, sync_profiles
.size());
834 EXPECT_EQ(0, expected_profiles
[0].Compare(sync_profiles
[0]));
837 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeWithDuplicatesEmptySync
) {
838 // There is buggy autofill code that allows duplicate name/value
839 // pairs to exist in the database with separate pair_ids.
840 std::vector
<AutofillEntry
> entries
;
841 entries
.push_back(MakeAutofillEntry("foo", "bar", 1));
842 entries
.push_back(MakeAutofillEntry("dup", "", 2));
843 entries
.push_back(MakeAutofillEntry("dup", "", 3));
844 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
845 WillOnce(DoAll(SetArgumentPointee
<0>(entries
), Return(true)));
846 SetIdleChangeProcessorExpectations();
847 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
848 EXPECT_CALL(*personal_data_manager_
, Refresh());
849 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
850 ASSERT_TRUE(create_root
.success());
851 std::vector
<AutofillEntry
> sync_entries
;
852 std::vector
<AutofillProfile
> sync_profiles
;
853 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
854 EXPECT_EQ(2U, sync_entries
.size());
857 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncNoMerge
) {
858 AutofillEntry
native_entry(MakeAutofillEntry("native", "entry", 1));
859 AutofillEntry
sync_entry(MakeAutofillEntry("sync", "entry", 2));
861 std::vector
<AutofillEntry
> native_entries
;
862 native_entries
.push_back(native_entry
);
864 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
865 WillOnce(DoAll(SetArgumentPointee
<0>(native_entries
), Return(true)));
867 std::vector
<AutofillEntry
> sync_entries
;
868 sync_entries
.push_back(sync_entry
);
870 AddAutofillHelper
<AutofillEntry
> add_autofill(this, sync_entries
);
872 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(ElementsAre(sync_entry
))).
873 WillOnce(Return(true));
875 EXPECT_CALL(*personal_data_manager_
, Refresh());
876 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL
);
877 ASSERT_TRUE(add_autofill
.success());
879 std::set
<AutofillEntry
> expected_entries
;
880 expected_entries
.insert(native_entry
);
881 expected_entries
.insert(sync_entry
);
883 std::vector
<AutofillEntry
> new_sync_entries
;
884 std::vector
<AutofillProfile
> new_sync_profiles
;
885 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
886 &new_sync_profiles
));
887 std::set
<AutofillEntry
> new_sync_entries_set(new_sync_entries
.begin(),
888 new_sync_entries
.end());
890 EXPECT_TRUE(expected_entries
== new_sync_entries_set
);
893 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeEntry
) {
894 AutofillEntry
native_entry(MakeAutofillEntry("merge", "entry", 1));
895 AutofillEntry
sync_entry(MakeAutofillEntry("merge", "entry", 2));
896 AutofillEntry
merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
898 std::vector
<AutofillEntry
> native_entries
;
899 native_entries
.push_back(native_entry
);
900 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
901 WillOnce(DoAll(SetArgumentPointee
<0>(native_entries
), Return(true)));
903 std::vector
<AutofillEntry
> sync_entries
;
904 sync_entries
.push_back(sync_entry
);
905 AddAutofillHelper
<AutofillEntry
> add_autofill(this, sync_entries
);
907 EXPECT_CALL(autofill_table_
,
908 UpdateAutofillEntries(ElementsAre(merged_entry
))).WillOnce(Return(true));
909 EXPECT_CALL(*personal_data_manager_
, Refresh());
910 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL
);
911 ASSERT_TRUE(add_autofill
.success());
913 std::vector
<AutofillEntry
> new_sync_entries
;
914 std::vector
<AutofillProfile
> new_sync_profiles
;
915 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
916 &new_sync_profiles
));
917 ASSERT_EQ(1U, new_sync_entries
.size());
918 EXPECT_TRUE(merged_entry
== new_sync_entries
[0]);
921 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeProfile
) {
922 AutofillProfile sync_profile
;
923 autofill_test::SetProfileInfoWithGuid(&sync_profile
,
924 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
925 "Mitchell", "Morrison",
926 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
927 "91601", "US", "12345678910");
929 AutofillProfile
* native_profile
= new AutofillProfile
;
930 autofill_test::SetProfileInfoWithGuid(native_profile
,
931 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
932 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
933 "32801", "US", "19482937549");
935 std::vector
<AutofillProfile
*> native_profiles
;
936 native_profiles
.push_back(native_profile
);
937 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
938 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
940 std::vector
<AutofillProfile
> sync_profiles
;
941 sync_profiles
.push_back(sync_profile
);
942 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
944 EXPECT_CALL(autofill_table_
,
945 UpdateAutofillProfileMulti(MatchProfiles(sync_profile
))).
946 WillOnce(Return(true));
947 EXPECT_CALL(*personal_data_manager_
, Refresh());
948 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
949 ASSERT_TRUE(add_autofill
.success());
951 std::vector
<AutofillProfile
> new_sync_profiles
;
952 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
953 &new_sync_profiles
));
954 ASSERT_EQ(1U, new_sync_profiles
.size());
955 EXPECT_EQ(0, sync_profile
.Compare(new_sync_profiles
[0]));
958 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeProfileCombine
) {
959 AutofillProfile sync_profile
;
960 autofill_test::SetProfileInfoWithGuid(&sync_profile
,
961 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
962 "Mitchell", "Morrison",
963 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
964 "91601", "US", "12345678910");
966 AutofillProfile
* native_profile
= new AutofillProfile
;
967 // Same address, but different names, phones and e-mails.
968 autofill_test::SetProfileInfoWithGuid(native_profile
,
969 "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "Alicia", "Saenz",
970 "joewayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
971 "91601", "US", "19482937549");
973 AutofillProfile
expected_profile(sync_profile
);
974 expected_profile
.OverwriteWithOrAddTo(*native_profile
);
976 std::vector
<AutofillProfile
*> native_profiles
;
977 native_profiles
.push_back(native_profile
);
978 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
979 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
980 EXPECT_CALL(autofill_table_
,
981 AddAutofillProfile(MatchProfiles(expected_profile
))).
982 WillOnce(Return(true));
983 EXPECT_CALL(autofill_table_
,
984 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")).
985 WillOnce(Return(true));
986 std::vector
<AutofillProfile
> sync_profiles
;
987 sync_profiles
.push_back(sync_profile
);
988 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
990 EXPECT_CALL(*personal_data_manager_
, Refresh());
991 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
992 ASSERT_TRUE(add_autofill
.success());
994 std::vector
<AutofillProfile
> new_sync_profiles
;
995 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
996 &new_sync_profiles
));
997 ASSERT_EQ(1U, new_sync_profiles
.size());
998 // Check that key fields are the same.
999 EXPECT_TRUE(new_sync_profiles
[0].IsSubsetOf(sync_profile
));
1000 // Check that multivalued fields of the synced back data include original
1002 EXPECT_TRUE(IncludesField(new_sync_profiles
[0], sync_profile
, NAME_FULL
));
1003 EXPECT_TRUE(IncludesField(new_sync_profiles
[0], sync_profile
, EMAIL_ADDRESS
));
1004 EXPECT_TRUE(IncludesField(new_sync_profiles
[0], sync_profile
,
1005 PHONE_HOME_WHOLE_NUMBER
));
1008 TEST_F(ProfileSyncServiceAutofillTest
, MergeProfileWithDifferentGuid
) {
1009 AutofillProfile sync_profile
;
1011 autofill_test::SetProfileInfoWithGuid(&sync_profile
,
1012 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1013 "Mitchell", "Morrison",
1014 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1015 "91601", "US", "12345678910");
1017 std::string native_guid
= "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
1018 AutofillProfile
* native_profile
= new AutofillProfile
;
1019 autofill_test::SetProfileInfoWithGuid(native_profile
,
1020 native_guid
.c_str(), "Billing",
1021 "Mitchell", "Morrison",
1022 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1023 "91601", "US", "12345678910");
1025 std::vector
<AutofillProfile
*> native_profiles
;
1026 native_profiles
.push_back(native_profile
);
1027 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1028 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1030 std::vector
<AutofillProfile
> sync_profiles
;
1031 sync_profiles
.push_back(sync_profile
);
1032 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1034 EXPECT_CALL(autofill_table_
, AddAutofillProfile(_
)).
1035 WillOnce(Return(true));
1036 EXPECT_CALL(autofill_table_
, RemoveAutofillProfile(native_guid
)).
1037 WillOnce(Return(true));
1038 EXPECT_CALL(*personal_data_manager_
, Refresh());
1039 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1040 ASSERT_TRUE(add_autofill
.success());
1042 std::vector
<AutofillProfile
> new_sync_profiles
;
1043 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1044 &new_sync_profiles
));
1045 ASSERT_EQ(1U, new_sync_profiles
.size());
1046 EXPECT_EQ(0, sync_profile
.Compare(new_sync_profiles
[0]));
1047 EXPECT_EQ(sync_profile
.guid(), new_sync_profiles
[0].guid());
1050 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeAddEntry
) {
1051 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).WillOnce(Return(true));
1052 EXPECT_CALL(*personal_data_manager_
, Refresh());
1053 SetIdleChangeProcessorExpectations();
1054 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1055 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1056 ASSERT_TRUE(create_root
.success());
1058 AutofillEntry
added_entry(MakeAutofillEntry("added", "entry", 1));
1059 std::vector
<base::Time
> timestamps(added_entry
.timestamps());
1061 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
)).
1062 WillOnce(DoAll(SetArgumentPointee
<2>(timestamps
), Return(true)));
1064 AutofillChangeList changes
;
1065 changes
.push_back(AutofillChange(AutofillChange::ADD
, added_entry
.key()));
1066 scoped_refptr
<ThreadNotifier
> notifier(new ThreadNotifier(
1067 db_thread_
.DeprecatedGetThreadObject()));
1068 notifier
->Notify(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED
,
1069 content::Source
<WebDataService
>(web_data_service_
.get()),
1070 content::Details
<AutofillChangeList
>(&changes
));
1072 std::vector
<AutofillEntry
> new_sync_entries
;
1073 std::vector
<AutofillProfile
> new_sync_profiles
;
1074 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1075 &new_sync_profiles
));
1076 ASSERT_EQ(1U, new_sync_entries
.size());
1077 EXPECT_TRUE(added_entry
== new_sync_entries
[0]);
1080 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeAddProfile
) {
1081 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).WillOnce(Return(true));
1082 EXPECT_CALL(*personal_data_manager_
, Refresh());
1083 SetIdleChangeProcessorExpectations();
1084 CreateRootHelper
create_root(this, syncer::AUTOFILL_PROFILE
);
1085 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL_PROFILE
);
1086 ASSERT_TRUE(create_root
.success());
1088 AutofillProfile added_profile
;
1089 autofill_test::SetProfileInfoWithGuid(&added_profile
,
1090 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
1091 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1092 "32801", "US", "19482937549");
1094 AutofillProfileChange
change(AutofillProfileChange::ADD
,
1095 added_profile
.guid(), &added_profile
);
1096 scoped_refptr
<ThreadNotifier
> notifier(new ThreadNotifier(
1097 db_thread_
.DeprecatedGetThreadObject()));
1098 notifier
->Notify(chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED
,
1099 content::Source
<WebDataService
>(web_data_service_
.get()),
1100 content::Details
<AutofillProfileChange
>(&change
));
1102 std::vector
<AutofillProfile
> new_sync_profiles
;
1103 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1104 &new_sync_profiles
));
1105 ASSERT_EQ(1U, new_sync_profiles
.size());
1106 EXPECT_EQ(0, added_profile
.Compare(new_sync_profiles
[0]));
1109 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeUpdateEntry
) {
1110 AutofillEntry
original_entry(MakeAutofillEntry("my", "entry", 1));
1111 std::vector
<AutofillEntry
> original_entries
;
1112 original_entries
.push_back(original_entry
);
1114 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1115 WillOnce(DoAll(SetArgumentPointee
<0>(original_entries
), Return(true)));
1116 EXPECT_CALL(*personal_data_manager_
, Refresh());
1117 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1118 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1119 ASSERT_TRUE(create_root
.success());
1121 AutofillEntry
updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
1122 std::vector
<base::Time
> timestamps(updated_entry
.timestamps());
1124 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
)).
1125 WillOnce(DoAll(SetArgumentPointee
<2>(timestamps
), Return(true)));
1127 AutofillChangeList changes
;
1128 changes
.push_back(AutofillChange(AutofillChange::UPDATE
,
1129 updated_entry
.key()));
1130 scoped_refptr
<ThreadNotifier
> notifier(new ThreadNotifier(
1131 db_thread_
.DeprecatedGetThreadObject()));
1132 notifier
->Notify(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED
,
1133 content::Source
<WebDataService
>(web_data_service_
.get()),
1134 content::Details
<AutofillChangeList
>(&changes
));
1136 std::vector
<AutofillEntry
> new_sync_entries
;
1137 std::vector
<AutofillProfile
> new_sync_profiles
;
1138 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1139 &new_sync_profiles
));
1140 ASSERT_EQ(1U, new_sync_entries
.size());
1141 EXPECT_TRUE(updated_entry
== new_sync_entries
[0]);
1145 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeRemoveEntry
) {
1146 AutofillEntry
original_entry(MakeAutofillEntry("my", "entry", 1));
1147 std::vector
<AutofillEntry
> original_entries
;
1148 original_entries
.push_back(original_entry
);
1150 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1151 WillOnce(DoAll(SetArgumentPointee
<0>(original_entries
), Return(true)));
1152 EXPECT_CALL(*personal_data_manager_
, Refresh());
1153 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1154 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1155 ASSERT_TRUE(create_root
.success());
1157 AutofillChangeList changes
;
1158 changes
.push_back(AutofillChange(AutofillChange::REMOVE
,
1159 original_entry
.key()));
1160 scoped_refptr
<ThreadNotifier
> notifier(new ThreadNotifier(
1161 db_thread_
.DeprecatedGetThreadObject()));
1162 notifier
->Notify(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED
,
1163 content::Source
<WebDataService
>(web_data_service_
.get()),
1164 content::Details
<AutofillChangeList
>(&changes
));
1166 std::vector
<AutofillEntry
> new_sync_entries
;
1167 std::vector
<AutofillProfile
> new_sync_profiles
;
1168 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1169 &new_sync_profiles
));
1170 ASSERT_EQ(0U, new_sync_entries
.size());
1173 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeRemoveProfile
) {
1174 AutofillProfile sync_profile
;
1175 autofill_test::SetProfileInfoWithGuid(&sync_profile
,
1176 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1177 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1178 "32801", "US", "19482937549");
1179 AutofillProfile
* native_profile
= new AutofillProfile
;
1180 autofill_test::SetProfileInfoWithGuid(native_profile
,
1181 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1182 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1183 "32801", "US", "19482937549");
1185 std::vector
<AutofillProfile
*> native_profiles
;
1186 native_profiles
.push_back(native_profile
);
1187 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1188 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1190 std::vector
<AutofillProfile
> sync_profiles
;
1191 sync_profiles
.push_back(sync_profile
);
1192 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1193 EXPECT_CALL(*personal_data_manager_
, Refresh());
1194 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1195 ASSERT_TRUE(add_autofill
.success());
1197 AutofillProfileChange
change(AutofillProfileChange::REMOVE
,
1198 sync_profile
.guid(), NULL
);
1199 scoped_refptr
<ThreadNotifier
> notifier(new ThreadNotifier(
1200 db_thread_
.DeprecatedGetThreadObject()));
1201 notifier
->Notify(chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED
,
1202 content::Source
<WebDataService
>(web_data_service_
.get()),
1203 content::Details
<AutofillProfileChange
>(&change
));
1205 std::vector
<AutofillProfile
> new_sync_profiles
;
1206 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1207 &new_sync_profiles
));
1208 ASSERT_EQ(0U, new_sync_profiles
.size());
1211 // http://crbug.com/57884
1212 TEST_F(ProfileSyncServiceAutofillTest
, DISABLED_ServerChangeRace
) {
1213 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via
1214 // LoadAutofillData().
1215 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1216 Times(3).WillRepeatedly(Return(true));
1217 // On the other hand Autofill and Autocomplete are separated now, so
1218 // GetAutofillProfiles() should not be called.
1219 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).Times(0);
1220 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(_
)).
1221 WillRepeatedly(Return(true));
1222 EXPECT_CALL(*personal_data_manager_
, Refresh()).Times(3);
1223 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1224 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1225 ASSERT_TRUE(create_root
.success());
1227 // (true, false) means we have to reset after |Signal|, init to unsignaled.
1228 scoped_ptr
<WaitableEvent
> wait_for_start(new WaitableEvent(true, false));
1229 scoped_ptr
<WaitableEvent
> wait_for_syncapi(new WaitableEvent(true, false));
1230 scoped_refptr
<FakeServerUpdater
> updater(new FakeServerUpdater(
1231 service_
.get(), &wait_for_start
, &wait_for_syncapi
));
1233 // This server side update will stall waiting for CommitWaiter.
1234 updater
->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
1235 wait_for_start
->Wait();
1237 AutofillEntry
syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
1238 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry
));
1239 DVLOG(1) << "Syncapi update finished.";
1241 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
1242 // Signal FakeServerUpdater that it can complete.
1243 wait_for_syncapi
->Signal();
1245 // Make another entry to ensure nothing broke afterwards and wait for finish
1247 updater
->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3));
1249 std::vector
<AutofillEntry
> sync_entries
;
1250 std::vector
<AutofillProfile
> sync_profiles
;
1251 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
1252 EXPECT_EQ(3U, sync_entries
.size());
1253 EXPECT_EQ(0U, sync_profiles
.size());
1254 for (size_t i
= 0; i
< sync_entries
.size(); i
++) {
1255 DVLOG(1) << "Entry " << i
<< ": " << sync_entries
[i
].key().name()
1256 << ", " << sync_entries
[i
].key().value();