1 // Copyright 2014 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 "chrome/browser/password_manager/password_syncable_service.h"
11 #include "base/basictypes.h"
12 #include "base/location.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "chrome/browser/password_manager/mock_password_store.h"
16 #include "sync/api/sync_change_processor.h"
17 #include "sync/api/sync_error.h"
18 #include "sync/api/sync_error_factory.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using syncer::SyncChange
;
23 using syncer::SyncData
;
24 using syncer::SyncDataList
;
25 using syncer::SyncError
;
26 using testing::Invoke
;
27 using testing::Return
;
28 using testing::SetArgPointee
;
33 typedef std::vector
<SyncChange
> SyncChangeList
;
35 const sync_pb::PasswordSpecificsData
& GetPasswordSpecifics(
36 const syncer::SyncData
& sync_data
) {
37 const sync_pb::EntitySpecifics
& specifics
= sync_data
.GetSpecifics();
38 return specifics
.password().client_only_encrypted_data();
41 void PasswordsEqual(const sync_pb::PasswordSpecificsData
& expected_password
,
42 const sync_pb::PasswordSpecificsData
& actual_password
) {
43 EXPECT_EQ(expected_password
.scheme(), actual_password
.scheme());
44 EXPECT_EQ(expected_password
.signon_realm(), actual_password
.signon_realm());
45 EXPECT_EQ(expected_password
.origin(), actual_password
.origin());
46 EXPECT_EQ(expected_password
.action(), actual_password
.action());
47 EXPECT_EQ(expected_password
.username_element(),
48 actual_password
.username_element());
49 EXPECT_EQ(expected_password
.password_element(),
50 actual_password
.password_element());
51 EXPECT_EQ(expected_password
.username_value(),
52 actual_password
.username_value());
53 EXPECT_EQ(expected_password
.password_value(),
54 actual_password
.password_value());
55 EXPECT_EQ(expected_password
.ssl_valid(), actual_password
.ssl_valid());
56 EXPECT_EQ(expected_password
.preferred(), actual_password
.preferred());
57 EXPECT_EQ(expected_password
.date_created(), actual_password
.date_created());
58 EXPECT_EQ(expected_password
.blacklisted(), actual_password
.blacklisted());
61 // Creates a sync data consisting of password specifics. The sign on realm is
62 // set to |signon_realm|.
63 SyncData
CreateSyncData(const std::string
& signon_realm
) {
64 sync_pb::EntitySpecifics password_data
;
65 sync_pb::PasswordSpecificsData
* password_specifics
=
66 password_data
.mutable_password()->mutable_client_only_encrypted_data();
67 password_specifics
->set_signon_realm(signon_realm
);
69 std::string tag
= MakePasswordSyncTag(*password_specifics
);
70 return syncer::SyncData::CreateLocalData(tag
, tag
, password_data
);
73 SyncChange
CreateSyncChange(const autofill::PasswordForm
& password
,
74 SyncChange::SyncChangeType type
) {
75 SyncData data
= SyncDataFromPassword(password
);
76 return SyncChange(FROM_HERE
, type
, data
);
79 // A testable implementation of the |PasswordSyncableService| that mocks
80 // out all interaction with the password database.
81 class MockPasswordSyncableService
: public PasswordSyncableService
{
83 explicit MockPasswordSyncableService(PasswordStore
* password_store
)
84 : PasswordSyncableService(password_store
) {}
85 virtual ~MockPasswordSyncableService() {}
87 MOCK_METHOD1(NotifyPasswordStoreOfLoginChanges
,
88 void (const PasswordStoreChangeList
&));
91 // Class to verify the arguments passed to |PasswordStore|.
92 class PasswordStoreDataVerifier
{
94 PasswordStoreDataVerifier() {}
95 ~PasswordStoreDataVerifier() {
96 EXPECT_TRUE(expected_db_add_changes_
.empty());
97 EXPECT_TRUE(expected_db_update_changes_
.empty());
98 EXPECT_TRUE(expected_db_delete_changes_
.empty());
101 class TestSyncChangeProcessor
;
103 // Sets expected changes to the password database.
104 void SetExpectedDBChanges(
105 const SyncDataList
& add_forms
,
106 const std::vector
<autofill::PasswordForm
*>& update_forms
,
107 const std::vector
<autofill::PasswordForm
*>& delete_forms
,
108 MockPasswordStore
* password_store
);
109 // Sets expected changes to TestSyncChangeProcessor.
110 void SetExpectedSyncChanges(SyncChangeList list
);
113 // Checks that |change_list| matches |expected_sync_change_list_|.
114 SyncError
TestSyncChanges(const SyncChangeList
& change_list
);
116 // Verifies that the |password| is present in the |expected_db_add_changes_|
117 // list. If found, |password| would be removed from
118 // |expected_db_add_changes_| list.
119 PasswordStoreChangeList
VerifyAdd(const autofill::PasswordForm
& password
) {
120 return VerifyChange(PasswordStoreChange::ADD
, password
,
121 &expected_db_add_changes_
);
124 // Verifies that the |password| is present in the
125 // |expected_db_update_changes_| list. If found, |password| would be removed
126 // from |expected_db_update_changes_| list.
127 PasswordStoreChangeList
VerifyUpdate(const autofill::PasswordForm
& password
) {
128 return VerifyChange(PasswordStoreChange::UPDATE
, password
,
129 &expected_db_update_changes_
);
132 // Verifies that the |password| is present in the
133 // |expected_db_delete_changes_| list. If found, |password| would be removed
134 // from |expected_db_delete_changes_| list.
135 PasswordStoreChangeList
VerifyDelete(const autofill::PasswordForm
& password
) {
136 return VerifyChange(PasswordStoreChange::REMOVE
, password
,
137 &expected_db_delete_changes_
);
140 static PasswordStoreChangeList
VerifyChange(
141 PasswordStoreChange::Type type
,
142 const autofill::PasswordForm
& password
,
143 std::vector
<autofill::PasswordForm
>* password_list
);
145 std::vector
<autofill::PasswordForm
> expected_db_add_changes_
;
146 std::vector
<autofill::PasswordForm
> expected_db_update_changes_
;
147 std::vector
<autofill::PasswordForm
> expected_db_delete_changes_
;
148 SyncChangeList expected_sync_change_list_
;
150 DISALLOW_COPY_AND_ASSIGN(PasswordStoreDataVerifier
);
153 class PasswordStoreDataVerifier::TestSyncChangeProcessor
154 : public syncer::SyncChangeProcessor
{
156 explicit TestSyncChangeProcessor(PasswordStoreDataVerifier
* verifier
)
157 : verifier_(verifier
) {
159 virtual ~TestSyncChangeProcessor() {}
161 virtual SyncError
ProcessSyncChanges(const tracked_objects::Location
&,
162 const SyncChangeList
& list
) OVERRIDE
{
163 return verifier_
->TestSyncChanges(list
);
166 virtual SyncDataList
GetAllSyncData(syncer::ModelType type
) const OVERRIDE
{
167 return SyncDataList();
170 PasswordStoreDataVerifier
* verifier_
;
172 DISALLOW_COPY_AND_ASSIGN(TestSyncChangeProcessor
);
175 void PasswordStoreDataVerifier::SetExpectedDBChanges(
176 const SyncDataList
& add_forms
,
177 const std::vector
<autofill::PasswordForm
*>& update_forms
,
178 const std::vector
<autofill::PasswordForm
*>& delete_forms
,
179 MockPasswordStore
* password_store
) {
180 DCHECK(expected_db_add_changes_
.empty());
181 DCHECK(expected_db_update_changes_
.empty());
182 DCHECK(password_store
);
184 for (SyncDataList::const_iterator it
= add_forms
.begin();
185 it
!= add_forms
.end(); ++it
) {
186 autofill::PasswordForm form
;
187 PasswordFromSpecifics(GetPasswordSpecifics(*it
), &form
);
188 expected_db_add_changes_
.push_back(form
);
190 if (expected_db_add_changes_
.empty()) {
191 EXPECT_CALL(*password_store
, AddLoginImpl(_
)).Times(0);
193 EXPECT_CALL(*password_store
, AddLoginImpl(_
))
194 .Times(expected_db_add_changes_
.size())
195 .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyAdd
));
198 for (std::vector
<autofill::PasswordForm
*>::const_iterator it
=
199 update_forms
.begin();
200 it
!= update_forms
.end(); ++it
) {
201 expected_db_update_changes_
.push_back(**it
);
203 if (expected_db_update_changes_
.empty()) {
204 EXPECT_CALL(*password_store
, UpdateLoginImpl(_
)).Times(0);
206 EXPECT_CALL(*password_store
, UpdateLoginImpl(_
))
207 .Times(expected_db_update_changes_
.size())
208 .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyUpdate
));
211 for (std::vector
<autofill::PasswordForm
*>::const_iterator it
=
212 delete_forms
.begin();
213 it
!= delete_forms
.end(); ++it
) {
214 expected_db_delete_changes_
.push_back(**it
);
216 if (expected_db_delete_changes_
.empty()) {
217 EXPECT_CALL(*password_store
, RemoveLoginImpl(_
)).Times(0);
219 EXPECT_CALL(*password_store
, RemoveLoginImpl(_
))
220 .Times(expected_db_delete_changes_
.size())
221 .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyDelete
));
225 void PasswordStoreDataVerifier::SetExpectedSyncChanges(SyncChangeList list
) {
226 expected_sync_change_list_
.swap(list
);
229 SyncError
PasswordStoreDataVerifier::TestSyncChanges(
230 const SyncChangeList
& change_list
) {
231 for (SyncChangeList::const_iterator it
= change_list
.begin();
232 it
!= change_list
.end(); ++it
) {
233 const SyncChange
& data
= *it
;
234 const sync_pb::PasswordSpecificsData
& actual_password(
235 GetPasswordSpecifics(data
.sync_data()));
236 std::string actual_tag
= MakePasswordSyncTag(actual_password
);
238 bool matched
= false;
239 for (SyncChangeList::iterator expected_it
=
240 expected_sync_change_list_
.begin();
241 expected_it
!= expected_sync_change_list_
.end();
243 const sync_pb::PasswordSpecificsData
& expected_password(
244 GetPasswordSpecifics(expected_it
->sync_data()));
245 if (actual_tag
== MakePasswordSyncTag(expected_password
)) {
246 PasswordsEqual(expected_password
, actual_password
);
247 EXPECT_EQ(expected_it
->change_type(), data
.change_type());
252 EXPECT_TRUE(matched
) << actual_tag
;
254 EXPECT_EQ(expected_sync_change_list_
.size(), change_list
.size());
259 PasswordStoreChangeList
PasswordStoreDataVerifier::VerifyChange(
260 PasswordStoreChange::Type type
,
261 const autofill::PasswordForm
& password
,
262 std::vector
<autofill::PasswordForm
>* password_list
) {
263 std::vector
<autofill::PasswordForm
>::iterator it
=
264 std::find(password_list
->begin(), password_list
->end(), password
);
265 EXPECT_NE(password_list
->end(), it
);
266 password_list
->erase(it
);
267 return PasswordStoreChangeList(1, PasswordStoreChange(type
, password
));
270 class PasswordSyncableServiceWrapper
{
272 PasswordSyncableServiceWrapper() {
273 password_store_
= new MockPasswordStore
;
274 service_
.reset(new MockPasswordSyncableService(password_store_
));
277 ~PasswordSyncableServiceWrapper() {
278 password_store_
->Shutdown();
281 MockPasswordStore
* password_store() {
282 return password_store_
;
285 MockPasswordSyncableService
* service() {
286 return service_
.get();
289 // Returnes the scoped_ptr to |service_| thus NULLing out it.
290 scoped_ptr
<syncer::SyncChangeProcessor
> ReleaseSyncableService() {
291 return service_
.PassAs
<syncer::SyncChangeProcessor
>();
294 PasswordStoreDataVerifier
* verifier() {
298 scoped_ptr
<syncer::SyncChangeProcessor
> CreateSyncChangeProcessor() {
299 return make_scoped_ptr
<syncer::SyncChangeProcessor
>(
300 new PasswordStoreDataVerifier::TestSyncChangeProcessor(verifier()));
303 // Sets the data that will be returned to the caller accessing password store.
304 void SetPasswordStoreData(
305 const std::vector
<autofill::PasswordForm
*>& forms
,
306 const std::vector
<autofill::PasswordForm
*>& blacklist_forms
) {
307 EXPECT_CALL(*password_store_
, FillAutofillableLogins(_
))
308 .WillOnce(Invoke(AppendVector(forms
)))
309 .RetiresOnSaturation();
310 EXPECT_CALL(*password_store_
, FillBlacklistLogins(_
))
311 .WillOnce(Invoke(AppendVector(blacklist_forms
)))
312 .RetiresOnSaturation();
316 scoped_refptr
<MockPasswordStore
> password_store_
;
317 scoped_ptr
<MockPasswordSyncableService
> service_
;
318 PasswordStoreDataVerifier verifier_
;
321 struct AppendVector
{
322 explicit AppendVector(
323 const std::vector
<autofill::PasswordForm
*>& append_forms
)
324 : append_forms_(append_forms
) {
329 bool operator()(std::vector
<autofill::PasswordForm
*>* forms
) const {
330 forms
->insert(forms
->end(), append_forms_
.begin(), append_forms_
.end());
334 std::vector
<autofill::PasswordForm
*> append_forms_
;
337 DISALLOW_COPY_AND_ASSIGN(PasswordSyncableServiceWrapper
);
340 class PasswordSyncableServiceTest
: public testing::Test
,
341 public PasswordSyncableServiceWrapper
{
343 PasswordSyncableServiceTest() {}
344 virtual ~PasswordSyncableServiceTest() {}
348 // Both sync and password db have data that are not present in the other.
349 TEST_F(PasswordSyncableServiceTest
, AdditionsInBoth
) {
350 scoped_ptr
<autofill::PasswordForm
> form1(new autofill::PasswordForm
);
351 form1
->signon_realm
= "abc";
352 std::vector
<autofill::PasswordForm
*> forms
;
353 forms
.push_back(form1
.release());
354 SetPasswordStoreData(forms
, std::vector
<autofill::PasswordForm
*>());
356 SyncData sync_data
= CreateSyncData("def");
358 list
.push_back(sync_data
);
360 verifier()->SetExpectedDBChanges(list
,
361 std::vector
<autofill::PasswordForm
*>(),
362 std::vector
<autofill::PasswordForm
*>(),
364 verifier()->SetExpectedSyncChanges(
365 SyncChangeList(1, CreateSyncChange(*forms
[0], SyncChange::ACTION_ADD
)));
366 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_
));
368 service()->MergeDataAndStartSyncing(syncer::PASSWORDS
,
370 CreateSyncChangeProcessor(),
371 scoped_ptr
<syncer::SyncErrorFactory
>());
374 // Sync has data that is not present in the password db.
375 TEST_F(PasswordSyncableServiceTest
, AdditionOnlyInSync
) {
376 SetPasswordStoreData(std::vector
<autofill::PasswordForm
*>(),
377 std::vector
<autofill::PasswordForm
*>());
379 SyncData sync_data
= CreateSyncData("def");
381 list
.push_back(sync_data
);
383 verifier()->SetExpectedDBChanges(list
,
384 std::vector
<autofill::PasswordForm
*>(),
385 std::vector
<autofill::PasswordForm
*>(),
387 verifier()->SetExpectedSyncChanges(SyncChangeList());
388 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_
));
390 service()->MergeDataAndStartSyncing(syncer::PASSWORDS
,
392 CreateSyncChangeProcessor(),
393 scoped_ptr
<syncer::SyncErrorFactory
>());
396 // Passwords db has data that is not present in sync.
397 TEST_F(PasswordSyncableServiceTest
, AdditionOnlyInPasswordStore
) {
398 scoped_ptr
<autofill::PasswordForm
> form1(new autofill::PasswordForm
);
399 form1
->signon_realm
= "abc";
400 std::vector
<autofill::PasswordForm
*> forms
;
401 forms
.push_back(form1
.release());
402 SetPasswordStoreData(forms
, std::vector
<autofill::PasswordForm
*>());
404 verifier()->SetExpectedDBChanges(SyncDataList(),
405 std::vector
<autofill::PasswordForm
*>(),
406 std::vector
<autofill::PasswordForm
*>(),
408 verifier()->SetExpectedSyncChanges(
409 SyncChangeList(1, CreateSyncChange(*forms
[0], SyncChange::ACTION_ADD
)));
410 EXPECT_CALL(*service_
,
411 NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
413 service()->MergeDataAndStartSyncing(syncer::PASSWORDS
,
415 CreateSyncChangeProcessor(),
416 scoped_ptr
<syncer::SyncErrorFactory
>());
419 // Both passwords db and sync contain the same data.
420 TEST_F(PasswordSyncableServiceTest
, BothInSync
) {
421 scoped_ptr
<autofill::PasswordForm
> form1(new autofill::PasswordForm
);
422 form1
->signon_realm
= "abc";
423 std::vector
<autofill::PasswordForm
*> forms
;
424 forms
.push_back(form1
.release());
425 SetPasswordStoreData(forms
, std::vector
<autofill::PasswordForm
*>());
427 verifier()->SetExpectedDBChanges(SyncDataList(),
428 std::vector
<autofill::PasswordForm
*>(),
429 std::vector
<autofill::PasswordForm
*>(),
431 verifier()->SetExpectedSyncChanges(SyncChangeList());
432 EXPECT_CALL(*service_
,
433 NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
435 service()->MergeDataAndStartSyncing(syncer::PASSWORDS
,
436 SyncDataList(1, CreateSyncData("abc")),
437 CreateSyncChangeProcessor(),
438 scoped_ptr
<syncer::SyncErrorFactory
>());
441 // Both passwords db and sync have the same data but they need to be merged
442 // as some fields of the data differ.
443 TEST_F(PasswordSyncableServiceTest
, Merge
) {
444 scoped_ptr
<autofill::PasswordForm
> form1(new autofill::PasswordForm
);
445 form1
->signon_realm
= "abc";
446 form1
->action
= GURL("http://pie.com");
447 form1
->date_created
= base::Time::Now();
448 std::vector
<autofill::PasswordForm
*> forms
;
449 forms
.push_back(form1
.release());
450 SetPasswordStoreData(forms
, std::vector
<autofill::PasswordForm
*>());
452 verifier()->SetExpectedDBChanges(SyncDataList(),
453 std::vector
<autofill::PasswordForm
*>(),
454 std::vector
<autofill::PasswordForm
*>(),
456 verifier()->SetExpectedSyncChanges(
457 SyncChangeList(1, CreateSyncChange(*forms
[0],
458 SyncChange::ACTION_UPDATE
)));
460 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_
));
462 service()->MergeDataAndStartSyncing(syncer::PASSWORDS
,
463 SyncDataList(1, CreateSyncData("abc")),
464 CreateSyncChangeProcessor(),
465 scoped_ptr
<syncer::SyncErrorFactory
>());
468 // Initiate sync due to local DB changes.
469 TEST_F(PasswordSyncableServiceTest
, PasswordStoreChanges
) {
470 // Set the sync change processor first.
471 SetPasswordStoreData(std::vector
<autofill::PasswordForm
*>(),
472 std::vector
<autofill::PasswordForm
*>());
473 verifier()->SetExpectedSyncChanges(SyncChangeList());
474 EXPECT_CALL(*service_
,
475 NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
476 service_
->MergeDataAndStartSyncing(syncer::PASSWORDS
,
478 CreateSyncChangeProcessor(),
479 scoped_ptr
<syncer::SyncErrorFactory
>());
481 autofill::PasswordForm form1
;
482 form1
.signon_realm
= "abc";
483 autofill::PasswordForm form2
;
484 form2
.signon_realm
= "def";
485 autofill::PasswordForm form3
;
486 form3
.signon_realm
= "xyz";
488 SyncChangeList sync_list
;
489 sync_list
.push_back(CreateSyncChange(form1
, SyncChange::ACTION_ADD
));
490 sync_list
.push_back(CreateSyncChange(form2
, SyncChange::ACTION_UPDATE
));
491 sync_list
.push_back(CreateSyncChange(form3
, SyncChange::ACTION_DELETE
));
493 verifier()->SetExpectedDBChanges(SyncDataList(),
494 std::vector
<autofill::PasswordForm
*>(),
495 std::vector
<autofill::PasswordForm
*>(),
497 verifier()->SetExpectedSyncChanges(sync_list
);
499 PasswordStoreChangeList list
;
500 list
.push_back(PasswordStoreChange(PasswordStoreChange::ADD
, form1
));
501 list
.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE
, form2
));
502 list
.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE
, form3
));
503 service()->ActOnPasswordStoreChanges(list
);
506 // Process all types of changes from sync.
507 TEST_F(PasswordSyncableServiceTest
, ProcessSyncChanges
) {
508 scoped_ptr
<autofill::PasswordForm
> form1(new autofill::PasswordForm
);
509 form1
->signon_realm
= "abc";
510 form1
->action
= GURL("http://foo.com");
511 scoped_ptr
<autofill::PasswordForm
> form2(new autofill::PasswordForm
);
512 form2
->signon_realm
= "xyz";
513 form2
->action
= GURL("http://bar.com");
514 form2
->date_created
= base::Time::Now();
515 form2
->blacklisted_by_user
= true;
516 std::vector
<autofill::PasswordForm
*> forms(1, form1
.release());
517 std::vector
<autofill::PasswordForm
*> blacklist_forms(1, form2
.release());
518 SetPasswordStoreData(forms
, blacklist_forms
);
520 SyncData add_data
= CreateSyncData("def");
521 autofill::PasswordForm updated_form
= *forms
[0];
522 updated_form
.date_created
= base::Time::Now();
523 std::vector
<autofill::PasswordForm
*> updated_passwords(1, &updated_form
);
524 std::vector
<autofill::PasswordForm
*> deleted_passwords(1, blacklist_forms
[0]);
525 verifier()->SetExpectedDBChanges(SyncDataList(1, add_data
),
531 list
.push_back(SyncChange(FROM_HERE
,
532 syncer::SyncChange::ACTION_ADD
,
534 list
.push_back(SyncChange(FROM_HERE
,
535 syncer::SyncChange::ACTION_UPDATE
,
536 SyncDataFromPassword(updated_form
)));
537 list
.push_back(CreateSyncChange(*blacklist_forms
[0],
538 syncer::SyncChange::ACTION_DELETE
));
539 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_
));
540 service()->ProcessSyncChanges(FROM_HERE
, list
);
543 // Retrives sync data from the model.
544 TEST_F(PasswordSyncableServiceTest
, GetAllSyncData
) {
545 scoped_ptr
<autofill::PasswordForm
> form1(new autofill::PasswordForm
);
546 form1
->signon_realm
= "abc";
547 form1
->action
= GURL("http://foo.com");
548 scoped_ptr
<autofill::PasswordForm
> form2(new autofill::PasswordForm
);
549 form2
->signon_realm
= "xyz";
550 form2
->action
= GURL("http://bar.com");
551 form2
->blacklisted_by_user
= true;
552 std::vector
<autofill::PasswordForm
*> forms(1, form1
.release());
553 std::vector
<autofill::PasswordForm
*> blacklist_forms(1, form2
.release());
554 SetPasswordStoreData(forms
, blacklist_forms
);
556 SyncDataList expected_list
;
557 expected_list
.push_back(SyncDataFromPassword(*forms
[0]));
558 expected_list
.push_back(SyncDataFromPassword(*blacklist_forms
[0]));
560 verifier()->SetExpectedDBChanges(SyncDataList(),
561 std::vector
<autofill::PasswordForm
*>(),
562 std::vector
<autofill::PasswordForm
*>(),
565 SyncDataList actual_list
= service()->GetAllSyncData(syncer::PASSWORDS
);
566 EXPECT_EQ(expected_list
.size(), actual_list
.size());
567 for (SyncDataList::iterator
i(actual_list
.begin()), j(expected_list
.begin());
568 i
!= actual_list
.end() && j
!= expected_list
.end(); ++i
, ++j
) {
569 PasswordsEqual(GetPasswordSpecifics(*j
), GetPasswordSpecifics(*i
));
573 // Creates 2 PasswordSyncableService instances, merges the content of the first
574 // one to the second one and back.
575 TEST_F(PasswordSyncableServiceTest
, MergeDataAndPushBack
) {
576 scoped_ptr
<autofill::PasswordForm
> form1(new autofill::PasswordForm
);
577 form1
->signon_realm
= "abc";
578 form1
->action
= GURL("http://foo.com");
579 std::vector
<autofill::PasswordForm
*> forms(1, form1
.release());
580 SetPasswordStoreData(forms
, std::vector
<autofill::PasswordForm
*>());
582 PasswordSyncableServiceWrapper other_service_wrapper
;
583 scoped_ptr
<autofill::PasswordForm
> form2(new autofill::PasswordForm
);
584 form2
->signon_realm
= "xyz";
585 form2
->action
= GURL("http://bar.com");
586 syncer::SyncData form2_sync_data
= SyncDataFromPassword(*form2
);
587 other_service_wrapper
.SetPasswordStoreData(
588 std::vector
<autofill::PasswordForm
*>(1, form2
.release()),
589 std::vector
<autofill::PasswordForm
*>());
591 verifier()->SetExpectedDBChanges(SyncDataList(1, form2_sync_data
),
592 std::vector
<autofill::PasswordForm
*>(),
593 std::vector
<autofill::PasswordForm
*>(),
595 other_service_wrapper
.verifier()->SetExpectedDBChanges(
596 SyncDataList(1, SyncDataFromPassword(*forms
[0])),
597 std::vector
<autofill::PasswordForm
*>(),
598 std::vector
<autofill::PasswordForm
*>(),
599 other_service_wrapper
.password_store());
600 EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_
));
601 EXPECT_CALL(*other_service_wrapper
.service(),
602 NotifyPasswordStoreOfLoginChanges(_
));
604 syncer::SyncDataList other_service_data
=
605 other_service_wrapper
.service()->GetAllSyncData(syncer::PASSWORDS
);
606 service()->MergeDataAndStartSyncing(
609 other_service_wrapper
.ReleaseSyncableService(),
610 scoped_ptr
<syncer::SyncErrorFactory
>());