Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / password_manager / core / browser / password_syncable_service_unittest.cc
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.
4
5 #include "components/password_manager/core/browser/password_syncable_service.h"
6
7 #include <algorithm>
8 #include <string>
9 #include <vector>
10
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 "components/password_manager/core/browser/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"
21
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;
29 using testing::_;
30
31 namespace password_manager {
32
33 namespace {
34
35 typedef std::vector<SyncChange> SyncChangeList;
36
37 const sync_pb::PasswordSpecificsData& GetPasswordSpecifics(
38     const syncer::SyncData& sync_data) {
39   const sync_pb::EntitySpecifics& specifics = sync_data.GetSpecifics();
40   return specifics.password().client_only_encrypted_data();
41 }
42
43 void PasswordsEqual(const sync_pb::PasswordSpecificsData& expected_password,
44                     const sync_pb::PasswordSpecificsData& actual_password) {
45   EXPECT_EQ(expected_password.scheme(), actual_password.scheme());
46   EXPECT_EQ(expected_password.signon_realm(), actual_password.signon_realm());
47   EXPECT_EQ(expected_password.origin(), actual_password.origin());
48   EXPECT_EQ(expected_password.action(), actual_password.action());
49   EXPECT_EQ(expected_password.username_element(),
50             actual_password.username_element());
51   EXPECT_EQ(expected_password.password_element(),
52             actual_password.password_element());
53   EXPECT_EQ(expected_password.username_value(),
54             actual_password.username_value());
55   EXPECT_EQ(expected_password.password_value(),
56             actual_password.password_value());
57   EXPECT_EQ(expected_password.ssl_valid(), actual_password.ssl_valid());
58   EXPECT_EQ(expected_password.preferred(), actual_password.preferred());
59   EXPECT_EQ(expected_password.date_created(), actual_password.date_created());
60   EXPECT_EQ(expected_password.blacklisted(), actual_password.blacklisted());
61   EXPECT_EQ(expected_password.type(), actual_password.type());
62   EXPECT_EQ(expected_password.times_used(), actual_password.times_used());
63 }
64
65 // Creates a sync data consisting of password specifics. The sign on realm is
66 // set to |signon_realm|.
67 SyncData CreateSyncData(const std::string& signon_realm) {
68   sync_pb::EntitySpecifics password_data;
69   sync_pb::PasswordSpecificsData* password_specifics =
70       password_data.mutable_password()->mutable_client_only_encrypted_data();
71   password_specifics->set_signon_realm(signon_realm);
72   password_specifics->set_type(autofill::PasswordForm::TYPE_GENERATED);
73   password_specifics->set_times_used(3);
74
75   std::string tag = MakePasswordSyncTag(*password_specifics);
76   return syncer::SyncData::CreateLocalData(tag, tag, password_data);
77 }
78
79 SyncChange CreateSyncChange(const autofill::PasswordForm& password,
80                             SyncChange::SyncChangeType type) {
81   SyncData data = SyncDataFromPassword(password);
82   return SyncChange(FROM_HERE, type, data);
83 }
84
85 // A testable implementation of the |PasswordSyncableService| that mocks
86 // out all interaction with the password database.
87 class MockPasswordSyncableService : public PasswordSyncableService {
88  public:
89   explicit MockPasswordSyncableService(PasswordStoreSync* password_store)
90       : PasswordSyncableService(password_store) {}
91   virtual ~MockPasswordSyncableService() {}
92
93   MOCK_METHOD1(NotifyPasswordStoreOfLoginChanges,
94                void (const PasswordStoreChangeList&));
95
96   MOCK_METHOD1(StartSyncFlare, void(syncer::ModelType));
97 };
98
99 // Class to verify the arguments passed to |PasswordStore|.
100 class PasswordStoreDataVerifier {
101  public:
102   PasswordStoreDataVerifier() {}
103   ~PasswordStoreDataVerifier() {
104     EXPECT_TRUE(expected_db_add_changes_.empty());
105     EXPECT_TRUE(expected_db_update_changes_.empty());
106     EXPECT_TRUE(expected_db_delete_changes_.empty());
107   }
108
109   class TestSyncChangeProcessor;
110
111   // Sets expected changes to the password database.
112   void SetExpectedDBChanges(
113       const SyncDataList& add_forms,
114       const std::vector<autofill::PasswordForm*>& update_forms,
115       const std::vector<autofill::PasswordForm*>& delete_forms,
116       MockPasswordStore* password_store);
117   // Sets expected changes to TestSyncChangeProcessor.
118   void SetExpectedSyncChanges(SyncChangeList list);
119
120  private:
121   // Checks that |change_list| matches |expected_sync_change_list_|.
122   SyncError TestSyncChanges(const SyncChangeList& change_list);
123
124   // Verifies that the |password| is present in the |expected_db_add_changes_|
125   // list. If found, |password| would be removed from
126   // |expected_db_add_changes_| list.
127   PasswordStoreChangeList VerifyAdd(const autofill::PasswordForm& password) {
128     return VerifyChange(PasswordStoreChange::ADD, password,
129                         &expected_db_add_changes_);
130   }
131
132   // Verifies that the |password| is present in the
133   // |expected_db_update_changes_| list. If found, |password| would be removed
134   // from |expected_db_update_changes_| list.
135   PasswordStoreChangeList VerifyUpdate(const autofill::PasswordForm& password) {
136     return VerifyChange(PasswordStoreChange::UPDATE, password,
137                         &expected_db_update_changes_);
138   }
139
140   // Verifies that the |password| is present in the
141   // |expected_db_delete_changes_| list. If found, |password| would be removed
142   // from |expected_db_delete_changes_| list.
143   PasswordStoreChangeList VerifyDelete(const autofill::PasswordForm& password) {
144     return VerifyChange(PasswordStoreChange::REMOVE, password,
145                         &expected_db_delete_changes_);
146   }
147
148   static PasswordStoreChangeList VerifyChange(
149       PasswordStoreChange::Type type,
150       const autofill::PasswordForm& password,
151       std::vector<autofill::PasswordForm>* password_list);
152
153   std::vector<autofill::PasswordForm> expected_db_add_changes_;
154   std::vector<autofill::PasswordForm> expected_db_update_changes_;
155   std::vector<autofill::PasswordForm> expected_db_delete_changes_;
156   SyncChangeList expected_sync_change_list_;
157
158   DISALLOW_COPY_AND_ASSIGN(PasswordStoreDataVerifier);
159 };
160
161 class PasswordStoreDataVerifier::TestSyncChangeProcessor
162     : public syncer::SyncChangeProcessor {
163  public:
164   explicit TestSyncChangeProcessor(PasswordStoreDataVerifier* verifier)
165       : verifier_(verifier) {
166   }
167   virtual ~TestSyncChangeProcessor() {}
168
169   virtual SyncError ProcessSyncChanges(const tracked_objects::Location&,
170                                        const SyncChangeList& list) OVERRIDE {
171     return verifier_->TestSyncChanges(list);
172   }
173
174   virtual SyncDataList GetAllSyncData(syncer::ModelType type) const OVERRIDE {
175     return SyncDataList();
176   }
177  private:
178   PasswordStoreDataVerifier* verifier_;
179
180   DISALLOW_COPY_AND_ASSIGN(TestSyncChangeProcessor);
181 };
182
183 void PasswordStoreDataVerifier::SetExpectedDBChanges(
184     const SyncDataList& add_forms,
185     const std::vector<autofill::PasswordForm*>& update_forms,
186     const std::vector<autofill::PasswordForm*>& delete_forms,
187     MockPasswordStore* password_store) {
188   DCHECK(expected_db_add_changes_.empty());
189   DCHECK(expected_db_update_changes_.empty());
190   DCHECK(password_store);
191
192   for (SyncDataList::const_iterator it = add_forms.begin();
193        it != add_forms.end(); ++it) {
194     autofill::PasswordForm form;
195     PasswordFromSpecifics(GetPasswordSpecifics(*it), &form);
196     expected_db_add_changes_.push_back(form);
197   }
198   if (expected_db_add_changes_.empty()) {
199     EXPECT_CALL(*password_store, AddLoginImpl(_)).Times(0);
200   } else {
201     EXPECT_CALL(*password_store, AddLoginImpl(_))
202         .Times(expected_db_add_changes_.size())
203         .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyAdd));
204   }
205
206   for (std::vector<autofill::PasswordForm*>::const_iterator it =
207            update_forms.begin();
208        it != update_forms.end(); ++it) {
209     expected_db_update_changes_.push_back(**it);
210   }
211   if (expected_db_update_changes_.empty()) {
212     EXPECT_CALL(*password_store, UpdateLoginImpl(_)).Times(0);
213   } else {
214     EXPECT_CALL(*password_store, UpdateLoginImpl(_))
215         .Times(expected_db_update_changes_.size())
216         .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyUpdate));
217   }
218
219   for (std::vector<autofill::PasswordForm*>::const_iterator it =
220            delete_forms.begin();
221        it != delete_forms.end(); ++it) {
222     expected_db_delete_changes_.push_back(**it);
223   }
224   if (expected_db_delete_changes_.empty()) {
225     EXPECT_CALL(*password_store, RemoveLoginImpl(_)).Times(0);
226   } else {
227     EXPECT_CALL(*password_store, RemoveLoginImpl(_))
228         .Times(expected_db_delete_changes_.size())
229         .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyDelete));
230   }
231 }
232
233 void PasswordStoreDataVerifier::SetExpectedSyncChanges(SyncChangeList list) {
234   expected_sync_change_list_.swap(list);
235 }
236
237 SyncError PasswordStoreDataVerifier::TestSyncChanges(
238     const SyncChangeList& change_list) {
239   for (SyncChangeList::const_iterator it = change_list.begin();
240       it != change_list.end(); ++it) {
241     const SyncChange& data = *it;
242     const sync_pb::PasswordSpecificsData& actual_password(
243         GetPasswordSpecifics(data.sync_data()));
244     std::string actual_tag = MakePasswordSyncTag(actual_password);
245
246     bool matched = false;
247     for (SyncChangeList::iterator expected_it =
248              expected_sync_change_list_.begin();
249          expected_it != expected_sync_change_list_.end();
250          ++expected_it) {
251       const sync_pb::PasswordSpecificsData& expected_password(
252           GetPasswordSpecifics(expected_it->sync_data()));
253       if (actual_tag == MakePasswordSyncTag(expected_password)) {
254         PasswordsEqual(expected_password, actual_password);
255         EXPECT_EQ(expected_it->change_type(), data.change_type());
256         matched = true;
257         break;
258       }
259     }
260     EXPECT_TRUE(matched) << actual_tag;
261   }
262   EXPECT_EQ(expected_sync_change_list_.size(), change_list.size());
263   return SyncError();
264 }
265
266 // static
267 PasswordStoreChangeList PasswordStoreDataVerifier::VerifyChange(
268     PasswordStoreChange::Type type,
269     const autofill::PasswordForm& password,
270     std::vector<autofill::PasswordForm>* password_list) {
271   std::vector<autofill::PasswordForm>::iterator it =
272       std::find(password_list->begin(), password_list->end(), password);
273   EXPECT_NE(password_list->end(), it);
274   password_list->erase(it);
275   return PasswordStoreChangeList(1, PasswordStoreChange(type, password));
276 }
277
278 class PasswordSyncableServiceWrapper {
279  public:
280   PasswordSyncableServiceWrapper() {
281     password_store_ = new MockPasswordStore;
282     service_.reset(new MockPasswordSyncableService(
283         password_store_->GetSyncInterface()));
284   }
285
286   ~PasswordSyncableServiceWrapper() {
287     password_store_->Shutdown();
288   }
289
290   MockPasswordStore* password_store() {
291     return password_store_;
292   }
293
294   MockPasswordSyncableService* service() {
295     return service_.get();
296   }
297
298   // Returnes the scoped_ptr to |service_| thus NULLing out it.
299   scoped_ptr<syncer::SyncChangeProcessor> ReleaseSyncableService() {
300     return service_.PassAs<syncer::SyncChangeProcessor>();
301   }
302
303   PasswordStoreDataVerifier* verifier() {
304     return &verifier_;
305   }
306
307   scoped_ptr<syncer::SyncChangeProcessor> CreateSyncChangeProcessor() {
308     return make_scoped_ptr<syncer::SyncChangeProcessor>(
309         new PasswordStoreDataVerifier::TestSyncChangeProcessor(verifier()));
310   }
311
312   // Sets the data that will be returned to the caller accessing password store.
313   void SetPasswordStoreData(
314       const std::vector<autofill::PasswordForm*>& forms,
315       const std::vector<autofill::PasswordForm*>& blacklist_forms) {
316     EXPECT_CALL(*password_store_, FillAutofillableLogins(_))
317         .WillOnce(Invoke(AppendVector(forms)))
318         .RetiresOnSaturation();
319     EXPECT_CALL(*password_store_, FillBlacklistLogins(_))
320         .WillOnce(Invoke(AppendVector(blacklist_forms)))
321         .RetiresOnSaturation();
322   }
323
324  protected:
325   scoped_refptr<MockPasswordStore> password_store_;
326   scoped_ptr<MockPasswordSyncableService> service_;
327   PasswordStoreDataVerifier verifier_;
328
329  private:
330   struct AppendVector {
331     explicit AppendVector(
332         const std::vector<autofill::PasswordForm*>& append_forms)
333         : append_forms_(append_forms) {
334     }
335
336     ~AppendVector() {}
337
338     bool operator()(std::vector<autofill::PasswordForm*>* forms) const {
339       forms->insert(forms->end(), append_forms_.begin(), append_forms_.end());
340       return true;
341     }
342
343     std::vector<autofill::PasswordForm*> append_forms_;
344   };
345
346   DISALLOW_COPY_AND_ASSIGN(PasswordSyncableServiceWrapper);
347 };
348
349 class PasswordSyncableServiceTest : public testing::Test,
350                                     public PasswordSyncableServiceWrapper {
351  public:
352   PasswordSyncableServiceTest() {}
353   virtual ~PasswordSyncableServiceTest() {}
354 };
355
356
357 // Both sync and password db have data that are not present in the other.
358 TEST_F(PasswordSyncableServiceTest, AdditionsInBoth) {
359   scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
360   form1->signon_realm = "abc";
361   std::vector<autofill::PasswordForm*> forms;
362   forms.push_back(form1.release());
363   SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
364
365   SyncData sync_data = CreateSyncData("def");
366   SyncDataList list;
367   list.push_back(sync_data);
368
369   verifier()->SetExpectedDBChanges(list,
370                                    std::vector<autofill::PasswordForm*>(),
371                                    std::vector<autofill::PasswordForm*>(),
372                                    password_store());
373   verifier()->SetExpectedSyncChanges(
374       SyncChangeList(1, CreateSyncChange(*forms[0], SyncChange::ACTION_ADD)));
375   EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
376
377   service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
378                                       list,
379                                       CreateSyncChangeProcessor(),
380                                       scoped_ptr<syncer::SyncErrorFactory>());
381 }
382
383 // Sync has data that is not present in the password db.
384 TEST_F(PasswordSyncableServiceTest, AdditionOnlyInSync) {
385   SetPasswordStoreData(std::vector<autofill::PasswordForm*>(),
386                        std::vector<autofill::PasswordForm*>());
387
388   SyncData sync_data = CreateSyncData("def");
389   SyncDataList list;
390   list.push_back(sync_data);
391
392   verifier()->SetExpectedDBChanges(list,
393                                    std::vector<autofill::PasswordForm*>(),
394                                    std::vector<autofill::PasswordForm*>(),
395                                    password_store());
396   verifier()->SetExpectedSyncChanges(SyncChangeList());
397   EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
398
399   service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
400                                       list,
401                                       CreateSyncChangeProcessor(),
402                                       scoped_ptr<syncer::SyncErrorFactory>());
403 }
404
405 // Passwords db has data that is not present in sync.
406 TEST_F(PasswordSyncableServiceTest, AdditionOnlyInPasswordStore) {
407   scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
408   form1->signon_realm = "abc";
409   form1->times_used = 2;
410   form1->type = autofill::PasswordForm::TYPE_GENERATED;
411   std::vector<autofill::PasswordForm*> forms;
412   forms.push_back(form1.release());
413   SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
414
415   verifier()->SetExpectedDBChanges(SyncDataList(),
416                                    std::vector<autofill::PasswordForm*>(),
417                                    std::vector<autofill::PasswordForm*>(),
418                                    password_store());
419   verifier()->SetExpectedSyncChanges(
420       SyncChangeList(1, CreateSyncChange(*forms[0], SyncChange::ACTION_ADD)));
421   EXPECT_CALL(*service_,
422               NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
423
424   service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
425                                       SyncDataList(),
426                                       CreateSyncChangeProcessor(),
427                                       scoped_ptr<syncer::SyncErrorFactory>());
428 }
429
430 // Both passwords db and sync contain the same data.
431 TEST_F(PasswordSyncableServiceTest, BothInSync) {
432   scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
433   form1->signon_realm = "abc";
434   form1->times_used = 3;
435   form1->type = autofill::PasswordForm::TYPE_GENERATED;
436   std::vector<autofill::PasswordForm*> forms;
437   forms.push_back(form1.release());
438   SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
439
440   verifier()->SetExpectedDBChanges(SyncDataList(),
441                                    std::vector<autofill::PasswordForm*>(),
442                                    std::vector<autofill::PasswordForm*>(),
443                                    password_store());
444   verifier()->SetExpectedSyncChanges(SyncChangeList());
445   EXPECT_CALL(*service_,
446               NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
447
448   service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
449                                       SyncDataList(1, CreateSyncData("abc")),
450                                       CreateSyncChangeProcessor(),
451                                       scoped_ptr<syncer::SyncErrorFactory>());
452 }
453
454 // Both passwords db and sync have the same data but they need to be merged
455 // as some fields of the data differ.
456 TEST_F(PasswordSyncableServiceTest, Merge) {
457   scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
458   form1->signon_realm = "abc";
459   form1->action = GURL("http://pie.com");
460   form1->date_created = base::Time::Now();
461   form1->preferred = true;
462   std::vector<autofill::PasswordForm*> forms;
463   forms.push_back(form1.release());
464   SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
465
466   autofill::PasswordForm form2(*forms[0]);
467   form2.preferred = false;
468   verifier()->SetExpectedDBChanges(SyncDataList(),
469                                    std::vector<autofill::PasswordForm*>(1,
470                                                                         &form2),
471                                    std::vector<autofill::PasswordForm*>(),
472                                    password_store());
473   verifier()->SetExpectedSyncChanges(SyncChangeList());
474
475   EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
476
477   service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
478                                       SyncDataList(1,
479                                                    SyncDataFromPassword(form2)),
480                                       CreateSyncChangeProcessor(),
481                                       scoped_ptr<syncer::SyncErrorFactory>());
482 }
483
484 // Initiate sync due to local DB changes.
485 TEST_F(PasswordSyncableServiceTest, PasswordStoreChanges) {
486   // Set the sync change processor first.
487   SetPasswordStoreData(std::vector<autofill::PasswordForm*>(),
488                        std::vector<autofill::PasswordForm*>());
489   verifier()->SetExpectedSyncChanges(SyncChangeList());
490   EXPECT_CALL(*service_,
491               NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
492   service_->MergeDataAndStartSyncing(syncer::PASSWORDS,
493                                      SyncDataList(),
494                                      CreateSyncChangeProcessor(),
495                                      scoped_ptr<syncer::SyncErrorFactory>());
496
497   autofill::PasswordForm form1;
498   form1.signon_realm = "abc";
499   autofill::PasswordForm form2;
500   form2.signon_realm = "def";
501   autofill::PasswordForm form3;
502   form3.signon_realm = "xyz";
503
504   SyncChangeList sync_list;
505   sync_list.push_back(CreateSyncChange(form1, SyncChange::ACTION_ADD));
506   sync_list.push_back(CreateSyncChange(form2, SyncChange::ACTION_UPDATE));
507   sync_list.push_back(CreateSyncChange(form3, SyncChange::ACTION_DELETE));
508
509   verifier()->SetExpectedDBChanges(SyncDataList(),
510                                    std::vector<autofill::PasswordForm*>(),
511                                    std::vector<autofill::PasswordForm*>(),
512                                    password_store());
513   verifier()->SetExpectedSyncChanges(sync_list);
514
515   PasswordStoreChangeList list;
516   list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form1));
517   list.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form2));
518   list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form3));
519   service()->ActOnPasswordStoreChanges(list);
520 }
521
522 // Process all types of changes from sync.
523 TEST_F(PasswordSyncableServiceTest, ProcessSyncChanges) {
524   autofill::PasswordForm updated_form;
525   updated_form.signon_realm = "abc";
526   updated_form.action = GURL("http://foo.com");
527   updated_form.date_created = base::Time::Now();
528   autofill::PasswordForm deleted_form;
529   deleted_form.signon_realm = "xyz";
530   deleted_form.action = GURL("http://bar.com");
531   deleted_form.blacklisted_by_user = true;
532
533   SyncData add_data = CreateSyncData("def");
534   std::vector<autofill::PasswordForm*> updated_passwords(1, &updated_form);
535   std::vector<autofill::PasswordForm*> deleted_passwords(1, &deleted_form);
536   verifier()->SetExpectedDBChanges(SyncDataList(1, add_data),
537                                    updated_passwords,
538                                    deleted_passwords,
539                                    password_store());
540
541   SyncChangeList list;
542   list.push_back(SyncChange(FROM_HERE,
543                             syncer::SyncChange::ACTION_ADD,
544                             add_data));
545   list.push_back(CreateSyncChange(updated_form,
546                                   syncer::SyncChange::ACTION_UPDATE));
547   list.push_back(CreateSyncChange(deleted_form,
548                                   syncer::SyncChange::ACTION_DELETE));
549   EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
550   service()->ProcessSyncChanges(FROM_HERE, list);
551 }
552
553 // Retrives sync data from the model.
554 TEST_F(PasswordSyncableServiceTest, GetAllSyncData) {
555   scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
556   form1->signon_realm = "abc";
557   form1->action = GURL("http://foo.com");
558   form1->times_used = 5;
559   form1->type = autofill::PasswordForm::TYPE_GENERATED;
560   scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm);
561   form2->signon_realm = "xyz";
562   form2->action = GURL("http://bar.com");
563   form2->blacklisted_by_user = true;
564   std::vector<autofill::PasswordForm*> forms(1, form1.release());
565   std::vector<autofill::PasswordForm*> blacklist_forms(1, form2.release());
566   SetPasswordStoreData(forms, blacklist_forms);
567
568   SyncDataList expected_list;
569   expected_list.push_back(SyncDataFromPassword(*forms[0]));
570   expected_list.push_back(SyncDataFromPassword(*blacklist_forms[0]));
571
572   verifier()->SetExpectedDBChanges(SyncDataList(),
573                                    std::vector<autofill::PasswordForm*>(),
574                                    std::vector<autofill::PasswordForm*>(),
575                                    password_store());
576
577   SyncDataList actual_list = service()->GetAllSyncData(syncer::PASSWORDS);
578   EXPECT_EQ(expected_list.size(), actual_list.size());
579   for (SyncDataList::iterator i(actual_list.begin()), j(expected_list.begin());
580        i != actual_list.end() && j != expected_list.end(); ++i, ++j) {
581     PasswordsEqual(GetPasswordSpecifics(*j), GetPasswordSpecifics(*i));
582   }
583 }
584
585 // Creates 2 PasswordSyncableService instances, merges the content of the first
586 // one to the second one and back.
587 TEST_F(PasswordSyncableServiceTest, MergeDataAndPushBack) {
588   scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
589   form1->signon_realm = "abc";
590   form1->action = GURL("http://foo.com");
591   std::vector<autofill::PasswordForm*> forms(1, form1.release());
592   SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
593
594   PasswordSyncableServiceWrapper other_service_wrapper;
595   scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm);
596   form2->signon_realm = "xyz";
597   form2->action = GURL("http://bar.com");
598   syncer::SyncData form2_sync_data = SyncDataFromPassword(*form2);
599   other_service_wrapper.SetPasswordStoreData(
600       std::vector<autofill::PasswordForm*>(1, form2.release()),
601       std::vector<autofill::PasswordForm*>());
602
603   verifier()->SetExpectedDBChanges(SyncDataList(1, form2_sync_data),
604                                    std::vector<autofill::PasswordForm*>(),
605                                    std::vector<autofill::PasswordForm*>(),
606                                    password_store());
607   other_service_wrapper.verifier()->SetExpectedDBChanges(
608       SyncDataList(1, SyncDataFromPassword(*forms[0])),
609       std::vector<autofill::PasswordForm*>(),
610       std::vector<autofill::PasswordForm*>(),
611       other_service_wrapper.password_store());
612   EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
613   EXPECT_CALL(*other_service_wrapper.service(),
614               NotifyPasswordStoreOfLoginChanges(_));
615
616   syncer::SyncDataList other_service_data =
617       other_service_wrapper.service()->GetAllSyncData(syncer::PASSWORDS);
618   service()->MergeDataAndStartSyncing(
619       syncer::PASSWORDS,
620       other_service_data,
621       other_service_wrapper.ReleaseSyncableService(),
622       scoped_ptr<syncer::SyncErrorFactory>());
623 }
624
625 // Calls ActOnPasswordStoreChanges without SyncChangeProcessor. StartSyncFlare
626 // should be called.
627 TEST_F(PasswordSyncableServiceTest, StartSyncFlare) {
628   autofill::PasswordForm form;
629   form.signon_realm = "abc";
630   PasswordStoreChangeList list;
631   list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
632
633   // No flare and no SyncChangeProcessor, the call shouldn't crash.
634   service()->ActOnPasswordStoreChanges(list);
635
636   // Set the flare. It should be called as there is no SyncChangeProcessor.
637   service()->InjectStartSyncFlare(
638       base::Bind(&MockPasswordSyncableService::StartSyncFlare,
639                  base::Unretained(service())));
640   EXPECT_CALL(*service(), StartSyncFlare(syncer::PASSWORDS));
641   service()->ActOnPasswordStoreChanges(list);
642 }
643
644 }  // namespace
645
646 }  // namespace password_manager