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/password_store.h"
20 #include "chrome/browser/password_manager/password_store_factory.h"
21 #include "chrome/browser/signin/profile_oauth2_token_service.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/signin_manager.h"
24 #include "chrome/browser/signin/signin_manager_factory.h"
25 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
26 #include "chrome/browser/sync/fake_oauth2_token_service_for_sync.h"
27 #include "chrome/browser/sync/glue/password_change_processor.h"
28 #include "chrome/browser/sync/glue/password_data_type_controller.h"
29 #include "chrome/browser/sync/glue/password_model_associator.h"
30 #include "chrome/browser/sync/profile_sync_components_factory.h"
31 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
32 #include "chrome/browser/sync/profile_sync_service.h"
33 #include "chrome/browser/sync/profile_sync_service_factory.h"
34 #include "chrome/browser/sync/profile_sync_test_util.h"
35 #include "chrome/browser/sync/test_profile_sync_service.h"
36 #include "chrome/common/pref_names.h"
37 #include "chrome/test/base/testing_profile.h"
38 #include "components/autofill/core/common/password_form.h"
39 #include "content/public/browser/notification_source.h"
40 #include "content/public/test/mock_notification_observer.h"
41 #include "content/public/test/test_browser_thread.h"
42 #include "google_apis/gaia/gaia_constants.h"
43 #include "sync/internal_api/public/read_node.h"
44 #include "sync/internal_api/public/read_transaction.h"
45 #include "sync/internal_api/public/write_node.h"
46 #include "sync/internal_api/public/write_transaction.h"
47 #include "sync/protocol/password_specifics.pb.h"
48 #include "sync/test/engine/test_id_factory.h"
49 #include "testing/gmock/include/gmock/gmock.h"
51 using autofill::PasswordForm
;
53 using base::UTF8ToUTF16
;
54 using browser_sync::PasswordChangeProcessor
;
55 using browser_sync::PasswordDataTypeController
;
56 using browser_sync::PasswordModelAssociator
;
57 using content::BrowserThread
;
58 using syncer::syncable::WriteTransaction
;
60 using testing::AtLeast
;
62 using testing::InvokeWithoutArgs
;
63 using testing::Return
;
64 using testing::SetArgumentPointee
;
66 ACTION_P3(MakePasswordSyncComponents
, service
, ps
, dtc
) {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB
));
68 PasswordModelAssociator
* model_associator
=
69 new PasswordModelAssociator(service
, ps
, NULL
);
70 PasswordChangeProcessor
* change_processor
=
71 new PasswordChangeProcessor(model_associator
, ps
, dtc
);
72 return ProfileSyncComponentsFactory::SyncComponents(model_associator
,
76 ACTION_P(AcquireSyncTransaction
, password_test_service
) {
77 // Check to make sure we can aquire a transaction (will crash if a transaction
78 // is already held by this thread, deadlock if held by another thread).
79 syncer::WriteTransaction
trans(
80 FROM_HERE
, password_test_service
->GetUserShare());
81 DVLOG(1) << "Sync transaction acquired.";
84 class NullPasswordStore
: public MockPasswordStore
{
86 NullPasswordStore() {}
88 static scoped_refptr
<RefcountedBrowserContextKeyedService
> Build(
89 content::BrowserContext
* profile
) {
90 return scoped_refptr
<RefcountedBrowserContextKeyedService
>();
94 virtual ~NullPasswordStore() {}
97 class PasswordTestProfileSyncService
: public TestProfileSyncService
{
99 PasswordTestProfileSyncService(
100 ProfileSyncComponentsFactory
* factory
,
102 SigninManagerBase
* signin
,
103 ProfileOAuth2TokenService
* oauth2_token_service
)
104 : TestProfileSyncService(factory
,
107 oauth2_token_service
,
108 ProfileSyncService::AUTO_START
) {}
110 virtual ~PasswordTestProfileSyncService() {}
112 virtual void OnPassphraseAccepted() OVERRIDE
{
113 if (!callback_
.is_null())
116 TestProfileSyncService::OnPassphraseAccepted();
119 static BrowserContextKeyedService
* Build(content::BrowserContext
* context
) {
120 Profile
* profile
= static_cast<Profile
*>(context
);
121 SigninManagerBase
* signin
=
122 SigninManagerFactory::GetForProfile(profile
);
123 ProfileOAuth2TokenService
* oauth2_token_service
=
124 ProfileOAuth2TokenServiceFactory::GetForProfile(profile
);
125 ProfileSyncComponentsFactoryMock
* factory
=
126 new ProfileSyncComponentsFactoryMock();
127 return new PasswordTestProfileSyncService(
128 factory
, profile
, signin
, oauth2_token_service
);
131 void set_passphrase_accept_callback(const base::Closure
& callback
) {
132 callback_
= callback
;
136 base::Closure callback_
;
139 class ProfileSyncServicePasswordTest
: public AbstractProfileSyncServiceTest
{
141 syncer::UserShare
* GetUserShare() {
142 return sync_service_
->GetUserShare();
145 void AddPasswordSyncNode(const PasswordForm
& entry
) {
146 syncer::WriteTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
147 syncer::ReadNode
password_root(&trans
);
148 ASSERT_EQ(syncer::BaseNode::INIT_OK
,
149 password_root
.InitByTagLookup(browser_sync::kPasswordTag
));
151 syncer::WriteNode
node(&trans
);
152 std::string tag
= PasswordModelAssociator::MakeTag(entry
);
153 syncer::WriteNode::InitUniqueByCreationResult result
=
154 node
.InitUniqueByCreation(syncer::PASSWORDS
, password_root
, tag
);
155 ASSERT_EQ(syncer::WriteNode::INIT_SUCCESS
, result
);
156 PasswordModelAssociator::WriteToSyncNode(entry
, &node
);
160 ProfileSyncServicePasswordTest() {}
162 virtual void SetUp() {
163 AbstractProfileSyncServiceTest::SetUp();
164 TestingProfile::Builder builder
;
165 builder
.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
166 FakeOAuth2TokenServiceForSync::BuildTokenService
);
167 profile_
= builder
.Build().Pass();
168 invalidation::InvalidationServiceFactory::GetInstance()->
169 SetBuildOnlyFakeInvalidatorsForTest(true);
170 password_store_
= static_cast<MockPasswordStore
*>(
171 PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
172 profile_
.get(), MockPasswordStore::Build
).get());
175 virtual void TearDown() {
176 if (password_store_
.get())
177 password_store_
->ShutdownOnUIThread();
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 sync
->set_backend_init_callback(root_callback
);
209 sync
->set_passphrase_accept_callback(node_callback
);
210 sync_service_
= sync
;
212 syncer::ModelTypeSet preferred_types
=
213 sync_service_
->GetPreferredDataTypes();
214 preferred_types
.Put(syncer::PASSWORDS
);
215 sync_service_
->ChangePreferredDataTypes(preferred_types
);
216 PasswordDataTypeController
* data_type_controller
=
217 new PasswordDataTypeController(sync_service_
->factory(),
220 ProfileSyncComponentsFactoryMock
* components
=
221 sync_service_
->components_factory_mock();
222 if (password_store_
.get()) {
223 EXPECT_CALL(*components
, CreatePasswordSyncComponents(_
, _
, _
))
224 .Times(AtLeast(1)). // Can be more if we hit NEEDS_CRYPTO.
225 WillRepeatedly(MakePasswordSyncComponents(
226 sync_service_
, password_store_
.get(), data_type_controller
));
228 // When the password store is unavailable, password sync components must
230 EXPECT_CALL(*components
, CreatePasswordSyncComponents(_
, _
, _
))
233 EXPECT_CALL(*components
, CreateDataTypeManager(_
, _
, _
, _
, _
, _
)).
234 WillOnce(ReturnNewDataTypeManager());
236 // We need tokens to get the tests going
237 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
.get())
238 ->UpdateCredentials("test_user@gmail.com", "oauth2_login_token");
240 sync_service_
->RegisterDataTypeController(data_type_controller
);
241 sync_service_
->Initialize();
242 base::MessageLoop::current()->Run();
245 sync_service_
->SetEncryptionPassphrase("foo",
246 ProfileSyncService::IMPLICIT
);
247 base::MessageLoop::current()->Run();
251 // Helper to sort the results of GetPasswordEntriesFromSyncDB. The sorting
252 // doesn't need to be particularly intelligent, it just needs to be consistent
253 // enough that we can base our tests expectations on the ordering it provides.
254 static bool PasswordFormComparator(const PasswordForm
& pf1
,
255 const PasswordForm
& pf2
) {
256 if (pf1
.submit_element
< pf2
.submit_element
)
258 if (pf1
.username_element
< pf2
.username_element
)
260 if (pf1
.username_value
< pf2
.username_value
)
262 if (pf1
.password_element
< pf2
.password_element
)
264 if (pf1
.password_value
< pf2
.password_value
)
270 void GetPasswordEntriesFromSyncDB(std::vector
<PasswordForm
>* entries
) {
271 syncer::ReadTransaction
trans(FROM_HERE
, sync_service_
->GetUserShare());
272 syncer::ReadNode
password_root(&trans
);
273 ASSERT_EQ(syncer::BaseNode::INIT_OK
,
274 password_root
.InitByTagLookup(browser_sync::kPasswordTag
));
276 int64 child_id
= password_root
.GetFirstChildId();
277 while (child_id
!= syncer::kInvalidId
) {
278 syncer::ReadNode
child_node(&trans
);
279 ASSERT_EQ(syncer::BaseNode::INIT_OK
,
280 child_node
.InitByIdLookup(child_id
));
282 const sync_pb::PasswordSpecificsData
& password
=
283 child_node
.GetPasswordSpecifics();
286 PasswordModelAssociator::CopyPassword(password
, &form
);
288 entries
->push_back(form
);
290 child_id
= child_node
.GetSuccessorId();
293 std::sort(entries
->begin(), entries
->end(), PasswordFormComparator
);
296 bool ComparePasswords(const PasswordForm
& lhs
, const PasswordForm
& rhs
) {
297 return lhs
.scheme
== rhs
.scheme
&&
298 lhs
.signon_realm
== rhs
.signon_realm
&&
299 lhs
.origin
== rhs
.origin
&&
300 lhs
.action
== rhs
.action
&&
301 lhs
.username_element
== rhs
.username_element
&&
302 lhs
.username_value
== rhs
.username_value
&&
303 lhs
.password_element
== rhs
.password_element
&&
304 lhs
.password_value
== rhs
.password_value
&&
305 lhs
.ssl_valid
== rhs
.ssl_valid
&&
306 lhs
.preferred
== rhs
.preferred
&&
307 lhs
.date_created
== rhs
.date_created
&&
308 lhs
.blacklisted_by_user
== rhs
.blacklisted_by_user
;
311 void SetIdleChangeProcessorExpectations() {
312 EXPECT_CALL(*password_store_
.get(), AddLoginImpl(_
)).Times(0);
313 EXPECT_CALL(*password_store_
.get(), UpdateLoginImpl(_
)).Times(0);
314 EXPECT_CALL(*password_store_
.get(), RemoveLoginImpl(_
)).Times(0);
317 content::MockNotificationObserver observer_
;
318 scoped_ptr
<TestingProfile
> profile_
;
319 scoped_refptr
<MockPasswordStore
> password_store_
;
320 content::NotificationRegistrar registrar_
;
323 void AddPasswordEntriesCallback(ProfileSyncServicePasswordTest
* test
,
324 const std::vector
<PasswordForm
>& entries
) {
325 for (size_t i
= 0; i
< entries
.size(); ++i
)
326 test
->AddPasswordSyncNode(entries
[i
]);
329 // Flaky on mac_rel. See http://crbug.com/228943
330 #if defined(OS_MACOSX)
331 #define MAYBE_EmptyNativeEmptySync DISABLED_EmptyNativeEmptySync
332 #define MAYBE_EnsureNoTransactions DISABLED_EnsureNoTransactions
333 #define MAYBE_FailModelAssociation DISABLED_FailModelAssociation
334 #define MAYBE_FailPasswordStoreLoad DISABLED_FailPasswordStoreLoad
335 #define MAYBE_HasNativeEntriesEmptySync DISABLED_HasNativeEntriesEmptySync
336 #define MAYBE_HasNativeEntriesEmptySyncSameUsername \
337 DISABLED_HasNativeEntriesEmptySyncSameUsername
338 #define MAYBE_HasNativeHasSyncMergeEntry DISABLED_HasNativeHasSyncMergeEntry
339 #define MAYBE_HasNativeHasSyncNoMerge DISABLED_HasNativeHasSyncNoMerge
341 #define MAYBE_EmptyNativeEmptySync EmptyNativeEmptySync
342 #define MAYBE_EnsureNoTransactions EnsureNoTransactions
343 #define MAYBE_FailModelAssociation FailModelAssociation
344 #define MAYBE_FailPasswordStoreLoad FailPasswordStoreLoad
345 #define MAYBE_HasNativeEntriesEmptySync HasNativeEntriesEmptySync
346 #define MAYBE_HasNativeEntriesEmptySyncSameUsername \
347 HasNativeEntriesEmptySyncSameUsername
348 #define MAYBE_HasNativeHasSyncMergeEntry HasNativeHasSyncMergeEntry
349 #define MAYBE_HasNativeHasSyncNoMerge HasNativeHasSyncNoMerge
352 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_FailModelAssociation
) {
353 StartSyncService(base::Closure(), base::Closure());
354 EXPECT_TRUE(sync_service_
->HasUnrecoverableError());
357 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_FailPasswordStoreLoad
) {
358 password_store_
= static_cast<NullPasswordStore
*>(
359 PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
360 profile_
.get(), NullPasswordStore::Build
).get());
361 StartSyncService(base::Closure(), base::Closure());
362 EXPECT_FALSE(sync_service_
->HasUnrecoverableError());
363 syncer::ModelTypeSet failed_types
=
364 sync_service_
->failed_data_types_handler().GetFailedTypes();
365 EXPECT_TRUE(failed_types
.Equals(syncer::ModelTypeSet(syncer::PASSWORDS
)));
368 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_EmptyNativeEmptySync
) {
369 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
370 .WillOnce(Return(true));
371 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
372 .WillOnce(Return(true));
373 SetIdleChangeProcessorExpectations();
374 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
375 StartSyncService(create_root
.callback(), base::Closure());
376 std::vector
<PasswordForm
> sync_entries
;
377 GetPasswordEntriesFromSyncDB(&sync_entries
);
378 EXPECT_EQ(0U, sync_entries
.size());
381 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_HasNativeEntriesEmptySync
) {
382 std::vector
<PasswordForm
*> forms
;
383 std::vector
<PasswordForm
> expected_forms
;
384 PasswordForm
* new_form
= new PasswordForm
;
385 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
386 new_form
->signon_realm
= "pie";
387 new_form
->origin
= GURL("http://pie.com");
388 new_form
->action
= GURL("http://pie.com/submit");
389 new_form
->username_element
= UTF8ToUTF16("name");
390 new_form
->username_value
= UTF8ToUTF16("tom");
391 new_form
->password_element
= UTF8ToUTF16("cork");
392 new_form
->password_value
= UTF8ToUTF16("password1");
393 new_form
->ssl_valid
= true;
394 new_form
->preferred
= false;
395 new_form
->date_created
= base::Time::FromInternalValue(1234);
396 new_form
->blacklisted_by_user
= false;
397 forms
.push_back(new_form
);
398 expected_forms
.push_back(*new_form
);
399 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
400 .WillOnce(DoAll(SetArgumentPointee
<0>(forms
), Return(true)));
401 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
402 .WillOnce(Return(true));
403 SetIdleChangeProcessorExpectations();
404 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
405 StartSyncService(create_root
.callback(), base::Closure());
406 std::vector
<PasswordForm
> sync_forms
;
407 GetPasswordEntriesFromSyncDB(&sync_forms
);
408 ASSERT_EQ(1U, sync_forms
.size());
409 EXPECT_TRUE(ComparePasswords(expected_forms
[0], sync_forms
[0]));
412 TEST_F(ProfileSyncServicePasswordTest
,
413 MAYBE_HasNativeEntriesEmptySyncSameUsername
) {
414 std::vector
<PasswordForm
*> forms
;
415 std::vector
<PasswordForm
> expected_forms
;
418 PasswordForm
* new_form
= new PasswordForm
;
419 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
420 new_form
->signon_realm
= "pie";
421 new_form
->origin
= GURL("http://pie.com");
422 new_form
->action
= GURL("http://pie.com/submit");
423 new_form
->username_element
= UTF8ToUTF16("name");
424 new_form
->username_value
= UTF8ToUTF16("tom");
425 new_form
->password_element
= UTF8ToUTF16("cork");
426 new_form
->password_value
= UTF8ToUTF16("password1");
427 new_form
->ssl_valid
= true;
428 new_form
->preferred
= false;
429 new_form
->date_created
= base::Time::FromInternalValue(1234);
430 new_form
->blacklisted_by_user
= false;
431 forms
.push_back(new_form
);
432 expected_forms
.push_back(*new_form
);
435 PasswordForm
* new_form
= new PasswordForm
;
436 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
437 new_form
->signon_realm
= "pie";
438 new_form
->origin
= GURL("http://pie.com");
439 new_form
->action
= GURL("http://pie.com/submit");
440 new_form
->username_element
= UTF8ToUTF16("name");
441 new_form
->username_value
= UTF8ToUTF16("pete");
442 new_form
->password_element
= UTF8ToUTF16("cork");
443 new_form
->password_value
= UTF8ToUTF16("password2");
444 new_form
->ssl_valid
= true;
445 new_form
->preferred
= false;
446 new_form
->date_created
= base::Time::FromInternalValue(1234);
447 new_form
->blacklisted_by_user
= false;
448 forms
.push_back(new_form
);
449 expected_forms
.push_back(*new_form
);
452 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
453 .WillOnce(DoAll(SetArgumentPointee
<0>(forms
), Return(true)));
454 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
455 .WillOnce(Return(true));
456 SetIdleChangeProcessorExpectations();
457 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
458 StartSyncService(create_root
.callback(), base::Closure());
459 std::vector
<PasswordForm
> sync_forms
;
460 GetPasswordEntriesFromSyncDB(&sync_forms
);
461 ASSERT_EQ(2U, sync_forms
.size());
462 EXPECT_TRUE(ComparePasswords(expected_forms
[0], sync_forms
[1]));
463 EXPECT_TRUE(ComparePasswords(expected_forms
[1], sync_forms
[0]));
466 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_HasNativeHasSyncNoMerge
) {
467 std::vector
<PasswordForm
*> native_forms
;
468 std::vector
<PasswordForm
> sync_forms
;
469 std::vector
<PasswordForm
> expected_forms
;
471 PasswordForm
* new_form
= new PasswordForm
;
472 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
473 new_form
->signon_realm
= "pie";
474 new_form
->origin
= GURL("http://pie.com");
475 new_form
->action
= GURL("http://pie.com/submit");
476 new_form
->username_element
= UTF8ToUTF16("name");
477 new_form
->username_value
= UTF8ToUTF16("tom");
478 new_form
->password_element
= UTF8ToUTF16("cork");
479 new_form
->password_value
= UTF8ToUTF16("password1");
480 new_form
->ssl_valid
= true;
481 new_form
->preferred
= false;
482 new_form
->date_created
= base::Time::FromInternalValue(1234);
483 new_form
->blacklisted_by_user
= false;
485 native_forms
.push_back(new_form
);
486 expected_forms
.push_back(*new_form
);
490 PasswordForm new_form
;
491 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
492 new_form
.signon_realm
= "pie2";
493 new_form
.origin
= GURL("http://pie2.com");
494 new_form
.action
= GURL("http://pie2.com/submit");
495 new_form
.username_element
= UTF8ToUTF16("name2");
496 new_form
.username_value
= UTF8ToUTF16("tom2");
497 new_form
.password_element
= UTF8ToUTF16("cork2");
498 new_form
.password_value
= UTF8ToUTF16("password12");
499 new_form
.ssl_valid
= false;
500 new_form
.preferred
= true;
501 new_form
.date_created
= base::Time::FromInternalValue(12345);
502 new_form
.blacklisted_by_user
= false;
503 sync_forms
.push_back(new_form
);
504 expected_forms
.push_back(new_form
);
507 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
508 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
), Return(true)));
509 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
510 .WillOnce(Return(true));
511 EXPECT_CALL(*password_store_
.get(), AddLoginImpl(_
)).Times(1);
513 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
514 StartSyncService(create_root
.callback(),
515 base::Bind(&AddPasswordEntriesCallback
, this, sync_forms
));
517 std::vector
<PasswordForm
> new_sync_forms
;
518 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
520 EXPECT_EQ(2U, new_sync_forms
.size());
521 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));
522 EXPECT_TRUE(ComparePasswords(expected_forms
[1], new_sync_forms
[1]));
525 // Same as HasNativeHasEmptyNoMerge, but we attempt to aquire a sync transaction
526 // every time the password store is accessed.
527 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_EnsureNoTransactions
) {
528 std::vector
<PasswordForm
*> native_forms
;
529 std::vector
<PasswordForm
> sync_forms
;
530 std::vector
<PasswordForm
> expected_forms
;
532 PasswordForm
* new_form
= new PasswordForm
;
533 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
534 new_form
->signon_realm
= "pie";
535 new_form
->origin
= GURL("http://pie.com");
536 new_form
->action
= GURL("http://pie.com/submit");
537 new_form
->username_element
= UTF8ToUTF16("name");
538 new_form
->username_value
= UTF8ToUTF16("tom");
539 new_form
->password_element
= UTF8ToUTF16("cork");
540 new_form
->password_value
= UTF8ToUTF16("password1");
541 new_form
->ssl_valid
= true;
542 new_form
->preferred
= false;
543 new_form
->date_created
= base::Time::FromInternalValue(1234);
544 new_form
->blacklisted_by_user
= false;
546 native_forms
.push_back(new_form
);
547 expected_forms
.push_back(*new_form
);
551 PasswordForm new_form
;
552 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
553 new_form
.signon_realm
= "pie2";
554 new_form
.origin
= GURL("http://pie2.com");
555 new_form
.action
= GURL("http://pie2.com/submit");
556 new_form
.username_element
= UTF8ToUTF16("name2");
557 new_form
.username_value
= UTF8ToUTF16("tom2");
558 new_form
.password_element
= UTF8ToUTF16("cork2");
559 new_form
.password_value
= UTF8ToUTF16("password12");
560 new_form
.ssl_valid
= false;
561 new_form
.preferred
= true;
562 new_form
.date_created
= base::Time::FromInternalValue(12345);
563 new_form
.blacklisted_by_user
= false;
564 sync_forms
.push_back(new_form
);
565 expected_forms
.push_back(new_form
);
568 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
569 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
),
570 AcquireSyncTransaction(this),
572 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
573 .WillOnce(DoAll(AcquireSyncTransaction(this), Return(true)));
574 EXPECT_CALL(*password_store_
.get(), AddLoginImpl(_
))
575 .WillOnce(AcquireSyncTransaction(this));
577 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
578 StartSyncService(create_root
.callback(),
579 base::Bind(&AddPasswordEntriesCallback
, this, sync_forms
));
581 std::vector
<PasswordForm
> new_sync_forms
;
582 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
584 EXPECT_EQ(2U, new_sync_forms
.size());
585 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));
586 EXPECT_TRUE(ComparePasswords(expected_forms
[1], new_sync_forms
[1]));
589 TEST_F(ProfileSyncServicePasswordTest
, MAYBE_HasNativeHasSyncMergeEntry
) {
590 std::vector
<PasswordForm
*> native_forms
;
591 std::vector
<PasswordForm
> sync_forms
;
592 std::vector
<PasswordForm
> expected_forms
;
594 PasswordForm
* new_form
= new PasswordForm
;
595 new_form
->scheme
= PasswordForm::SCHEME_HTML
;
596 new_form
->signon_realm
= "pie";
597 new_form
->origin
= GURL("http://pie.com");
598 new_form
->action
= GURL("http://pie.com/submit");
599 new_form
->username_element
= UTF8ToUTF16("name");
600 new_form
->username_value
= UTF8ToUTF16("tom");
601 new_form
->password_element
= UTF8ToUTF16("cork");
602 new_form
->password_value
= UTF8ToUTF16("password1");
603 new_form
->ssl_valid
= true;
604 new_form
->preferred
= false;
605 new_form
->date_created
= base::Time::FromInternalValue(1234);
606 new_form
->blacklisted_by_user
= false;
608 native_forms
.push_back(new_form
);
612 PasswordForm new_form
;
613 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
614 new_form
.signon_realm
= "pie";
615 new_form
.origin
= GURL("http://pie.com");
616 new_form
.action
= GURL("http://pie.com/submit");
617 new_form
.username_element
= UTF8ToUTF16("name");
618 new_form
.username_value
= UTF8ToUTF16("tom");
619 new_form
.password_element
= UTF8ToUTF16("cork");
620 new_form
.password_value
= UTF8ToUTF16("password12");
621 new_form
.ssl_valid
= false;
622 new_form
.preferred
= true;
623 new_form
.date_created
= base::Time::FromInternalValue(12345);
624 new_form
.blacklisted_by_user
= false;
625 sync_forms
.push_back(new_form
);
629 PasswordForm new_form
;
630 new_form
.scheme
= PasswordForm::SCHEME_HTML
;
631 new_form
.signon_realm
= "pie";
632 new_form
.origin
= GURL("http://pie.com");
633 new_form
.action
= GURL("http://pie.com/submit");
634 new_form
.username_element
= UTF8ToUTF16("name");
635 new_form
.username_value
= UTF8ToUTF16("tom");
636 new_form
.password_element
= UTF8ToUTF16("cork");
637 new_form
.password_value
= UTF8ToUTF16("password12");
638 new_form
.ssl_valid
= false;
639 new_form
.preferred
= true;
640 new_form
.date_created
= base::Time::FromInternalValue(12345);
641 new_form
.blacklisted_by_user
= false;
642 expected_forms
.push_back(new_form
);
645 EXPECT_CALL(*password_store_
.get(), FillAutofillableLogins(_
))
646 .WillOnce(DoAll(SetArgumentPointee
<0>(native_forms
), Return(true)));
647 EXPECT_CALL(*password_store_
.get(), FillBlacklistLogins(_
))
648 .WillOnce(Return(true));
649 EXPECT_CALL(*password_store_
.get(), UpdateLoginImpl(_
)).Times(1);
651 CreateRootHelper
create_root(this, syncer::PASSWORDS
);
652 StartSyncService(create_root
.callback(),
653 base::Bind(&AddPasswordEntriesCallback
, this, sync_forms
));
655 std::vector
<PasswordForm
> new_sync_forms
;
656 GetPasswordEntriesFromSyncDB(&new_sync_forms
);
658 EXPECT_EQ(1U, new_sync_forms
.size());
659 EXPECT_TRUE(ComparePasswords(expected_forms
[0], new_sync_forms
[0]));