Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_service_password_unittest.cc
blobc15a7ef94dc0d67289a60f5343e1be8a713a59c9
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/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;
52 using base::Time;
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;
59 using testing::_;
60 using testing::AtLeast;
61 using testing::DoAll;
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,
73 change_processor);
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 {
85 public:
86 NullPasswordStore() {}
88 static scoped_refptr<RefcountedBrowserContextKeyedService> Build(
89 content::BrowserContext* profile) {
90 return scoped_refptr<RefcountedBrowserContextKeyedService>();
93 protected:
94 virtual ~NullPasswordStore() {}
97 class PasswordTestProfileSyncService : public TestProfileSyncService {
98 public:
99 PasswordTestProfileSyncService(
100 ProfileSyncComponentsFactory* factory,
101 Profile* profile,
102 SigninManagerBase* signin,
103 ProfileOAuth2TokenService* oauth2_token_service)
104 : TestProfileSyncService(factory,
105 profile,
106 signin,
107 oauth2_token_service,
108 ProfileSyncService::AUTO_START) {}
110 virtual ~PasswordTestProfileSyncService() {}
112 virtual void OnPassphraseAccepted() OVERRIDE {
113 if (!callback_.is_null())
114 callback_.Run();
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;
135 private:
136 base::Closure callback_;
139 class ProfileSyncServicePasswordTest : public AbstractProfileSyncServiceTest {
140 public:
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);
159 protected:
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);
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 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(),
218 profile_.get(),
219 sync_service_);
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));
227 } else {
228 // When the password store is unavailable, password sync components must
229 // not be created.
230 EXPECT_CALL(*components, CreatePasswordSyncComponents(_, _, _))
231 .Times(0);
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();
243 FlushLastDBTask();
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)
257 return true;
258 if (pf1.username_element < pf2.username_element)
259 return true;
260 if (pf1.username_value < pf2.username_value)
261 return true;
262 if (pf1.password_element < pf2.password_element)
263 return true;
264 if (pf1.password_value < pf2.password_value)
265 return true;
267 return false;
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();
285 PasswordForm form;
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
340 #else
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
350 #endif
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),
571 Return(true)));
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]));