NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_service_password_unittest.cc
blob2a4a191a5c935e999b4bc8390a19d13a8b0696e1
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.
5 #include <vector>
7 #include "testing/gtest/include/gtest/gtest.h"
9 #include "base/bind.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;
55 using base::Time;
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;
62 using testing::_;
63 using testing::AtLeast;
64 using testing::DoAll;
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,
75 change_processor);
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 {
87 public:
88 NullPasswordStore() {}
90 protected:
91 virtual ~NullPasswordStore() {}
94 class PasswordTestProfileSyncService : public TestProfileSyncService {
95 public:
96 PasswordTestProfileSyncService(
97 ProfileSyncComponentsFactory* factory,
98 Profile* profile,
99 SigninManagerBase* signin,
100 ProfileOAuth2TokenService* oauth2_token_service)
101 : TestProfileSyncService(factory,
102 profile,
103 signin,
104 oauth2_token_service,
105 ProfileSyncService::AUTO_START) {}
107 virtual ~PasswordTestProfileSyncService() {}
109 virtual void OnPassphraseAccepted() OVERRIDE {
110 if (!callback_.is_null())
111 callback_.Run();
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;
132 private:
133 base::Closure callback_;
136 class ProfileSyncServicePasswordTest : public AbstractProfileSyncServiceTest {
137 public:
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);
156 protected:
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() {
176 if (password_store_)
177 password_store_->Shutdown();
178 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
179 profile_.get(), NULL);
180 profile_.reset();
181 AbstractProfileSyncServiceTest::TearDown();
184 static void SignalEvent(base::WaitableEvent* done) {
185 done->Signal();
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(_,_,_)).
212 WillOnce(Return(
213 new browser_sync::SyncBackendHostForProfileSyncTest(
214 profile_.get(),
215 sync->sync_prefs_.AsWeakPtr(),
216 root_callback)));
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(),
226 profile_.get(),
227 sync_service_);
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));
233 } else {
234 // When the password store is unavailable, password sync components must
235 // not be created.
236 EXPECT_CALL(*components, CreatePasswordSyncComponents(_, _, _))
237 .Times(0);
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();
249 FlushLastDBTask();
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)
263 return true;
264 if (pf1.username_element < pf2.username_element)
265 return true;
266 if (pf1.username_value < pf2.username_value)
267 return true;
268 if (pf1.password_element < pf2.password_element)
269 return true;
270 if (pf1.password_value < pf2.password_value)
271 return true;
273 return false;
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();
291 PasswordForm form;
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
346 #else
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
356 #endif
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;
516 changes.push_back(
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),
584 Return(true)));
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;
659 changes.push_back(
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]));