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/fake_profile_oauth2_token_service.h"
27 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
28 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
29 #include "chrome/browser/signin/signin_manager_factory.h"
30 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
31 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
32 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
33 #include "chrome/browser/sync/profile_sync_components_factory.h"
34 #include "chrome/browser/sync/profile_sync_service.h"
35 #include "chrome/browser/sync/profile_sync_service_factory.h"
36 #include "chrome/browser/sync/profile_sync_test_util.h"
37 #include "chrome/browser/sync/test_profile_sync_service.h"
38 #include "chrome/browser/webdata/autocomplete_syncable_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/autofill_change.h"
46 #include "components/autofill/core/browser/webdata/autofill_entry.h"
47 #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
48 #include "components/autofill/core/browser/webdata/autofill_table.h"
49 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
50 #include "components/signin/core/browser/signin_manager.h"
51 #include "components/sync_driver/data_type_controller.h"
52 #include "components/webdata/common/web_data_service_test_util.h"
53 #include "components/webdata/common/web_database.h"
54 #include "content/public/test/test_browser_thread.h"
55 #include "google_apis/gaia/gaia_constants.h"
56 #include "sync/internal_api/public/base/model_type.h"
57 #include "sync/internal_api/public/data_type_debug_info_listener.h"
58 #include "sync/internal_api/public/read_node.h"
59 #include "sync/internal_api/public/read_transaction.h"
60 #include "sync/internal_api/public/write_node.h"
61 #include "sync/internal_api/public/write_transaction.h"
62 #include "sync/protocol/autofill_specifics.pb.h"
63 #include "sync/syncable/mutable_entry.h"
64 #include "sync/syncable/syncable_write_transaction.h"
65 #include "sync/test/engine/test_id_factory.h"
66 #include "testing/gmock/include/gmock/gmock.h"
68 using autofill::AutofillChange
;
69 using autofill::AutofillChangeList
;
70 using autofill::AutofillEntry
;
71 using autofill::ServerFieldType
;
72 using autofill::AutofillKey
;
73 using autofill::AutofillProfile
;
74 using autofill::AutofillProfileChange
;
75 using autofill::AutofillProfileSyncableService
;
76 using autofill::AutofillTable
;
77 using autofill::AutofillWebDataService
;
78 using autofill::PersonalDataManager
;
80 using base::TimeDelta
;
81 using base::WaitableEvent
;
82 using browser_sync::AutofillDataTypeController
;
83 using browser_sync::AutofillProfileDataTypeController
;
84 using content::BrowserThread
;
85 using syncer::AUTOFILL
;
86 using syncer::AUTOFILL_PROFILE
;
87 using syncer::BaseNode
;
88 using syncer::syncable::BASE_VERSION
;
89 using syncer::syncable::CREATE
;
90 using syncer::syncable::GET_TYPE_ROOT
;
91 using syncer::syncable::MutableEntry
;
92 using syncer::syncable::SERVER_SPECIFICS
;
93 using syncer::syncable::SPECIFICS
;
94 using syncer::syncable::UNITTEST
;
95 using syncer::syncable::WriterTag
;
96 using syncer::syncable::WriteTransaction
;
97 using sync_driver::DataTypeController
;
100 using testing::ElementsAre
;
102 using testing::SetArgumentPointee
;
103 using testing::Return
;
105 class HistoryService
;
113 const char kTestProfileName
[] = "test-profile";
115 void RunAndSignal(const base::Closure
& cb
, WaitableEvent
* event
) {
122 class AutofillTableMock
: public AutofillTable
{
124 AutofillTableMock() : AutofillTable("en-US") {}
125 MOCK_METHOD2(RemoveFormElement
,
126 bool(const base::string16
& name
,
127 const base::string16
& value
)); // NOLINT
128 MOCK_METHOD1(GetAllAutofillEntries
,
129 bool(std::vector
<AutofillEntry
>* entries
)); // NOLINT
130 MOCK_METHOD4(GetAutofillTimestamps
,
131 bool(const base::string16
& name
, // NOLINT
132 const base::string16
& value
,
133 base::Time
* date_created
,
134 base::Time
* date_last_used
));
135 MOCK_METHOD1(UpdateAutofillEntries
,
136 bool(const std::vector
<AutofillEntry
>&)); // NOLINT
137 MOCK_METHOD1(GetAutofillProfiles
,
138 bool(std::vector
<AutofillProfile
*>*)); // NOLINT
139 MOCK_METHOD1(UpdateAutofillProfile
,
140 bool(const AutofillProfile
&)); // NOLINT
141 MOCK_METHOD1(AddAutofillProfile
,
142 bool(const AutofillProfile
&)); // NOLINT
143 MOCK_METHOD1(RemoveAutofillProfile
,
144 bool(const std::string
&)); // NOLINT
147 MATCHER_P(MatchProfiles
, profile
, "") {
148 return (profile
.Compare(arg
) == 0);
151 class WebDatabaseFake
: public WebDatabase
{
153 explicit WebDatabaseFake(AutofillTable
* autofill_table
) {
154 AddTable(autofill_table
);
158 class MockAutofillBackend
: public autofill::AutofillWebDataBackend
{
161 WebDatabase
* web_database
,
162 const base::Closure
& on_changed
)
163 : web_database_(web_database
),
164 on_changed_(on_changed
) {
167 virtual ~MockAutofillBackend() {}
168 virtual WebDatabase
* GetDatabase() override
{ return web_database_
; }
169 virtual void AddObserver(
170 autofill::AutofillWebDataServiceObserverOnDBThread
* observer
) override
{}
171 virtual void RemoveObserver(
172 autofill::AutofillWebDataServiceObserverOnDBThread
* observer
) override
{}
173 virtual void RemoveExpiredFormElements() override
{}
174 virtual void NotifyOfMultipleAutofillChanges() override
{
175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB
));
176 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, on_changed_
);
180 WebDatabase
* web_database_
;
181 base::Closure on_changed_
;
184 class ProfileSyncServiceAutofillTest
;
186 template<class AutofillProfile
>
187 syncer::ModelType
GetModelType() {
188 return syncer::UNSPECIFIED
;
192 syncer::ModelType GetModelType
<AutofillEntry
>() {
193 return syncer::AUTOFILL
;
197 syncer::ModelType GetModelType
<AutofillProfile
>() {
198 return syncer::AUTOFILL_PROFILE
;
201 class TokenWebDataServiceFake
: public TokenWebData
{
203 TokenWebDataServiceFake()
205 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI
),
206 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB
)) {
209 virtual bool IsDatabaseLoaded() override
{
213 virtual AutofillWebDataService::Handle
GetAllTokens(
214 WebDataServiceConsumer
* consumer
) override
{
215 // TODO(tim): It would be nice if WebDataService was injected on
216 // construction of ProfileOAuth2TokenService rather than fetched by
217 // Initialize so that this isn't necessary (we could pass a NULL service).
218 // We currently do return it via EXPECT_CALLs, but without depending on
219 // order-of-initialization (which seems way more fragile) we can't tell
220 // which component is asking at what time, and some components in these
221 // Autofill tests require a WebDataService.
226 virtual ~TokenWebDataServiceFake() {}
228 DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake
);
231 class WebDataServiceFake
: public AutofillWebDataService
{
234 : AutofillWebDataService(
235 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI
),
236 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB
)),
238 autocomplete_syncable_service_(NULL
),
239 autofill_profile_syncable_service_(NULL
),
240 syncable_service_created_or_destroyed_(false, false) {
243 void SetDatabase(WebDatabase
* web_database
) {
244 web_database_
= web_database
;
247 void StartSyncableService() {
248 // The |autofill_profile_syncable_service_| must be constructed on the DB
250 const base::Closure
& on_changed_callback
= base::Bind(
251 &WebDataServiceFake::NotifyAutofillMultipleChangedOnUIThread
,
254 BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
255 base::Bind(&WebDataServiceFake::CreateSyncableService
,
256 base::Unretained(this),
257 on_changed_callback
));
258 syncable_service_created_or_destroyed_
.Wait();
261 void ShutdownSyncableService() {
262 // The |autofill_profile_syncable_service_| must be destructed on the DB
264 BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
265 base::Bind(&WebDataServiceFake::DestroySyncableService
,
266 base::Unretained(this)));
267 syncable_service_created_or_destroyed_
.Wait();
270 virtual bool IsDatabaseLoaded() override
{
274 virtual WebDatabase
* GetDatabase() override
{
275 return web_database_
;
278 void OnAutofillEntriesChanged(const AutofillChangeList
& changes
) {
279 WaitableEvent
event(true, false);
281 base::Closure notify_cb
=
282 base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged
,
283 base::Unretained(autocomplete_syncable_service_
),
285 BrowserThread::PostTask(
288 base::Bind(&RunAndSignal
, notify_cb
, &event
));
292 void OnAutofillProfileChanged(const AutofillProfileChange
& changes
) {
293 WaitableEvent
event(true, false);
295 base::Closure notify_cb
=
296 base::Bind(&AutocompleteSyncableService::AutofillProfileChanged
,
297 base::Unretained(autofill_profile_syncable_service_
),
299 BrowserThread::PostTask(
302 base::Bind(&RunAndSignal
, notify_cb
, &event
));
307 virtual ~WebDataServiceFake() {}
309 void CreateSyncableService(const base::Closure
& on_changed_callback
) {
310 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
311 // These services are deleted in DestroySyncableService().
312 backend_
.reset(new MockAutofillBackend(
313 GetDatabase(), on_changed_callback
));
314 AutocompleteSyncableService::CreateForWebDataServiceAndBackend(
315 this, backend_
.get());
316 AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
317 this, backend_
.get(), "en-US");
319 autocomplete_syncable_service_
=
320 AutocompleteSyncableService::FromWebDataService(this);
321 autofill_profile_syncable_service_
=
322 AutofillProfileSyncableService::FromWebDataService(this);
324 syncable_service_created_or_destroyed_
.Signal();
327 void DestroySyncableService() {
328 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
329 autocomplete_syncable_service_
= NULL
;
330 autofill_profile_syncable_service_
= NULL
;
332 syncable_service_created_or_destroyed_
.Signal();
335 WebDatabase
* web_database_
;
336 AutocompleteSyncableService
* autocomplete_syncable_service_
;
337 AutofillProfileSyncableService
* autofill_profile_syncable_service_
;
338 scoped_ptr
<autofill::AutofillWebDataBackend
> backend_
;
340 WaitableEvent syncable_service_created_or_destroyed_
;
342 DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake
);
345 KeyedService
* BuildMockWebDataServiceWrapper(content::BrowserContext
* profile
) {
346 return new MockWebDataServiceWrapper(
347 new WebDataServiceFake(),
348 new TokenWebDataServiceFake());
351 ACTION_P(MakeAutocompleteSyncComponents
, wds
) {
352 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
353 if (!BrowserThread::CurrentlyOn(BrowserThread::DB
))
354 return base::WeakPtr
<syncer::SyncableService
>();
355 return AutocompleteSyncableService::FromWebDataService(wds
)->AsWeakPtr();
358 ACTION_P(ReturnNewDataTypeManagerWithDebugListener
, debug_listener
) {
359 return new sync_driver::DataTypeManagerImpl(
368 ACTION_P(MakeAutofillProfileSyncComponents
, wds
) {
369 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
370 if (!BrowserThread::CurrentlyOn(BrowserThread::DB
))
371 return base::WeakPtr
<syncer::SyncableService
>();
372 return AutofillProfileSyncableService::FromWebDataService(wds
)->AsWeakPtr();
375 class AbstractAutofillFactory
{
377 virtual DataTypeController
* CreateDataTypeController(
378 ProfileSyncComponentsFactory
* factory
,
379 TestingProfile
* profile
,
380 ProfileSyncService
* service
) = 0;
381 virtual void SetExpectation(ProfileSyncComponentsFactoryMock
* factory
,
382 ProfileSyncService
* service
,
383 AutofillWebDataService
* wds
,
384 DataTypeController
* dtc
) = 0;
385 virtual ~AbstractAutofillFactory() {}
388 class AutofillEntryFactory
: public AbstractAutofillFactory
{
390 virtual DataTypeController
* CreateDataTypeController(
391 ProfileSyncComponentsFactory
* factory
,
392 TestingProfile
* profile
,
393 ProfileSyncService
* service
) override
{
394 return new AutofillDataTypeController(factory
, profile
);
397 virtual void SetExpectation(ProfileSyncComponentsFactoryMock
* factory
,
398 ProfileSyncService
* service
,
399 AutofillWebDataService
* wds
,
400 DataTypeController
* dtc
) override
{
401 EXPECT_CALL(*factory
, GetSyncableServiceForType(syncer::AUTOFILL
)).
402 WillOnce(MakeAutocompleteSyncComponents(wds
));
406 class AutofillProfileFactory
: public AbstractAutofillFactory
{
408 virtual DataTypeController
* CreateDataTypeController(
409 ProfileSyncComponentsFactory
* factory
,
410 TestingProfile
* profile
,
411 ProfileSyncService
* service
) override
{
412 return new AutofillProfileDataTypeController(factory
, profile
);
415 virtual void SetExpectation(ProfileSyncComponentsFactoryMock
* factory
,
416 ProfileSyncService
* service
,
417 AutofillWebDataService
* wds
,
418 DataTypeController
* dtc
) override
{
419 EXPECT_CALL(*factory
,
420 GetSyncableServiceForType(syncer::AUTOFILL_PROFILE
)).
421 WillOnce(MakeAutofillProfileSyncComponents(wds
));
425 class MockPersonalDataManager
: public PersonalDataManager
{
427 MockPersonalDataManager() : PersonalDataManager("en-US") {}
428 MOCK_CONST_METHOD0(IsDataLoaded
, bool());
429 MOCK_METHOD0(LoadProfiles
, void());
430 MOCK_METHOD0(LoadCreditCards
, void());
431 MOCK_METHOD0(Refresh
, void());
433 static KeyedService
* Build(content::BrowserContext
* profile
) {
434 return new MockPersonalDataManager();
438 template <class T
> class AddAutofillHelper
;
440 class ProfileSyncServiceAutofillTest
441 : public AbstractProfileSyncServiceTest
,
442 public syncer::DataTypeDebugInfoListener
{
444 // DataTypeDebugInfoListener implementation.
445 virtual void OnDataTypeConfigureComplete(
446 const std::vector
<syncer::DataTypeConfigurationStats
>&
447 configuration_stats
) override
{
448 ASSERT_EQ(1u, configuration_stats
.size());
449 association_stats_
= configuration_stats
[0].association_stats
;
453 ProfileSyncServiceAutofillTest()
454 : profile_manager_(TestingBrowserProcess::GetGlobal()),
455 debug_ptr_factory_(this) {
457 virtual ~ProfileSyncServiceAutofillTest() {
460 AutofillProfileFactory profile_factory_
;
461 AutofillEntryFactory entry_factory_
;
463 AbstractAutofillFactory
* GetFactory(syncer::ModelType type
) {
464 if (type
== syncer::AUTOFILL
) {
465 return &entry_factory_
;
466 } else if (type
== syncer::AUTOFILL_PROFILE
) {
467 return &profile_factory_
;
474 virtual void SetUp() override
{
475 AbstractProfileSyncServiceTest::SetUp();
476 ASSERT_TRUE(profile_manager_
.SetUp());
477 TestingProfile::TestingFactories testing_factories
;
478 testing_factories
.push_back(std::make_pair(
479 ProfileOAuth2TokenServiceFactory::GetInstance(),
480 BuildAutoIssuingFakeProfileOAuth2TokenService
));
481 profile_
= profile_manager_
.CreateTestingProfile(
483 scoped_ptr
<PrefServiceSyncable
>(),
484 base::UTF8ToUTF16(kTestProfileName
),
488 web_database_
.reset(new WebDatabaseFake(&autofill_table_
));
489 MockWebDataServiceWrapper
* wrapper
=
490 static_cast<MockWebDataServiceWrapper
*>(
491 WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse(
492 profile_
, BuildMockWebDataServiceWrapper
));
494 static_cast<WebDataServiceFake
*>(wrapper
->GetAutofillWebData().get());
495 web_data_service_
->SetDatabase(web_database_
.get());
497 personal_data_manager_
= static_cast<MockPersonalDataManager
*>(
498 autofill::PersonalDataManagerFactory::GetInstance()
499 ->SetTestingFactoryAndUse(profile_
,
500 MockPersonalDataManager::Build
));
502 EXPECT_CALL(*personal_data_manager_
, LoadProfiles()).Times(1);
503 EXPECT_CALL(*personal_data_manager_
, LoadCreditCards()).Times(1);
505 personal_data_manager_
->Init(
506 WebDataServiceFactory::GetAutofillWebDataForProfile(
507 profile_
, Profile::EXPLICIT_ACCESS
),
508 profile_
->GetPrefs(),
509 profile_
->IsOffTheRecord());
511 web_data_service_
->StartSyncableService();
513 // When UpdateAutofillEntries() is called with an empty list, the return
514 // value should be |true|, rather than the default of |false|.
515 std::vector
<AutofillEntry
> empty
;
516 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(empty
))
517 .WillRepeatedly(Return(true));
520 virtual void TearDown() override
{
521 // Note: The tear down order is important.
522 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(profile_
, NULL
);
523 web_data_service_
->ShutdownOnUIThread();
524 web_data_service_
->ShutdownSyncableService();
525 web_data_service_
= NULL
;
526 // To prevent a leak, fully release TestURLRequestContext to ensure its
527 // destruction on the IO message loop.
529 profile_manager_
.DeleteTestingProfile(kTestProfileName
);
530 AbstractProfileSyncServiceTest::TearDown();
533 int GetSyncCount(syncer::ModelType type
) {
534 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
535 syncer::ReadNode
node(&trans
);
536 if (node
.InitTypeRoot(type
) != syncer::BaseNode::INIT_OK
)
538 return node
.GetTotalNodeCount() - 1;
541 void StartSyncService(const base::Closure
& callback
,
542 bool will_fail_association
,
543 syncer::ModelType type
) {
544 AbstractAutofillFactory
* factory
= GetFactory(type
);
545 SigninManagerBase
* signin
= SigninManagerFactory::GetForProfile(profile_
);
546 signin
->SetAuthenticatedUsername("test_user@gmail.com");
547 sync_service_
= TestProfileSyncService::BuildAutoStartAsyncInit(profile_
,
550 ProfileSyncComponentsFactoryMock
* components
=
551 sync_service_
->components_factory_mock();
552 DataTypeController
* data_type_controller
=
553 factory
->CreateDataTypeController(components
, profile_
, sync_service_
);
554 factory
->SetExpectation(components
,
556 web_data_service_
.get(),
557 data_type_controller
);
559 EXPECT_CALL(*components
, CreateDataTypeManager(_
, _
, _
, _
, _
)).
560 WillOnce(ReturnNewDataTypeManagerWithDebugListener(
561 syncer::MakeWeakHandle(debug_ptr_factory_
.GetWeakPtr())));
563 EXPECT_CALL(*personal_data_manager_
, IsDataLoaded()).
564 WillRepeatedly(Return(true));
566 // We need tokens to get the tests going
567 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
)
568 ->UpdateCredentials("test_user@gmail.com", "oauth2_login_token");
570 sync_service_
->RegisterDataTypeController(data_type_controller
);
571 sync_service_
->Initialize();
572 base::MessageLoop::current()->Run();
574 // It's possible this test triggered an unrecoverable error, in which case
575 // we can't get the sync count.
576 if (sync_service_
->SyncActive()) {
577 EXPECT_EQ(GetSyncCount(type
),
578 association_stats_
.num_sync_items_after_association
);
580 EXPECT_EQ(association_stats_
.num_sync_items_after_association
,
581 association_stats_
.num_sync_items_before_association
+
582 association_stats_
.num_sync_items_added
-
583 association_stats_
.num_sync_items_deleted
);
586 bool AddAutofillSyncNode(const AutofillEntry
& entry
) {
587 syncer::WriteTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
588 syncer::ReadNode
autofill_root(&trans
);
589 if (autofill_root
.InitTypeRoot(syncer::AUTOFILL
) != BaseNode::INIT_OK
) {
593 syncer::WriteNode
node(&trans
);
594 std::string tag
= AutocompleteSyncableService::KeyToTag(
595 base::UTF16ToUTF8(entry
.key().name()),
596 base::UTF16ToUTF8(entry
.key().value()));
597 syncer::WriteNode::InitUniqueByCreationResult result
=
598 node
.InitUniqueByCreation(syncer::AUTOFILL
, autofill_root
, tag
);
599 if (result
!= syncer::WriteNode::INIT_SUCCESS
)
602 sync_pb::EntitySpecifics specifics
;
603 AutocompleteSyncableService::WriteAutofillEntry(entry
, &specifics
);
604 sync_pb::AutofillSpecifics
* autofill_specifics
=
605 specifics
.mutable_autofill();
606 node
.SetAutofillSpecifics(*autofill_specifics
);
610 bool AddAutofillSyncNode(const AutofillProfile
& profile
) {
611 syncer::WriteTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
612 syncer::ReadNode
autofill_root(&trans
);
613 if (autofill_root
.InitTypeRoot(AUTOFILL_PROFILE
) != BaseNode::INIT_OK
) {
616 syncer::WriteNode
node(&trans
);
617 std::string tag
= profile
.guid();
618 syncer::WriteNode::InitUniqueByCreationResult result
=
619 node
.InitUniqueByCreation(syncer::AUTOFILL_PROFILE
,
621 if (result
!= syncer::WriteNode::INIT_SUCCESS
)
624 sync_pb::EntitySpecifics specifics
;
625 AutofillProfileSyncableService::WriteAutofillProfile(profile
, &specifics
);
626 sync_pb::AutofillProfileSpecifics
* profile_specifics
=
627 specifics
.mutable_autofill_profile();
628 node
.SetAutofillProfileSpecifics(*profile_specifics
);
632 bool GetAutofillEntriesFromSyncDB(std::vector
<AutofillEntry
>* entries
,
633 std::vector
<AutofillProfile
>* profiles
) {
634 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
635 syncer::ReadNode
autofill_root(&trans
);
636 if (autofill_root
.InitTypeRoot(syncer::AUTOFILL
) != BaseNode::INIT_OK
) {
640 int64 child_id
= autofill_root
.GetFirstChildId();
641 while (child_id
!= syncer::kInvalidId
) {
642 syncer::ReadNode
child_node(&trans
);
643 if (child_node
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
646 const sync_pb::AutofillSpecifics
& autofill(
647 child_node
.GetAutofillSpecifics());
648 if (autofill
.has_value()) {
649 AutofillKey
key(base::UTF8ToUTF16(autofill
.name()),
650 base::UTF8ToUTF16(autofill
.value()));
651 std::vector
<base::Time
> timestamps
;
652 int timestamps_count
= autofill
.usage_timestamp_size();
653 for (int i
= 0; i
< timestamps_count
; ++i
) {
654 timestamps
.push_back(Time::FromInternalValue(
655 autofill
.usage_timestamp(i
)));
658 AutofillEntry(key
, timestamps
.front(), timestamps
.back()));
659 } else if (autofill
.has_profile()) {
661 p
.set_guid(autofill
.profile().guid());
662 AutofillProfileSyncableService::OverwriteProfileWithServerData(
663 autofill
.profile(), &p
, "en-US");
664 profiles
->push_back(p
);
666 child_id
= child_node
.GetSuccessorId();
671 bool GetAutofillProfilesFromSyncDBUnderProfileNode(
672 std::vector
<AutofillProfile
>* profiles
) {
673 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
674 syncer::ReadNode
autofill_root(&trans
);
675 if (autofill_root
.InitTypeRoot(AUTOFILL_PROFILE
) != BaseNode::INIT_OK
) {
679 int64 child_id
= autofill_root
.GetFirstChildId();
680 while (child_id
!= syncer::kInvalidId
) {
681 syncer::ReadNode
child_node(&trans
);
682 if (child_node
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
685 const sync_pb::AutofillProfileSpecifics
& autofill(
686 child_node
.GetAutofillProfileSpecifics());
688 p
.set_guid(autofill
.guid());
689 AutofillProfileSyncableService::OverwriteProfileWithServerData(
690 autofill
, &p
, "en-US");
691 profiles
->push_back(p
);
692 child_id
= child_node
.GetSuccessorId();
697 void SetIdleChangeProcessorExpectations() {
698 EXPECT_CALL(autofill_table_
, RemoveFormElement(_
, _
)).Times(0);
699 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
, _
)).Times(0);
701 // Only permit UpdateAutofillEntries() to be called with an empty list.
702 std::vector
<AutofillEntry
> empty
;
703 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(Not(empty
))).Times(0);
706 static AutofillEntry
MakeAutofillEntry(const char* name
,
710 // Time deep in the past would cause Autocomplete sync to discard the
712 static Time base_time
= Time::Now().LocalMidnight();
714 base::Time date_created
= base_time
+ TimeDelta::FromSeconds(time_shift0
);
715 base::Time date_last_used
= date_created
;
716 if (time_shift1
>= 0)
717 date_last_used
= base_time
+ TimeDelta::FromSeconds(time_shift1
);
718 return AutofillEntry(
719 AutofillKey(base::ASCIIToUTF16(name
), base::ASCIIToUTF16(value
)),
720 date_created
, date_last_used
);
723 static AutofillEntry
MakeAutofillEntry(const char* name
,
726 return MakeAutofillEntry(name
, value
, time_shift
, -1);
729 friend class AddAutofillHelper
<AutofillEntry
>;
730 friend class AddAutofillHelper
<AutofillProfile
>;
731 friend class FakeServerUpdater
;
733 TestingProfileManager profile_manager_
;
734 TestingProfile
* profile_
;
735 AutofillTableMock autofill_table_
;
736 scoped_ptr
<WebDatabaseFake
> web_database_
;
737 scoped_refptr
<WebDataServiceFake
> web_data_service_
;
738 MockPersonalDataManager
* personal_data_manager_
;
739 syncer::DataTypeAssociationStats association_stats_
;
740 base::WeakPtrFactory
<DataTypeDebugInfoListener
> debug_ptr_factory_
;
744 class AddAutofillHelper
{
746 AddAutofillHelper(ProfileSyncServiceAutofillTest
* test
,
747 const std::vector
<T
>& entries
)
748 : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback
,
749 base::Unretained(this), test
, entries
)),
753 const base::Closure
& callback() const { return callback_
; }
754 bool success() { return success_
; }
757 void AddAutofillCallback(ProfileSyncServiceAutofillTest
* test
,
758 const std::vector
<T
>& entries
) {
759 if (!test
->CreateRoot(GetModelType
<T
>()))
762 for (size_t i
= 0; i
< entries
.size(); ++i
) {
763 if (!test
->AddAutofillSyncNode(entries
[i
]))
769 base::Closure callback_
;
773 // Overload write transaction to use custom NotifyTransactionComplete
774 class WriteTransactionTest
: public WriteTransaction
{
776 WriteTransactionTest(const tracked_objects::Location
& from_here
,
778 syncer::syncable::Directory
* directory
,
779 scoped_ptr
<WaitableEvent
>* wait_for_syncapi
)
780 : WriteTransaction(from_here
, writer
, directory
),
781 wait_for_syncapi_(wait_for_syncapi
) { }
783 virtual void NotifyTransactionComplete(
784 syncer::ModelTypeSet types
) override
{
785 // This is where we differ. Force a thread change here, giving another
786 // thread a chance to create a WriteTransaction
787 (*wait_for_syncapi_
)->Wait();
789 WriteTransaction::NotifyTransactionComplete(types
);
793 scoped_ptr
<WaitableEvent
>* wait_for_syncapi_
;
796 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
797 // post tasks with it.
798 class FakeServerUpdater
: public base::RefCountedThreadSafe
<FakeServerUpdater
> {
800 FakeServerUpdater(TestProfileSyncService
* service
,
801 scoped_ptr
<WaitableEvent
>* wait_for_start
,
802 scoped_ptr
<WaitableEvent
>* wait_for_syncapi
)
803 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)),
805 wait_for_start_(wait_for_start
),
806 wait_for_syncapi_(wait_for_syncapi
),
807 is_finished_(false, false) { }
810 // This gets called in a modelsafeworker thread.
811 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
813 syncer::UserShare
* user_share
= service_
->GetUserShare();
814 syncer::syncable::Directory
* directory
= user_share
->directory
.get();
816 // Create autofill protobuf.
817 std::string tag
= AutocompleteSyncableService::KeyToTag(
818 base::UTF16ToUTF8(entry_
.key().name()),
819 base::UTF16ToUTF8(entry_
.key().value()));
820 sync_pb::AutofillSpecifics new_autofill
;
821 new_autofill
.set_name(base::UTF16ToUTF8(entry_
.key().name()));
822 new_autofill
.set_value(base::UTF16ToUTF8(entry_
.key().value()));
823 new_autofill
.add_usage_timestamp(entry_
.date_created().ToInternalValue());
824 if (entry_
.date_created() != entry_
.date_last_used()) {
825 new_autofill
.add_usage_timestamp(
826 entry_
.date_last_used().ToInternalValue());
829 sync_pb::EntitySpecifics entity_specifics
;
830 entity_specifics
.mutable_autofill()->CopyFrom(new_autofill
);
833 // Tell main thread we've started
834 (*wait_for_start_
)->Signal();
836 // Create write transaction.
837 WriteTransactionTest
trans(FROM_HERE
, UNITTEST
, directory
,
840 // Create actual entry based on autofill protobuf information.
841 // Simulates effects of UpdateLocalDataFromServerData
842 MutableEntry
parent(&trans
, GET_TYPE_ROOT
, syncer::AUTOFILL
);
843 MutableEntry
item(&trans
, CREATE
, syncer::AUTOFILL
, parent
.GetId(), tag
);
844 ASSERT_TRUE(item
.good());
845 item
.PutSpecifics(entity_specifics
);
846 item
.PutServerSpecifics(entity_specifics
);
847 item
.PutBaseVersion(1);
848 syncer::syncable::Id server_item_id
=
849 service_
->id_factory()->NewServerId();
850 item
.PutId(server_item_id
);
851 syncer::syncable::Id new_predecessor
;
852 ASSERT_TRUE(item
.PutPredecessor(new_predecessor
));
854 DVLOG(1) << "FakeServerUpdater finishing.";
855 is_finished_
.Signal();
858 void CreateNewEntry(const AutofillEntry
& entry
) {
860 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
861 if (!BrowserThread::PostTask(
862 BrowserThread::DB
, FROM_HERE
,
863 base::Bind(&FakeServerUpdater::Update
, this))) {
864 NOTREACHED() << "Failed to post task to the db thread.";
869 void CreateNewEntryAndWait(const AutofillEntry
& entry
) {
871 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB
));
872 is_finished_
.Reset();
873 if (!BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
874 base::Bind(&FakeServerUpdater::Update
, this))) {
875 NOTREACHED() << "Failed to post task to the db thread.";
882 friend class base::RefCountedThreadSafe
<FakeServerUpdater
>;
883 ~FakeServerUpdater() { }
885 AutofillEntry entry_
;
886 TestProfileSyncService
* service_
;
887 scoped_ptr
<WaitableEvent
>* wait_for_start_
;
888 scoped_ptr
<WaitableEvent
>* wait_for_syncapi_
;
889 WaitableEvent is_finished_
;
890 syncer::syncable::Id parent_id_
;
895 // Checks if the field of type |field_type| in |profile1| includes all values
896 // of the field in |profile2|.
897 bool IncludesField(const AutofillProfile
& profile1
,
898 const AutofillProfile
& profile2
,
899 ServerFieldType field_type
) {
900 std::vector
<base::string16
> values1
;
901 profile1
.GetRawMultiInfo(field_type
, &values1
);
902 std::vector
<base::string16
> values2
;
903 profile2
.GetRawMultiInfo(field_type
, &values2
);
905 std::set
<base::string16
> values_set
;
906 for (size_t i
= 0; i
< values1
.size(); ++i
)
907 values_set
.insert(values1
[i
]);
908 for (size_t i
= 0; i
< values2
.size(); ++i
)
909 if (values_set
.find(values2
[i
]) == values_set
.end())
916 // TODO(skrul): Test abort startup.
917 // TODO(skrul): Test processing of cloud changes.
918 // TODO(tim): Add autofill data type controller test, and a case to cover
919 // waiting for the PersonalDataManager.
920 TEST_F(ProfileSyncServiceAutofillTest
, FailModelAssociation
) {
921 // Don't create the root autofill node so startup fails.
922 StartSyncService(base::Closure(), true, syncer::AUTOFILL
);
923 EXPECT_TRUE(sync_service_
->HasUnrecoverableError());
926 TEST_F(ProfileSyncServiceAutofillTest
, EmptyNativeEmptySync
) {
927 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).WillOnce(Return(true));
928 SetIdleChangeProcessorExpectations();
929 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
930 EXPECT_CALL(*personal_data_manager_
, Refresh());
931 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
932 EXPECT_TRUE(create_root
.success());
933 std::vector
<AutofillEntry
> sync_entries
;
934 std::vector
<AutofillProfile
> sync_profiles
;
935 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
936 EXPECT_EQ(0U, sync_entries
.size());
937 EXPECT_EQ(0U, sync_profiles
.size());
940 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeEntriesEmptySync
) {
941 std::vector
<AutofillEntry
> entries
;
942 entries
.push_back(MakeAutofillEntry("foo", "bar", 1));
943 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
944 WillOnce(DoAll(SetArgumentPointee
<0>(entries
), Return(true)));
945 SetIdleChangeProcessorExpectations();
946 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
947 EXPECT_CALL(*personal_data_manager_
, Refresh());
948 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
949 ASSERT_TRUE(create_root
.success());
950 std::vector
<AutofillEntry
> sync_entries
;
951 std::vector
<AutofillProfile
> sync_profiles
;
952 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
953 ASSERT_EQ(1U, entries
.size());
954 EXPECT_TRUE(entries
[0] == sync_entries
[0]);
955 EXPECT_EQ(0U, sync_profiles
.size());
958 TEST_F(ProfileSyncServiceAutofillTest
, HasProfileEmptySync
) {
959 std::vector
<AutofillProfile
*> profiles
;
960 std::vector
<AutofillProfile
> expected_profiles
;
961 // Owned by GetAutofillProfiles caller.
962 AutofillProfile
* profile0
= new AutofillProfile
;
963 autofill::test::SetProfileInfoWithGuid(profile0
,
964 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
965 "Mitchell", "Morrison",
966 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
967 "91601", "US", "12345678910");
968 profiles
.push_back(profile0
);
969 expected_profiles
.push_back(*profile0
);
970 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
971 WillOnce(DoAll(SetArgumentPointee
<0>(profiles
), Return(true)));
972 EXPECT_CALL(*personal_data_manager_
, Refresh());
973 SetIdleChangeProcessorExpectations();
974 CreateRootHelper
create_root(this, syncer::AUTOFILL_PROFILE
);
975 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL_PROFILE
);
976 ASSERT_TRUE(create_root
.success());
977 std::vector
<AutofillProfile
> sync_profiles
;
978 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles
));
979 EXPECT_EQ(1U, sync_profiles
.size());
980 EXPECT_EQ(0, expected_profiles
[0].Compare(sync_profiles
[0]));
983 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeWithDuplicatesEmptySync
) {
984 // There is buggy autofill code that allows duplicate name/value
985 // pairs to exist in the database with separate pair_ids.
986 std::vector
<AutofillEntry
> entries
;
987 entries
.push_back(MakeAutofillEntry("foo", "bar", 1));
988 entries
.push_back(MakeAutofillEntry("dup", "", 2));
989 entries
.push_back(MakeAutofillEntry("dup", "", 3));
990 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
991 WillOnce(DoAll(SetArgumentPointee
<0>(entries
), Return(true)));
992 SetIdleChangeProcessorExpectations();
993 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
994 EXPECT_CALL(*personal_data_manager_
, Refresh());
995 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
996 ASSERT_TRUE(create_root
.success());
997 std::vector
<AutofillEntry
> sync_entries
;
998 std::vector
<AutofillProfile
> sync_profiles
;
999 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
1000 EXPECT_EQ(2U, sync_entries
.size());
1003 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncNoMerge
) {
1004 AutofillEntry
native_entry(MakeAutofillEntry("native", "entry", 1));
1005 AutofillEntry
sync_entry(MakeAutofillEntry("sync", "entry", 2));
1007 std::vector
<AutofillEntry
> native_entries
;
1008 native_entries
.push_back(native_entry
);
1010 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1011 WillOnce(DoAll(SetArgumentPointee
<0>(native_entries
), Return(true)));
1013 std::vector
<AutofillEntry
> sync_entries
;
1014 sync_entries
.push_back(sync_entry
);
1016 AddAutofillHelper
<AutofillEntry
> add_autofill(this, sync_entries
);
1018 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(ElementsAre(sync_entry
))).
1019 WillOnce(Return(true));
1021 EXPECT_CALL(*personal_data_manager_
, Refresh());
1022 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL
);
1023 ASSERT_TRUE(add_autofill
.success());
1025 std::set
<AutofillEntry
> expected_entries
;
1026 expected_entries
.insert(native_entry
);
1027 expected_entries
.insert(sync_entry
);
1029 std::vector
<AutofillEntry
> new_sync_entries
;
1030 std::vector
<AutofillProfile
> new_sync_profiles
;
1031 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1032 &new_sync_profiles
));
1033 std::set
<AutofillEntry
> new_sync_entries_set(new_sync_entries
.begin(),
1034 new_sync_entries
.end());
1036 EXPECT_TRUE(expected_entries
== new_sync_entries_set
);
1039 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeEntry
) {
1040 AutofillEntry
native_entry(MakeAutofillEntry("merge", "entry", 1));
1041 AutofillEntry
sync_entry(MakeAutofillEntry("merge", "entry", 2));
1042 AutofillEntry
merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
1044 std::vector
<AutofillEntry
> native_entries
;
1045 native_entries
.push_back(native_entry
);
1046 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1047 WillOnce(DoAll(SetArgumentPointee
<0>(native_entries
), Return(true)));
1049 std::vector
<AutofillEntry
> sync_entries
;
1050 sync_entries
.push_back(sync_entry
);
1051 AddAutofillHelper
<AutofillEntry
> add_autofill(this, sync_entries
);
1053 EXPECT_CALL(autofill_table_
,
1054 UpdateAutofillEntries(ElementsAre(merged_entry
))).WillOnce(Return(true));
1055 EXPECT_CALL(*personal_data_manager_
, Refresh());
1056 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL
);
1057 ASSERT_TRUE(add_autofill
.success());
1059 std::vector
<AutofillEntry
> new_sync_entries
;
1060 std::vector
<AutofillProfile
> new_sync_profiles
;
1061 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1062 &new_sync_profiles
));
1063 ASSERT_EQ(1U, new_sync_entries
.size());
1064 EXPECT_TRUE(merged_entry
== new_sync_entries
[0]);
1067 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeProfile
) {
1068 AutofillProfile sync_profile
;
1069 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1070 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1071 "Mitchell", "Morrison",
1072 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1073 "91601", "US", "12345678910");
1075 AutofillProfile
* native_profile
= new AutofillProfile
;
1076 autofill::test::SetProfileInfoWithGuid(native_profile
,
1077 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
1078 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1079 "32801", "US", "19482937549");
1081 std::vector
<AutofillProfile
*> native_profiles
;
1082 native_profiles
.push_back(native_profile
);
1083 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1084 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1086 std::vector
<AutofillProfile
> sync_profiles
;
1087 sync_profiles
.push_back(sync_profile
);
1088 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1090 EXPECT_CALL(autofill_table_
,
1091 UpdateAutofillProfile(MatchProfiles(sync_profile
))).
1092 WillOnce(Return(true));
1093 EXPECT_CALL(*personal_data_manager_
, Refresh());
1094 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1095 ASSERT_TRUE(add_autofill
.success());
1097 std::vector
<AutofillProfile
> new_sync_profiles
;
1098 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1099 &new_sync_profiles
));
1100 ASSERT_EQ(1U, new_sync_profiles
.size());
1101 EXPECT_EQ(0, sync_profile
.Compare(new_sync_profiles
[0]));
1104 TEST_F(ProfileSyncServiceAutofillTest
, HasNativeHasSyncMergeProfileCombine
) {
1105 AutofillProfile sync_profile
;
1106 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1107 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1108 "Mitchell", "Morrison",
1109 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1110 "91601", "US", "12345678910");
1112 AutofillProfile
* native_profile
= new AutofillProfile
;
1113 // Same address, but different names, phones and e-mails.
1114 autofill::test::SetProfileInfoWithGuid(native_profile
,
1115 "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "Alicia", "Saenz",
1116 "joewayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1117 "91601", "US", "19482937549");
1119 AutofillProfile
expected_profile(sync_profile
);
1120 expected_profile
.OverwriteWithOrAddTo(*native_profile
, "en-US");
1122 std::vector
<AutofillProfile
*> native_profiles
;
1123 native_profiles
.push_back(native_profile
);
1124 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1125 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1126 EXPECT_CALL(autofill_table_
,
1127 AddAutofillProfile(MatchProfiles(expected_profile
))).
1128 WillOnce(Return(true));
1129 EXPECT_CALL(autofill_table_
,
1130 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")).
1131 WillOnce(Return(true));
1132 std::vector
<AutofillProfile
> sync_profiles
;
1133 sync_profiles
.push_back(sync_profile
);
1134 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1136 EXPECT_CALL(*personal_data_manager_
, Refresh());
1137 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1138 ASSERT_TRUE(add_autofill
.success());
1140 std::vector
<AutofillProfile
> new_sync_profiles
;
1141 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1142 &new_sync_profiles
));
1143 ASSERT_EQ(1U, new_sync_profiles
.size());
1144 // Check that key fields are the same.
1145 EXPECT_TRUE(new_sync_profiles
[0].IsSubsetOf(sync_profile
, "en-US"));
1146 // Check that multivalued fields of the synced back data include original
1149 IncludesField(new_sync_profiles
[0], sync_profile
, autofill::NAME_FULL
));
1150 EXPECT_TRUE(IncludesField(
1151 new_sync_profiles
[0], sync_profile
, autofill::EMAIL_ADDRESS
));
1152 EXPECT_TRUE(IncludesField(
1153 new_sync_profiles
[0], sync_profile
, autofill::PHONE_HOME_WHOLE_NUMBER
));
1156 TEST_F(ProfileSyncServiceAutofillTest
, MergeProfileWithDifferentGuid
) {
1157 AutofillProfile sync_profile
;
1159 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1160 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
1161 "Mitchell", "Morrison",
1162 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1163 "91601", "US", "12345678910");
1165 std::string native_guid
= "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
1166 AutofillProfile
* native_profile
= new AutofillProfile
;
1167 autofill::test::SetProfileInfoWithGuid(native_profile
,
1168 native_guid
.c_str(), "Billing",
1169 "Mitchell", "Morrison",
1170 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
1171 "91601", "US", "12345678910");
1173 std::vector
<AutofillProfile
*> native_profiles
;
1174 native_profiles
.push_back(native_profile
);
1175 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1176 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1178 std::vector
<AutofillProfile
> sync_profiles
;
1179 sync_profiles
.push_back(sync_profile
);
1180 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1182 EXPECT_CALL(autofill_table_
, AddAutofillProfile(_
)).
1183 WillOnce(Return(true));
1184 EXPECT_CALL(autofill_table_
, RemoveAutofillProfile(native_guid
)).
1185 WillOnce(Return(true));
1186 EXPECT_CALL(*personal_data_manager_
, Refresh());
1187 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1188 ASSERT_TRUE(add_autofill
.success());
1190 std::vector
<AutofillProfile
> new_sync_profiles
;
1191 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1192 &new_sync_profiles
));
1193 ASSERT_EQ(1U, new_sync_profiles
.size());
1194 EXPECT_EQ(0, sync_profile
.Compare(new_sync_profiles
[0]));
1195 EXPECT_EQ(sync_profile
.guid(), new_sync_profiles
[0].guid());
1198 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeAddEntry
) {
1199 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).WillOnce(Return(true));
1200 EXPECT_CALL(*personal_data_manager_
, Refresh());
1201 SetIdleChangeProcessorExpectations();
1202 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1203 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1204 ASSERT_TRUE(create_root
.success());
1206 AutofillEntry
added_entry(MakeAutofillEntry("added", "entry", 1));
1208 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
, _
)).
1209 WillOnce(DoAll(SetArgumentPointee
<2>(added_entry
.date_created()),
1210 SetArgumentPointee
<3>(added_entry
.date_last_used()),
1213 AutofillChangeList changes
;
1214 changes
.push_back(AutofillChange(AutofillChange::ADD
, added_entry
.key()));
1216 web_data_service_
->OnAutofillEntriesChanged(changes
);
1218 std::vector
<AutofillEntry
> new_sync_entries
;
1219 std::vector
<AutofillProfile
> new_sync_profiles
;
1220 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1221 &new_sync_profiles
));
1222 ASSERT_EQ(1U, new_sync_entries
.size());
1223 EXPECT_TRUE(added_entry
== new_sync_entries
[0]);
1226 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeAddProfile
) {
1227 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).WillOnce(Return(true));
1228 EXPECT_CALL(*personal_data_manager_
, Refresh());
1229 SetIdleChangeProcessorExpectations();
1230 CreateRootHelper
create_root(this, syncer::AUTOFILL_PROFILE
);
1231 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL_PROFILE
);
1232 ASSERT_TRUE(create_root
.success());
1234 AutofillProfile added_profile
;
1235 autofill::test::SetProfileInfoWithGuid(&added_profile
,
1236 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
1237 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1238 "32801", "US", "19482937549");
1240 AutofillProfileChange
change(
1241 AutofillProfileChange::ADD
, added_profile
.guid(), &added_profile
);
1242 web_data_service_
->OnAutofillProfileChanged(change
);
1244 std::vector
<AutofillProfile
> new_sync_profiles
;
1245 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1246 &new_sync_profiles
));
1247 ASSERT_EQ(1U, new_sync_profiles
.size());
1248 EXPECT_EQ(0, added_profile
.Compare(new_sync_profiles
[0]));
1251 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeUpdateEntry
) {
1252 AutofillEntry
original_entry(MakeAutofillEntry("my", "entry", 1));
1253 std::vector
<AutofillEntry
> original_entries
;
1254 original_entries
.push_back(original_entry
);
1256 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1257 WillOnce(DoAll(SetArgumentPointee
<0>(original_entries
), Return(true)));
1258 EXPECT_CALL(*personal_data_manager_
, Refresh());
1259 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1260 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1261 ASSERT_TRUE(create_root
.success());
1263 AutofillEntry
updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
1265 EXPECT_CALL(autofill_table_
, GetAutofillTimestamps(_
, _
, _
, _
)).
1266 WillOnce(DoAll(SetArgumentPointee
<2>(updated_entry
.date_created()),
1267 SetArgumentPointee
<3>(updated_entry
.date_last_used()),
1270 AutofillChangeList changes
;
1271 changes
.push_back(AutofillChange(AutofillChange::UPDATE
,
1272 updated_entry
.key()));
1273 web_data_service_
->OnAutofillEntriesChanged(changes
);
1275 std::vector
<AutofillEntry
> new_sync_entries
;
1276 std::vector
<AutofillProfile
> new_sync_profiles
;
1277 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1278 &new_sync_profiles
));
1279 ASSERT_EQ(1U, new_sync_entries
.size());
1280 EXPECT_TRUE(updated_entry
== new_sync_entries
[0]);
1284 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeRemoveEntry
) {
1285 AutofillEntry
original_entry(MakeAutofillEntry("my", "entry", 1));
1286 std::vector
<AutofillEntry
> original_entries
;
1287 original_entries
.push_back(original_entry
);
1289 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1290 WillOnce(DoAll(SetArgumentPointee
<0>(original_entries
), Return(true)));
1291 EXPECT_CALL(*personal_data_manager_
, Refresh());
1292 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1293 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1294 ASSERT_TRUE(create_root
.success());
1296 AutofillChangeList changes
;
1297 changes
.push_back(AutofillChange(AutofillChange::REMOVE
,
1298 original_entry
.key()));
1299 web_data_service_
->OnAutofillEntriesChanged(changes
);
1301 std::vector
<AutofillEntry
> new_sync_entries
;
1302 std::vector
<AutofillProfile
> new_sync_profiles
;
1303 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries
,
1304 &new_sync_profiles
));
1305 ASSERT_EQ(0U, new_sync_entries
.size());
1308 TEST_F(ProfileSyncServiceAutofillTest
, ProcessUserChangeRemoveProfile
) {
1309 AutofillProfile sync_profile
;
1310 autofill::test::SetProfileInfoWithGuid(&sync_profile
,
1311 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1312 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1313 "32801", "US", "19482937549");
1314 AutofillProfile
* native_profile
= new AutofillProfile
;
1315 autofill::test::SetProfileInfoWithGuid(native_profile
,
1316 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
1317 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
1318 "32801", "US", "19482937549");
1320 std::vector
<AutofillProfile
*> native_profiles
;
1321 native_profiles
.push_back(native_profile
);
1322 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).
1323 WillOnce(DoAll(SetArgumentPointee
<0>(native_profiles
), Return(true)));
1325 std::vector
<AutofillProfile
> sync_profiles
;
1326 sync_profiles
.push_back(sync_profile
);
1327 AddAutofillHelper
<AutofillProfile
> add_autofill(this, sync_profiles
);
1328 EXPECT_CALL(*personal_data_manager_
, Refresh());
1329 StartSyncService(add_autofill
.callback(), false, syncer::AUTOFILL_PROFILE
);
1330 ASSERT_TRUE(add_autofill
.success());
1332 AutofillProfileChange
change(
1333 AutofillProfileChange::REMOVE
, sync_profile
.guid(), NULL
);
1334 web_data_service_
->OnAutofillProfileChanged(change
);
1336 std::vector
<AutofillProfile
> new_sync_profiles
;
1337 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1338 &new_sync_profiles
));
1339 ASSERT_EQ(0U, new_sync_profiles
.size());
1342 // http://crbug.com/57884
1343 TEST_F(ProfileSyncServiceAutofillTest
, DISABLED_ServerChangeRace
) {
1344 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via
1345 // LoadAutofillData().
1346 EXPECT_CALL(autofill_table_
, GetAllAutofillEntries(_
)).
1347 Times(3).WillRepeatedly(Return(true));
1348 // On the other hand Autofill and Autocomplete are separated now, so
1349 // GetAutofillProfiles() should not be called.
1350 EXPECT_CALL(autofill_table_
, GetAutofillProfiles(_
)).Times(0);
1351 EXPECT_CALL(autofill_table_
, UpdateAutofillEntries(_
)).
1352 WillRepeatedly(Return(true));
1353 EXPECT_CALL(*personal_data_manager_
, Refresh()).Times(3);
1354 CreateRootHelper
create_root(this, syncer::AUTOFILL
);
1355 StartSyncService(create_root
.callback(), false, syncer::AUTOFILL
);
1356 ASSERT_TRUE(create_root
.success());
1358 // (true, false) means we have to reset after |Signal|, init to unsignaled.
1359 scoped_ptr
<WaitableEvent
> wait_for_start(new WaitableEvent(true, false));
1360 scoped_ptr
<WaitableEvent
> wait_for_syncapi(new WaitableEvent(true, false));
1361 scoped_refptr
<FakeServerUpdater
> updater(new FakeServerUpdater(
1362 sync_service_
, &wait_for_start
, &wait_for_syncapi
));
1364 // This server side update will stall waiting for CommitWaiter.
1365 updater
->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
1366 wait_for_start
->Wait();
1368 AutofillEntry
syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
1369 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry
));
1370 DVLOG(1) << "Syncapi update finished.";
1372 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
1373 // Signal FakeServerUpdater that it can complete.
1374 wait_for_syncapi
->Signal();
1376 // Make another entry to ensure nothing broke afterwards and wait for finish
1378 updater
->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3));
1380 std::vector
<AutofillEntry
> sync_entries
;
1381 std::vector
<AutofillProfile
> sync_profiles
;
1382 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries
, &sync_profiles
));
1383 EXPECT_EQ(3U, sync_entries
.size());
1384 EXPECT_EQ(0U, sync_profiles
.size());
1385 for (size_t i
= 0; i
< sync_entries
.size(); i
++) {
1386 DVLOG(1) << "Entry " << i
<< ": " << sync_entries
[i
].key().name()
1387 << ", " << sync_entries
[i
].key().value();