Home | History | Annotate | Download | only in browser
      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 class FormFinder {
     86  public:
     87   explicit FormFinder(const autofill::PasswordForm& form) : form_(form) {}
     88   ~FormFinder() {}
     89 
     90   bool operator()(const autofill::PasswordForm& form) const;
     91 
     92  private:
     93   const autofill::PasswordForm form_;
     94 };
     95 
     96 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:
    108   explicit MockPasswordSyncableService(PasswordStoreSync* password_store)
    109       : PasswordSyncableService(password_store) {}
    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:
    121   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.
    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.
    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.
    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:
    183   explicit TestSyncChangeProcessor(PasswordStoreDataVerifier* verifier)
    184       : verifier_(verifier) {
    185   }
    186   virtual ~TestSyncChangeProcessor() {}
    187 
    188   virtual SyncError ProcessSyncChanges(const tracked_objects::Location&,
    189                                        const SyncChangeList& list) OVERRIDE {
    190     return verifier_->TestSyncChanges(list);
    191   }
    192 
    193   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 
    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 
    252 void PasswordStoreDataVerifier::SetExpectedSyncChanges(SyncChangeList list) {
    253   expected_sync_change_list_.swap(list);
    254 }
    255 
    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
    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:
    304   PasswordSyncableServiceWrapper() {
    305     password_store_ = new MockPasswordStore;
    306     service_.reset(new MockPasswordSyncableService(
    307         password_store_->GetSyncInterface()));
    308   }
    309 
    310   ~PasswordSyncableServiceWrapper() {
    311     password_store_->Shutdown();
    312   }
    313 
    314   MockPasswordStore* password_store() {
    315     return password_store_;
    316   }
    317 
    318   MockPasswordSyncableService* service() {
    319     return service_.get();
    320   }
    321 
    322   // Returnes the scoped_ptr to |service_| thus NULLing out it.
    323   scoped_ptr<syncer::SyncChangeProcessor> ReleaseSyncableService() {
    324     return service_.PassAs<syncer::SyncChangeProcessor>();
    325   }
    326 
    327   PasswordStoreDataVerifier* verifier() {
    328     return &verifier_;
    329   }
    330 
    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.
    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 {
    355     explicit AppendVector(
    356         const std::vector<autofill::PasswordForm*>& append_forms)
    357         : append_forms_(append_forms) {
    358     }
    359 
    360     ~AppendVector() {}
    361 
    362     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:
    376   PasswordSyncableServiceTest() {}
    377   virtual ~PasswordSyncableServiceTest() {}
    378 };
    379 
    380 
    381 // Both sync and password db have data that are not present in the other.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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