1 // Copyright (c) 2011 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.
7 #include "testing/gtest/include/gtest/gtest.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/task.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/time.h"
13 #include "base/utf_string_conversions.h"
14 #include "chrome/browser/password_manager/password_store.h"
15 #include "chrome/browser/prefs/pref_service.h"
16 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
17 #include "chrome/browser/sync/engine/syncapi.h"
18 #include "chrome/browser/sync/glue/password_change_processor.h"
19 #include "chrome/browser/sync/glue/password_data_type_controller.h"
20 #include "chrome/browser/sync/glue/password_model_associator.h"
21 #include "chrome/browser/sync/profile_sync_factory.h"
22 #include "chrome/browser/sync/profile_sync_factory_mock.h"
23 #include "chrome/browser/sync/profile_sync_service.h"
24 #include "chrome/browser/sync/profile_sync_test_util.h"
25 #include "chrome/browser/sync/protocol/password_specifics.pb.h"
26 #include "chrome/browser/sync/syncable/directory_manager.h"
27 #include "chrome/browser/sync/syncable/syncable.h"
28 #include "chrome/browser/sync/test_profile_sync_service.h"
29 #include "chrome/common/net/gaia/gaia_constants.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/test/sync/engine/test_id_factory.h"
32 #include "chrome/test/profile_mock.h"
33 #include "content/browser/browser_thread.h"
34 #include "content/common/notification_observer_mock.h"
35 #include "content/common/notification_source.h"
36 #include "content/common/notification_type.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "webkit/glue/password_form.h"
41 using browser_sync::PasswordChangeProcessor
;
42 using browser_sync::PasswordDataTypeController
;
43 using browser_sync::PasswordModelAssociator
;
44 using browser_sync::TestIdFactory
;
45 using browser_sync::UnrecoverableErrorHandler
;
46 using sync_api::SyncManager
;
47 using sync_api::UserShare
;
48 using syncable::BASE_VERSION
;
49 using syncable::CREATE
;
50 using syncable::DirectoryManager
;
51 using syncable::IS_DEL
;
52 using syncable::IS_DIR
;
53 using syncable::IS_UNAPPLIED_UPDATE
;
54 using syncable::IS_UNSYNCED
;
55 using syncable::MutableEntry
;
56 using syncable::SERVER_IS_DIR
;
57 using syncable::SERVER_VERSION
;
58 using syncable::SPECIFICS
;
59 using syncable::ScopedDirLookup
;
60 using syncable::UNIQUE_SERVER_TAG
;
61 using syncable::UNITTEST
;
62 using syncable::WriteTransaction
;
64 using testing::AtLeast
;
66 using testing::DoDefault
;
67 using testing::ElementsAre
;
69 using testing::Invoke
;
70 using testing::InvokeWithoutArgs
;
71 using testing::Return
;
72 using testing::SaveArg
;
73 using testing::SetArgumentPointee
;
74 using webkit_glue::PasswordForm
;
76 ACTION_P3(MakePasswordSyncComponents
, service
, ps
, dtc
) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB
));
78 PasswordModelAssociator
* model_associator
=
79 new PasswordModelAssociator(service
, ps
);
80 PasswordChangeProcessor
* change_processor
=
81 new PasswordChangeProcessor(model_associator
, ps
, dtc
);
82 return ProfileSyncFactory::SyncComponents(model_associator
,
86 ACTION_P(AcquireSyncTransaction
, password_test_service
) {
87 // Check to make sure we can aquire a transaction (will crash if a transaction
88 // is already held by this thread, deadlock if held by another thread).
89 sync_api::WriteTransaction
trans(password_test_service
->GetUserShare());
90 VLOG(1) << "Sync transaction acquired.";
93 static void QuitMessageLoop() {
94 MessageLoop::current()->Quit();
97 class MockPasswordStore
: public PasswordStore
{
99 MOCK_METHOD1(RemoveLogin
, void(const PasswordForm
&));
100 MOCK_METHOD2(GetLogins
, int(const PasswordForm
&, PasswordStoreConsumer
*));
101 MOCK_METHOD1(AddLogin
, void(const PasswordForm
&));
102 MOCK_METHOD1(UpdateLogin
, void(const PasswordForm
&));
103 MOCK_METHOD0(ReportMetrics
, void());
104 MOCK_METHOD0(ReportMetricsImpl
, void());
105 MOCK_METHOD1(AddLoginImpl
, void(const PasswordForm
&));
106 MOCK_METHOD1(UpdateLoginImpl
, void(const PasswordForm
&));
107 MOCK_METHOD1(RemoveLoginImpl
, void(const PasswordForm
&));
108 MOCK_METHOD2(RemoveLoginsCreatedBetweenImpl
, void(const base::Time
&,
110 MOCK_METHOD2(GetLoginsImpl
, void(GetLoginsRequest
*, const PasswordForm
&));
111 MOCK_METHOD1(GetAutofillableLoginsImpl
, void(GetLoginsRequest
*));
112 MOCK_METHOD1(GetBlacklistLoginsImpl
, void(GetLoginsRequest
*));
113 MOCK_METHOD1(FillAutofillableLogins
,
114 bool(std::vector
<PasswordForm
*>*));
115 MOCK_METHOD1(FillBlacklistLogins
,
116 bool(std::vector
<PasswordForm
*>*));
119 class PasswordTestProfileSyncService
: public TestProfileSyncService
{
121 PasswordTestProfileSyncService(ProfileSyncFactory
* factory
,
123 const std::string
& test_user
,
124 bool synchronous_backend_initialization
,
125 Task
* initial_condition_setup_task
,
126 Task
* passphrase_accept_task
)
127 : TestProfileSyncService(factory
, profile
, test_user
,
128 synchronous_backend_initialization
,
129 initial_condition_setup_task
),
130 passphrase_accept_task_(passphrase_accept_task
) {}
132 virtual ~PasswordTestProfileSyncService() {}
134 virtual void OnPassphraseAccepted() {
135 if (passphrase_accept_task_
) {
136 passphrase_accept_task_
->Run();
139 TestProfileSyncService::OnPassphraseAccepted();
143 Task
* passphrase_accept_task_
;
146 class ProfileSyncServicePasswordTest
: public AbstractProfileSyncServiceTest
{
148 sync_api::UserShare
* GetUserShare() {
149 return service_
->GetUserShare();
152 ProfileSyncServicePasswordTest() {}
154 virtual void SetUp() {
155 AbstractProfileSyncServiceTest::SetUp();
156 profile_
.CreateRequestContext();
157 password_store_
= new MockPasswordStore();
159 notification_service_
= new ThreadNotificationService(&db_thread_
);
160 notification_service_
->Init();
161 registrar_
.Add(&observer_
,
162 NotificationType::SYNC_CONFIGURE_DONE
,
163 NotificationService::AllSources());
164 registrar_
.Add(&observer_
,
165 NotificationType::SYNC_CONFIGURE_BLOCKED
,
166 NotificationService::AllSources());
169 virtual void TearDown() {
170 password_store_
->Shutdown();
172 notification_service_
->TearDown();
173 profile_
.ResetRequestContext();
174 AbstractProfileSyncServiceTest::TearDown();
177 static void SignalEvent(base::WaitableEvent
* done
) {
181 void FlushLastDBTask() {
182 base::WaitableEvent
done(false, false);
183 BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
184 NewRunnableFunction(&ProfileSyncServicePasswordTest::SignalEvent
,
186 done
.TimedWait(base::TimeDelta::FromMilliseconds(
187 TestTimeouts::action_timeout_ms()));
190 void StartSyncService(Task
* root_task
, Task
* node_task
) {
191 if (!service_
.get()) {
192 service_
.reset(new PasswordTestProfileSyncService(
193 &factory_
, &profile_
, "test_user", false, root_task
, node_task
));
194 service_
->RegisterPreferences();
195 profile_
.GetPrefs()->SetBoolean(prefs::kSyncPasswords
, true);
196 EXPECT_CALL(profile_
, GetProfileSyncService()).WillRepeatedly(
197 Return(service_
.get()));
198 PasswordDataTypeController
* data_type_controller
=
199 new PasswordDataTypeController(&factory_
,
202 EXPECT_CALL(factory_
, CreatePasswordSyncComponents(_
, _
, _
)).
203 Times(AtLeast(1)). // Can be more if we hit NEEDS_CRYPTO.
204 WillRepeatedly(MakePasswordSyncComponents(service_
.get(),
205 password_store_
.get(),
206 data_type_controller
));
207 EXPECT_CALL(factory_
, CreateDataTypeManager(_
, _
)).
208 WillOnce(ReturnNewDataTypeManager());
210 // We need tokens to get the tests going
211 token_service_
.IssueAuthTokenForTest(
212 GaiaConstants::kSyncService
, "token");
214 EXPECT_CALL(profile_
, GetTokenService()).
215 WillRepeatedly(Return(&token_service_
));
217 EXPECT_CALL(profile_
, GetPasswordStore(_
)).
218 Times(AtLeast(2)). // Can be more if we hit NEEDS_CRYPTO.
219 WillRepeatedly(Return(password_store_
.get()));
221 EXPECT_CALL(observer_
,
223 NotificationType(NotificationType::SYNC_CONFIGURE_DONE
),_
,_
));
224 EXPECT_CALL(observer_
,
227 NotificationType::SYNC_CONFIGURE_BLOCKED
),_
,_
))
228 .WillOnce(InvokeWithoutArgs(QuitMessageLoop
));
230 service_
->RegisterDataTypeController(data_type_controller
);
231 service_
->Initialize();
232 MessageLoop::current()->Run();
235 service_
->SetPassphrase("foo", false, true);
236 MessageLoop::current()->Run();
240 void AddPasswordSyncNode(const PasswordForm
& entry
) {
241 sync_api::WriteTransaction
trans(service_
->GetUserShare());
242 sync_api::ReadNode
password_root(&trans
);
243 ASSERT_TRUE(password_root
.InitByTagLookup(browser_sync::kPasswordTag
));
245 sync_api::WriteNode
node(&trans
);
246 std::string tag
= PasswordModelAssociator::MakeTag(entry
);
247 ASSERT_TRUE(node
.InitUniqueByCreation(syncable::PASSWORDS
,
250 PasswordModelAssociator::WriteToSyncNode(entry
, &node
);
253 void GetPasswordEntriesFromSyncDB(std::vector
<PasswordForm
>* entries
) {
254 sync_api::ReadTransaction
trans(service_
->GetUserShare());
255 sync_api::ReadNode
password_root(&trans
);
256 ASSERT_TRUE(password_root
.InitByTagLookup(browser_sync::kPasswordTag
));
258 int64 child_id
= password_root
.GetFirstChildId();
259 while (child_id
!= sync_api::kInvalidId
) {
260 sync_api::ReadNode
child_node(&trans
);
261 ASSERT_TRUE(child_node
.InitByIdLookup(child_id
));
263 const sync_pb::PasswordSpecificsData
& password
=
264 child_node
.GetPasswordSpecifics();
267 PasswordModelAssociator::CopyPassword(password
, &form
);
269 entries
->push_back(form
);
271 child_id
= child_node
.GetSuccessorId();
275 bool ComparePasswords(const PasswordForm
& lhs
, const PasswordForm
& rhs
) {
276 return lhs
.scheme
== rhs
.scheme
&&
277 lhs
.signon_realm
== rhs
.signon_realm
&&
278 lhs
.origin
== rhs
.origin
&&
279 lhs
.action
== rhs
.action
&&
280 lhs
.username_element
== rhs
.username_element
&&
281 lhs
.username_value
== rhs
.username_value
&&
282 lhs
.password_element
== rhs
.password_element
&&
283 lhs
.password_value
== rhs
.password_value
&&
284 lhs
.ssl_valid
== rhs
.ssl_valid
&&
285 lhs
.preferred
== rhs
.preferred
&&
286 lhs
.date_created
== rhs
.date_created
&&
287 lhs
.blacklisted_by_user
== rhs
.blacklisted_by_user
;
290 void SetIdleChangeProcessorExpectations() {
291 EXPECT_CALL(*password_store_
, AddLoginImpl(_
)).Times(0);
292 EXPECT_CALL(*password_store_
, UpdateLoginImpl(_
)).Times(0);
293 EXPECT_CALL(*password_store_
, RemoveLoginImpl(_
)).Times(0);
296 friend class AddPasswordEntriesTask
;
298 scoped_refptr
<ThreadNotificationService
> notification_service_
;
299 NotificationObserverMock observer_
;
300 ProfileMock profile_
;
301 scoped_refptr
<MockPasswordStore
> password_store_
;
302 NotificationRegistrar registrar_
;
305 class AddPasswordEntriesTask
: public Task
{
307 AddPasswordEntriesTask(ProfileSyncServicePasswordTest
* test
,
308 const std::vector
<PasswordForm
>& entries
)
309 : test_(test
), entries_(entries
) {
313 for (size_t i
= 0; i
< entries_
.size(); ++i
) {
314 test_
->AddPasswordSyncNode(entries_
[i
]);
319 ProfileSyncServicePasswordTest
* test_
;
320 const std::vector
<PasswordForm
>& entries_
;
323 TEST_F(ProfileSyncServicePasswordTest
, FailModelAssociation
) {
324 StartSyncService(NULL
, NULL
);
325 EXPECT_TRUE(service_
->unrecoverable_error_detected());
328 TEST_F(ProfileSyncServicePasswordTest
, EmptyNativeEmptySync
) {
329 EXPECT_CALL(*password_store_
, FillAutofillableLogins(_
))
330 .WillOnce(Return(true));
331 EXPECT_CALL(*password_store_
, FillBlacklistLogins(_
))
332 .WillOnce(Return(true));
333 SetIdleChangeProcessorExpectations();
334 CreateRootTask
task(this, syncable::PASSWORDS
);
335 StartSyncService(&task
, NULL
);
336 std::vector
<PasswordForm
> sync_entries
;
337 GetPasswordEntriesFromSyncDB(&sync_entries
);
338 EXPECT_EQ(0U, sync_entries
.size());
341 TEST_F(ProfileSyncServicePasswordTest
, HasNativeEntriesEmptySync
) {
342 std::vector
<PasswordForm
*> forms
;
343 std::vector
<PasswordForm
> expected_forms
;
344 PasswordForm
* new_form
= new PasswordForm
;
345 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
346 new_form
->signon_realm
= "pie";
347 new_form
->origin
= GURL("http://pie.com");
348 new_form
->action
= GURL("http://pie.com/submit");
349 new_form
->username_element
= UTF8ToUTF16("name");
350 new_form
->username_value
= UTF8ToUTF16("tom");
351 new_form
->password_element
= UTF8ToUTF16("cork");
352 new_form
->password_value
= UTF8ToUTF16("password1");
353 new_form
->ssl_valid
= true;
354 new_form
->preferred
= false;
355 new_form
->date_created
= base::Time::FromInternalValue(1234);
356 new_form
->blacklisted_by_user
= false;
357 forms
.push_back(new_form
);
358 expected_forms
.push_back(*new_form
);
359 EXPECT_CALL(*password_store_
, FillAutofillableLogins(_
))
360 .WillOnce(DoAll(SetArgumentPointee
<0>(forms
), Return(true)));
361 EXPECT_CALL(*password_store_
, FillBlacklistLogins(_
))
362 .WillOnce(Return(true));
363 SetIdleChangeProcessorExpectations();
364 CreateRootTask
task(this, syncable::PASSWORDS
);
365 StartSyncService(&task
, NULL
);
366 std::vector
<PasswordForm
> sync_forms
;
367 GetPasswordEntriesFromSyncDB(&sync_forms
);
368 ASSERT_EQ(1U, sync_forms
.size());
369 EXPECT_TRUE(ComparePasswords(expected_forms
[0], sync_forms
[0]));
372 TEST_F(ProfileSyncServicePasswordTest
, HasNativeEntriesEmptySyncSameUsername
) {
373 std::vector
<PasswordForm
*> forms
;
374 std::vector
<PasswordForm
> expected_forms
;
377 PasswordForm
* new_form
= new PasswordForm
;
378 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
379 new_form
->signon_realm
= "pie";
380 new_form
->origin
= GURL("http://pie.com");
381 new_form
->action
= GURL("http://pie.com/submit");
382 new_form
->username_element
= UTF8ToUTF16("name");
383 new_form
->username_value
= UTF8ToUTF16("tom");
384 new_form
->password_element
= UTF8ToUTF16("cork");
385 new_form
->password_value
= UTF8ToUTF16("password1");
386 new_form
->ssl_valid
= true;
387 new_form
->preferred
= false;
388 new_form
->date_created
= base::Time::FromInternalValue(1234);
389 new_form
->blacklisted_by_user
= false;
390 forms
.push_back(new_form
);
391 expected_forms
.push_back(*new_form
);
394 PasswordForm
* new_form
= new PasswordForm
;
395 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
396 new_form
->signon_realm
= "pie";
397 new_form
->origin
= GURL("http://pie.com");
398 new_form
->action
= GURL("http://pie.com/submit");
399 new_form
->username_element
= UTF8ToUTF16("name");
400 new_form
->username_value
= UTF8ToUTF16("pete");
401 new_form
->password_element
= UTF8ToUTF16("cork");
402 new_form
->password_value
= UTF8ToUTF16("password2");
403 new_form
->ssl_valid
= true;
404 new_form
->preferred
= false;
405 new_form
->date_created
= base::Time::FromInternalValue(1234);
406 new_form
->blacklisted_by_user
= false;
407 forms
.push_back(new_form
);
408 expected_forms
.push_back(*new_form
);
411 EXPECT_CALL(*password_store_
, FillAutofillableLogins(_
))
412 .WillOnce(DoAll(SetArgumentPointee
<0>(forms
), Return(true)));
413 EXPECT_CALL(*password_store_
, FillBlacklistLogins(_
))
414 .WillOnce(Return(true));
415 SetIdleChangeProcessorExpectations();
416 CreateRootTask
task(this, syncable::PASSWORDS
);
417 StartSyncService(&task
, NULL
);
418 std::vector
<PasswordForm
> sync_forms
;
419 GetPasswordEntriesFromSyncDB(&sync_forms
);
420 ASSERT_EQ(2U, sync_forms
.size());
421 EXPECT_TRUE(ComparePasswords(expected_forms
[0], sync_forms
[1]));
422 EXPECT_TRUE(ComparePasswords(expected_forms
[1], sync_forms
[0]));
425 TEST_F(ProfileSyncServicePasswordTest
, HasNativeHasSyncNoMerge
) {
426 std::vector
<PasswordForm
*> native_forms
;
427 std::vector
<PasswordForm
> sync_forms
;
428 std::vector
<PasswordForm
> expected_forms
;
430 PasswordForm
* new_form
= new PasswordForm
;
431 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
432 new_form
->signon_realm
= "pie";
433 new_form
->origin
= GURL("http://pie.com");
434 new_form
->action
= GURL("http://pie.com/submit");
435 new_form
->username_element
= UTF8ToUTF16("name");
436 new_form
->username_value
= UTF8ToUTF16("tom");
437 new_form
->password_element
= UTF8ToUTF16("cork");
438 new_form
->password_value
= UTF8ToUTF16("password1");
439 new_form
->ssl_valid
= true;
440 new_form
->preferred
= false;
441 new_form
->date_created
= base::Time::FromInternalValue(1234);
442 new_form
->blacklisted_by_user
= false;
444 native_forms
.push_back(new_form
);
445 expected_forms
.push_back(*new_form
);
449 PasswordForm new_form
;
450 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
451 new_form
.signon_realm
= "pie2";
452 new_form
.origin
= GURL("http://pie2.com");
453 new_form
.action
= GURL("http://pie2.com/submit");
454 new_form
.username_element
= UTF8ToUTF16("name2");
455 new_form
.username_value
= UTF8ToUTF16("tom2");
456 new_form
.password_element
= UTF8ToUTF16("cork2");
457 new_form
.password_value
= UTF8ToUTF16("password12");
458 new_form
.ssl_valid
= false;
459 new_form
.preferred
= true;
460 new_form
.date_created
= base::Time::FromInternalValue(12345);
461 new_form
.blacklisted_by_user
= false;
462 sync_forms
.push_back(new_form
);
463 expected_forms
.push_back(new_form
);
466 EXPECT_CALL(*password_store_
, FillAutofillableLogins(_
))
467 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
), Return(true)));
468 EXPECT_CALL(*password_store_
, FillBlacklistLogins(_
)).WillOnce(Return(true));
469 EXPECT_CALL(*password_store_
, AddLoginImpl(_
)).Times(1);
471 CreateRootTask
root_task(this, syncable::PASSWORDS
);
472 AddPasswordEntriesTask
node_task(this, sync_forms
);
473 StartSyncService(&root_task
, &node_task
);
475 std::vector
<PasswordForm
> new_sync_forms
;
476 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
478 EXPECT_EQ(2U, new_sync_forms
.size());
479 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));
480 EXPECT_TRUE(ComparePasswords(expected_forms
[1], new_sync_forms
[1]));
483 // Same as HasNativeHasEmptyNoMerge, but we attempt to aquire a sync transaction
484 // every time the password store is accessed.
485 TEST_F(ProfileSyncServicePasswordTest
, EnsureNoTransactions
) {
486 std::vector
<PasswordForm
*> native_forms
;
487 std::vector
<PasswordForm
> sync_forms
;
488 std::vector
<PasswordForm
> expected_forms
;
490 PasswordForm
* new_form
= new PasswordForm
;
491 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
492 new_form
->signon_realm
= "pie";
493 new_form
->origin
= GURL("http://pie.com");
494 new_form
->action
= GURL("http://pie.com/submit");
495 new_form
->username_element
= UTF8ToUTF16("name");
496 new_form
->username_value
= UTF8ToUTF16("tom");
497 new_form
->password_element
= UTF8ToUTF16("cork");
498 new_form
->password_value
= UTF8ToUTF16("password1");
499 new_form
->ssl_valid
= true;
500 new_form
->preferred
= false;
501 new_form
->date_created
= base::Time::FromInternalValue(1234);
502 new_form
->blacklisted_by_user
= false;
504 native_forms
.push_back(new_form
);
505 expected_forms
.push_back(*new_form
);
509 PasswordForm new_form
;
510 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
511 new_form
.signon_realm
= "pie2";
512 new_form
.origin
= GURL("http://pie2.com");
513 new_form
.action
= GURL("http://pie2.com/submit");
514 new_form
.username_element
= UTF8ToUTF16("name2");
515 new_form
.username_value
= UTF8ToUTF16("tom2");
516 new_form
.password_element
= UTF8ToUTF16("cork2");
517 new_form
.password_value
= UTF8ToUTF16("password12");
518 new_form
.ssl_valid
= false;
519 new_form
.preferred
= true;
520 new_form
.date_created
= base::Time::FromInternalValue(12345);
521 new_form
.blacklisted_by_user
= false;
522 sync_forms
.push_back(new_form
);
523 expected_forms
.push_back(new_form
);
526 EXPECT_CALL(*password_store_
, FillAutofillableLogins(_
))
527 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
),
528 AcquireSyncTransaction(this),
530 EXPECT_CALL(*password_store_
, FillBlacklistLogins(_
))
531 .WillOnce(DoAll(AcquireSyncTransaction(this),
533 EXPECT_CALL(*password_store_
, AddLoginImpl(_
))
534 .WillOnce(AcquireSyncTransaction(this));
536 CreateRootTask
root_task(this, syncable::PASSWORDS
);
537 AddPasswordEntriesTask
node_task(this, sync_forms
);
538 StartSyncService(&root_task
, &node_task
);
540 std::vector
<PasswordForm
> new_sync_forms
;
541 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
543 EXPECT_EQ(2U, new_sync_forms
.size());
544 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));
545 EXPECT_TRUE(ComparePasswords(expected_forms
[1], new_sync_forms
[1]));
548 TEST_F(ProfileSyncServicePasswordTest
, HasNativeHasSyncMergeEntry
) {
549 std::vector
<PasswordForm
*> native_forms
;
550 std::vector
<PasswordForm
> sync_forms
;
551 std::vector
<PasswordForm
> expected_forms
;
553 PasswordForm
* new_form
= new PasswordForm
;
554 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
555 new_form
->signon_realm
= "pie";
556 new_form
->origin
= GURL("http://pie.com");
557 new_form
->action
= GURL("http://pie.com/submit");
558 new_form
->username_element
= UTF8ToUTF16("name");
559 new_form
->username_value
= UTF8ToUTF16("tom");
560 new_form
->password_element
= UTF8ToUTF16("cork");
561 new_form
->password_value
= UTF8ToUTF16("password1");
562 new_form
->ssl_valid
= true;
563 new_form
->preferred
= false;
564 new_form
->date_created
= base::Time::FromInternalValue(1234);
565 new_form
->blacklisted_by_user
= false;
567 native_forms
.push_back(new_form
);
571 PasswordForm new_form
;
572 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
573 new_form
.signon_realm
= "pie";
574 new_form
.origin
= GURL("http://pie.com");
575 new_form
.action
= GURL("http://pie.com/submit");
576 new_form
.username_element
= UTF8ToUTF16("name");
577 new_form
.username_value
= UTF8ToUTF16("tom");
578 new_form
.password_element
= UTF8ToUTF16("cork");
579 new_form
.password_value
= UTF8ToUTF16("password12");
580 new_form
.ssl_valid
= false;
581 new_form
.preferred
= true;
582 new_form
.date_created
= base::Time::FromInternalValue(12345);
583 new_form
.blacklisted_by_user
= false;
584 sync_forms
.push_back(new_form
);
588 PasswordForm new_form
;
589 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
590 new_form
.signon_realm
= "pie";
591 new_form
.origin
= GURL("http://pie.com");
592 new_form
.action
= GURL("http://pie.com/submit");
593 new_form
.username_element
= UTF8ToUTF16("name");
594 new_form
.username_value
= UTF8ToUTF16("tom");
595 new_form
.password_element
= UTF8ToUTF16("cork");
596 new_form
.password_value
= UTF8ToUTF16("password12");
597 new_form
.ssl_valid
= false;
598 new_form
.preferred
= true;
599 new_form
.date_created
= base::Time::FromInternalValue(12345);
600 new_form
.blacklisted_by_user
= false;
601 expected_forms
.push_back(new_form
);
604 EXPECT_CALL(*password_store_
, FillAutofillableLogins(_
))
605 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
), Return(true)));
606 EXPECT_CALL(*password_store_
, FillBlacklistLogins(_
)).WillOnce(Return(true));
607 EXPECT_CALL(*password_store_
, UpdateLoginImpl(_
)).Times(1);
609 CreateRootTask
root_task(this, syncable::PASSWORDS
);
610 AddPasswordEntriesTask
node_task(this, sync_forms
);
612 StartSyncService(&root_task
, &node_task
);
614 std::vector
<PasswordForm
> new_sync_forms
;
615 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
617 EXPECT_EQ(1U, new_sync_forms
.size());
618 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));