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