// 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 "components/password_manager/core/browser/login_database.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <utility>

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/common/password_form.h"
#include "components/os_crypt/os_crypt.h"
#include "components/os_crypt/os_crypt_mocker.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/psl_matching_helper.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "sql/database.h"
#include "sql/statement.h"
#include "sql/test/test_helpers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h"

using autofill::PasswordForm;
using autofill::ValueElementPair;
using autofill::ValueElementVector;
using base::ASCIIToUTF16;
using ::testing::Eq;
using ::testing::Pointee;
using ::testing::UnorderedElementsAre;

namespace password_manager {
namespace {

PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) {
  return PasswordStoreChangeList(
      1, PasswordStoreChange(PasswordStoreChange::ADD, form));
}

PasswordStoreChangeList UpdateChangeForForm(const PasswordForm& form) {
  return PasswordStoreChangeList(
      1, PasswordStoreChange(PasswordStoreChange::UPDATE, form));
}

void GenerateExamplePasswordForm(PasswordForm* form) {
  form->origin = GURL("http://accounts.google.com/LoginAuth");
  form->action = GURL("http://accounts.google.com/Login");
  form->username_element = ASCIIToUTF16("Email");
  form->username_value = ASCIIToUTF16("test@gmail.com");
  form->password_element = ASCIIToUTF16("Passwd");
  form->password_value = ASCIIToUTF16("test");
  form->submit_element = ASCIIToUTF16("signIn");
  form->signon_realm = "http://www.google.com/";
  form->preferred = false;
  form->scheme = PasswordForm::SCHEME_HTML;
  form->times_used = 1;
  form->form_data.name = ASCIIToUTF16("form_name");
  form->date_synced = base::Time::Now();
  form->display_name = ASCIIToUTF16("Mr. Smith");
  form->icon_url = GURL("https://accounts.google.com/Icon");
  form->federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));
  form->skip_zero_click = true;
}

// Helper functions to read the value of the first column of an executed
// statement if we know its type. You must implement a specialization for
// every column type you use.
template<class T> struct must_be_specialized {
  static const bool is_specialized = false;
};

template<class T> T GetFirstColumn(const sql::Statement& s) {
  static_assert(must_be_specialized<T>::is_specialized,
                "Implement a specialization.");
}

template<> int64_t GetFirstColumn(const sql::Statement& s) {
  return s.ColumnInt64(0);
}

template<> std::string GetFirstColumn(const sql::Statement& s) {
  return s.ColumnString(0);
}

// Returns an empty vector on failure. Otherwise returns values in the column
// |column_name| of the logins table. The order of the
// returned rows is well-defined.
template <class T>
std::vector<T> GetColumnValuesFromDatabase(const base::FilePath& database_path,
                                           const std::string& column_name) {
  sql::Database db;
  std::vector<T> results;
  CHECK(db.Open(database_path));

  std::string statement = base::StringPrintf(
      "SELECT %s FROM logins ORDER BY username_value, %s DESC",
      column_name.c_str(), column_name.c_str());
  sql::Statement s(db.GetCachedStatement(SQL_FROM_HERE, statement.c_str()));
  EXPECT_TRUE(s.is_valid());

  while (s.Step())
    results.push_back(GetFirstColumn<T>(s));

  return results;
}

bool AddZeroClickableLogin(LoginDatabase* db,
                           const std::string& unique_string,
                           const GURL& origin) {
  // Example password form.
  PasswordForm form;
  form.origin = origin;
  form.username_element = ASCIIToUTF16(unique_string);
  form.username_value = ASCIIToUTF16(unique_string);
  form.password_element = ASCIIToUTF16(unique_string);
  form.submit_element = ASCIIToUTF16("signIn");
  form.signon_realm = form.origin.spec();
  form.display_name = ASCIIToUTF16(unique_string);
  form.icon_url = origin;
  form.federation_origin = url::Origin::Create(origin);
  form.date_created = base::Time::Now();

  form.skip_zero_click = false;

  return db->AddLogin(form) == AddChangeForForm(form);
}

MATCHER(IsGoogle1Account, "") {
  return arg.origin.spec() == "https://accounts.google.com/ServiceLogin" &&
         arg.action.spec() == "https://accounts.google.com/ServiceLoginAuth" &&
         arg.username_value == ASCIIToUTF16("theerikchen") &&
         arg.scheme == PasswordForm::SCHEME_HTML;
}

MATCHER(IsGoogle2Account, "") {
  return arg.origin.spec() == "https://accounts.google.com/ServiceLogin" &&
         arg.action.spec() == "https://accounts.google.com/ServiceLoginAuth" &&
         arg.username_value == ASCIIToUTF16("theerikchen2") &&
         arg.scheme == PasswordForm::SCHEME_HTML;
}

MATCHER(IsBasicAuthAccount, "") {
  return arg.scheme == PasswordForm::SCHEME_BASIC;
}

}  // namespace

// Serialization routines for vectors implemented in login_database.cc.
base::Pickle SerializeValueElementPairs(const ValueElementVector& vec);
ValueElementVector DeserializeValueElementPairs(const base::Pickle& pickle);

class LoginDatabaseTest : public testing::Test {
 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    file_ = temp_dir_.GetPath().AppendASCII("TestMetadataStoreMacDatabase");
    OSCryptMocker::SetUp();

    db_.reset(new LoginDatabase(file_));
    ASSERT_TRUE(db_->Init());
  }

  void TearDown() override { OSCryptMocker::TearDown(); }

  LoginDatabase& db() { return *db_; }

  void TestNonHTMLFormPSLMatching(const PasswordForm::Scheme& scheme) {
    std::vector<std::unique_ptr<PasswordForm>> result;

    base::Time now = base::Time::Now();

    // Simple non-html auth form.
    PasswordForm non_html_auth;
    non_html_auth.origin = GURL("http://example.com");
    non_html_auth.username_value = ASCIIToUTF16("test@gmail.com");
    non_html_auth.password_value = ASCIIToUTF16("test");
    non_html_auth.signon_realm = "http://example.com/Realm";
    non_html_auth.scheme = scheme;
    non_html_auth.date_created = now;

    // Simple password form.
    PasswordForm html_form(non_html_auth);
    html_form.action = GURL("http://example.com/login");
    html_form.username_element = ASCIIToUTF16("username");
    html_form.username_value = ASCIIToUTF16("test2@gmail.com");
    html_form.password_element = ASCIIToUTF16("password");
    html_form.submit_element = ASCIIToUTF16("");
    html_form.signon_realm = "http://example.com/";
    html_form.scheme = PasswordForm::SCHEME_HTML;
    html_form.date_created = now;

    // Add them and make sure they are there.
    EXPECT_EQ(AddChangeForForm(non_html_auth), db().AddLogin(non_html_auth));
    EXPECT_EQ(AddChangeForForm(html_form), db().AddLogin(html_form));
    EXPECT_TRUE(db().GetAutofillableLogins(&result));
    EXPECT_EQ(2U, result.size());
    result.clear();

    PasswordStore::FormDigest second_non_html_auth = {
        scheme, "http://second.example.com/Realm",
        GURL("http://second.example.com")};

    // This shouldn't match anything.
    EXPECT_TRUE(db().GetLogins(second_non_html_auth, &result));
    EXPECT_EQ(0U, result.size());

    // non-html auth still matches against itself.
    EXPECT_TRUE(
        db().GetLogins(PasswordStore::FormDigest(non_html_auth), &result));
    ASSERT_EQ(1U, result.size());
    EXPECT_EQ(result[0]->signon_realm, "http://example.com/Realm");

    // Clear state.
    db().RemoveLoginsCreatedBetween(now, base::Time(), /*changes=*/nullptr);
  }

  // Checks that a form of a given |scheme|, once stored, can be successfully
  // retrieved from the database.
  void TestRetrievingIPAddress(const PasswordForm::Scheme& scheme) {
    SCOPED_TRACE(testing::Message() << "scheme = " << scheme);
    std::vector<std::unique_ptr<PasswordForm>> result;

    base::Time now = base::Time::Now();
    std::string origin("http://56.7.8.90");

    PasswordForm ip_form;
    ip_form.origin = GURL(origin);
    ip_form.username_value = ASCIIToUTF16("test@gmail.com");
    ip_form.password_value = ASCIIToUTF16("test");
    ip_form.signon_realm = origin;
    ip_form.scheme = scheme;
    ip_form.date_created = now;

    EXPECT_EQ(AddChangeForForm(ip_form), db().AddLogin(ip_form));
    EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(ip_form), &result));
    ASSERT_EQ(1U, result.size());
    EXPECT_EQ(result[0]->signon_realm, origin);

    // Clear state.
    db().RemoveLoginsCreatedBetween(now, base::Time(), /*changes=*/nullptr);
  }

  base::ScopedTempDir temp_dir_;
  base::FilePath file_;
  std::unique_ptr<LoginDatabase> db_;
  base::test::ScopedTaskEnvironment scoped_task_environment_;
};

TEST_F(LoginDatabaseTest, Logins) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  // Example password form.
  PasswordForm form;
  GenerateExamplePasswordForm(&form);

  // Add it and make sure it is there and that all the fields were retrieved
  // correctly.
  PasswordStoreChangeList changes = db().AddLogin(form);
  ASSERT_EQ(AddChangeForForm(form), changes);
  EXPECT_EQ(1, changes[0].primary_key());
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  ASSERT_EQ(1U, result.size());
  EXPECT_EQ(form, *result[0]);
  result.clear();

  // Match against an exact copy.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  ASSERT_EQ(1U, result.size());
  EXPECT_EQ(form, *result[0]);
  result.clear();

  // The example site changes...
  PasswordForm form2(form);
  form2.origin = GURL("http://www.google.com/new/accounts/LoginAuth");
  form2.submit_element = ASCIIToUTF16("reallySignIn");

  // Match against an inexact copy
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // Uh oh, the site changed origin & action URLs all at once!
  PasswordForm form3(form2);
  form3.action = GURL("http://www.google.com/new/accounts/Login");

  // signon_realm is the same, should match.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form3), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // Imagine the site moves to a secure server for login.
  PasswordForm form4(form3);
  form4.signon_realm = "https://www.google.com/";

  // We have only an http record, so no match for this.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form4), &result));
  EXPECT_EQ(0U, result.size());

  // Let's imagine the user logs into the secure site.
  changes = db().AddLogin(form4);
  ASSERT_EQ(AddChangeForForm(form4), changes);
  EXPECT_EQ(2, changes[0].primary_key());
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(2U, result.size());
  result.clear();

  // Now the match works
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form4), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // The user chose to forget the original but not the new.
  EXPECT_TRUE(db().RemoveLogin(form, &changes));
  ASSERT_EQ(1U, changes.size());
  EXPECT_EQ(1, changes[0].primary_key());
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // The old form wont match the new site (http vs https).
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  EXPECT_EQ(0U, result.size());

  // User changes their password.
  PasswordForm form5(form4);
  form5.password_value = ASCIIToUTF16("test6");
  form5.preferred = true;

  // We update, and check to make sure it matches the
  // old form, and there is only one record.
  EXPECT_EQ(UpdateChangeForForm(form5), db().UpdateLogin(form5));
  // matches
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form5), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();
  // Only one record.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(1U, result.size());
  // Password element was updated.
  EXPECT_EQ(form5.password_value, result[0]->password_value);
  // Preferred login.
  EXPECT_TRUE(form5.preferred);
  result.clear();

  // Make sure everything can disappear.
  EXPECT_TRUE(db().RemoveLogin(form4, &changes));
  ASSERT_EQ(1U, changes.size());
  EXPECT_EQ(2, changes[0].primary_key());
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());
}

TEST_F(LoginDatabaseTest, AddLoginReturnsPrimaryKey) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  // Example password form.
  PasswordForm form;
  GenerateExamplePasswordForm(&form);

  // Add it and make sure the primary key is returned in the
  // PasswordStoreChange.
  PasswordStoreChangeList change_list = db().AddLogin(form);
  ASSERT_EQ(1U, change_list.size());
  EXPECT_EQ(AddChangeForForm(form), change_list);
  EXPECT_EQ(1, change_list[0].primary_key());
}

TEST_F(LoginDatabaseTest, RemoveLoginsById) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  // Example password form.
  PasswordForm form;
  GenerateExamplePasswordForm(&form);

  // Add it and make sure it is there and that all the fields were retrieved
  // correctly.
  PasswordStoreChangeList change_list = db().AddLogin(form);
  ASSERT_EQ(1U, change_list.size());
  int id = change_list[0].primary_key();
  EXPECT_EQ(AddChangeForForm(form), change_list);
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  ASSERT_EQ(1U, result.size());
  EXPECT_EQ(form, *result[0]);
  result.clear();

  EXPECT_TRUE(db().RemoveLoginById(id));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());
}

TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatching) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  // Example password form.
  PasswordForm form;
  form.origin = GURL("https://foo.com/");
  form.action = GURL("https://foo.com/login");
  form.username_element = ASCIIToUTF16("username");
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.password_element = ASCIIToUTF16("password");
  form.password_value = ASCIIToUTF16("test");
  form.submit_element = ASCIIToUTF16("");
  form.signon_realm = "https://foo.com/";
  form.preferred = false;
  form.scheme = PasswordForm::SCHEME_HTML;

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // Match against an exact copy.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // We go to the mobile site.
  PasswordForm form2(form);
  form2.origin = GURL("https://mobile.foo.com/");
  form2.action = GURL("https://mobile.foo.com/login");
  form2.signon_realm = "https://mobile.foo.com/";

  // Match against the mobile site.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  EXPECT_EQ("https://foo.com/", result[0]->signon_realm);
  EXPECT_TRUE(result[0]->is_public_suffix_match);

  // Try to remove PSL matched form
  EXPECT_FALSE(db().RemoveLogin(*result[0], /*changes=*/nullptr));
  result.clear();
  // Ensure that the original form is still there
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();
}

TEST_F(LoginDatabaseTest, TestFederatedMatching) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Example password form.
  PasswordForm form;
  form.origin = GURL("https://foo.com/");
  form.action = GURL("https://foo.com/login");
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.password_value = ASCIIToUTF16("test");
  form.signon_realm = "https://foo.com/";
  form.preferred = false;
  form.scheme = PasswordForm::SCHEME_HTML;

  // We go to the mobile site.
  PasswordForm form2(form);
  form2.origin = GURL("https://mobile.foo.com/");
  form2.action = GURL("https://mobile.foo.com/login");
  form2.signon_realm = "federation://mobile.foo.com/accounts.google.com";
  form2.username_value = ASCIIToUTF16("test1@gmail.com");
  form2.type = PasswordForm::TYPE_API;
  form2.federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_EQ(AddChangeForForm(form2), db().AddLogin(form2));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(2U, result.size());

  // Match against desktop.
  PasswordStore::FormDigest form_request = {
      PasswordForm::SCHEME_HTML, "https://foo.com/", GURL("https://foo.com/")};
  EXPECT_TRUE(db().GetLogins(form_request, &result));
  // Both forms are matched, only form2 is a PSL match.
  form.is_public_suffix_match = false;
  form2.is_public_suffix_match = true;
  EXPECT_THAT(result, UnorderedElementsAre(Pointee(form), Pointee(form2)));

  // Match against the mobile site.
  form_request.origin = GURL("https://mobile.foo.com/");
  form_request.signon_realm = "https://mobile.foo.com/";
  EXPECT_TRUE(db().GetLogins(form_request, &result));
  // Both forms are matched, only form is a PSL match.
  form.is_public_suffix_match = true;
  form2.is_public_suffix_match = false;
  EXPECT_THAT(result, UnorderedElementsAre(Pointee(form), Pointee(form2)));
}

TEST_F(LoginDatabaseTest, TestFederatedMatchingLocalhost) {
  PasswordForm form;
  form.origin = GURL("http://localhost/");
  form.signon_realm = "federation://localhost/accounts.google.com";
  form.federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.type = PasswordForm::TYPE_API;
  form.scheme = PasswordForm::SCHEME_HTML;

  PasswordForm form_with_port(form);
  form_with_port.origin = GURL("http://localhost:8080/");
  form_with_port.signon_realm = "federation://localhost/accounts.google.com";

  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_EQ(AddChangeForForm(form_with_port), db().AddLogin(form_with_port));

  // Match localhost with and without port.
  PasswordStore::FormDigest form_request(PasswordForm::SCHEME_HTML,
                                         "http://localhost/",
                                         GURL("http://localhost/"));
  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_TRUE(db().GetLogins(form_request, &result));
  EXPECT_THAT(result, UnorderedElementsAre(Pointee(form)));

  form_request.origin = GURL("http://localhost:8080/");
  form_request.signon_realm = "http://localhost:8080/";
  EXPECT_TRUE(db().GetLogins(form_request, &result));
  EXPECT_THAT(result, UnorderedElementsAre(Pointee(form_with_port)));
}

TEST_F(LoginDatabaseTest, TestPublicSuffixDisabledForNonHTMLForms) {
  TestNonHTMLFormPSLMatching(PasswordForm::SCHEME_BASIC);
  TestNonHTMLFormPSLMatching(PasswordForm::SCHEME_DIGEST);
  TestNonHTMLFormPSLMatching(PasswordForm::SCHEME_OTHER);
}

TEST_F(LoginDatabaseTest, TestIPAddressMatches_HTML) {
  TestRetrievingIPAddress(PasswordForm::SCHEME_HTML);
}

TEST_F(LoginDatabaseTest, TestIPAddressMatches_basic) {
  TestRetrievingIPAddress(PasswordForm::SCHEME_BASIC);
}

TEST_F(LoginDatabaseTest, TestIPAddressMatches_digest) {
  TestRetrievingIPAddress(PasswordForm::SCHEME_DIGEST);
}

TEST_F(LoginDatabaseTest, TestIPAddressMatches_other) {
  TestRetrievingIPAddress(PasswordForm::SCHEME_OTHER);
}

TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingShouldMatchingApply) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  // Example password form.
  PasswordForm form;
  form.origin = GURL("https://accounts.google.com/");
  form.action = GURL("https://accounts.google.com/login");
  form.username_element = ASCIIToUTF16("username");
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.password_element = ASCIIToUTF16("password");
  form.password_value = ASCIIToUTF16("test");
  form.submit_element = ASCIIToUTF16("");
  form.signon_realm = "https://accounts.google.com/";
  form.preferred = false;
  form.scheme = PasswordForm::SCHEME_HTML;

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // Match against an exact copy.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // We go to a different site on the same domain where feature is not needed.
  PasswordStore::FormDigest form2 = {PasswordForm::SCHEME_HTML,
                                     "https://some.other.google.com/",
                                     GURL("https://some.other.google.com/")};

  // Match against the other site. Should not match since feature should not be
  // enabled for this domain.
  ASSERT_FALSE(ShouldPSLDomainMatchingApply(
      GetRegistryControlledDomain(GURL(form2.signon_realm))));

  EXPECT_TRUE(db().GetLogins(form2, &result));
  EXPECT_EQ(0U, result.size());
}

TEST_F(LoginDatabaseTest, TestFederatedMatchingWithoutPSLMatching) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Example password form.
  PasswordForm form;
  form.origin = GURL("https://accounts.google.com/");
  form.action = GURL("https://accounts.google.com/login");
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.password_value = ASCIIToUTF16("test");
  form.signon_realm = "https://accounts.google.com/";
  form.preferred = false;
  form.scheme = PasswordForm::SCHEME_HTML;

  // We go to a different site on the same domain where PSL is disabled.
  PasswordForm form2(form);
  form2.origin = GURL("https://some.other.google.com/");
  form2.action = GURL("https://some.other.google.com/login");
  form2.signon_realm = "federation://some.other.google.com/accounts.google.com";
  form2.username_value = ASCIIToUTF16("test1@gmail.com");
  form2.type = PasswordForm::TYPE_API;
  form2.federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_EQ(AddChangeForForm(form2), db().AddLogin(form2));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(2U, result.size());

  // Match against the first one.
  PasswordStore::FormDigest form_request = {PasswordForm::SCHEME_HTML,
                                            form.signon_realm, form.origin};
  EXPECT_TRUE(db().GetLogins(form_request, &result));
  EXPECT_THAT(result, testing::ElementsAre(Pointee(form)));

  // Match against the second one.
  ASSERT_FALSE(ShouldPSLDomainMatchingApply(
      GetRegistryControlledDomain(GURL(form2.signon_realm))));
  form_request.origin = form2.origin;
  form_request.signon_realm = form2.signon_realm;
  EXPECT_TRUE(db().GetLogins(form_request, &result));
  form.is_public_suffix_match = true;
  EXPECT_THAT(result, testing::ElementsAre(Pointee(form2)));
}

TEST_F(LoginDatabaseTest, TestFederatedPSLMatching) {
  // Save a federated credential for the PSL matched site.
  PasswordForm form;
  form.origin = GURL("https://psl.example.com/");
  form.action = GURL("https://psl.example.com/login");
  form.signon_realm = "federation://psl.example.com/accounts.google.com";
  form.username_value = ASCIIToUTF16("test1@gmail.com");
  form.type = PasswordForm::TYPE_API;
  form.federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));
  form.scheme = PasswordForm::SCHEME_HTML;
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));

  // Match against.
  PasswordStore::FormDigest form_request = {PasswordForm::SCHEME_HTML,
                                            "https://example.com/",
                                            GURL("https://example.com/login")};
  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_TRUE(db().GetLogins(form_request, &result));
  form.is_public_suffix_match = true;
  EXPECT_THAT(result, testing::ElementsAre(Pointee(form)));
}

// This test fails if the implementation of GetLogins uses GetCachedStatement
// instead of GetUniqueStatement, since REGEXP is in use. See
// http://crbug.com/248608.
TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingDifferentSites) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  // Example password form.
  PasswordForm form;
  form.origin = GURL("https://foo.com/");
  form.action = GURL("https://foo.com/login");
  form.username_element = ASCIIToUTF16("username");
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.password_element = ASCIIToUTF16("password");
  form.password_value = ASCIIToUTF16("test");
  form.submit_element = ASCIIToUTF16("");
  form.signon_realm = "https://foo.com/";
  form.preferred = false;
  form.scheme = PasswordForm::SCHEME_HTML;

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // Match against an exact copy.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // We go to the mobile site.
  PasswordStore::FormDigest form2(form);
  form2.origin = GURL("https://mobile.foo.com/");
  form2.signon_realm = "https://mobile.foo.com/";

  // Match against the mobile site.
  EXPECT_TRUE(db().GetLogins(form2, &result));
  EXPECT_EQ(1U, result.size());
  EXPECT_EQ("https://foo.com/", result[0]->signon_realm);
  EXPECT_TRUE(result[0]->is_public_suffix_match);
  result.clear();

  // Add baz.com desktop site.
  form.origin = GURL("https://baz.com/login/");
  form.action = GURL("https://baz.com/login/");
  form.username_element = ASCIIToUTF16("email");
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.password_element = ASCIIToUTF16("password");
  form.password_value = ASCIIToUTF16("test");
  form.submit_element = ASCIIToUTF16("");
  form.signon_realm = "https://baz.com/";
  form.preferred = false;
  form.scheme = PasswordForm::SCHEME_HTML;

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(2U, result.size());
  result.clear();

  // We go to the mobile site of baz.com.
  PasswordStore::FormDigest form3(form);
  form3.origin = GURL("https://m.baz.com/login/");
  form3.signon_realm = "https://m.baz.com/";

  // Match against the mobile site of baz.com.
  EXPECT_TRUE(db().GetLogins(form3, &result));
  EXPECT_EQ(1U, result.size());
  EXPECT_EQ("https://baz.com/", result[0]->signon_realm);
  EXPECT_TRUE(result[0]->is_public_suffix_match);
  result.clear();
}

PasswordForm GetFormWithNewSignonRealm(PasswordForm form,
                                       std::string signon_realm) {
  PasswordForm form2(form);
  form2.origin = GURL(signon_realm);
  form2.action = GURL(signon_realm);
  form2.signon_realm = signon_realm;
  return form2;
}

TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingRegexp) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  // Example password form.
  PasswordForm form;
  form.origin = GURL("http://foo.com/");
  form.action = GURL("http://foo.com/login");
  form.username_element = ASCIIToUTF16("username");
  form.username_value = ASCIIToUTF16("test@gmail.com");
  form.password_element = ASCIIToUTF16("password");
  form.password_value = ASCIIToUTF16("test");
  form.submit_element = ASCIIToUTF16("");
  form.signon_realm = "http://foo.com/";
  form.preferred = false;
  form.scheme = PasswordForm::SCHEME_HTML;

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // Example password form that has - in the domain name.
  PasswordForm form_dash =
      GetFormWithNewSignonRealm(form, "http://www.foo-bar.com/");

  // Add it and make sure it is there.
  EXPECT_EQ(AddChangeForForm(form_dash), db().AddLogin(form_dash));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(2U, result.size());
  result.clear();

  // Match against an exact copy.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // www.foo.com should match.
  PasswordForm form2 = GetFormWithNewSignonRealm(form, "http://www.foo.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // a.b.foo.com should match.
  form2 = GetFormWithNewSignonRealm(form, "http://a.b.foo.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // a-b.foo.com should match.
  form2 = GetFormWithNewSignonRealm(form, "http://a-b.foo.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // foo-bar.com should match.
  form2 = GetFormWithNewSignonRealm(form, "http://foo-bar.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // www.foo-bar.com should match.
  form2 = GetFormWithNewSignonRealm(form, "http://www.foo-bar.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // a.b.foo-bar.com should match.
  form2 = GetFormWithNewSignonRealm(form, "http://a.b.foo-bar.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // a-b.foo-bar.com should match.
  form2 = GetFormWithNewSignonRealm(form, "http://a-b.foo-bar.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // foo.com with port 1337 should not match.
  form2 = GetFormWithNewSignonRealm(form, "http://foo.com:1337/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(0U, result.size());

  // http://foo.com should not match since the scheme is wrong.
  form2 = GetFormWithNewSignonRealm(form, "https://foo.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(0U, result.size());

  // notfoo.com should not match.
  form2 = GetFormWithNewSignonRealm(form, "http://notfoo.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(0U, result.size());

  // baz.com should not match.
  form2 = GetFormWithNewSignonRealm(form, "http://baz.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(0U, result.size());

  // foo-baz.com should not match.
  form2 = GetFormWithNewSignonRealm(form, "http://foo-baz.com/");
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form2), &result));
  EXPECT_EQ(0U, result.size());
}

TEST_F(LoginDatabaseTest,
       GetLoginsForSameOrganizationName_OnlyWebHTTPFormsAreConsidered) {
  static constexpr const struct {
    const PasswordFormData form_data;
    bool use_federated_login;
    const char* other_queried_signon_realm;
    bool expected_matches_itself;
    bool expected_matches_other_realm;
  } kTestCases[] = {
      {{PasswordForm::SCHEME_HTML, "https://example.com/",
        "https://example.com/origin", "", L"", L"", L"", L"u", L"p", false, 1},
       false,
       nullptr,
       true,
       true},
      {{PasswordForm::SCHEME_BASIC, "http://example.com/realm",
        "http://example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
       false,
       nullptr,
       false,
       false},
      {{PasswordForm::SCHEME_OTHER, "ftp://example.com/realm",
        "ftp://example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
       false,
       "http://example.com/realm",
       false,
       false},
      {{PasswordForm::SCHEME_HTML,
        "federation://example.com/accounts.google.com",
        "https://example.com/orgin", "", L"", L"", L"", L"u", L"", false, 1},
       true,
       "http://example.com/",
       false,
       false},
      {{PasswordForm::SCHEME_HTML, "android://hash@example.com/",
        "android://hash@example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
       false,
       "http://example.com/",
       false,
       false},
  };

  for (const auto& test_case : kTestCases) {
    SCOPED_TRACE(test_case.form_data.signon_realm);

    std::unique_ptr<PasswordForm> form = FillPasswordFormWithData(
        test_case.form_data, test_case.use_federated_login);
    ASSERT_EQ(AddChangeForForm(*form), db().AddLogin(*form));

    std::vector<std::unique_ptr<PasswordForm>> same_organization_forms;
    EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
        form->signon_realm, &same_organization_forms));
    EXPECT_EQ(test_case.expected_matches_itself ? 1u : 0u,
              same_organization_forms.size());

    if (test_case.other_queried_signon_realm) {
      same_organization_forms.clear();
      EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
          test_case.other_queried_signon_realm, &same_organization_forms));
      EXPECT_EQ(test_case.expected_matches_other_realm ? 1u : 0u,
                same_organization_forms.size());
    }

    ASSERT_TRUE(db().RemoveLogin(*form, /*changes=*/nullptr));
  }
}

TEST_F(LoginDatabaseTest, GetLoginsForSameOrganizationName_DetailsOfMatching) {
  const struct {
    const char* saved_signon_realm;
    const char* queried_signon_realm;
    bool expected_matches;
  } kTestCases[] = {
      // PSL matches are also same-organization-name matches.
      {"http://psl.example.com/", "http://example.com/", true},
      {"http://example.com/", "http://sub.example.com/", true},
      {"https://a.b.example.co.uk/", "https://c.d.e.example.co.uk/", true},

      // Non-PSL but same-organization-name matches. Also an illustration why it
      // would be unsafe to offer these credentials for filling.
      {"https://example.com/", "https://example.co.uk/", true},
      {"https://example.co.uk/", "https://example.com/", true},
      {"https://a.example.appspot.com/", "https://b.example.co.uk/", true},

      // Same-organization-name matches are HTTP/HTTPS-agnostic.
      {"https://example.com/", "http://example.com/", true},
      {"http://example.com/", "https://example.com/", true},

      {"http://www.foo-bar.com/", "http://sub.foo-bar.com", true},
      {"http://www.foo_bar.com/", "http://sub.foo_bar.com", true},
      {"http://www.foo-bar.com/", "http://sub.foo%2Dbar.com", true},
      {"http://www.foo%21bar.com/", "http://sub.foo!bar.com", true},
      {"http://a.xn--sztr-7na0i.co.uk/", "http://xn--sztr-7na0i.com/", true},
      {"http://a.xn--sztr-7na0i.co.uk/", "http://www.sz\xc3\xb3t\xc3\xa1r.com/",
       true},

      {"http://www.foo+bar.com/", "http://sub.foo+bar.com", true},
      {"http://www.foooobar.com/", "http://sub.foo+bar.com", false},
      {"http://www.fobar.com/", "http://sub.foo?bar.com", false},
      {"http://www.foozbar.com/", "http://sub.foo.bar.com", false},
      {"http://www.foozbar.com/", "http://sub.foo[a-z]bar.com", false},

      {"https://notexample.com/", "https://example.com/", false},
      {"https://a.notexample.com/", "https://example.com/", false},
      {"https://example.com/", "https://notexample.com/", false},
      {"https://example.com/", "https://example.bar.com/", false},
      {"https://example.foo.com/", "https://example.com/", false},
      {"https://example.foo.com/", "https://example.bar.com/", false},

      // URLs without host portions, hosts without registry controlled domains
      // or hosts consisting of a registry.
      {"http://localhost/", "http://localhost/", false},
      {"https://example/", "https://example/", false},
      {"https://co.uk/", "https://co.uk/", false},
      {"https://example/", "https://example.com/", false},
      {"https://a.example/", "https://example.com/", false},
      {"https://example.com/", "https://example/", false},
      {"https://127.0.0.1/", "https://127.0.0.1/", false},
      {"https:/[3ffe:2a00:100:7031::1]/", "https:/[3ffe:2a00:100:7031::1]/",
       false},

      // Queried |signon-realms| are invalid URIs.
      {"https://example.com/", "", false},
      {"https://example.com/", "bad url", false},
      {"https://example.com/", "https://", false},
      {"https://example.com/", "http://www.foo;bar.com", false},
      {"https://example.com/", "example", false},
  };

  for (const auto& test_case : kTestCases) {
    SCOPED_TRACE(test_case.saved_signon_realm);
    SCOPED_TRACE(test_case.queried_signon_realm);

    std::unique_ptr<PasswordForm> form = FillPasswordFormWithData(
        {PasswordForm::SCHEME_HTML, test_case.saved_signon_realm,
         test_case.saved_signon_realm, "", L"", L"", L"", L"u", L"p", true, 1});
    std::vector<std::unique_ptr<PasswordForm>> result;
    ASSERT_EQ(AddChangeForForm(*form), db().AddLogin(*form));
    EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
        test_case.queried_signon_realm, &result));
    EXPECT_EQ(test_case.expected_matches ? 1u : 0u, result.size());
    ASSERT_TRUE(db().RemoveLogin(*form, /*changes=*/nullptr));
  }
}

static bool AddTimestampedLogin(LoginDatabase* db,
                                std::string url,
                                const std::string& unique_string,
                                const base::Time& time,
                                bool date_is_creation) {
  // Example password form.
  PasswordForm form;
  form.origin = GURL(url + std::string("/LoginAuth"));
  form.username_element = ASCIIToUTF16(unique_string);
  form.username_value = ASCIIToUTF16(unique_string);
  form.password_element = ASCIIToUTF16(unique_string);
  form.submit_element = ASCIIToUTF16("signIn");
  form.signon_realm = url;
  form.display_name = ASCIIToUTF16(unique_string);
  form.icon_url = GURL("https://accounts.google.com/Icon");
  form.federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));
  form.skip_zero_click = true;

  if (date_is_creation)
    form.date_created = time;
  else
    form.date_synced = time;
  return db->AddLogin(form) == AddChangeForForm(form);
}

TEST_F(LoginDatabaseTest, ClearPrivateData_SavedPasswords) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());

  base::Time now = base::Time::Now();
  base::TimeDelta one_day = base::TimeDelta::FromDays(1);
  base::Time back_30_days = now - base::TimeDelta::FromDays(30);
  base::Time back_31_days = now - base::TimeDelta::FromDays(31);

  // Create one with a 0 time.
  EXPECT_TRUE(
      AddTimestampedLogin(&db(), "http://1.com", "foo1", base::Time(), true));
  // Create one for now and +/- 1 day.
  EXPECT_TRUE(
      AddTimestampedLogin(&db(), "http://2.com", "foo2", now - one_day, true));
  EXPECT_TRUE(AddTimestampedLogin(&db(), "http://3.com", "foo3", now, true));
  EXPECT_TRUE(
      AddTimestampedLogin(&db(), "http://4.com", "foo4", now + one_day, true));
  // Create one with 31 days old.
  EXPECT_TRUE(
      AddTimestampedLogin(&db(), "http://5.com", "foo5", back_31_days, true));

  // Verify inserts worked.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(5U, result.size());
  result.clear();

  // Get everything from today's date and on.
  PrimaryKeyToFormMap key_to_form_map;
  EXPECT_TRUE(
      db().GetLoginsCreatedBetween(now, base::Time(), &key_to_form_map));
  EXPECT_EQ(2U, key_to_form_map.size());
  key_to_form_map.clear();

  // Get all logins created more than 30 days back.
  EXPECT_TRUE(db().GetLoginsCreatedBetween(base::Time(), back_30_days,
                                           &key_to_form_map));
  EXPECT_EQ(2U, key_to_form_map.size());
  key_to_form_map.clear();

  // Delete everything from today's date and on.
  PasswordStoreChangeList changes;
  db().RemoveLoginsCreatedBetween(now, base::Time(), &changes);
  ASSERT_EQ(2U, changes.size());
  // The 3rd and the 4th should have been deleted.
  EXPECT_EQ(3, changes[0].primary_key());
  EXPECT_EQ(4, changes[1].primary_key());

  // Should have deleted two logins.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(3U, result.size());
  result.clear();

  // Delete all logins created more than 30 days back.
  db().RemoveLoginsCreatedBetween(base::Time(), back_30_days, &changes);
  ASSERT_EQ(2U, changes.size());
  // The 1st and the 5th should have been deleted.
  EXPECT_EQ(1, changes[0].primary_key());
  EXPECT_EQ(5, changes[1].primary_key());

  // Should have deleted two logins.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(1U, result.size());
  result.clear();

  // Delete with 0 date (should delete all).
  db().RemoveLoginsCreatedBetween(base::Time(), base::Time(), &changes);
  ASSERT_EQ(1U, changes.size());
  // The 2nd should have been deleted.
  EXPECT_EQ(2, changes[0].primary_key());

  // Verify nothing is left.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());
}

TEST_F(LoginDatabaseTest, RemoveLoginsSyncedBetween) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  base::Time now = base::Time::Now();
  base::TimeDelta one_day = base::TimeDelta::FromDays(1);

  // Create one with a 0 time.
  EXPECT_TRUE(
      AddTimestampedLogin(&db(), "http://1.com", "foo1", base::Time(), false));
  // Create one for now and +/- 1 day.
  EXPECT_TRUE(
      AddTimestampedLogin(&db(), "http://2.com", "foo2", now - one_day, false));
  EXPECT_TRUE(AddTimestampedLogin(&db(), "http://3.com", "foo3", now, false));
  EXPECT_TRUE(
      AddTimestampedLogin(&db(), "http://4.com", "foo4", now + one_day, false));

  // Verify inserts worked.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(4U, result.size());
  result.clear();

  // Delete everything from today's date and on.
  PasswordStoreChangeList changes;
  EXPECT_TRUE(db().RemoveLoginsSyncedBetween(now, base::Time(), &changes));
  ASSERT_EQ(2U, changes.size());
  EXPECT_EQ("http://3.com", changes[0].form().signon_realm);
  EXPECT_EQ(3, changes[0].primary_key());
  EXPECT_EQ("http://4.com", changes[1].form().signon_realm);
  EXPECT_EQ(4, changes[1].primary_key());

  // Should have deleted half of what we inserted.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  ASSERT_EQ(2U, result.size());
  EXPECT_EQ("http://1.com", result[0]->signon_realm);
  EXPECT_EQ("http://2.com", result[1]->signon_realm);
  result.clear();

  // Delete with 0 date (should delete all).
  db().RemoveLoginsSyncedBetween(base::Time(), now, &changes);
  ASSERT_EQ(2U, changes.size());
  EXPECT_EQ(1, changes[0].primary_key());
  EXPECT_EQ(2, changes[1].primary_key());

  // Verify nothing is left.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  EXPECT_EQ(0U, result.size());
}

TEST_F(LoginDatabaseTest, GetAutoSignInLogins) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  GURL origin("https://example.com");
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo1", origin));
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo2", origin));
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo3", origin));
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo4", origin));

  EXPECT_TRUE(db().GetAutoSignInLogins(&result));
  EXPECT_EQ(4U, result.size());
  for (const auto& form : result)
    EXPECT_FALSE(form->skip_zero_click);

  EXPECT_TRUE(db().DisableAutoSignInForOrigin(origin));
  EXPECT_TRUE(db().GetAutoSignInLogins(&result));
  EXPECT_EQ(0U, result.size());
}

TEST_F(LoginDatabaseTest, DisableAutoSignInForOrigin) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  GURL origin1("https://google.com");
  GURL origin2("https://chrome.com");
  GURL origin3("http://example.com");
  GURL origin4("http://localhost");
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo1", origin1));
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo2", origin2));
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo3", origin3));
  EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo4", origin4));

  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  for (const auto& form : result)
    EXPECT_FALSE(form->skip_zero_click);

  EXPECT_TRUE(db().DisableAutoSignInForOrigin(origin1));
  EXPECT_TRUE(db().DisableAutoSignInForOrigin(origin3));
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  for (const auto& form : result) {
    if (form->origin == origin1 || form->origin == origin3)
      EXPECT_TRUE(form->skip_zero_click);
    else
      EXPECT_FALSE(form->skip_zero_click);
  }
}

TEST_F(LoginDatabaseTest, BlacklistedLogins) {
  std::vector<std::unique_ptr<PasswordForm>> result;

  // Verify the database is empty.
  EXPECT_TRUE(db().GetBlacklistLogins(&result));
  ASSERT_EQ(0U, result.size());

  // Save a form as blacklisted.
  PasswordForm form;
  form.origin = GURL("http://accounts.google.com/LoginAuth");
  form.action = GURL("http://accounts.google.com/Login");
  form.username_element = ASCIIToUTF16("Email");
  form.password_element = ASCIIToUTF16("Passwd");
  form.submit_element = ASCIIToUTF16("signIn");
  form.signon_realm = "http://www.google.com/";
  form.preferred = true;
  form.blacklisted_by_user = true;
  form.scheme = PasswordForm::SCHEME_HTML;
  form.date_synced = base::Time::Now();
  form.display_name = ASCIIToUTF16("Mr. Smith");
  form.icon_url = GURL("https://accounts.google.com/Icon");
  form.federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));
  form.skip_zero_click = true;
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));

  // Get all non-blacklisted logins (should be none).
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  ASSERT_EQ(0U, result.size());

  // GetLogins should give the blacklisted result.
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  ASSERT_EQ(1U, result.size());
  EXPECT_EQ(form, *result[0]);
  result.clear();

  // So should GetBlacklistedLogins.
  EXPECT_TRUE(db().GetBlacklistLogins(&result));
  ASSERT_EQ(1U, result.size());
  EXPECT_EQ(form, *result[0]);
  result.clear();
}

TEST_F(LoginDatabaseTest, VectorSerialization) {
  // Empty vector.
  ValueElementVector vec;
  base::Pickle temp = SerializeValueElementPairs(vec);
  ValueElementVector output = DeserializeValueElementPairs(temp);
  EXPECT_THAT(output, Eq(vec));

  // Normal data.
  vec.push_back({ASCIIToUTF16("first"), ASCIIToUTF16("id1")});
  vec.push_back({ASCIIToUTF16("second"), ASCIIToUTF16("id2")});
  vec.push_back({ASCIIToUTF16("third"), ASCIIToUTF16("id3")});

  temp = SerializeValueElementPairs(vec);
  output = DeserializeValueElementPairs(temp);
  EXPECT_THAT(output, Eq(vec));
}

TEST_F(LoginDatabaseTest, UpdateIncompleteCredentials) {
  std::vector<std::unique_ptr<PasswordForm>> result;
  // Verify the database is empty.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  ASSERT_EQ(0U, result.size());

  // Save an incomplete form. Note that it only has a few fields set, ex. it's
  // missing 'action', 'username_element' and 'password_element'. Such forms
  // are sometimes inserted during import from other browsers (which may not
  // store this info).
  PasswordForm incomplete_form;
  incomplete_form.origin = GURL("http://accounts.google.com/LoginAuth");
  incomplete_form.signon_realm = "http://accounts.google.com/";
  incomplete_form.username_value = ASCIIToUTF16("my_username");
  incomplete_form.password_value = ASCIIToUTF16("my_password");
  incomplete_form.preferred = true;
  incomplete_form.blacklisted_by_user = false;
  incomplete_form.scheme = PasswordForm::SCHEME_HTML;
  EXPECT_EQ(AddChangeForForm(incomplete_form), db().AddLogin(incomplete_form));

  // A form on some website. It should trigger a match with the stored one.
  PasswordForm encountered_form;
  encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
  encountered_form.signon_realm = "http://accounts.google.com/";
  encountered_form.action = GURL("http://accounts.google.com/Login");
  encountered_form.username_element = ASCIIToUTF16("Email");
  encountered_form.password_element = ASCIIToUTF16("Passwd");
  encountered_form.submit_element = ASCIIToUTF16("signIn");

  // Get matches for encountered_form.
  EXPECT_TRUE(
      db().GetLogins(PasswordStore::FormDigest(encountered_form), &result));
  ASSERT_EQ(1U, result.size());
  EXPECT_EQ(incomplete_form.origin, result[0]->origin);
  EXPECT_EQ(incomplete_form.signon_realm, result[0]->signon_realm);
  EXPECT_EQ(incomplete_form.username_value, result[0]->username_value);
  EXPECT_EQ(incomplete_form.password_value, result[0]->password_value);
  EXPECT_TRUE(result[0]->preferred);

  // We should return empty 'action', 'username_element', 'password_element'
  // and 'submit_element' as we can't be sure if the credentials were entered
  // in this particular form on the page.
  EXPECT_EQ(GURL(), result[0]->action);
  EXPECT_TRUE(result[0]->username_element.empty());
  EXPECT_TRUE(result[0]->password_element.empty());
  EXPECT_TRUE(result[0]->submit_element.empty());
  result.clear();

  // Let's say this login form worked. Now update the stored credentials with
  // 'action', 'username_element', 'password_element' and 'submit_element' from
  // the encountered form.
  PasswordForm completed_form(incomplete_form);
  completed_form.action = encountered_form.action;
  completed_form.username_element = encountered_form.username_element;
  completed_form.password_element = encountered_form.password_element;
  completed_form.submit_element = encountered_form.submit_element;
  EXPECT_EQ(AddChangeForForm(completed_form), db().AddLogin(completed_form));
  EXPECT_TRUE(db().RemoveLogin(incomplete_form, /*changes=*/nullptr));

  // Get matches for encountered_form again.
  EXPECT_TRUE(
      db().GetLogins(PasswordStore::FormDigest(encountered_form), &result));
  ASSERT_EQ(1U, result.size());

  // This time we should have all the info available.
  PasswordForm expected_form(completed_form);
  EXPECT_EQ(expected_form, *result[0]);
  result.clear();
}

TEST_F(LoginDatabaseTest, UpdateOverlappingCredentials) {
  // Save an incomplete form. Note that it only has a few fields set, ex. it's
  // missing 'action', 'username_element' and 'password_element'. Such forms
  // are sometimes inserted during import from other browsers (which may not
  // store this info).
  PasswordForm incomplete_form;
  incomplete_form.origin = GURL("http://accounts.google.com/LoginAuth");
  incomplete_form.signon_realm = "http://accounts.google.com/";
  incomplete_form.username_value = ASCIIToUTF16("my_username");
  incomplete_form.password_value = ASCIIToUTF16("my_password");
  incomplete_form.preferred = true;
  incomplete_form.blacklisted_by_user = false;
  incomplete_form.scheme = PasswordForm::SCHEME_HTML;
  EXPECT_EQ(AddChangeForForm(incomplete_form), db().AddLogin(incomplete_form));

  // Save a complete version of the previous form. Both forms could exist if
  // the user created the complete version before importing the incomplete
  // version from a different browser.
  PasswordForm complete_form = incomplete_form;
  complete_form.action = GURL("http://accounts.google.com/Login");
  complete_form.username_element = ASCIIToUTF16("username_element");
  complete_form.password_element = ASCIIToUTF16("password_element");
  complete_form.submit_element = ASCIIToUTF16("submit");

  // An update fails because the primary key for |complete_form| is different.
  EXPECT_EQ(PasswordStoreChangeList(), db().UpdateLogin(complete_form));
  EXPECT_EQ(AddChangeForForm(complete_form), db().AddLogin(complete_form));

  // Make sure both passwords exist.
  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  ASSERT_EQ(2U, result.size());
  result.clear();

  // Simulate the user changing their password.
  complete_form.password_value = ASCIIToUTF16("new_password");
  complete_form.date_synced = base::Time::Now();
  EXPECT_EQ(UpdateChangeForForm(complete_form),
            db().UpdateLogin(complete_form));

  // Both still exist now.
  EXPECT_TRUE(db().GetAutofillableLogins(&result));
  ASSERT_EQ(2U, result.size());

  if (result[0]->username_element.empty())
    std::swap(result[0], result[1]);
  EXPECT_EQ(complete_form, *result[0]);
  EXPECT_EQ(incomplete_form, *result[1]);
}

TEST_F(LoginDatabaseTest, DoubleAdd) {
  PasswordForm form;
  form.origin = GURL("http://accounts.google.com/LoginAuth");
  form.signon_realm = "http://accounts.google.com/";
  form.username_value = ASCIIToUTF16("my_username");
  form.password_value = ASCIIToUTF16("my_password");
  form.preferred = true;
  form.blacklisted_by_user = false;
  form.scheme = PasswordForm::SCHEME_HTML;
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));

  // Add almost the same form again.
  form.times_used++;
  PasswordStoreChangeList list;
  list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
  list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
  EXPECT_EQ(list, db().AddLogin(form));
}

TEST_F(LoginDatabaseTest, AddWrongForm) {
  PasswordForm form;
  // |origin| shouldn't be empty.
  form.origin = GURL();
  form.signon_realm = "http://accounts.google.com/";
  form.username_value = ASCIIToUTF16("my_username");
  form.password_value = ASCIIToUTF16("my_password");
  form.preferred = true;
  form.blacklisted_by_user = false;
  form.scheme = PasswordForm::SCHEME_HTML;
  EXPECT_EQ(PasswordStoreChangeList(), db().AddLogin(form));

  // |signon_realm| shouldn't be empty.
  form.origin = GURL("http://accounts.google.com/LoginAuth");
  form.signon_realm.clear();
  EXPECT_EQ(PasswordStoreChangeList(), db().AddLogin(form));
}

TEST_F(LoginDatabaseTest, UpdateLogin) {
  PasswordForm form;
  form.origin = GURL("http://accounts.google.com/LoginAuth");
  form.signon_realm = "http://accounts.google.com/";
  form.username_value = ASCIIToUTF16("my_username");
  form.password_value = ASCIIToUTF16("my_password");
  form.preferred = true;
  form.blacklisted_by_user = false;
  form.scheme = PasswordForm::SCHEME_HTML;
  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));

  form.action = GURL("http://accounts.google.com/login");
  form.password_value = ASCIIToUTF16("my_new_password");
  form.preferred = false;
  form.other_possible_usernames.push_back(autofill::ValueElementPair(
      ASCIIToUTF16("my_new_username"), ASCIIToUTF16("new_username_id")));
  form.times_used = 20;
  form.submit_element = ASCIIToUTF16("submit_element");
  form.date_synced = base::Time::Now();
  form.date_created = base::Time::Now() - base::TimeDelta::FromDays(1);
  form.blacklisted_by_user = true;
  form.scheme = PasswordForm::SCHEME_BASIC;
  form.type = PasswordForm::TYPE_GENERATED;
  form.display_name = ASCIIToUTF16("Mr. Smith");
  form.icon_url = GURL("https://accounts.google.com/Icon");
  form.federation_origin =
      url::Origin::Create(GURL("https://accounts.google.com/"));
  form.skip_zero_click = true;

  PasswordStoreChangeList changes = db().UpdateLogin(form);
  EXPECT_EQ(UpdateChangeForForm(form), changes);
  ASSERT_EQ(1U, changes.size());
  EXPECT_EQ(1, changes[0].primary_key());
  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result));
  ASSERT_EQ(1U, result.size());
  EXPECT_EQ(form, *result[0]);
}

TEST_F(LoginDatabaseTest, RemoveWrongForm) {
  PasswordForm form;
  // |origin| shouldn't be empty.
  form.origin = GURL("http://accounts.google.com/LoginAuth");
  form.signon_realm = "http://accounts.google.com/";
  form.username_value = ASCIIToUTF16("my_username");
  form.password_value = ASCIIToUTF16("my_password");
  form.preferred = true;
  form.blacklisted_by_user = false;
  form.scheme = PasswordForm::SCHEME_HTML;
  // The form isn't in the database.
  EXPECT_FALSE(db().RemoveLogin(form, /*changes=*/nullptr));

  EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
  EXPECT_TRUE(db().RemoveLogin(form, /*changes=*/nullptr));
  EXPECT_FALSE(db().RemoveLogin(form, /*changes=*/nullptr));
}

TEST_F(LoginDatabaseTest, ReportMetricsTest) {
  PasswordForm password_form;
  password_form.origin = GURL("http://example.com");
  password_form.username_value = ASCIIToUTF16("test1@gmail.com");
  password_form.password_value = ASCIIToUTF16("test");
  password_form.signon_realm = "http://example.com/";
  password_form.times_used = 0;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.username_value = ASCIIToUTF16("test2@gmail.com");
  password_form.times_used = 1;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("http://second.example.com");
  password_form.signon_realm = "http://second.example.com";
  password_form.times_used = 3;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.username_value = ASCIIToUTF16("test3@gmail.com");
  password_form.type = PasswordForm::TYPE_GENERATED;
  password_form.times_used = 2;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("ftp://third.example.com/");
  password_form.signon_realm = "ftp://third.example.com/";
  password_form.times_used = 4;
  password_form.scheme = PasswordForm::SCHEME_OTHER;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("http://fourth.example.com/");
  password_form.signon_realm = "http://fourth.example.com/";
  password_form.type = PasswordForm::TYPE_MANUAL;
  password_form.username_value = ASCIIToUTF16("");
  password_form.times_used = 10;
  password_form.scheme = PasswordForm::SCHEME_HTML;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("https://fifth.example.com/");
  password_form.signon_realm = "https://fifth.example.com/";
  password_form.password_value = ASCIIToUTF16("");
  password_form.blacklisted_by_user = true;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("https://sixth.example.com/");
  password_form.signon_realm = "https://sixth.example.com/";
  password_form.username_value = ASCIIToUTF16("");
  password_form.password_value = ASCIIToUTF16("my_password");
  password_form.blacklisted_by_user = false;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.username_element = ASCIIToUTF16("some_other_input");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.username_value = ASCIIToUTF16("my_username");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL();
  password_form.signon_realm = "android://hash@com.example.android/";
  password_form.username_value = ASCIIToUTF16("JohnDoe");
  password_form.password_value = ASCIIToUTF16("my_password");
  password_form.blacklisted_by_user = false;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.username_value = ASCIIToUTF16("JaneDoe");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("http://rsolomakhin.github.io/autofill/");
  password_form.signon_realm = "http://rsolomakhin.github.io/";
  password_form.blacklisted_by_user = true;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("https://rsolomakhin.github.io/autofill/");
  password_form.signon_realm = "https://rsolomakhin.github.io/";
  password_form.blacklisted_by_user = true;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("http://rsolomakhin.github.io/autofill/123");
  password_form.signon_realm = "http://rsolomakhin.github.io/";
  password_form.blacklisted_by_user = true;
  EXPECT_EQ(AddChangeForForm(password_form),
            db().AddBlacklistedLoginForTesting(password_form));

  password_form.origin = GURL("https://rsolomakhin.github.io/autofill/1234");
  password_form.signon_realm = "https://rsolomakhin.github.io/";
  password_form.blacklisted_by_user = true;
  EXPECT_EQ(AddChangeForForm(password_form),
            db().AddBlacklistedLoginForTesting(password_form));

  base::HistogramTester histogram_tester;
  db().ReportMetrics("", false);

  histogram_tester.ExpectUniqueSample(
      "PasswordManager.TotalAccounts.UserCreated.WithoutCustomPassphrase", 9,
      1);
  histogram_tester.ExpectBucketCount(
      "PasswordManager.AccountsPerSite.UserCreated.WithoutCustomPassphrase",
      1,
      2);
  histogram_tester.ExpectBucketCount(
      "PasswordManager.AccountsPerSite.UserCreated.WithoutCustomPassphrase", 2,
      3);
  histogram_tester.ExpectBucketCount(
      "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase",
      0,
      1);
  histogram_tester.ExpectBucketCount(
      "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase",
      1,
      1);
  histogram_tester.ExpectBucketCount(
      "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase",
      3,
      1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.TotalAccounts.AutoGenerated.WithoutCustomPassphrase",
      2,
      1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.TotalAccountsHiRes.WithScheme.Android", 2, 1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.TotalAccountsHiRes.WithScheme.Ftp", 1, 1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.TotalAccountsHiRes.WithScheme.Http", 5, 1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.TotalAccountsHiRes.WithScheme.Https", 3, 1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.TotalAccountsHiRes.WithScheme.Other", 0, 1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.AccountsPerSite.AutoGenerated.WithoutCustomPassphrase",
      1, 2);
  histogram_tester.ExpectBucketCount(
      "PasswordManager.TimesPasswordUsed.AutoGenerated.WithoutCustomPassphrase",
      2,
      1);
  histogram_tester.ExpectBucketCount(
      "PasswordManager.TimesPasswordUsed.AutoGenerated.WithoutCustomPassphrase",
      4,
      1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.EmptyUsernames.CountInDatabase",
      3,
      1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.EmptyUsernames.WithoutCorrespondingNonempty",
      1,
      1);
  histogram_tester.ExpectUniqueSample("PasswordManager.InaccessiblePasswords",
                                      0, 1);
}

// This test will check that adding a blacklist entry is prevented due to an
// already existing entry.
TEST_F(LoginDatabaseTest, AddBlacklistedDuplicates) {
  PasswordForm password_form;
  password_form.origin = GURL("http://rsolomakhin.github.io/autofill/");
  password_form.signon_realm = "http://rsolomakhin.github.io/";
  password_form.blacklisted_by_user = true;
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  PasswordForm password_form_duplicated;
  password_form_duplicated.origin =
      GURL("http://rsolomakhin.github.io/autofill/123");
  password_form_duplicated.signon_realm = "http://rsolomakhin.github.io/";
  password_form_duplicated.blacklisted_by_user = true;
  EXPECT_EQ(PasswordStoreChangeList(), db().AddLogin(password_form_duplicated));

  PasswordForm password_form_example;
  password_form_example.origin = GURL("http://example.com/");
  password_form_example.signon_realm = "http://example.com/";
  password_form_example.blacklisted_by_user = false;
  EXPECT_EQ(AddChangeForForm(password_form_example),
            db().AddLogin(password_form_example));

  PasswordForm password_form_example_blacklisted;
  password_form_example_blacklisted.origin = GURL("http://example.com/1");
  password_form_example_blacklisted.signon_realm = "http://example.com/";
  password_form_example_blacklisted.blacklisted_by_user = true;
  EXPECT_EQ(AddChangeForForm(password_form_example_blacklisted),
            db().AddLogin(password_form_example_blacklisted));

  PasswordForm password_form_example_blacklisted_duplicated;
  password_form_example_blacklisted_duplicated.origin =
      GURL("http://example.com/123");
  password_form_example_blacklisted_duplicated.signon_realm =
      "http://example.com/";
  password_form_example_blacklisted_duplicated.blacklisted_by_user = true;
  EXPECT_EQ(PasswordStoreChangeList(),
            db().AddLogin(password_form_example_blacklisted_duplicated));

  std::vector<std::unique_ptr<PasswordForm>> forms;
  ASSERT_TRUE(db().GetAutofillableLogins(&forms));
  EXPECT_THAT(forms,
              UnorderedElementsAre(::testing::Pointee(password_form_example)));

  std::vector<std::unique_ptr<PasswordForm>> blacklisted_forms;
  ASSERT_TRUE(db().GetBlacklistLogins(&blacklisted_forms));
  EXPECT_THAT(blacklisted_forms,
              UnorderedElementsAre(
                  ::testing::Pointee(password_form),
                  ::testing::Pointee(password_form_example_blacklisted)));
}

TEST_F(LoginDatabaseTest, PasswordReuseMetrics) {
  // -- Group of accounts that are reusing password #1.
  //
  //                                     Destination account
  // +-----------------+-------+-------+-------+-------+-------+-------+-------+
  // |                 |   1   |   2   |   3   |   4   |   5   |   6   |   7   |
  // +-----------------+-------+-------+-------+-------+-------+-------+-------+
  // | Scheme?         | HTTP  | HTTP  | HTTP  | HTTP  | HTTPS | HTTPS | HTTPS |
  // +-----------------+-------+-------+-------+-------+-------+-------+-------+
  // |           |  1  |   -   | Same  |  PSL  | Diff. | Same  | Diff. | Diff. |
  // |           |  2  | Same  |   -   |  PSL  | Diff. | Same  | Diff. | Diff. |
  // | Relation  |  3  |  PSL  |  PSL  |   -   | Diff. | Diff. | Same  | Diff. |
  // | to host   |  4  | Diff. | Diff. | Diff. |   -   | Diff. | Diff. | Same  |
  // | of source |  5  | Same  | Same  | Diff. | Diff. |   -   |  PSL  | Diff. |
  // | account:  |  6  | Diff. | Diff. | Same  | Diff. |  PSL  |   -   | Diff. |
  // |           |  7  | Diff. | Diff. | Diff. | Same  | Diff. | Diff. |   -   |
  // +-----------------+-------+-------+-------+-------+-------+-------+-------+

  PasswordForm password_form;
  password_form.signon_realm = "http://example.com/";
  password_form.origin = GURL("http://example.com/");
  password_form.username_value = ASCIIToUTF16("username_1");
  password_form.password_value = ASCIIToUTF16("password_1");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.origin = GURL("http://example.com/");
  password_form.username_value = ASCIIToUTF16("username_2");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  // Note: This PSL matches http://example.com, but not https://example.com.
  password_form.signon_realm = "http://www.example.com/";
  password_form.origin = GURL("http://www.example.com/");
  password_form.username_value = ASCIIToUTF16("username_3");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.signon_realm = "http://not-example.com/";
  password_form.origin = GURL("http://not-example.com/");
  password_form.username_value = ASCIIToUTF16("username_4");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.signon_realm = "https://example.com/";
  password_form.origin = GURL("https://example.com/");
  password_form.username_value = ASCIIToUTF16("username_5");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  // Note: This PSL matches https://example.com, but not http://example.com.
  password_form.signon_realm = "https://www.example.com/";
  password_form.origin = GURL("https://www.example.com/");
  password_form.username_value = ASCIIToUTF16("username_6");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.signon_realm = "https://not-example.com/";
  password_form.origin = GURL("https://not-example.com/");
  password_form.username_value = ASCIIToUTF16("username_7");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  // -- Group of accounts that are reusing password #2.
  // Both HTTP, different host.
  password_form.signon_realm = "http://example.com/";
  password_form.origin = GURL("http://example.com/");
  password_form.username_value = ASCIIToUTF16("username_8");
  password_form.password_value = ASCIIToUTF16("password_2");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.signon_realm = "http://not-example.com/";
  password_form.origin = GURL("http://not-example.com/");
  password_form.username_value = ASCIIToUTF16("username_9");
  password_form.password_value = ASCIIToUTF16("password_2");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  // -- Group of accounts that are reusing password #3.
  // HTTP sites identified by different IP addresses, so they should not be
  // considered a public suffix match.
  password_form.signon_realm = "http://1.2.3.4/";
  password_form.origin = GURL("http://1.2.3.4/");
  password_form.username_value = ASCIIToUTF16("username_10");
  password_form.password_value = ASCIIToUTF16("password_3");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  password_form.signon_realm = "http://2.2.3.4/";
  password_form.origin = GURL("http://2.2.3.4/");
  password_form.username_value = ASCIIToUTF16("username_11");
  password_form.password_value = ASCIIToUTF16("password_3");
  EXPECT_EQ(AddChangeForForm(password_form), db().AddLogin(password_form));

  // -- Not HTML form based logins or blacklisted logins. Should be ignored.
  PasswordForm ignored_form;
  ignored_form.scheme = PasswordForm::SCHEME_HTML;
  ignored_form.signon_realm = "http://example.org/";
  ignored_form.origin = GURL("http://example.org/blacklist");
  ignored_form.blacklisted_by_user = true;
  ignored_form.username_value = ASCIIToUTF16("username_x");
  ignored_form.password_value = ASCIIToUTF16("password_y");
  EXPECT_EQ(AddChangeForForm(ignored_form), db().AddLogin(ignored_form));

  ignored_form.scheme = PasswordForm::SCHEME_BASIC;
  ignored_form.signon_realm = "http://example.org/HTTP Auth Realm";
  ignored_form.origin = GURL("http://example.org/");
  ignored_form.blacklisted_by_user = false;
  EXPECT_EQ(AddChangeForForm(ignored_form), db().AddLogin(ignored_form));

  ignored_form.scheme = PasswordForm::SCHEME_HTML;
  ignored_form.signon_realm = "android://hash@com.example/";
  ignored_form.origin = GURL();
  ignored_form.blacklisted_by_user = false;
  EXPECT_EQ(AddChangeForForm(ignored_form), db().AddLogin(ignored_form));

  ignored_form.scheme = PasswordForm::SCHEME_HTML;
  ignored_form.signon_realm = "federation://example.com/federation.com";
  ignored_form.origin = GURL("https://example.com/");
  ignored_form.blacklisted_by_user = false;
  EXPECT_EQ(AddChangeForForm(ignored_form), db().AddLogin(ignored_form));

  base::HistogramTester histogram_tester;
  db().ReportMetrics("", false);

  const std::string kPrefix("PasswordManager.AccountsReusingPassword.");
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpRealm.OnHttpRealmWithSameHost"),
              testing::ElementsAre(base::Bucket(0, 6), base::Bucket(1, 2)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpRealm.OnHttpsRealmWithSameHost"),
              testing::ElementsAre(base::Bucket(0, 4), base::Bucket(1, 4)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpRealm.OnPSLMatchingRealm"),
              testing::ElementsAre(base::Bucket(0, 5), base::Bucket(1, 2),
                                   base::Bucket(2, 1)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpRealm.OnHttpsRealmWithDifferentHost"),
              testing::ElementsAre(base::Bucket(0, 4), base::Bucket(2, 4)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpRealm.OnHttpRealmWithDifferentHost"),
              testing::ElementsAre(base::Bucket(1, 7), base::Bucket(3, 1)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpRealm.OnAnyRealmWithDifferentHost"),
              testing::ElementsAre(base::Bucket(1, 4), base::Bucket(3, 3),
                                   base::Bucket(5, 1)));

  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpsRealm.OnHttpRealmWithSameHost"),
              testing::ElementsAre(base::Bucket(1, 2), base::Bucket(2, 1)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpsRealm.OnHttpsRealmWithSameHost"),
              testing::ElementsAre(base::Bucket(0, 3)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpsRealm.OnPSLMatchingRealm"),
              testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 2)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpsRealm.OnHttpRealmWithDifferentHost"),
              testing::ElementsAre(base::Bucket(2, 1), base::Bucket(3, 2)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpsRealm.OnHttpsRealmWithDifferentHost"),
              testing::ElementsAre(base::Bucket(1, 2), base::Bucket(2, 1)));
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  kPrefix + "FromHttpsRealm.OnAnyRealmWithDifferentHost"),
              testing::ElementsAre(base::Bucket(3, 1), base::Bucket(4, 1),
                                   base::Bucket(5, 1)));
}

TEST_F(LoginDatabaseTest, NoMetadata) {
  std::unique_ptr<syncer::MetadataBatch> metadata_batch =
      db().GetAllSyncMetadataForTesting();
  ASSERT_THAT(metadata_batch, testing::NotNull());
  EXPECT_EQ(0u, metadata_batch->TakeAllMetadata().size());
  EXPECT_EQ(sync_pb::ModelTypeState().SerializeAsString(),
            metadata_batch->GetModelTypeState().SerializeAsString());
}

TEST_F(LoginDatabaseTest, GetAllSyncMetadata) {
  sync_pb::EntityMetadata metadata;
  // Storage keys must be integers.
  const std::string kStorageKey1 = "1";
  const std::string kStorageKey2 = "2";
  metadata.set_sequence_number(1);

  EXPECT_TRUE(
      db().UpdateSyncMetadata(syncer::PASSWORDS, kStorageKey1, metadata));

  sync_pb::ModelTypeState model_type_state;
  model_type_state.set_initial_sync_done(true);

  EXPECT_TRUE(db().UpdateModelTypeState(syncer::PASSWORDS, model_type_state));

  metadata.set_sequence_number(2);
  EXPECT_TRUE(
      db().UpdateSyncMetadata(syncer::PASSWORDS, kStorageKey2, metadata));

  std::unique_ptr<syncer::MetadataBatch> metadata_batch =
      db().GetAllSyncMetadataForTesting();
  ASSERT_THAT(metadata_batch, testing::NotNull());

  EXPECT_TRUE(metadata_batch->GetModelTypeState().initial_sync_done());

  syncer::EntityMetadataMap metadata_records =
      metadata_batch->TakeAllMetadata();

  EXPECT_EQ(metadata_records.size(), 2u);
  EXPECT_EQ(metadata_records[kStorageKey1].sequence_number(), 1);
  EXPECT_EQ(metadata_records[kStorageKey2].sequence_number(), 2);

  // Now check that a model type state update replaces the old value
  model_type_state.set_initial_sync_done(false);
  EXPECT_TRUE(db().UpdateModelTypeState(syncer::PASSWORDS, model_type_state));

  metadata_batch = db().GetAllSyncMetadataForTesting();
  ASSERT_THAT(metadata_batch, testing::NotNull());
  EXPECT_FALSE(metadata_batch->GetModelTypeState().initial_sync_done());
}

TEST_F(LoginDatabaseTest, WriteThenDeleteSyncMetadata) {
  sync_pb::EntityMetadata metadata;
  const std::string kStorageKey = "1";
  sync_pb::ModelTypeState model_type_state;

  model_type_state.set_initial_sync_done(true);

  metadata.set_client_tag_hash("client_hash");

  // Write the data into the store.
  EXPECT_TRUE(
      db().UpdateSyncMetadata(syncer::PASSWORDS, kStorageKey, metadata));
  EXPECT_TRUE(db().UpdateModelTypeState(syncer::PASSWORDS, model_type_state));
  // Delete the data we just wrote.
  EXPECT_TRUE(db().ClearSyncMetadata(syncer::PASSWORDS, kStorageKey));

  std::unique_ptr<syncer::MetadataBatch> metadata_batch =
      db().GetAllSyncMetadataForTesting();
  ASSERT_THAT(metadata_batch, testing::NotNull());

  // It shouldn't be there any more.
  syncer::EntityMetadataMap metadata_records =
      metadata_batch->TakeAllMetadata();
  EXPECT_EQ(metadata_records.size(), 0u);

  // Now delete the model type state.
  EXPECT_TRUE(db().ClearModelTypeState(syncer::PASSWORDS));
  metadata_batch = db().GetAllSyncMetadataForTesting();
  ASSERT_THAT(metadata_batch, testing::NotNull());

  EXPECT_EQ(sync_pb::ModelTypeState().SerializeAsString(),
            metadata_batch->GetModelTypeState().SerializeAsString());
}

#if defined(OS_POSIX)
// Only the current user has permission to read the database.
//
// Only POSIX because GetPosixFilePermissions() only exists on POSIX.
// This tests that sql::Database::set_restrict_to_user() was called,
// and that function is a noop on non-POSIX platforms in any case.
TEST_F(LoginDatabaseTest, FilePermissions) {
  int mode = base::FILE_PERMISSION_MASK;
  EXPECT_TRUE(base::GetPosixFilePermissions(file_, &mode));
  EXPECT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
}
#endif  // defined(OS_POSIX)

#if !defined(OS_IOS)
// Test that LoginDatabase encrypts the password values that it stores.
TEST_F(LoginDatabaseTest, EncryptionEnabled) {
  PasswordForm password_form;
  GenerateExamplePasswordForm(&password_form);
  base::FilePath file = temp_dir_.GetPath().AppendASCII("TestUnencryptedDB");
  {
    LoginDatabase db(file);
    ASSERT_TRUE(db.Init());
    EXPECT_EQ(AddChangeForForm(password_form), db.AddLogin(password_form));
  }
  base::string16 decrypted_pw;
  ASSERT_TRUE(OSCrypt::DecryptString16(
      GetColumnValuesFromDatabase<std::string>(file, "password_value").at(0),
      &decrypted_pw));
  EXPECT_EQ(decrypted_pw, password_form.password_value);
}
#endif  // !defined(OS_IOS)

#if defined(OS_LINUX)
// Test that LoginDatabase does not encrypt values when encryption is disabled.
// TODO(crbug.com/829857) This is supported only for Linux, while transitioning
// into LoginDB with full encryption.
TEST_F(LoginDatabaseTest, EncryptionDisabled) {
  PasswordForm password_form;
  GenerateExamplePasswordForm(&password_form);
  base::FilePath file = temp_dir_.GetPath().AppendASCII("TestUnencryptedDB");
  {
    LoginDatabase db(file);
    db.disable_encryption();
    ASSERT_TRUE(db.Init());
    EXPECT_EQ(AddChangeForForm(password_form), db.AddLogin(password_form));
  }
  EXPECT_EQ(
      GetColumnValuesFromDatabase<std::string>(file, "password_value").at(0),
      base::UTF16ToUTF8(password_form.password_value));
}
#endif  // defined(OS_LINUX)

// If the database initialisation fails, the initialisation transaction should
// roll back without crashing.
TEST(LoginDatabaseFailureTest, Init_NoCrashOnFailedRollback) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath database_path = temp_dir.GetPath().AppendASCII("test.db");

  // To cause an init failure, set the compatible version to be higher than the
  // current version (in reality, this could happen if, e.g., someone opened a
  // Canary-created profile with Chrome Stable.
  {
    sql::Database connection;
    sql::MetaTable meta_table;
    ASSERT_TRUE(connection.Open(database_path));
    ASSERT_TRUE(meta_table.Init(&connection, kCurrentVersionNumber + 1,
                                kCurrentVersionNumber + 1));
  }

  // Now try to init the database with the file. The test succeeds if it does
  // not crash.
  LoginDatabase db(database_path);
  EXPECT_FALSE(db.Init());
}

// Test the migration from GetParam() version to kCurrentVersionNumber.
class LoginDatabaseMigrationTest : public testing::TestWithParam<int> {
 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    database_dump_location_ = database_dump_location_.AppendASCII("components")
                                  .AppendASCII("test")
                                  .AppendASCII("data")
                                  .AppendASCII("password_manager");
    database_path_ = temp_dir_.GetPath().AppendASCII("test.db");
    OSCryptMocker::SetUp();
  }

  void TearDown() override { OSCryptMocker::TearDown(); }

  // Creates the database from |sql_file|.
  void CreateDatabase(base::StringPiece sql_file) {
    base::FilePath database_dump;
    ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &database_dump));
    database_dump =
        database_dump.Append(database_dump_location_).AppendASCII(sql_file);
    ASSERT_TRUE(
        sql::test::CreateDatabaseFromSQL(database_path_, database_dump));
  }

  void DestroyDatabase() {
    if (!database_path_.empty())
      sql::Database::Delete(database_path_);
  }

  // Returns the database version for the test.
  int version() const { return GetParam(); }

  // Actual test body.
  void MigrationToVCurrent(base::StringPiece sql_file);

  base::FilePath database_path_;

 private:
  base::FilePath database_dump_location_;
  base::ScopedTempDir temp_dir_;
  base::test::ScopedTaskEnvironment scoped_task_environment_;
};

void LoginDatabaseMigrationTest::MigrationToVCurrent(
    base::StringPiece sql_file) {
  SCOPED_TRACE(testing::Message("Version file = ") << sql_file);
  CreateDatabase(sql_file);
  // Original date, in seconds since UTC epoch.
  std::vector<int64_t> date_created(
      GetColumnValuesFromDatabase<int64_t>(database_path_, "date_created"));
  if (version() == 10)  // Version 10 has a duplicate entry.
    ASSERT_EQ(4U, date_created.size());
  else
    ASSERT_EQ(3U, date_created.size());
  // Migration to version 8 performs changes dates to the new format.
  // So for versions less of equal to 8 create date should be in old
  // format before migration and in new format after.
  if (version() <= 8) {
    ASSERT_EQ(1402955745, date_created[0]);
    ASSERT_EQ(1402950000, date_created[1]);
    ASSERT_EQ(1402950000, date_created[2]);
  } else {
    ASSERT_EQ(13047429345000000, date_created[0]);
    ASSERT_EQ(13047423600000000, date_created[1]);
    ASSERT_EQ(13047423600000000, date_created[2]);
  }

  {
    // Assert that the database was successfully opened and updated
    // to current version.
    LoginDatabase db(database_path_);
    ASSERT_TRUE(db.Init());

    // Check that the contents was preserved.
    std::vector<std::unique_ptr<PasswordForm>> result;
    EXPECT_TRUE(db.GetAutofillableLogins(&result));
    EXPECT_THAT(result, UnorderedElementsAre(Pointee(IsGoogle1Account()),
                                             Pointee(IsGoogle2Account()),
                                             Pointee(IsBasicAuthAccount())));

    // Verifies that the final version can save all the appropriate fields.
    PasswordForm form;
    GenerateExamplePasswordForm(&form);
    // Add the same form twice to test the constraints in the database.
    EXPECT_EQ(AddChangeForForm(form), db.AddLogin(form));
    PasswordStoreChangeList list;
    list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
    list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
    EXPECT_EQ(list, db.AddLogin(form));

    result.clear();
    EXPECT_TRUE(db.GetLogins(PasswordStore::FormDigest(form), &result));
    ASSERT_EQ(1U, result.size());
    EXPECT_EQ(form, *result[0]);
    EXPECT_TRUE(db.RemoveLogin(form, /*changes=*/nullptr));
  }
  // New date, in microseconds since platform independent epoch.
  std::vector<int64_t> new_date_created(
      GetColumnValuesFromDatabase<int64_t>(database_path_, "date_created"));
  ASSERT_EQ(3U, new_date_created.size());
  if (version() <= 8) {
    // Check that the two dates match up.
    for (size_t i = 0; i < date_created.size(); ++i) {
      EXPECT_EQ(base::Time::FromInternalValue(new_date_created[i]),
                base::Time::FromTimeT(date_created[i]));
    }
  } else {
    ASSERT_EQ(13047429345000000, new_date_created[0]);
    ASSERT_EQ(13047423600000000, new_date_created[1]);
    ASSERT_EQ(13047423600000000, new_date_created[2]);
  }

  if (version() >= 7 && version() <= 13) {
    // The "avatar_url" column first appeared in version 7. In version 14,
    // it was renamed to "icon_url". Migration from a version <= 13
    // to >= 14 should not break theses URLs.
    std::vector<std::string> urls(
        GetColumnValuesFromDatabase<std::string>(database_path_, "icon_url"));

    EXPECT_THAT(urls, UnorderedElementsAre("", "https://www.google.com/icon",
                                           "https://www.google.com/icon"));
  }

  {
    // On versions < 15 |kCompatibleVersionNumber| was set to 1, but
    // the migration should bring it to the correct value.
    sql::Database db;
    sql::MetaTable meta_table;
    ASSERT_TRUE(db.Open(database_path_));
    ASSERT_TRUE(
        meta_table.Init(&db, kCurrentVersionNumber, kCompatibleVersionNumber));
    EXPECT_EQ(password_manager::kCompatibleVersionNumber,
              meta_table.GetCompatibleVersionNumber());
  }
  DestroyDatabase();
}

// Tests the migration of the login database from version() to
// kCurrentVersionNumber.
TEST_P(LoginDatabaseMigrationTest, MigrationToVCurrent) {
  MigrationToVCurrent(base::StringPrintf("login_db_v%d.sql", version()));
}

class LoginDatabaseMigrationTestV9 : public LoginDatabaseMigrationTest {};

// Tests migration from the alternative version #9, see crbug.com/423716.
TEST_P(LoginDatabaseMigrationTestV9, V9WithoutUseAdditionalAuthField) {
  ASSERT_EQ(9, version());
  MigrationToVCurrent("login_db_v9_without_use_additional_auth_field.sql");
}

class LoginDatabaseMigrationTestBroken : public LoginDatabaseMigrationTest {};

// Test migrating certain databases with incorrect version.
// http://crbug.com/295851
TEST_P(LoginDatabaseMigrationTestBroken, Broken) {
  MigrationToVCurrent(base::StringPrintf("login_db_v%d_broken.sql", version()));
}

INSTANTIATE_TEST_CASE_P(MigrationToVCurrent,
                        LoginDatabaseMigrationTest,
                        testing::Range(1, kCurrentVersionNumber + 1));
INSTANTIATE_TEST_CASE_P(MigrationToVCurrent,
                        LoginDatabaseMigrationTestV9,
                        testing::Values(9));
INSTANTIATE_TEST_CASE_P(MigrationToVCurrent,
                        LoginDatabaseMigrationTestBroken,
                        testing::Range(1, 4));

class LoginDatabaseUndecryptableLoginsTest : public testing::Test {
 protected:
  LoginDatabaseUndecryptableLoginsTest() {}

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    database_path_ = temp_dir_.GetPath().AppendASCII("test.db");
    OSCryptMocker::SetUp();
  }

  void TearDown() override { OSCryptMocker::TearDown(); }

  // Generates login depending on |unique_string| and |origin| parameters and
  // adds it to the database. Changes encrypted password in the database if the
  // |should_be_corrupted| flag is active.
  PasswordForm AddDummyLogin(const std::string& unique_string,
                             const GURL& origin,
                             bool should_be_corrupted);

  base::FilePath database_path() const { return database_path_; }

  TestingPrefServiceSimple& testing_local_state() {
    return testing_local_state_;
  }

  void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); }

 private:
  base::FilePath database_path_;
  base::ScopedTempDir temp_dir_;
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  TestingPrefServiceSimple testing_local_state_;

  DISALLOW_COPY_AND_ASSIGN(LoginDatabaseUndecryptableLoginsTest);
};

PasswordForm LoginDatabaseUndecryptableLoginsTest::AddDummyLogin(
    const std::string& unique_string,
    const GURL& origin,
    bool should_be_corrupted) {
  // Create a dummy password form.
  const base::string16 unique_string16 = ASCIIToUTF16(unique_string);
  PasswordForm form;
  form.origin = origin;
  form.username_element = unique_string16;
  form.username_value = unique_string16;
  form.password_element = unique_string16;
  form.password_value = unique_string16;
  form.signon_realm = origin.GetOrigin().spec();

  {
    LoginDatabase db(database_path());
    EXPECT_TRUE(db.Init());
    EXPECT_EQ(db.AddLogin(form), AddChangeForForm(form));
  }

  if (should_be_corrupted) {
    sql::Database db;
    EXPECT_TRUE(db.Open(database_path()));

    // Change encrypted password in the database if the login should be
    // corrupted.
    std::string statement =
        "UPDATE logins SET password_value = password_value || 'trash' "
        "WHERE signon_realm = ? AND username_value = ?";
    sql::Statement s(db.GetCachedStatement(SQL_FROM_HERE, statement.c_str()));
    s.BindString(0, form.signon_realm);
    s.BindString(1, base::UTF16ToUTF8(form.username_value));

    EXPECT_TRUE(s.is_valid());
    EXPECT_TRUE(s.Run());
    EXPECT_EQ(db.GetLastChangeCount(), 1);
  }

  return form;
}

TEST_F(LoginDatabaseUndecryptableLoginsTest, DeleteUndecryptableLoginsTest) {
  // Disable feature for deleting corrupted passwords, so GetAutofillableLogins
  // doesn't remove any passwords.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(
      features::kDeleteCorruptedPasswords);

  auto form1 = AddDummyLogin("foo1", GURL("https://foo1.com/"), false);
  auto form2 = AddDummyLogin("foo2", GURL("https://foo2.com/"), true);
  auto form3 = AddDummyLogin("foo3", GURL("https://foo3.com/"), false);

  LoginDatabase db(database_path());
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(db.Init());

#if defined(OS_MACOSX) && !defined(OS_IOS)
  testing_local_state().registry()->RegisterTimePref(prefs::kPasswordRecovery,
                                                     base::Time());
  db.InitPasswordRecoveryUtil(std::make_unique<PasswordRecoveryUtilMac>(
      &testing_local_state(), base::ThreadTaskRunnerHandle::Get()));

  // Make sure that we can't get any logins when database is corrupted.
  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_FALSE(db.GetAutofillableLogins(&result));
  EXPECT_TRUE(result.empty());

  // Delete undecryptable logins and make sure we can get valid logins.
  EXPECT_EQ(DatabaseCleanupResult::kSuccess, db.DeleteUndecryptableLogins());
  EXPECT_TRUE(db.GetAutofillableLogins(&result));
  EXPECT_THAT(result, UnorderedElementsAre(Pointee(form1), Pointee(form3)));

  RunUntilIdle();

  // Make sure that password recovery pref is set.
  ASSERT_TRUE(testing_local_state().HasPrefPath(prefs::kPasswordRecovery));
#else
  EXPECT_EQ(DatabaseCleanupResult::kSuccess, db.DeleteUndecryptableLogins());
#endif

// Check histograms.
#if defined(OS_MACOSX) && !defined(OS_IOS)
  histogram_tester.ExpectUniqueSample("PasswordManager.CleanedUpPasswords", 1,
                                      1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.DeleteUndecryptableLoginsReturnValue",
      metrics_util::DeleteCorruptedPasswordsResult::kSuccessPasswordsDeleted,
      1);
#else
  EXPECT_TRUE(
      histogram_tester.GetAllSamples("PasswordManager.CleanedUpPasswords")
          .empty());
#endif
}

#if defined(OS_MACOSX) && !defined(OS_IOS)
TEST_F(LoginDatabaseUndecryptableLoginsTest, PasswordRecoveryEnabledGetLogins) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(features::kDeleteCorruptedPasswords);

  auto form1 = AddDummyLogin("foo1", GURL("https://foo1.com/"), false);
  auto form2 = AddDummyLogin("foo2", GURL("https://foo2.com/"), true);
  auto form3 = AddDummyLogin("foo3", GURL("https://foo3.com/"), false);

  LoginDatabase db(database_path());
  ASSERT_TRUE(db.Init());

  testing_local_state().registry()->RegisterTimePref(prefs::kPasswordRecovery,
                                                     base::Time());
  db.InitPasswordRecoveryUtil(std::make_unique<PasswordRecoveryUtilMac>(
      &testing_local_state(), base::ThreadTaskRunnerHandle::Get()));

  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_TRUE(db.GetAutofillableLogins(&result));
  EXPECT_THAT(result, UnorderedElementsAre(Pointee(form1), Pointee(form3)));

  RunUntilIdle();
  EXPECT_TRUE(testing_local_state().HasPrefPath(prefs::kPasswordRecovery));

  histogram_tester.ExpectUniqueSample(
      "PasswordManager.RemovedCorruptedPasswords", 1, 1);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.DeleteCorruptedPasswordsResult",
      metrics_util::DeleteCorruptedPasswordsResult::kSuccessPasswordsDeleted,
      1);
}

TEST_F(LoginDatabaseUndecryptableLoginsTest,
       PasswordRecoveryDisabledGetLogins) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(
      features::kDeleteCorruptedPasswords);

  AddDummyLogin("foo1", GURL("https://foo1.com/"), false);
  AddDummyLogin("foo2", GURL("https://foo2.com/"), true);

  LoginDatabase db(database_path());
  ASSERT_TRUE(db.Init());

  testing_local_state().registry()->RegisterTimePref(prefs::kPasswordRecovery,
                                                     base::Time());
  db.InitPasswordRecoveryUtil(std::make_unique<PasswordRecoveryUtilMac>(
      &testing_local_state(), base::ThreadTaskRunnerHandle::Get()));

  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_FALSE(db.GetAutofillableLogins(&result));
  EXPECT_TRUE(result.empty());

  RunUntilIdle();
  EXPECT_FALSE(testing_local_state().HasPrefPath(prefs::kPasswordRecovery));

  EXPECT_TRUE(histogram_tester
                  .GetAllSamples("PasswordManager.RemovedCorruptedPasswords")
                  .empty());
  EXPECT_TRUE(
      histogram_tester
          .GetAllSamples("PasswordManager.DeleteCorruptedPasswordsResult")
          .empty());
}

TEST_F(LoginDatabaseUndecryptableLoginsTest,
       PasswordRecoveryEnabledKeychainLocked) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(features::kDeleteCorruptedPasswords);

  // This is a valid entry.
  auto form = AddDummyLogin("foo", GURL("https://foo.com/"), false);

  OSCryptMocker::SetBackendLocked(true);

  LoginDatabase db(database_path());
  ASSERT_TRUE(db.Init());

  testing_local_state().registry()->RegisterTimePref(prefs::kPasswordRecovery,
                                                     base::Time());
  db.InitPasswordRecoveryUtil(std::make_unique<PasswordRecoveryUtilMac>(
      &testing_local_state(), base::ThreadTaskRunnerHandle::Get()));

  std::vector<std::unique_ptr<PasswordForm>> result;
  EXPECT_FALSE(db.GetAutofillableLogins(&result));
  EXPECT_TRUE(result.empty());

  RunUntilIdle();
  EXPECT_FALSE(testing_local_state().HasPrefPath(prefs::kPasswordRecovery));

  EXPECT_TRUE(histogram_tester
                  .GetAllSamples("PasswordManager.RemovedCorruptedPasswords")
                  .empty());
  EXPECT_TRUE(
      histogram_tester
          .GetAllSamples("PasswordManager.DeleteCorruptedPasswordsResult")
          .empty());

  // Note: it's not possible that encryption suddenly becomes available. This is
  // only used to check that the form is not removed from the database.
  OSCryptMocker::SetBackendLocked(false);

  EXPECT_TRUE(db.GetAutofillableLogins(&result));
  EXPECT_THAT(result, UnorderedElementsAre(Pointee(form)));
}

TEST_F(LoginDatabaseUndecryptableLoginsTest, KeychainLockedTest) {
  AddDummyLogin("foo1", GURL("https://foo1.com/"), false);
  AddDummyLogin("foo2", GURL("https://foo2.com/"), true);

  OSCryptMocker::SetBackendLocked(true);
  LoginDatabase db(database_path());
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(db.Init());
  EXPECT_EQ(DatabaseCleanupResult::kEncryptionUnavailable,
            db.DeleteUndecryptableLogins());

  EXPECT_TRUE(
      histogram_tester.GetAllSamples("PasswordManager.CleanedUpPasswords")
          .empty());
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.DeleteUndecryptableLoginsReturnValue",
      metrics_util::DeleteCorruptedPasswordsResult::kEncryptionUnavailable, 1);
}
#endif  // defined(OS_MACOSX) && !defined(OS_IOS)

}  // namespace password_manager
