| Index: components/password_manager/core/browser/form_saver_impl_unittest.cc
|
| diff --git a/components/password_manager/core/browser/form_saver_impl_unittest.cc b/components/password_manager/core/browser/form_saver_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..00760834d0e848d8c1b2c6b6f4c4b6cb2f804a6a
|
| --- /dev/null
|
| +++ b/components/password_manager/core/browser/form_saver_impl_unittest.cc
|
| @@ -0,0 +1,504 @@
|
| +// Copyright 2016 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 "components/password_manager/core/browser/form_saver_impl.h"
|
| +
|
| +#include <set>
|
| +#include <vector>
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "components/autofill/core/common/password_form.h"
|
| +#include "components/password_manager/core/browser/mock_password_store.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "url/gurl.h"
|
| +
|
| +using autofill::PasswordForm;
|
| +using autofill::PasswordFormMap;
|
| +using base::ASCIIToUTF16;
|
| +using base::WrapUnique;
|
| +using testing::_;
|
| +using testing::DoAll;
|
| +using testing::SaveArg;
|
| +using testing::StrictMock;
|
| +
|
| +namespace password_manager {
|
| +
|
| +namespace {
|
| +
|
| +// Creates a dummy observed form with some basic arbitrary values.
|
| +PasswordForm CreateObserved() {
|
| + PasswordForm form;
|
| + form.origin = GURL("https://example.in");
|
| + form.signon_realm = form.origin.spec();
|
| + form.action = GURL("https://login.example.org");
|
| + return form;
|
| +}
|
| +
|
| +// Creates a dummy pending (for saving) form with some basic arbitrary values
|
| +// and |username| and |password| values as specified.
|
| +PasswordForm CreatePending(const char* username, const char* password) {
|
| + PasswordForm form = CreateObserved();
|
| + form.username_value = ASCIIToUTF16(username);
|
| + form.password_value = ASCIIToUTF16(password);
|
| + form.preferred = true;
|
| + return form;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class FormSaverImplTest : public testing::Test {
|
| + public:
|
| + FormSaverImplTest()
|
| + : mock_store_(new StrictMock<MockPasswordStore>()),
|
| + form_saver_(mock_store_.get()) {}
|
| +
|
| + ~FormSaverImplTest() override { mock_store_->ShutdownOnUIThread(); }
|
| +
|
| + protected:
|
| + base::MessageLoop message_loop_; // For the MockPasswordStore.
|
| + scoped_refptr<StrictMock<MockPasswordStore>> mock_store_;
|
| + FormSaverImpl form_saver_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(FormSaverImplTest);
|
| +};
|
| +
|
| +// Check that blacklisting an observed form sets the right properties and calls
|
| +// the PasswordStore.
|
| +TEST_F(FormSaverImplTest, PermanentlyBlacklist) {
|
| + PasswordForm observed = CreateObserved();
|
| + PasswordForm saved;
|
| +
|
| + observed.blacklisted_by_user = false;
|
| + observed.preferred = true;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + form_saver_.PermanentlyBlacklist(&observed);
|
| + EXPECT_TRUE(saved.blacklisted_by_user);
|
| + EXPECT_FALSE(saved.preferred);
|
| +}
|
| +
|
| +// Check that saving the pending form as new adds the credential to the store
|
| +// (rather than updating).
|
| +TEST_F(FormSaverImplTest, Save_AsNew) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + form_saver_.Save(pending, true, PasswordFormMap(), nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| +}
|
| +
|
| +// Check that saving the pending form as not new updates the store with the
|
| +// credential.
|
| +TEST_F(FormSaverImplTest, Save_Update) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + form_saver_.Save(pending, false, PasswordFormMap(), nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| +}
|
| +
|
| +// Check that passing other credentials to update to the Save call results in
|
| +// the store being updated with those credentials in addition to the pending
|
| +// one.
|
| +TEST_F(FormSaverImplTest, Save_UpdateAlsoOtherCredentials) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| + PasswordForm related1 = pending;
|
| + related1.origin = GURL("https://other.example.ca");
|
| + related1.signon_realm = related1.origin.spec();
|
| + PasswordForm related2 = pending;
|
| + related2.origin = GURL("http://complete.example.net");
|
| + related2.signon_realm = related2.origin.spec();
|
| + std::vector<const autofill::PasswordForm*> credentials_to_update = {
|
| + &related1, &related2};
|
| + pending.password_value = ASCIIToUTF16("abcd");
|
| +
|
| + PasswordForm saved[3];
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_))
|
| + .WillOnce(SaveArg<0>(&saved[0]))
|
| + .WillOnce(SaveArg<0>(&saved[1]))
|
| + .WillOnce(SaveArg<0>(&saved[2]));
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + form_saver_.Save(pending, false, PasswordFormMap(), &credentials_to_update,
|
| + nullptr);
|
| + std::set<GURL> different_origins;
|
| + for (const PasswordForm& form : saved) {
|
| + different_origins.insert(form.origin);
|
| + }
|
| + EXPECT_THAT(different_origins,
|
| + testing::UnorderedElementsAre(pending.origin, related1.origin,
|
| + related2.origin));
|
| +}
|
| +
|
| +// Check that if the old primary key is supplied, the appropriate store method
|
| +// for update is used.
|
| +TEST_F(FormSaverImplTest, Save_UpdateWithPrimaryKey) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| + PasswordForm old_key = pending;
|
| + old_key.username_value = ASCIIToUTF16("old username");
|
| + PasswordForm saved_new;
|
| + PasswordForm saved_old;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&saved_new), SaveArg<1>(&saved_old)));
|
| + form_saver_.Save(pending, false, PasswordFormMap(), nullptr, &old_key);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved_new.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved_new.password_value);
|
| + EXPECT_EQ(ASCIIToUTF16("old username"), saved_old.username_value);
|
| +}
|
| +
|
| +// Check that the "preferred" bit of best matches is updated accordingly in the
|
| +// store.
|
| +TEST_F(FormSaverImplTest, Save_AndUpdatePreferredLoginState) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| + pending.preferred = true;
|
| +
|
| + // |best_matches| will contain two forms: one non-PSL matched with a username
|
| + // different from the pending one, and one PSL-matched with a username same
|
| + // as the pending one, both marked as "preferred". FormSaver should ignore
|
| + // the pending and PSL-matched one, but should update the non-PSL matched
|
| + // form (with different username) to no longer be preferred.
|
| + PasswordFormMap best_matches;
|
| + PasswordForm other = pending;
|
| + other.username_value = ASCIIToUTF16("othername");
|
| + best_matches[other.username_value] = WrapUnique(new PasswordForm(other));
|
| + PasswordForm psl_match = pending;
|
| + psl_match.is_public_suffix_match = true;
|
| + best_matches[psl_match.username_value] =
|
| + WrapUnique(new PasswordForm(psl_match));
|
| +
|
| + PasswordForm saved;
|
| + PasswordForm updated;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).WillOnce(SaveArg<0>(&updated));
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + form_saver_.Save(pending, true, best_matches, nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| + EXPECT_TRUE(saved.preferred);
|
| + EXPECT_FALSE(saved.is_public_suffix_match);
|
| + EXPECT_EQ(ASCIIToUTF16("othername"), updated.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), updated.password_value);
|
| + EXPECT_FALSE(updated.preferred);
|
| + EXPECT_FALSE(updated.is_public_suffix_match);
|
| +}
|
| +
|
| +// Check that storing credentials with a non-empty username results in deleting
|
| +// credentials with the same password but no username, if present in best
|
| +// matches.
|
| +TEST_F(FormSaverImplTest, Save_AndDeleteEmptyUsernameCredentials) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + PasswordFormMap best_matches;
|
| + best_matches[pending.username_value] = WrapUnique(new PasswordForm(pending));
|
| + PasswordForm no_username = pending;
|
| + no_username.username_value.clear();
|
| + no_username.preferred = false;
|
| + best_matches[no_username.username_value] =
|
| + WrapUnique(new PasswordForm(no_username));
|
| +
|
| + PasswordForm saved;
|
| + PasswordForm removed;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).WillOnce(SaveArg<0>(&removed));
|
| + form_saver_.Save(pending, true, best_matches, nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| + EXPECT_TRUE(removed.username_value.empty());
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), removed.password_value);
|
| +}
|
| +
|
| +// Check that storing credentials with a non-empty username does not result in
|
| +// deleting credentials with a different password, even if they have no
|
| +// username.
|
| +TEST_F(FormSaverImplTest,
|
| + Save_AndDoNotDeleteEmptyUsernameCredentialsWithDifferentPassword) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + PasswordFormMap best_matches;
|
| + best_matches[pending.username_value] = WrapUnique(new PasswordForm(pending));
|
| + PasswordForm no_username = pending;
|
| + no_username.username_value.clear();
|
| + no_username.preferred = false;
|
| + no_username.password_value = ASCIIToUTF16("abcd");
|
| + best_matches[no_username.username_value] =
|
| + WrapUnique(new PasswordForm(no_username));
|
| +
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).Times(0);
|
| + form_saver_.Save(pending, true, best_matches, nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| +}
|
| +
|
| +// Check that if both "abc"/"pwd" and ""/"pwd" are both stored, and "abc"/"pwd"
|
| +// is updated to "abc"/"def", then ""/"pwd" is not deleted.
|
| +TEST_F(FormSaverImplTest,
|
| + Save_DoNotDeleteUsernamelessOnUpdatingPasswordWithUsername) {
|
| + PasswordForm pending = CreatePending("abc", "pwd");
|
| +
|
| + PasswordFormMap best_matches;
|
| + best_matches[pending.username_value] = WrapUnique(new PasswordForm(pending));
|
| + PasswordForm no_username = pending;
|
| + no_username.username_value.clear();
|
| + no_username.preferred = false;
|
| + best_matches[no_username.username_value] =
|
| + WrapUnique(new PasswordForm(no_username));
|
| +
|
| + pending.password_value = ASCIIToUTF16("def");
|
| +
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).Times(0);
|
| + form_saver_.Save(pending, true, best_matches, nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("abc"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("def"), saved.password_value);
|
| +}
|
| +
|
| +// Check that if a credential without username is saved, and another credential
|
| +// with the same password (and a non-empty username) is present in best matches,
|
| +// nothing is deleted.
|
| +TEST_F(FormSaverImplTest, Save_EmptyUsernameWillNotCauseDeletion) {
|
| + PasswordForm pending = CreatePending("", "wordToP4a55");
|
| +
|
| + PasswordFormMap best_matches;
|
| + PasswordForm with_username = pending;
|
| + with_username.username_value = ASCIIToUTF16("nameofuser");
|
| + with_username.preferred = false;
|
| + best_matches[with_username.username_value] =
|
| + WrapUnique(new PasswordForm(with_username));
|
| +
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).Times(0);
|
| + form_saver_.Save(pending, true, best_matches, nullptr, nullptr);
|
| + EXPECT_TRUE(saved.username_value.empty());
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| +}
|
| +
|
| +// Check that PSL-matched credentials in best matches are exempt from deletion,
|
| +// even if they have an empty username and the same password as the pending
|
| +// credential.
|
| +TEST_F(FormSaverImplTest, Save_AndDoNotDeleteEmptyUsernamePSLCredentials) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + PasswordFormMap best_matches;
|
| + best_matches[pending.username_value] = WrapUnique(new PasswordForm(pending));
|
| + PasswordForm no_username_psl = pending;
|
| + no_username_psl.username_value.clear();
|
| + no_username_psl.is_public_suffix_match = true;
|
| + best_matches[no_username_psl.username_value] =
|
| + WrapUnique(new PasswordForm(no_username_psl));
|
| +
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).Times(0);
|
| + form_saver_.Save(pending, true, best_matches, nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| +}
|
| +
|
| +// Check that on storing a credential, other credentials with the same password
|
| +// are not removed, as long as they have a non-empty username.
|
| +TEST_F(FormSaverImplTest, Save_AndDoNotDeleteNonEmptyUsernameCredentials) {
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + PasswordFormMap best_matches;
|
| + best_matches[pending.username_value] = WrapUnique(new PasswordForm(pending));
|
| + PasswordForm other_username = pending;
|
| + other_username.username_value = ASCIIToUTF16("other username");
|
| + other_username.preferred = false;
|
| + best_matches[other_username.username_value] =
|
| + WrapUnique(new PasswordForm(other_username));
|
| +
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).Times(0);
|
| + form_saver_.Save(pending, true, best_matches, nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| +}
|
| +
|
| +// Check that presaving a password for the first time results in adding it.
|
| +TEST_F(FormSaverImplTest, PresaveGeneratedPassword_New) {
|
| + PasswordForm generated = CreatePending("nameofuser", "wordToP4a55");
|
| + PasswordForm saved;
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved.password_value);
|
| +}
|
| +
|
| +// Check that presaving a password for the second time results in updating it.
|
| +TEST_F(FormSaverImplTest, PresaveGeneratedPassword_Replace) {
|
| + PasswordForm generated = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| +
|
| + generated.password_value = ASCIIToUTF16("newgenpwd");
|
| + PasswordForm saved_new;
|
| + PasswordForm saved_old;
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&saved_new), SaveArg<1>(&saved_old)));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved_old.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved_old.password_value);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved_new.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("newgenpwd"), saved_new.password_value);
|
| +}
|
| +
|
| +// Check that presaving a password followed by a call to save a pending
|
| +// credential (as new) results in replacing the presaved password with the
|
| +// pending one.
|
| +TEST_F(FormSaverImplTest, PresaveGeneratedPassword_ThenSaveAsNew) {
|
| + PasswordForm generated = CreatePending("generatedU", "generatedP");
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| +
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| + PasswordForm saved_new;
|
| + PasswordForm saved_old;
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&saved_new), SaveArg<1>(&saved_old)));
|
| + form_saver_.Save(pending, true, PasswordFormMap(), nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("generatedU"), saved_old.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("generatedP"), saved_old.password_value);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved_new.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved_new.password_value);
|
| +}
|
| +
|
| +// Check that presaving a password followed by a call to save a pending
|
| +// credential (as update) results in replacing the presaved password with the
|
| +// pending one.
|
| +TEST_F(FormSaverImplTest, PresaveGeneratedPassword_ThenUpdate) {
|
| + PasswordForm generated = CreatePending("generatedU", "generatedP");
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| +
|
| + PasswordForm pending = CreatePending("nameofuser", "wordToP4a55");
|
| + PasswordForm saved_new;
|
| + PasswordForm saved_old;
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&saved_new), SaveArg<1>(&saved_old)));
|
| + form_saver_.Save(pending, false, PasswordFormMap(), nullptr, nullptr);
|
| + EXPECT_EQ(ASCIIToUTF16("generatedU"), saved_old.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("generatedP"), saved_old.password_value);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved_new.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved_new.password_value);
|
| +}
|
| +
|
| +// Check that presaving a password for the third time results in updating it.
|
| +TEST_F(FormSaverImplTest, PresaveGeneratedPassword_ReplaceTwice) {
|
| + PasswordForm generated = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| +
|
| + generated.password_value = ASCIIToUTF16("newgenpwd");
|
| + PasswordForm saved_new;
|
| + PasswordForm saved_old;
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&saved_new), SaveArg<1>(&saved_old)));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved_old.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), saved_old.password_value);
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), saved_new.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("newgenpwd"), saved_new.password_value);
|
| +}
|
| +
|
| +// Check that removing a presaved password is a no-op if none was presaved.
|
| +TEST_F(FormSaverImplTest, RemovePresavedPassword_NonePresaved) {
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).Times(0);
|
| + form_saver_.RemovePresavedPassword();
|
| +}
|
| +
|
| +// Check that removing a presaved password removes the presaved password.
|
| +TEST_F(FormSaverImplTest, RemovePresavedPassword) {
|
| + PasswordForm generated = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| +
|
| + PasswordForm removed;
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_)).WillOnce(SaveArg<0>(&removed));
|
| + form_saver_.RemovePresavedPassword();
|
| + EXPECT_EQ(ASCIIToUTF16("nameofuser"), removed.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("wordToP4a55"), removed.password_value);
|
| +}
|
| +
|
| +// Check that removing the presaved password and then presaving again results in
|
| +// adding the second presaved password as new.
|
| +TEST_F(FormSaverImplTest, RemovePresavedPassword_AndPresaveAgain) {
|
| + PasswordForm generated = CreatePending("nameofuser", "wordToP4a55");
|
| +
|
| + EXPECT_CALL(*mock_store_, AddLogin(_));
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| +
|
| + EXPECT_CALL(*mock_store_, RemoveLogin(_));
|
| + form_saver_.RemovePresavedPassword();
|
| +
|
| + PasswordForm saved;
|
| + generated.username_value = ASCIIToUTF16("newgen");
|
| + generated.password_value = ASCIIToUTF16("newgenpwd");
|
| + EXPECT_CALL(*mock_store_, AddLogin(_)).WillOnce(SaveArg<0>(&saved));
|
| + EXPECT_CALL(*mock_store_, UpdateLogin(_)).Times(0);
|
| + EXPECT_CALL(*mock_store_, UpdateLoginWithPrimaryKey(_, _)).Times(0);
|
| + form_saver_.PresaveGeneratedPassword(generated);
|
| + EXPECT_EQ(ASCIIToUTF16("newgen"), saved.username_value);
|
| + EXPECT_EQ(ASCIIToUTF16("newgenpwd"), saved.password_value);
|
| +}
|
| +
|
| +} // namespace password_manager
|
|
|