summaryrefslogtreecommitdiffstats
path: root/chrome/browser/password_manager
diff options
context:
space:
mode:
authorvabr@chromium.org <vabr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-18 20:19:05 +0000
committervabr@chromium.org <vabr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-18 20:19:05 +0000
commite264060920c1a56685eaccbb0ace72f1050e9b2c (patch)
treed70fb9e6018ddddc5acf9e760ddfb35e3bf0d20c /chrome/browser/password_manager
parent6dfd1d71ad9c6b7b0f8c822a2d8ba84be85038bf (diff)
downloadchromium_src-e264060920c1a56685eaccbb0ace72f1050e9b2c.zip
chromium_src-e264060920c1a56685eaccbb0ace72f1050e9b2c.tar.gz
chromium_src-e264060920c1a56685eaccbb0ace72f1050e9b2c.tar.bz2
Componentize PasswordSyncableService
This just moves the files and adds needed dependencies. BUG=344456 TBR=atwilson@chromium.org,rvargas@chromium.org Review URL: https://codereview.chromium.org/170313003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251818 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/password_manager')
-rw-r--r--chrome/browser/password_manager/password_syncable_service.cc448
-rw-r--r--chrome/browser/password_manager/password_syncable_service.h116
-rw-r--r--chrome/browser/password_manager/password_syncable_service_unittest.cc613
3 files changed, 0 insertions, 1177 deletions
diff --git a/chrome/browser/password_manager/password_syncable_service.cc b/chrome/browser/password_manager/password_syncable_service.cc
deleted file mode 100644
index 4bee8dc..0000000
--- a/chrome/browser/password_manager/password_syncable_service.cc
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/password_manager/password_syncable_service.h"
-
-#include "base/location.h"
-#include "base/memory/scoped_vector.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/common/password_form.h"
-#include "components/password_manager/core/browser/password_store.h"
-#include "net/base/escape.h"
-#include "sync/api/sync_error_factory.h"
-
-namespace {
-
-// Describes the result of merging sync and local passwords.
-enum MergeResult {
- IDENTICAL,
- SYNC,
- LOCAL,
-};
-
-// Merges the local and sync passwords and outputs the entry into
-// |new_password_form|. Returns MergeResult value describing the content of
-// |new_password_form|.
-MergeResult MergeLocalAndSyncPasswords(
- const sync_pb::PasswordSpecificsData& password_specifics,
- const autofill::PasswordForm& password_form,
- autofill::PasswordForm* new_password_form) {
- DCHECK(new_password_form);
- if (password_form.scheme == password_specifics.scheme() &&
- password_form.signon_realm == password_specifics.signon_realm() &&
- password_form.origin.spec() == password_specifics.origin() &&
- password_form.action.spec() == password_specifics.action() &&
- base::UTF16ToUTF8(password_form.username_element) ==
- password_specifics.username_element() &&
- base::UTF16ToUTF8(password_form.password_element) ==
- password_specifics.password_element() &&
- base::UTF16ToUTF8(password_form.username_value) ==
- password_specifics.username_value() &&
- base::UTF16ToUTF8(password_form.password_value) ==
- password_specifics.password_value() &&
- password_form.ssl_valid == password_specifics.ssl_valid() &&
- password_form.preferred == password_specifics.preferred() &&
- password_form.date_created.ToInternalValue() ==
- password_specifics.date_created() &&
- password_form.blacklisted_by_user == password_specifics.blacklisted()) {
- return IDENTICAL;
- }
-
- // If the passwords differ, take the one that was created more recently.
- if (base::Time::FromInternalValue(password_specifics.date_created()) <=
- password_form.date_created) {
- *new_password_form = password_form;
- return LOCAL;
- }
-
- PasswordFromSpecifics(password_specifics, new_password_form);
- return SYNC;
-}
-
-std::string MakePasswordSyncTag(const std::string& origin_url,
- const std::string& username_element,
- const std::string& username_value,
- const std::string& password_element,
- const std::string& signon_realm) {
- return net::EscapePath(origin_url) + "|" +
- net::EscapePath(username_element) + "|" +
- net::EscapePath(username_value) + "|" +
- net::EscapePath(password_element) + "|" +
- net::EscapePath(signon_realm);
-}
-
-std::string MakePasswordSyncTag(const autofill::PasswordForm& password) {
- return MakePasswordSyncTag(password.origin.spec(),
- base::UTF16ToUTF8(password.username_element),
- base::UTF16ToUTF8(password.username_value),
- base::UTF16ToUTF8(password.password_element),
- password.signon_realm);
-}
-
-syncer::SyncChange::SyncChangeType GetSyncChangeType(
- PasswordStoreChange::Type type) {
- switch (type) {
- case PasswordStoreChange::ADD:
- return syncer::SyncChange::ACTION_ADD;
- case PasswordStoreChange::UPDATE:
- return syncer::SyncChange::ACTION_UPDATE;
- case PasswordStoreChange::REMOVE:
- return syncer::SyncChange::ACTION_DELETE;
- }
- NOTREACHED();
- return syncer::SyncChange::ACTION_INVALID;
-}
-
-void AppendChanges(const PasswordStoreChangeList& new_changes,
- PasswordStoreChangeList* all_changes) {
- all_changes->insert(all_changes->end(),
- new_changes.begin(),
- new_changes.end());
-}
-
-} // namespace
-
-PasswordSyncableService::PasswordSyncableService(
- scoped_refptr<PasswordStore> password_store)
- : password_store_(password_store) {
-}
-
-PasswordSyncableService::~PasswordSyncableService() {}
-
-syncer::SyncMergeResult PasswordSyncableService::MergeDataAndStartSyncing(
- syncer::ModelType type,
- const syncer::SyncDataList& initial_sync_data,
- scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
- scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
- DCHECK_EQ(syncer::PASSWORDS, type);
- syncer::SyncMergeResult merge_result(type);
- sync_error_factory_ = sync_error_factory.Pass();
- sync_processor_ = sync_processor.Pass();
-
- // We add all the db entries as |new_local_entries| initially. During model
- // association entries that match a sync entry will be removed and this list
- // will only contain entries that are not in sync.
- ScopedVector<autofill::PasswordForm> password_entries;
- PasswordEntryMap new_local_entries;
- if (!ReadFromPasswordStore(&password_entries, &new_local_entries)) {
- DCHECK(sync_error_factory_);
- merge_result.set_error(sync_error_factory_->CreateAndUploadError(
- FROM_HERE,
- "Failed to get passwords from store."));
- return merge_result;
- }
-
- merge_result.set_num_items_before_association(new_local_entries.size());
-
- // List that contains the entries that are known only to sync.
- ScopedVector<autofill::PasswordForm> new_sync_entries;
-
- // List that contains the entries that are known to both sync and db but
- // have updates in sync. They need to be updated in the passwords db.
- ScopedVector<autofill::PasswordForm> updated_sync_entries;
-
- // Changes from password db that need to be propagated to sync.
- syncer::SyncChangeList updated_db_entries;
- for (syncer::SyncDataList::const_iterator sync_iter =
- initial_sync_data.begin();
- sync_iter != initial_sync_data.end(); ++sync_iter) {
- CreateOrUpdateEntry(*sync_iter,
- &new_local_entries,
- &new_sync_entries,
- &updated_sync_entries,
- &updated_db_entries);
- }
-
- WriteToPasswordStore(new_sync_entries.get(),
- updated_sync_entries.get(),
- PasswordForms());
-
- merge_result.set_num_items_after_association(
- merge_result.num_items_before_association() + new_sync_entries.size());
-
- merge_result.set_num_items_added(new_sync_entries.size());
-
- merge_result.set_num_items_modified(updated_sync_entries.size());
-
- for (PasswordEntryMap::iterator it = new_local_entries.begin();
- it != new_local_entries.end();
- ++it) {
- updated_db_entries.push_back(
- syncer::SyncChange(FROM_HERE,
- syncer::SyncChange::ACTION_ADD,
- SyncDataFromPassword(*it->second)));
- }
-
- merge_result.set_error(
- sync_processor_->ProcessSyncChanges(FROM_HERE, updated_db_entries));
- return merge_result;
-}
-
-void PasswordSyncableService::StopSyncing(syncer::ModelType type) {
- sync_processor_.reset();
- sync_error_factory_.reset();
-}
-
-syncer::SyncDataList PasswordSyncableService::GetAllSyncData(
- syncer::ModelType type) const {
- DCHECK_EQ(syncer::PASSWORDS, type);
- ScopedVector<autofill::PasswordForm> password_entries;
- ReadFromPasswordStore(&password_entries, NULL);
-
- syncer::SyncDataList sync_data;
- for (PasswordForms::iterator it = password_entries.begin();
- it != password_entries.end(); ++it) {
- sync_data.push_back(SyncDataFromPassword(**it));
- }
- return sync_data;
-}
-
-syncer::SyncError PasswordSyncableService::ProcessSyncChanges(
- const tracked_objects::Location& from_here,
- const syncer::SyncChangeList& change_list) {
- // The |db_entries_map| and associated vectors are filled only in case of
- // update change.
- PasswordEntryMap db_entries_map;
- ScopedVector<autofill::PasswordForm> password_db_entries;
- ScopedVector<autofill::PasswordForm> new_sync_entries;
- ScopedVector<autofill::PasswordForm> updated_sync_entries;
- ScopedVector<autofill::PasswordForm> deleted_entries;
- bool has_read_passwords = false;
-
- for (syncer::SyncChangeList::const_iterator it = change_list.begin();
- it != change_list.end();
- ++it) {
- switch (it->change_type()) {
- case syncer::SyncChange::ACTION_ADD: {
- const sync_pb::EntitySpecifics& specifics =
- it->sync_data().GetSpecifics();
- new_sync_entries.push_back(new autofill::PasswordForm);
- PasswordFromSpecifics(specifics.password().client_only_encrypted_data(),
- new_sync_entries.back());
- break;
- }
- case syncer::SyncChange::ACTION_UPDATE: {
- if (!has_read_passwords) {
- if (ReadFromPasswordStore(&password_db_entries,
- &db_entries_map)) {
- has_read_passwords = true;
- } else {
- return sync_error_factory_->CreateAndUploadError(
- FROM_HERE,
- "Failed to get passwords from store.");
- }
- }
- syncer::SyncChangeList sync_changes;
-
- CreateOrUpdateEntry(it->sync_data(),
- &db_entries_map,
- &new_sync_entries,
- &updated_sync_entries,
- &sync_changes);
- DCHECK(sync_changes.empty());
- break;
- }
-
- case syncer::SyncChange::ACTION_DELETE: {
- const sync_pb::EntitySpecifics& specifics =
- it->sync_data().GetSpecifics();
- const sync_pb::PasswordSpecificsData& password_specifics(
- specifics.password().client_only_encrypted_data());
- deleted_entries.push_back(new autofill::PasswordForm);
- PasswordFromSpecifics(password_specifics, deleted_entries.back());
- break;
- }
- case syncer::SyncChange::ACTION_INVALID:
- return sync_error_factory_->CreateAndUploadError(
- FROM_HERE,
- "Failed to process sync changes for passwords datatype.");
- }
- }
- WriteToPasswordStore(new_sync_entries.get(),
- updated_sync_entries.get(),
- deleted_entries.get());
- return syncer::SyncError();
-}
-
-void PasswordSyncableService::ActOnPasswordStoreChanges(
- const PasswordStoreChangeList& local_changes) {
- if (!sync_processor_)
- return;
- syncer::SyncChangeList sync_changes;
- for (PasswordStoreChangeList::const_iterator it = local_changes.begin();
- it != local_changes.end();
- ++it) {
- sync_changes.push_back(
- syncer::SyncChange(FROM_HERE,
- GetSyncChangeType(it->type()),
- SyncDataFromPassword(it->form())));
- }
- sync_processor_->ProcessSyncChanges(FROM_HERE, sync_changes);
-}
-
-bool PasswordSyncableService::ReadFromPasswordStore(
- ScopedVector<autofill::PasswordForm>* password_entries,
- PasswordEntryMap* passwords_entry_map) const {
- DCHECK(password_entries);
- if (!password_store_->FillAutofillableLogins(&password_entries->get()) ||
- !password_store_->FillBlacklistLogins(&password_entries->get())) {
- // Password store often fails to load passwords. Track failures with UMA.
- // (http://crbug.com/249000)
- UMA_HISTOGRAM_ENUMERATION("Sync.LocalDataFailedToLoad",
- ModelTypeToHistogramInt(syncer::PASSWORDS),
- syncer::MODEL_TYPE_COUNT);
- return false;
- }
-
- if (!passwords_entry_map)
- return true;
-
- for (PasswordForms::iterator it = password_entries->begin();
- it != password_entries->end(); ++it) {
- autofill::PasswordForm* password_form = *it;
- passwords_entry_map->insert(
- std::make_pair(MakePasswordSyncTag(*password_form), password_form));
- }
-
- return true;
-}
-
-void PasswordSyncableService::WriteToPasswordStore(
- const PasswordForms& new_entries,
- const PasswordForms& updated_entries,
- const PasswordForms& deleted_entries) {
- PasswordStoreChangeList changes;
- for (std::vector<autofill::PasswordForm*>::const_iterator it =
- new_entries.begin();
- it != new_entries.end();
- ++it) {
- AppendChanges(password_store_->AddLoginImpl(**it), &changes);
- }
-
- for (std::vector<autofill::PasswordForm*>::const_iterator it =
- updated_entries.begin();
- it != updated_entries.end();
- ++it) {
- AppendChanges(password_store_->UpdateLoginImpl(**it), &changes);
- }
-
- for (std::vector<autofill::PasswordForm*>::const_iterator it =
- deleted_entries.begin();
- it != deleted_entries.end();
- ++it) {
- AppendChanges(password_store_->RemoveLoginImpl(**it), &changes);
- }
-
- // We have to notify password store observers of the change by hand since
- // we use internal password store interfaces to make changes synchronously.
- NotifyPasswordStoreOfLoginChanges(changes);
-}
-
-void PasswordSyncableService::NotifyPasswordStoreOfLoginChanges(
- const PasswordStoreChangeList& changes) {
- password_store_->NotifyLoginsChanged(changes);
-}
-
-void PasswordSyncableService::CreateOrUpdateEntry(
- const syncer::SyncData& data,
- PasswordEntryMap* umatched_data_from_password_db,
- ScopedVector<autofill::PasswordForm>* new_sync_entries,
- ScopedVector<autofill::PasswordForm>* updated_sync_entries,
- syncer::SyncChangeList* updated_db_entries) {
- const sync_pb::EntitySpecifics& specifics = data.GetSpecifics();
- const sync_pb::PasswordSpecificsData& password_specifics(
- specifics.password().client_only_encrypted_data());
- std::string tag = MakePasswordSyncTag(password_specifics);
-
- // Check whether the data from sync is already in the password store.
- PasswordEntryMap::iterator existing_local_entry_iter =
- umatched_data_from_password_db->find(tag);
- if (existing_local_entry_iter == umatched_data_from_password_db->end()) {
- // The sync data is not in the password store, so we need to create it in
- // the password store. Add the entry to the new_entries list.
- scoped_ptr<autofill::PasswordForm> new_password(new autofill::PasswordForm);
- PasswordFromSpecifics(password_specifics, new_password.get());
- new_sync_entries->push_back(new_password.release());
- } else {
- // The entry is in password store. If the entries are not identical, then
- // the entries need to be merged.
- scoped_ptr<autofill::PasswordForm> new_password(new autofill::PasswordForm);
- switch (MergeLocalAndSyncPasswords(password_specifics,
- *existing_local_entry_iter->second,
- new_password.get())) {
- case IDENTICAL:
- break;
- case SYNC:
- updated_sync_entries->push_back(new_password.release());
- break;
- case LOCAL:
- updated_db_entries->push_back(
- syncer::SyncChange(FROM_HERE,
- syncer::SyncChange::ACTION_UPDATE,
- SyncDataFromPassword(*new_password)));
- break;
- }
- // Remove the entry from the entry map to indicate a match has been found.
- // Entries that remain in the map at the end of associating all sync entries
- // will be treated as additions that need to be propagated to sync.
- umatched_data_from_password_db->erase(existing_local_entry_iter);
- }
-}
-
-syncer::SyncData SyncDataFromPassword(
- const autofill::PasswordForm& password_form) {
- sync_pb::EntitySpecifics password_data;
- sync_pb::PasswordSpecificsData* password_specifics =
- password_data.mutable_password()->mutable_client_only_encrypted_data();
- password_specifics->set_scheme(password_form.scheme);
- password_specifics->set_signon_realm(password_form.signon_realm);
- password_specifics->set_origin(password_form.origin.spec());
- password_specifics->set_action(password_form.action.spec());
- password_specifics->set_username_element(
- base::UTF16ToUTF8(password_form.username_element));
- password_specifics->set_password_element(
- base::UTF16ToUTF8(password_form.password_element));
- password_specifics->set_username_value(
- base::UTF16ToUTF8(password_form.username_value));
- password_specifics->set_password_value(
- base::UTF16ToUTF8(password_form.password_value));
- password_specifics->set_ssl_valid(password_form.ssl_valid);
- password_specifics->set_preferred(password_form.preferred);
- password_specifics->set_date_created(
- password_form.date_created.ToInternalValue());
- password_specifics->set_blacklisted(password_form.blacklisted_by_user);
-
- std::string tag = MakePasswordSyncTag(*password_specifics);
- return syncer::SyncData::CreateLocalData(tag, tag, password_data);
-}
-
-void PasswordFromSpecifics(const sync_pb::PasswordSpecificsData& password,
- autofill::PasswordForm* new_password) {
- new_password->scheme =
- static_cast<autofill::PasswordForm::Scheme>(password.scheme());
- new_password->signon_realm = password.signon_realm();
- new_password->origin = GURL(password.origin());
- new_password->action = GURL(password.action());
- new_password->username_element =
- base::UTF8ToUTF16(password.username_element());
- new_password->password_element =
- base::UTF8ToUTF16(password.password_element());
- new_password->username_value = base::UTF8ToUTF16(password.username_value());
- new_password->password_value = base::UTF8ToUTF16(password.password_value());
- new_password->ssl_valid = password.ssl_valid();
- new_password->preferred = password.preferred();
- new_password->date_created =
- base::Time::FromInternalValue(password.date_created());
- new_password->blacklisted_by_user = password.blacklisted();
-}
-
-std::string MakePasswordSyncTag(
- const sync_pb::PasswordSpecificsData& password) {
- return MakePasswordSyncTag(password.origin(),
- password.username_element(),
- password.username_value(),
- password.password_element(),
- password.signon_realm());
-}
diff --git a/chrome/browser/password_manager/password_syncable_service.h b/chrome/browser/password_manager/password_syncable_service.h
deleted file mode 100644
index 38e8ef3..0000000
--- a/chrome/browser/password_manager/password_syncable_service.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_SYNCABLE_SERVICE_H__
-#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_SYNCABLE_SERVICE_H__
-
-#include <string>
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "components/password_manager/core/browser/password_store_change.h"
-#include "sync/api/sync_change.h"
-#include "sync/api/sync_data.h"
-#include "sync/api/sync_error.h"
-#include "sync/api/syncable_service.h"
-#include "sync/protocol/password_specifics.pb.h"
-#include "sync/protocol/sync.pb.h"
-
-namespace autofill {
-struct PasswordForm;
-}
-
-namespace syncer {
-class SyncErrorFactory;
-}
-
-class PasswordStore;
-
-class PasswordSyncableService : public syncer::SyncableService {
- public:
- // TODO(lipalani) - The |PasswordStore| should outlive
- // |PasswordSyncableService| and there should be a code
- // guarantee to that effect. Currently this object is not instantiated.
- // When this class is completed and instantiated the object lifetime
- // guarantee will be implemented.
- explicit PasswordSyncableService(
- scoped_refptr<PasswordStore> password_store);
- virtual ~PasswordSyncableService();
-
- // syncer::SyncableServiceImplementations
- virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
- syncer::ModelType type,
- const syncer::SyncDataList& initial_sync_data,
- scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
- scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
- virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
- virtual syncer::SyncDataList GetAllSyncData(
- syncer::ModelType type) const OVERRIDE;
- virtual syncer::SyncError ProcessSyncChanges(
- const tracked_objects::Location& from_here,
- const syncer::SyncChangeList& change_list) OVERRIDE;
-
- // Notifies sync of changes to the password database.
- void ActOnPasswordStoreChanges(const PasswordStoreChangeList& changes);
-
- private:
- typedef std::vector<autofill::PasswordForm*> PasswordForms;
- // Map from password sync tag to password form.
- typedef std::map<std::string, autofill::PasswordForm*> PasswordEntryMap;
-
- // Helper function to retrieve the entries from password db and fill both
- // |password_entries| and |passwords_entry_map|. |passwords_entry_map| can be
- // NULL.
- bool ReadFromPasswordStore(
- ScopedVector<autofill::PasswordForm>* password_entries,
- PasswordEntryMap* passwords_entry_map) const;
-
- // Uses the |PasswordStore| APIs to change entries.
- void WriteToPasswordStore(const PasswordForms& new_entries,
- const PasswordForms& updated_entries,
- const PasswordForms& deleted_entries);
-
- // Notifies password store of a change that was performed by sync.
- // Virtual so tests can override.
- virtual void NotifyPasswordStoreOfLoginChanges(
- const PasswordStoreChangeList& changes);
-
- // Checks if |data|, the entry in sync db, needs to be created or updated
- // in the passwords db. Depending on what action needs to be performed, the
- // entry may be added to |new_sync_entries| or to |updated_sync_entries|. If
- // the item is identical to an entry in the passwords db, no action is
- // performed. If an item needs to be updated in the sync db, then the item is
- // also added to |updated_db_entries| list. If |data|'s tag is identical to
- // an entry's tag in |umatched_data_from_password_db| then that entry will be
- // removed from |umatched_data_from_password_db|.
- void CreateOrUpdateEntry(
- const syncer::SyncData& data,
- PasswordEntryMap* umatched_data_from_password_db,
- ScopedVector<autofill::PasswordForm>* new_sync_entries,
- ScopedVector<autofill::PasswordForm>* updated_sync_entries,
- syncer::SyncChangeList* updated_db_entries);
-
- // The factory that creates sync errors. |SyncError| has rich data
- // suitable for debugging.
- scoped_ptr<syncer::SyncErrorFactory> sync_error_factory_;
-
- // |SyncProcessor| will mirror the |PasswordStore| changes in the sync db.
- scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
-
- // The password store that adds/updates/deletes password entries.
- scoped_refptr<PasswordStore> password_store_;
-};
-
-// Converts the |password| into a SyncData object.
-syncer::SyncData SyncDataFromPassword(const autofill::PasswordForm& password);
-
-// Extracts the |PasswordForm| data from sync's protobuffer format.
-void PasswordFromSpecifics(const sync_pb::PasswordSpecificsData& password,
- autofill::PasswordForm* new_password);
-
-// Returns the unique tag that will serve as the sync identifier for the
-// |password| entry.
-std::string MakePasswordSyncTag(const sync_pb::PasswordSpecificsData& password);
-
-#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_SYNCABLE_SERVICE_H__
diff --git a/chrome/browser/password_manager/password_syncable_service_unittest.cc b/chrome/browser/password_manager/password_syncable_service_unittest.cc
deleted file mode 100644
index 98a36af..0000000
--- a/chrome/browser/password_manager/password_syncable_service_unittest.cc
+++ /dev/null
@@ -1,613 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/password_manager/password_syncable_service.h"
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/location.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "components/password_manager/core/browser/mock_password_store.h"
-#include "sync/api/sync_change_processor.h"
-#include "sync/api/sync_error.h"
-#include "sync/api/sync_error_factory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using syncer::SyncChange;
-using syncer::SyncData;
-using syncer::SyncDataList;
-using syncer::SyncError;
-using testing::Invoke;
-using testing::Return;
-using testing::SetArgPointee;
-using testing::_;
-
-namespace {
-
-typedef std::vector<SyncChange> SyncChangeList;
-
-const sync_pb::PasswordSpecificsData& GetPasswordSpecifics(
- const syncer::SyncData& sync_data) {
- const sync_pb::EntitySpecifics& specifics = sync_data.GetSpecifics();
- return specifics.password().client_only_encrypted_data();
-}
-
-void PasswordsEqual(const sync_pb::PasswordSpecificsData& expected_password,
- const sync_pb::PasswordSpecificsData& actual_password) {
- EXPECT_EQ(expected_password.scheme(), actual_password.scheme());
- EXPECT_EQ(expected_password.signon_realm(), actual_password.signon_realm());
- EXPECT_EQ(expected_password.origin(), actual_password.origin());
- EXPECT_EQ(expected_password.action(), actual_password.action());
- EXPECT_EQ(expected_password.username_element(),
- actual_password.username_element());
- EXPECT_EQ(expected_password.password_element(),
- actual_password.password_element());
- EXPECT_EQ(expected_password.username_value(),
- actual_password.username_value());
- EXPECT_EQ(expected_password.password_value(),
- actual_password.password_value());
- EXPECT_EQ(expected_password.ssl_valid(), actual_password.ssl_valid());
- EXPECT_EQ(expected_password.preferred(), actual_password.preferred());
- EXPECT_EQ(expected_password.date_created(), actual_password.date_created());
- EXPECT_EQ(expected_password.blacklisted(), actual_password.blacklisted());
-}
-
-// Creates a sync data consisting of password specifics. The sign on realm is
-// set to |signon_realm|.
-SyncData CreateSyncData(const std::string& signon_realm) {
- sync_pb::EntitySpecifics password_data;
- sync_pb::PasswordSpecificsData* password_specifics =
- password_data.mutable_password()->mutable_client_only_encrypted_data();
- password_specifics->set_signon_realm(signon_realm);
-
- std::string tag = MakePasswordSyncTag(*password_specifics);
- return syncer::SyncData::CreateLocalData(tag, tag, password_data);
-}
-
-SyncChange CreateSyncChange(const autofill::PasswordForm& password,
- SyncChange::SyncChangeType type) {
- SyncData data = SyncDataFromPassword(password);
- return SyncChange(FROM_HERE, type, data);
-}
-
-// A testable implementation of the |PasswordSyncableService| that mocks
-// out all interaction with the password database.
-class MockPasswordSyncableService : public PasswordSyncableService {
- public:
- explicit MockPasswordSyncableService(PasswordStore* password_store)
- : PasswordSyncableService(password_store) {}
- virtual ~MockPasswordSyncableService() {}
-
- MOCK_METHOD1(NotifyPasswordStoreOfLoginChanges,
- void (const PasswordStoreChangeList&));
-};
-
-// Class to verify the arguments passed to |PasswordStore|.
-class PasswordStoreDataVerifier {
- public:
- PasswordStoreDataVerifier() {}
- ~PasswordStoreDataVerifier() {
- EXPECT_TRUE(expected_db_add_changes_.empty());
- EXPECT_TRUE(expected_db_update_changes_.empty());
- EXPECT_TRUE(expected_db_delete_changes_.empty());
- }
-
- class TestSyncChangeProcessor;
-
- // Sets expected changes to the password database.
- void SetExpectedDBChanges(
- const SyncDataList& add_forms,
- const std::vector<autofill::PasswordForm*>& update_forms,
- const std::vector<autofill::PasswordForm*>& delete_forms,
- MockPasswordStore* password_store);
- // Sets expected changes to TestSyncChangeProcessor.
- void SetExpectedSyncChanges(SyncChangeList list);
-
- private:
- // Checks that |change_list| matches |expected_sync_change_list_|.
- SyncError TestSyncChanges(const SyncChangeList& change_list);
-
- // Verifies that the |password| is present in the |expected_db_add_changes_|
- // list. If found, |password| would be removed from
- // |expected_db_add_changes_| list.
- PasswordStoreChangeList VerifyAdd(const autofill::PasswordForm& password) {
- return VerifyChange(PasswordStoreChange::ADD, password,
- &expected_db_add_changes_);
- }
-
- // Verifies that the |password| is present in the
- // |expected_db_update_changes_| list. If found, |password| would be removed
- // from |expected_db_update_changes_| list.
- PasswordStoreChangeList VerifyUpdate(const autofill::PasswordForm& password) {
- return VerifyChange(PasswordStoreChange::UPDATE, password,
- &expected_db_update_changes_);
- }
-
- // Verifies that the |password| is present in the
- // |expected_db_delete_changes_| list. If found, |password| would be removed
- // from |expected_db_delete_changes_| list.
- PasswordStoreChangeList VerifyDelete(const autofill::PasswordForm& password) {
- return VerifyChange(PasswordStoreChange::REMOVE, password,
- &expected_db_delete_changes_);
- }
-
- static PasswordStoreChangeList VerifyChange(
- PasswordStoreChange::Type type,
- const autofill::PasswordForm& password,
- std::vector<autofill::PasswordForm>* password_list);
-
- std::vector<autofill::PasswordForm> expected_db_add_changes_;
- std::vector<autofill::PasswordForm> expected_db_update_changes_;
- std::vector<autofill::PasswordForm> expected_db_delete_changes_;
- SyncChangeList expected_sync_change_list_;
-
- DISALLOW_COPY_AND_ASSIGN(PasswordStoreDataVerifier);
-};
-
-class PasswordStoreDataVerifier::TestSyncChangeProcessor
- : public syncer::SyncChangeProcessor {
- public:
- explicit TestSyncChangeProcessor(PasswordStoreDataVerifier* verifier)
- : verifier_(verifier) {
- }
- virtual ~TestSyncChangeProcessor() {}
-
- virtual SyncError ProcessSyncChanges(const tracked_objects::Location&,
- const SyncChangeList& list) OVERRIDE {
- return verifier_->TestSyncChanges(list);
- }
-
- virtual SyncDataList GetAllSyncData(syncer::ModelType type) const OVERRIDE {
- return SyncDataList();
- }
- private:
- PasswordStoreDataVerifier* verifier_;
-
- DISALLOW_COPY_AND_ASSIGN(TestSyncChangeProcessor);
-};
-
-void PasswordStoreDataVerifier::SetExpectedDBChanges(
- const SyncDataList& add_forms,
- const std::vector<autofill::PasswordForm*>& update_forms,
- const std::vector<autofill::PasswordForm*>& delete_forms,
- MockPasswordStore* password_store) {
- DCHECK(expected_db_add_changes_.empty());
- DCHECK(expected_db_update_changes_.empty());
- DCHECK(password_store);
-
- for (SyncDataList::const_iterator it = add_forms.begin();
- it != add_forms.end(); ++it) {
- autofill::PasswordForm form;
- PasswordFromSpecifics(GetPasswordSpecifics(*it), &form);
- expected_db_add_changes_.push_back(form);
- }
- if (expected_db_add_changes_.empty()) {
- EXPECT_CALL(*password_store, AddLoginImpl(_)).Times(0);
- } else {
- EXPECT_CALL(*password_store, AddLoginImpl(_))
- .Times(expected_db_add_changes_.size())
- .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyAdd));
- }
-
- for (std::vector<autofill::PasswordForm*>::const_iterator it =
- update_forms.begin();
- it != update_forms.end(); ++it) {
- expected_db_update_changes_.push_back(**it);
- }
- if (expected_db_update_changes_.empty()) {
- EXPECT_CALL(*password_store, UpdateLoginImpl(_)).Times(0);
- } else {
- EXPECT_CALL(*password_store, UpdateLoginImpl(_))
- .Times(expected_db_update_changes_.size())
- .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyUpdate));
- }
-
- for (std::vector<autofill::PasswordForm*>::const_iterator it =
- delete_forms.begin();
- it != delete_forms.end(); ++it) {
- expected_db_delete_changes_.push_back(**it);
- }
- if (expected_db_delete_changes_.empty()) {
- EXPECT_CALL(*password_store, RemoveLoginImpl(_)).Times(0);
- } else {
- EXPECT_CALL(*password_store, RemoveLoginImpl(_))
- .Times(expected_db_delete_changes_.size())
- .WillRepeatedly(Invoke(this, &PasswordStoreDataVerifier::VerifyDelete));
- }
-}
-
-void PasswordStoreDataVerifier::SetExpectedSyncChanges(SyncChangeList list) {
- expected_sync_change_list_.swap(list);
-}
-
-SyncError PasswordStoreDataVerifier::TestSyncChanges(
- const SyncChangeList& change_list) {
- for (SyncChangeList::const_iterator it = change_list.begin();
- it != change_list.end(); ++it) {
- const SyncChange& data = *it;
- const sync_pb::PasswordSpecificsData& actual_password(
- GetPasswordSpecifics(data.sync_data()));
- std::string actual_tag = MakePasswordSyncTag(actual_password);
-
- bool matched = false;
- for (SyncChangeList::iterator expected_it =
- expected_sync_change_list_.begin();
- expected_it != expected_sync_change_list_.end();
- ++expected_it) {
- const sync_pb::PasswordSpecificsData& expected_password(
- GetPasswordSpecifics(expected_it->sync_data()));
- if (actual_tag == MakePasswordSyncTag(expected_password)) {
- PasswordsEqual(expected_password, actual_password);
- EXPECT_EQ(expected_it->change_type(), data.change_type());
- matched = true;
- break;
- }
- }
- EXPECT_TRUE(matched) << actual_tag;
- }
- EXPECT_EQ(expected_sync_change_list_.size(), change_list.size());
- return SyncError();
-}
-
-// static
-PasswordStoreChangeList PasswordStoreDataVerifier::VerifyChange(
- PasswordStoreChange::Type type,
- const autofill::PasswordForm& password,
- std::vector<autofill::PasswordForm>* password_list) {
- std::vector<autofill::PasswordForm>::iterator it =
- std::find(password_list->begin(), password_list->end(), password);
- EXPECT_NE(password_list->end(), it);
- password_list->erase(it);
- return PasswordStoreChangeList(1, PasswordStoreChange(type, password));
-}
-
-class PasswordSyncableServiceWrapper {
- public:
- PasswordSyncableServiceWrapper() {
- password_store_ = new MockPasswordStore;
- service_.reset(new MockPasswordSyncableService(password_store_));
- }
-
- ~PasswordSyncableServiceWrapper() {
- password_store_->Shutdown();
- }
-
- MockPasswordStore* password_store() {
- return password_store_;
- }
-
- MockPasswordSyncableService* service() {
- return service_.get();
- }
-
- // Returnes the scoped_ptr to |service_| thus NULLing out it.
- scoped_ptr<syncer::SyncChangeProcessor> ReleaseSyncableService() {
- return service_.PassAs<syncer::SyncChangeProcessor>();
- }
-
- PasswordStoreDataVerifier* verifier() {
- return &verifier_;
- }
-
- scoped_ptr<syncer::SyncChangeProcessor> CreateSyncChangeProcessor() {
- return make_scoped_ptr<syncer::SyncChangeProcessor>(
- new PasswordStoreDataVerifier::TestSyncChangeProcessor(verifier()));
- }
-
- // Sets the data that will be returned to the caller accessing password store.
- void SetPasswordStoreData(
- const std::vector<autofill::PasswordForm*>& forms,
- const std::vector<autofill::PasswordForm*>& blacklist_forms) {
- EXPECT_CALL(*password_store_, FillAutofillableLogins(_))
- .WillOnce(Invoke(AppendVector(forms)))
- .RetiresOnSaturation();
- EXPECT_CALL(*password_store_, FillBlacklistLogins(_))
- .WillOnce(Invoke(AppendVector(blacklist_forms)))
- .RetiresOnSaturation();
- }
-
- protected:
- scoped_refptr<MockPasswordStore> password_store_;
- scoped_ptr<MockPasswordSyncableService> service_;
- PasswordStoreDataVerifier verifier_;
-
- private:
- struct AppendVector {
- explicit AppendVector(
- const std::vector<autofill::PasswordForm*>& append_forms)
- : append_forms_(append_forms) {
- }
-
- ~AppendVector() {}
-
- bool operator()(std::vector<autofill::PasswordForm*>* forms) const {
- forms->insert(forms->end(), append_forms_.begin(), append_forms_.end());
- return true;
- }
-
- std::vector<autofill::PasswordForm*> append_forms_;
- };
-
- DISALLOW_COPY_AND_ASSIGN(PasswordSyncableServiceWrapper);
-};
-
-class PasswordSyncableServiceTest : public testing::Test,
- public PasswordSyncableServiceWrapper {
- public:
- PasswordSyncableServiceTest() {}
- virtual ~PasswordSyncableServiceTest() {}
-};
-
-
-// Both sync and password db have data that are not present in the other.
-TEST_F(PasswordSyncableServiceTest, AdditionsInBoth) {
- scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
- form1->signon_realm = "abc";
- std::vector<autofill::PasswordForm*> forms;
- forms.push_back(form1.release());
- SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
-
- SyncData sync_data = CreateSyncData("def");
- SyncDataList list;
- list.push_back(sync_data);
-
- verifier()->SetExpectedDBChanges(list,
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
- verifier()->SetExpectedSyncChanges(
- SyncChangeList(1, CreateSyncChange(*forms[0], SyncChange::ACTION_ADD)));
- EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
-
- service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
- list,
- CreateSyncChangeProcessor(),
- scoped_ptr<syncer::SyncErrorFactory>());
-}
-
-// Sync has data that is not present in the password db.
-TEST_F(PasswordSyncableServiceTest, AdditionOnlyInSync) {
- SetPasswordStoreData(std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>());
-
- SyncData sync_data = CreateSyncData("def");
- SyncDataList list;
- list.push_back(sync_data);
-
- verifier()->SetExpectedDBChanges(list,
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
- verifier()->SetExpectedSyncChanges(SyncChangeList());
- EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
-
- service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
- list,
- CreateSyncChangeProcessor(),
- scoped_ptr<syncer::SyncErrorFactory>());
-}
-
-// Passwords db has data that is not present in sync.
-TEST_F(PasswordSyncableServiceTest, AdditionOnlyInPasswordStore) {
- scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
- form1->signon_realm = "abc";
- std::vector<autofill::PasswordForm*> forms;
- forms.push_back(form1.release());
- SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
-
- verifier()->SetExpectedDBChanges(SyncDataList(),
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
- verifier()->SetExpectedSyncChanges(
- SyncChangeList(1, CreateSyncChange(*forms[0], SyncChange::ACTION_ADD)));
- EXPECT_CALL(*service_,
- NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
-
- service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
- SyncDataList(),
- CreateSyncChangeProcessor(),
- scoped_ptr<syncer::SyncErrorFactory>());
-}
-
-// Both passwords db and sync contain the same data.
-TEST_F(PasswordSyncableServiceTest, BothInSync) {
- scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
- form1->signon_realm = "abc";
- std::vector<autofill::PasswordForm*> forms;
- forms.push_back(form1.release());
- SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
-
- verifier()->SetExpectedDBChanges(SyncDataList(),
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
- verifier()->SetExpectedSyncChanges(SyncChangeList());
- EXPECT_CALL(*service_,
- NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
-
- service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
- SyncDataList(1, CreateSyncData("abc")),
- CreateSyncChangeProcessor(),
- scoped_ptr<syncer::SyncErrorFactory>());
-}
-
-// Both passwords db and sync have the same data but they need to be merged
-// as some fields of the data differ.
-TEST_F(PasswordSyncableServiceTest, Merge) {
- scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
- form1->signon_realm = "abc";
- form1->action = GURL("http://pie.com");
- form1->date_created = base::Time::Now();
- std::vector<autofill::PasswordForm*> forms;
- forms.push_back(form1.release());
- SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
-
- verifier()->SetExpectedDBChanges(SyncDataList(),
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
- verifier()->SetExpectedSyncChanges(
- SyncChangeList(1, CreateSyncChange(*forms[0],
- SyncChange::ACTION_UPDATE)));
-
- EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
-
- service()->MergeDataAndStartSyncing(syncer::PASSWORDS,
- SyncDataList(1, CreateSyncData("abc")),
- CreateSyncChangeProcessor(),
- scoped_ptr<syncer::SyncErrorFactory>());
-}
-
-// Initiate sync due to local DB changes.
-TEST_F(PasswordSyncableServiceTest, PasswordStoreChanges) {
- // Set the sync change processor first.
- SetPasswordStoreData(std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>());
- verifier()->SetExpectedSyncChanges(SyncChangeList());
- EXPECT_CALL(*service_,
- NotifyPasswordStoreOfLoginChanges(PasswordStoreChangeList()));
- service_->MergeDataAndStartSyncing(syncer::PASSWORDS,
- SyncDataList(),
- CreateSyncChangeProcessor(),
- scoped_ptr<syncer::SyncErrorFactory>());
-
- autofill::PasswordForm form1;
- form1.signon_realm = "abc";
- autofill::PasswordForm form2;
- form2.signon_realm = "def";
- autofill::PasswordForm form3;
- form3.signon_realm = "xyz";
-
- SyncChangeList sync_list;
- sync_list.push_back(CreateSyncChange(form1, SyncChange::ACTION_ADD));
- sync_list.push_back(CreateSyncChange(form2, SyncChange::ACTION_UPDATE));
- sync_list.push_back(CreateSyncChange(form3, SyncChange::ACTION_DELETE));
-
- verifier()->SetExpectedDBChanges(SyncDataList(),
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
- verifier()->SetExpectedSyncChanges(sync_list);
-
- PasswordStoreChangeList list;
- list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form1));
- list.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form2));
- list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form3));
- service()->ActOnPasswordStoreChanges(list);
-}
-
-// Process all types of changes from sync.
-TEST_F(PasswordSyncableServiceTest, ProcessSyncChanges) {
- scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
- form1->signon_realm = "abc";
- form1->action = GURL("http://foo.com");
- scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm);
- form2->signon_realm = "xyz";
- form2->action = GURL("http://bar.com");
- form2->date_created = base::Time::Now();
- form2->blacklisted_by_user = true;
- std::vector<autofill::PasswordForm*> forms(1, form1.release());
- std::vector<autofill::PasswordForm*> blacklist_forms(1, form2.release());
- SetPasswordStoreData(forms, blacklist_forms);
-
- SyncData add_data = CreateSyncData("def");
- autofill::PasswordForm updated_form = *forms[0];
- updated_form.date_created = base::Time::Now();
- std::vector<autofill::PasswordForm*> updated_passwords(1, &updated_form);
- std::vector<autofill::PasswordForm*> deleted_passwords(1, blacklist_forms[0]);
- verifier()->SetExpectedDBChanges(SyncDataList(1, add_data),
- updated_passwords,
- deleted_passwords,
- password_store());
-
- SyncChangeList list;
- list.push_back(SyncChange(FROM_HERE,
- syncer::SyncChange::ACTION_ADD,
- add_data));
- list.push_back(SyncChange(FROM_HERE,
- syncer::SyncChange::ACTION_UPDATE,
- SyncDataFromPassword(updated_form)));
- list.push_back(CreateSyncChange(*blacklist_forms[0],
- syncer::SyncChange::ACTION_DELETE));
- EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
- service()->ProcessSyncChanges(FROM_HERE, list);
-}
-
-// Retrives sync data from the model.
-TEST_F(PasswordSyncableServiceTest, GetAllSyncData) {
- scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
- form1->signon_realm = "abc";
- form1->action = GURL("http://foo.com");
- scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm);
- form2->signon_realm = "xyz";
- form2->action = GURL("http://bar.com");
- form2->blacklisted_by_user = true;
- std::vector<autofill::PasswordForm*> forms(1, form1.release());
- std::vector<autofill::PasswordForm*> blacklist_forms(1, form2.release());
- SetPasswordStoreData(forms, blacklist_forms);
-
- SyncDataList expected_list;
- expected_list.push_back(SyncDataFromPassword(*forms[0]));
- expected_list.push_back(SyncDataFromPassword(*blacklist_forms[0]));
-
- verifier()->SetExpectedDBChanges(SyncDataList(),
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
-
- SyncDataList actual_list = service()->GetAllSyncData(syncer::PASSWORDS);
- EXPECT_EQ(expected_list.size(), actual_list.size());
- for (SyncDataList::iterator i(actual_list.begin()), j(expected_list.begin());
- i != actual_list.end() && j != expected_list.end(); ++i, ++j) {
- PasswordsEqual(GetPasswordSpecifics(*j), GetPasswordSpecifics(*i));
- }
-}
-
-// Creates 2 PasswordSyncableService instances, merges the content of the first
-// one to the second one and back.
-TEST_F(PasswordSyncableServiceTest, MergeDataAndPushBack) {
- scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
- form1->signon_realm = "abc";
- form1->action = GURL("http://foo.com");
- std::vector<autofill::PasswordForm*> forms(1, form1.release());
- SetPasswordStoreData(forms, std::vector<autofill::PasswordForm*>());
-
- PasswordSyncableServiceWrapper other_service_wrapper;
- scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm);
- form2->signon_realm = "xyz";
- form2->action = GURL("http://bar.com");
- syncer::SyncData form2_sync_data = SyncDataFromPassword(*form2);
- other_service_wrapper.SetPasswordStoreData(
- std::vector<autofill::PasswordForm*>(1, form2.release()),
- std::vector<autofill::PasswordForm*>());
-
- verifier()->SetExpectedDBChanges(SyncDataList(1, form2_sync_data),
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- password_store());
- other_service_wrapper.verifier()->SetExpectedDBChanges(
- SyncDataList(1, SyncDataFromPassword(*forms[0])),
- std::vector<autofill::PasswordForm*>(),
- std::vector<autofill::PasswordForm*>(),
- other_service_wrapper.password_store());
- EXPECT_CALL(*service(), NotifyPasswordStoreOfLoginChanges(_));
- EXPECT_CALL(*other_service_wrapper.service(),
- NotifyPasswordStoreOfLoginChanges(_));
-
- syncer::SyncDataList other_service_data =
- other_service_wrapper.service()->GetAllSyncData(syncer::PASSWORDS);
- service()->MergeDataAndStartSyncing(
- syncer::PASSWORDS,
- other_service_data,
- other_service_wrapper.ReleaseSyncableService(),
- scoped_ptr<syncer::SyncErrorFactory>());
-}
-
-} // namespace