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.
7 #include "testing/gtest/include/gtest/gtest.h"
10 #include "base/location.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/test/test_timeouts.h"
15 #include "base/time/time.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/invalidation/invalidation_service_factory.h"
18 #include "chrome/browser/password_manager/mock_password_store.h"
19 #include "chrome/browser/password_manager/mock_password_store_service.h"
20 #include "chrome/browser/password_manager/null_password_store_service.h"
21 #include "chrome/browser/password_manager/password_store_factory.h"
22 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
23 #include "chrome/browser/signin/fake_profile_oauth2_token_service_wrapper.h"
24 #include "chrome/browser/signin/profile_oauth2_token_service.h"
25 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
26 #include "chrome/browser/signin/signin_manager.h"
27 #include "chrome/browser/signin/signin_manager_factory.h"
28 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
29 #include "chrome/browser/sync/glue/password_change_processor.h"
30 #include "chrome/browser/sync/glue/password_data_type_controller.h"
31 #include "chrome/browser/sync/glue/password_model_associator.h"
32 #include "chrome/browser/sync/profile_sync_components_factory.h"
33 #include "chrome/browser/sync/profile_sync_components_factory_mock.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/common/pref_names.h"
39 #include "chrome/test/base/testing_profile.h"
40 #include "components/autofill/core/common/password_form.h"
41 #include "components/password_manager/core/browser/password_store.h"
42 #include "content/public/browser/notification_source.h"
43 #include "content/public/test/mock_notification_observer.h"
44 #include "content/public/test/test_browser_thread.h"
45 #include "google_apis/gaia/gaia_constants.h"
46 #include "sync/internal_api/public/read_node.h"
47 #include "sync/internal_api/public/read_transaction.h"
48 #include "sync/internal_api/public/write_node.h"
49 #include "sync/internal_api/public/write_transaction.h"
50 #include "sync/protocol/password_specifics.pb.h"
51 #include "sync/test/engine/test_id_factory.h"
52 #include "testing/gmock/include/gmock/gmock.h"
54 using autofill::PasswordForm
;
56 using base::UTF8ToUTF16
;
57 using browser_sync::PasswordChangeProcessor
;
58 using browser_sync::PasswordDataTypeController
;
59 using browser_sync::PasswordModelAssociator
;
60 using content::BrowserThread
;
61 using syncer::syncable::WriteTransaction
;
63 using testing::AtLeast
;
65 using testing::InvokeWithoutArgs
;
66 using testing::Return
;
67 using testing::SetArgumentPointee
;
69 ACTION_P3(MakePasswordSyncComponents
, service
, ps
, dtc
) {
70 PasswordModelAssociator
* model_associator
=
71 new PasswordModelAssociator(service
, ps
, NULL
);
72 PasswordChangeProcessor
* change_processor
=
73 new PasswordChangeProcessor(model_associator
, ps
, dtc
);
74 return ProfileSyncComponentsFactory::SyncComponents(model_associator
,
78 ACTION_P(AcquireSyncTransaction
, password_test_service
) {
79 // Check to make sure we can aquire a transaction (will crash if a transaction
80 // is already held by this thread, deadlock if held by another thread).
81 syncer::WriteTransaction
trans(
82 FROM_HERE
, password_test_service
->GetUserShare());
83 DVLOG(1) << "Sync transaction acquired.";
86 class NullPasswordStore
: public MockPasswordStore
{
88 NullPasswordStore() {}
91 virtual ~NullPasswordStore() {}
94 class PasswordTestProfileSyncService
: public TestProfileSyncService
{
96 PasswordTestProfileSyncService(
97 ProfileSyncComponentsFactory
* factory
,
99 SigninManagerBase
* signin
,
100 ProfileOAuth2TokenService
* oauth2_token_service
)
101 : TestProfileSyncService(factory
,
104 oauth2_token_service
,
105 ProfileSyncService::AUTO_START
) {}
107 virtual ~PasswordTestProfileSyncService() {}
109 virtual void OnPassphraseAccepted() OVERRIDE
{
110 if (!callback_
.is_null())
113 TestProfileSyncService::OnPassphraseAccepted();
116 static BrowserContextKeyedService
* Build(content::BrowserContext
* context
) {
117 Profile
* profile
= static_cast<Profile
*>(context
);
118 SigninManagerBase
* signin
=
119 SigninManagerFactory::GetForProfile(profile
);
120 ProfileOAuth2TokenService
* oauth2_token_service
=
121 ProfileOAuth2TokenServiceFactory::GetForProfile(profile
);
122 ProfileSyncComponentsFactoryMock
* factory
=
123 new ProfileSyncComponentsFactoryMock();
124 return new PasswordTestProfileSyncService(
125 factory
, profile
, signin
, oauth2_token_service
);
128 void set_passphrase_accept_callback(const base::Closure
& callback
) {
129 callback_
= callback
;
133 base::Closure callback_
;
136 class ProfileSyncServicePasswordTest
: public AbstractProfileSyncServiceTest
{
138 syncer::UserShare
* GetUserShare() {
139 return sync_service_
->GetUserShare();
142 void AddPasswordSyncNode(const PasswordForm
& entry
) {
143 syncer::WriteTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
144 syncer::ReadNode
password_root(&trans
);
145 ASSERT_EQ(syncer::BaseNode::INIT_OK
,
146 password_root
.InitByTagLookup(browser_sync::kPasswordTag
));
148 syncer::WriteNode
node(&trans
);
149 std::string tag
= PasswordModelAssociator::MakeTag(entry
);
150 syncer::WriteNode::InitUniqueByCreationResult result
=
151 node
.InitUniqueByCreation(syncer::PASSWORDS
, password_root
, tag
);
152 ASSERT_EQ(syncer::WriteNode::INIT_SUCCESS
, result
);
153 PasswordModelAssociator::WriteToSyncNode(entry
, &node
);
157 ProfileSyncServicePasswordTest() {}
159 virtual void SetUp() {
160 AbstractProfileSyncServiceTest::SetUp();
161 TestingProfile::Builder builder
;
162 builder
.AddTestingFactory(
163 ProfileOAuth2TokenServiceFactory::GetInstance(),
164 FakeProfileOAuth2TokenServiceWrapper::BuildAutoIssuingTokenService
);
165 profile_
= builder
.Build().Pass();
166 invalidation::InvalidationServiceFactory::GetInstance()->
167 SetBuildOnlyFakeInvalidatorsForTest(true);
168 PasswordStoreFactory
* factory
= PasswordStoreFactory::GetInstance();
169 factory
->SetTestingFactory(profile_
.get(), MockPasswordStoreService::Build
);
170 scoped_refptr
<PasswordStore
> store_temp(
171 factory
->GetForProfile(profile_
.get(), Profile::IMPLICIT_ACCESS
));
172 password_store_
= static_cast<MockPasswordStore
*>(store_temp
.get());
175 virtual void TearDown() {
177 password_store_
->Shutdown();
178 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
179 profile_
.get(), NULL
);
181 AbstractProfileSyncServiceTest::TearDown();
184 static void SignalEvent(base::WaitableEvent
* done
) {
188 void FlushLastDBTask() {
189 base::WaitableEvent
done(false, false);
190 BrowserThread::PostTask(
191 BrowserThread::DB
, FROM_HERE
,
192 base::Bind(&ProfileSyncServicePasswordTest::SignalEvent
, &done
));
193 done
.TimedWait(TestTimeouts::action_timeout());
196 void StartSyncService(const base::Closure
& root_callback
,
197 const base::Closure
& node_callback
) {
198 if (!sync_service_
) {
199 SigninManagerBase
* signin
=
200 SigninManagerFactory::GetForProfile(profile_
.get());
201 signin
->SetAuthenticatedUsername("test_user@gmail.com");
203 PasswordTestProfileSyncService
* sync
=
204 static_cast<PasswordTestProfileSyncService
*>(
205 ProfileSyncServiceFactory::GetInstance()->
206 SetTestingFactoryAndUse(profile_
.get(),
207 &PasswordTestProfileSyncService::Build
));
208 ProfileSyncComponentsFactoryMock
* components
=
209 sync
->components_factory_mock();
210 EXPECT_CALL(*components
,
211 CreateSyncBackendHost(_
,_
,_
)).
213 new browser_sync::SyncBackendHostForProfileSyncTest(
215 sync
->sync_prefs_
.AsWeakPtr(),
217 sync
->set_passphrase_accept_callback(node_callback
);
218 sync_service_
= sync
;
220 syncer::ModelTypeSet preferred_types
=
221 sync_service_
->GetPreferredDataTypes();
222 preferred_types
.Put(syncer::PASSWORDS
);
223 sync_service_
->ChangePreferredDataTypes(preferred_types
);
224 PasswordDataTypeController
* data_type_controller
=
225 new PasswordDataTypeController(sync_service_
->factory(),
228 if (password_store_
.get()) {
229 EXPECT_CALL(*components
, CreatePasswordSyncComponents(_
, _
, _
))
230 .Times(AtLeast(1)). // Can be more if we hit NEEDS_CRYPTO.
231 WillRepeatedly(MakePasswordSyncComponents(
232 sync_service_
, password_store_
.get(), data_type_controller
));
234 // When the password store is unavailable, password sync components must
236 EXPECT_CALL(*components
, CreatePasswordSyncComponents(_
, _
, _
))
239 EXPECT_CALL(*components
, CreateDataTypeManager(_
, _
, _
, _
, _
, _
)).
240 WillOnce(ReturnNewDataTypeManager());
242 // We need tokens to get the tests going
243 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
.get())
244 ->UpdateCredentials("test_user@gmail.com", "oauth2_login_token");
246 sync_service_
->RegisterDataTypeController(data_type_controller
);
247 sync_service_
->Initialize();
248 base::MessageLoop::current()->Run();
251 sync_service_
->SetEncryptionPassphrase("foo",
252 ProfileSyncService::IMPLICIT
);
253 base::MessageLoop::current()->Run();
257 // Helper to sort the results of GetPasswordEntriesFromSyncDB. The sorting
258 // doesn't need to be particularly intelligent, it just needs to be consistent
259 // enough that we can base our tests expectations on the ordering it provides.
260 static bool PasswordFormComparator(const PasswordForm
& pf1
,
261 const PasswordForm
& pf2
) {
262 if (pf1
.submit_element
< pf2
.submit_element
)
264 if (pf1
.username_element
< pf2
.username_element
)
266 if (pf1
.username_value
< pf2
.username_value
)
268 if (pf1
.password_element
< pf2
.password_element
)
270 if (pf1
.password_value
< pf2
.password_value
)
276 void GetPasswordEntriesFromSyncDB(std::vector
<PasswordForm
>* entries
) {
277 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
278 syncer::ReadNode
password_root(&trans
);
279 ASSERT_EQ(syncer::BaseNode::INIT_OK
,
280 password_root
.InitByTagLookup(browser_sync::kPasswordTag
));
282 int64 child_id
= password_root
.GetFirstChildId();
283 while (child_id
!= syncer::kInvalidId
) {
284 syncer::ReadNode
child_node(&trans
);
285 ASSERT_EQ(syncer::BaseNode::INIT_OK
,
286 child_node
.InitByIdLookup(child_id
));
288 const sync_pb::PasswordSpecificsData
& password
=
289 child_node
.GetPasswordSpecifics();
292 PasswordModelAssociator::CopyPassword(password
, &form
);
294 entries
->push_back(form
);
296 child_id
= child_node
.GetSuccessorId();
299 std::sort(entries
->begin(), entries
->end(), PasswordFormComparator
);
302 bool ComparePasswords(const PasswordForm
& lhs
, const PasswordForm
& rhs
) {
303 return lhs
.scheme
== rhs
.scheme
&&
304 lhs
.signon_realm
== rhs
.signon_realm
&&
305 lhs
.origin
== rhs
.origin
&&
306 lhs
.action
== rhs
.action
&&
307 lhs
.username_element
== rhs
.username_element
&&
308 lhs
.username_value
== rhs
.username_value
&&
309 lhs
.password_element
== rhs
.password_element
&&
310 lhs
.password_value
== rhs
.password_value
&&
311 lhs
.ssl_valid
== rhs
.ssl_valid
&&
312 lhs
.preferred
== rhs
.preferred
&&
313 lhs
.date_created
== rhs
.date_created
&&
314 lhs
.blacklisted_by_user
== rhs
.blacklisted_by_user
;
317 void SetIdleChangeProcessorExpectations() {
318 EXPECT_CALL(*password_store_
.get(), AddLoginImpl(_
)).Times(0);
319 EXPECT_CALL(*password_store_
.get(), UpdateLoginImpl(_
)).Times(0);
320 EXPECT_CALL(*password_store_
.get(), RemoveLoginImpl(_
)).Times(0);
323 content::MockNotificationObserver observer_
;
324 scoped_ptr
<TestingProfile
> profile_
;
325 scoped_refptr
<MockPasswordStore
> password_store_
;
326 content::NotificationRegistrar registrar_
;
329 void AddPasswordEntriesCallback(ProfileSyncServicePasswordTest
* test
,
330 const std::vector
<PasswordForm
>& entries
) {
331 for (size_t i
= 0; i
< entries
.size(); ++i
)
332 test
->AddPasswordSyncNode(entries
[i
]);
335 // Flaky on mac_rel. See http://crbug.com/228943
336 #if defined(OS_MACOSX)
337 #define MAYBE_EmptyNativeEmptySync DISABLED_EmptyNativeEmptySync
338 #define MAYBE_EnsureNoTransactions DISABLED_EnsureNoTransactions
339 #define MAYBE_FailModelAssociation DISABLED_FailModelAssociation
340 #define MAYBE_FailPasswordStoreLoad DISABLED_FailPasswordStoreLoad
341 #define MAYBE_HasNativeEntriesEmptySync DISABLED_HasNativeEntriesEmptySync
342 #define MAYBE_HasNativeEntriesEmptySyncSameUsername \
343 DISABLED_HasNativeEntriesEmptySyncSameUsername
344 #define MAYBE_HasNativeHasSyncMergeEntry DISABLED_HasNativeHasSyncMergeEntry
345 #define MAYBE_HasNativeHasSyncNoMerge DISABLED_HasNativeHasSyncNoMerge
347 #define MAYBE_EmptyNativeEmptySync EmptyNativeEmptySync
348 #define MAYBE_EnsureNoTransactions EnsureNoTransactions
349 #define MAYBE_FailModelAssociation FailModelAssociation
350 #define MAYBE_FailPasswordStoreLoad FailPasswordStoreLoad
351 #define MAYBE_HasNativeEntriesEmptySync HasNativeEntriesEmptySync
352 #define MAYBE_HasNativeEntriesEmptySyncSameUsername \
353 HasNativeEntriesEmptySyncSameUsername
354 #define MAYBE_HasNativeHasSyncMergeEntry HasNativeHasSyncMergeEntry
355 #define MAYBE_HasNativeHasSyncNoMerge HasNativeHasSyncNoMerge
358 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_FailModelAssociation
) {
359 StartSyncService(base::Closure(), base::Closure());
360 EXPECT_TRUE(sync_service_
->HasUnrecoverableError());
363 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_FailPasswordStoreLoad
) {
364 PasswordStoreFactory
* factory
= PasswordStoreFactory::GetInstance();
365 factory
->SetTestingFactory(profile_
.get(), NullPasswordStoreService::Build
);
366 scoped_refptr
<PasswordStore
> store_temp(
367 factory
->GetForProfile(profile_
.get(), Profile::IMPLICIT_ACCESS
));
368 password_store_
= static_cast<NullPasswordStore
*>(store_temp
.get());
369 StartSyncService(base::Closure(), base::Closure());
370 EXPECT_FALSE(sync_service_
->HasUnrecoverableError());
371 syncer::ModelTypeSet failed_types
=
372 sync_service_
->failed_data_types_handler().GetFailedTypes();
373 EXPECT_TRUE(failed_types
.Equals(syncer::ModelTypeSet(syncer::PASSWORDS
)));
376 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_EmptyNativeEmptySync
) {
377 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
378 .WillOnce(Return(true));
379 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
380 .WillOnce(Return(true));
381 SetIdleChangeProcessorExpectations();
382 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
383 StartSyncService(create_root
.callback(), base::Closure());
384 std::vector
<PasswordForm
> sync_entries
;
385 GetPasswordEntriesFromSyncDB(&sync_entries
);
386 EXPECT_EQ(0U, sync_entries
.size());
389 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_HasNativeEntriesEmptySync
) {
390 std::vector
<PasswordForm
*> forms
;
391 std::vector
<PasswordForm
> expected_forms
;
392 PasswordForm
* new_form
= new PasswordForm
;
393 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
394 new_form
->signon_realm
= "pie";
395 new_form
->origin
= GURL("http://pie.com");
396 new_form
->action
= GURL("http://pie.com/submit");
397 new_form
->username_element
= UTF8ToUTF16("name");
398 new_form
->username_value
= UTF8ToUTF16("tom");
399 new_form
->password_element
= UTF8ToUTF16("cork");
400 new_form
->password_value
= UTF8ToUTF16("password1");
401 new_form
->ssl_valid
= true;
402 new_form
->preferred
= false;
403 new_form
->date_created
= base::Time::FromInternalValue(1234);
404 new_form
->blacklisted_by_user
= false;
405 forms
.push_back(new_form
);
406 expected_forms
.push_back(*new_form
);
407 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
408 .WillOnce(DoAll(SetArgumentPointee
<0>(forms
), Return(true)));
409 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
410 .WillOnce(Return(true));
411 SetIdleChangeProcessorExpectations();
412 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
413 StartSyncService(create_root
.callback(), base::Closure());
414 std::vector
<PasswordForm
> sync_forms
;
415 GetPasswordEntriesFromSyncDB(&sync_forms
);
416 ASSERT_EQ(1U, sync_forms
.size());
417 EXPECT_TRUE(ComparePasswords(expected_forms
[0], sync_forms
[0]));
420 TEST_F(ProfileSyncServicePasswordTest
,
421 MAYBE_HasNativeEntriesEmptySyncSameUsername
) {
422 std::vector
<PasswordForm
*> forms
;
423 std::vector
<PasswordForm
> expected_forms
;
426 PasswordForm
* new_form
= new PasswordForm
;
427 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
428 new_form
->signon_realm
= "pie";
429 new_form
->origin
= GURL("http://pie.com");
430 new_form
->action
= GURL("http://pie.com/submit");
431 new_form
->username_element
= UTF8ToUTF16("name");
432 new_form
->username_value
= UTF8ToUTF16("tom");
433 new_form
->password_element
= UTF8ToUTF16("cork");
434 new_form
->password_value
= UTF8ToUTF16("password1");
435 new_form
->ssl_valid
= true;
436 new_form
->preferred
= false;
437 new_form
->date_created
= base::Time::FromInternalValue(1234);
438 new_form
->blacklisted_by_user
= false;
439 forms
.push_back(new_form
);
440 expected_forms
.push_back(*new_form
);
443 PasswordForm
* new_form
= new PasswordForm
;
444 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
445 new_form
->signon_realm
= "pie";
446 new_form
->origin
= GURL("http://pie.com");
447 new_form
->action
= GURL("http://pie.com/submit");
448 new_form
->username_element
= UTF8ToUTF16("name");
449 new_form
->username_value
= UTF8ToUTF16("pete");
450 new_form
->password_element
= UTF8ToUTF16("cork");
451 new_form
->password_value
= UTF8ToUTF16("password2");
452 new_form
->ssl_valid
= true;
453 new_form
->preferred
= false;
454 new_form
->date_created
= base::Time::FromInternalValue(1234);
455 new_form
->blacklisted_by_user
= false;
456 forms
.push_back(new_form
);
457 expected_forms
.push_back(*new_form
);
460 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
461 .WillOnce(DoAll(SetArgumentPointee
<0>(forms
), Return(true)));
462 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
463 .WillOnce(Return(true));
464 SetIdleChangeProcessorExpectations();
465 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
466 StartSyncService(create_root
.callback(), base::Closure());
467 std::vector
<PasswordForm
> sync_forms
;
468 GetPasswordEntriesFromSyncDB(&sync_forms
);
469 ASSERT_EQ(2U, sync_forms
.size());
470 EXPECT_TRUE(ComparePasswords(expected_forms
[0], sync_forms
[1]));
471 EXPECT_TRUE(ComparePasswords(expected_forms
[1], sync_forms
[0]));
474 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_HasNativeHasSyncNoMerge
) {
475 std::vector
<PasswordForm
*> native_forms
;
476 std::vector
<PasswordForm
> sync_forms
;
477 std::vector
<PasswordForm
> expected_forms
;
479 PasswordForm
* new_form
= new PasswordForm
;
480 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
481 new_form
->signon_realm
= "pie";
482 new_form
->origin
= GURL("http://pie.com");
483 new_form
->action
= GURL("http://pie.com/submit");
484 new_form
->username_element
= UTF8ToUTF16("name");
485 new_form
->username_value
= UTF8ToUTF16("tom");
486 new_form
->password_element
= UTF8ToUTF16("cork");
487 new_form
->password_value
= UTF8ToUTF16("password1");
488 new_form
->ssl_valid
= true;
489 new_form
->preferred
= false;
490 new_form
->date_created
= base::Time::FromInternalValue(1234);
491 new_form
->blacklisted_by_user
= false;
493 native_forms
.push_back(new_form
);
494 expected_forms
.push_back(*new_form
);
498 PasswordForm new_form
;
499 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
500 new_form
.signon_realm
= "pie2";
501 new_form
.origin
= GURL("http://pie2.com");
502 new_form
.action
= GURL("http://pie2.com/submit");
503 new_form
.username_element
= UTF8ToUTF16("name2");
504 new_form
.username_value
= UTF8ToUTF16("tom2");
505 new_form
.password_element
= UTF8ToUTF16("cork2");
506 new_form
.password_value
= UTF8ToUTF16("password12");
507 new_form
.ssl_valid
= false;
508 new_form
.preferred
= true;
509 new_form
.date_created
= base::Time::FromInternalValue(12345);
510 new_form
.blacklisted_by_user
= false;
511 sync_forms
.push_back(new_form
);
512 expected_forms
.push_back(new_form
);
515 PasswordStoreChangeList changes
;
517 PasswordStoreChange(PasswordStoreChange::ADD
, expected_forms
[1]));
518 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
519 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
), Return(true)));
520 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
521 .WillOnce(Return(true));
522 EXPECT_CALL(*password_store_
.get(), AddLoginImpl(_
)).
523 WillOnce(Return(changes
));
525 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
526 StartSyncService(create_root
.callback(),
527 base::Bind(&AddPasswordEntriesCallback
, this, sync_forms
));
529 std::vector
<PasswordForm
> new_sync_forms
;
530 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
532 EXPECT_EQ(2U, new_sync_forms
.size());
533 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));
534 EXPECT_TRUE(ComparePasswords(expected_forms
[1], new_sync_forms
[1]));
537 // Same as HasNativeHasEmptyNoMerge, but we attempt to aquire a sync transaction
538 // every time the password store is accessed.
539 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_EnsureNoTransactions
) {
540 std::vector
<PasswordForm
*> native_forms
;
541 std::vector
<PasswordForm
> sync_forms
;
542 std::vector
<PasswordForm
> expected_forms
;
544 PasswordForm
* new_form
= new PasswordForm
;
545 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
546 new_form
->signon_realm
= "pie";
547 new_form
->origin
= GURL("http://pie.com");
548 new_form
->action
= GURL("http://pie.com/submit");
549 new_form
->username_element
= UTF8ToUTF16("name");
550 new_form
->username_value
= UTF8ToUTF16("tom");
551 new_form
->password_element
= UTF8ToUTF16("cork");
552 new_form
->password_value
= UTF8ToUTF16("password1");
553 new_form
->ssl_valid
= true;
554 new_form
->preferred
= false;
555 new_form
->date_created
= base::Time::FromInternalValue(1234);
556 new_form
->blacklisted_by_user
= false;
558 native_forms
.push_back(new_form
);
559 expected_forms
.push_back(*new_form
);
563 PasswordForm new_form
;
564 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
565 new_form
.signon_realm
= "pie2";
566 new_form
.origin
= GURL("http://pie2.com");
567 new_form
.action
= GURL("http://pie2.com/submit");
568 new_form
.username_element
= UTF8ToUTF16("name2");
569 new_form
.username_value
= UTF8ToUTF16("tom2");
570 new_form
.password_element
= UTF8ToUTF16("cork2");
571 new_form
.password_value
= UTF8ToUTF16("password12");
572 new_form
.ssl_valid
= false;
573 new_form
.preferred
= true;
574 new_form
.date_created
= base::Time::FromInternalValue(12345);
575 new_form
.blacklisted_by_user
= false;
576 sync_forms
.push_back(new_form
);
577 expected_forms
.push_back(new_form
);
580 PasswordStoreChangeList changes
;
581 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
582 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
),
583 AcquireSyncTransaction(this),
585 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
586 .WillOnce(DoAll(AcquireSyncTransaction(this), Return(true)));
587 EXPECT_CALL(*password_store_
.get(), AddLoginImpl(_
))
588 .WillOnce(DoAll(AcquireSyncTransaction(this), Return(changes
)));
590 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
591 StartSyncService(create_root
.callback(),
592 base::Bind(&AddPasswordEntriesCallback
, this, sync_forms
));
594 std::vector
<PasswordForm
> new_sync_forms
;
595 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
597 EXPECT_EQ(2U, new_sync_forms
.size());
598 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));
599 EXPECT_TRUE(ComparePasswords(expected_forms
[1], new_sync_forms
[1]));
602 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_HasNativeHasSyncMergeEntry
) {
603 std::vector
<PasswordForm
*> native_forms
;
604 std::vector
<PasswordForm
> sync_forms
;
605 std::vector
<PasswordForm
> expected_forms
;
607 PasswordForm
* new_form
= new PasswordForm
;
608 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
609 new_form
->signon_realm
= "pie";
610 new_form
->origin
= GURL("http://pie.com");
611 new_form
->action
= GURL("http://pie.com/submit");
612 new_form
->username_element
= UTF8ToUTF16("name");
613 new_form
->username_value
= UTF8ToUTF16("tom");
614 new_form
->password_element
= UTF8ToUTF16("cork");
615 new_form
->password_value
= UTF8ToUTF16("password1");
616 new_form
->ssl_valid
= true;
617 new_form
->preferred
= false;
618 new_form
->date_created
= base::Time::FromInternalValue(1234);
619 new_form
->blacklisted_by_user
= false;
621 native_forms
.push_back(new_form
);
625 PasswordForm new_form
;
626 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
627 new_form
.signon_realm
= "pie";
628 new_form
.origin
= GURL("http://pie.com");
629 new_form
.action
= GURL("http://pie.com/submit");
630 new_form
.username_element
= UTF8ToUTF16("name");
631 new_form
.username_value
= UTF8ToUTF16("tom");
632 new_form
.password_element
= UTF8ToUTF16("cork");
633 new_form
.password_value
= UTF8ToUTF16("password12");
634 new_form
.ssl_valid
= false;
635 new_form
.preferred
= true;
636 new_form
.date_created
= base::Time::FromInternalValue(12345);
637 new_form
.blacklisted_by_user
= false;
638 sync_forms
.push_back(new_form
);
642 PasswordForm new_form
;
643 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
644 new_form
.signon_realm
= "pie";
645 new_form
.origin
= GURL("http://pie.com");
646 new_form
.action
= GURL("http://pie.com/submit");
647 new_form
.username_element
= UTF8ToUTF16("name");
648 new_form
.username_value
= UTF8ToUTF16("tom");
649 new_form
.password_element
= UTF8ToUTF16("cork");
650 new_form
.password_value
= UTF8ToUTF16("password12");
651 new_form
.ssl_valid
= false;
652 new_form
.preferred
= true;
653 new_form
.date_created
= base::Time::FromInternalValue(12345);
654 new_form
.blacklisted_by_user
= false;
655 expected_forms
.push_back(new_form
);
658 PasswordStoreChangeList changes
;
660 PasswordStoreChange(PasswordStoreChange::UPDATE
, expected_forms
[0]));
661 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
662 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
), Return(true)));
663 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
664 .WillOnce(Return(true));
665 EXPECT_CALL(*password_store_
.get(), UpdateLoginImpl(_
))
666 .WillOnce(Return(changes
));
668 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
669 StartSyncService(create_root
.callback(),
670 base::Bind(&AddPasswordEntriesCallback
, this, sync_forms
));
672 std::vector
<PasswordForm
> new_sync_forms
;
673 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
675 EXPECT_EQ(1U, new_sync_forms
.size());
676 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));