// Copyright (c) 2012 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 <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/pickle.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/test/scoped_task_environment.h"
#include "chrome/browser/password_manager/native_backend_kwallet_x.h"
#include "chrome/test/base/testing_profile.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/prefs/pref_service.h"
#include "dbus/message.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using autofill::PasswordForm;
using base::UTF8ToUTF16;
using password_manager::PasswordStoreChange;
using password_manager::PasswordStoreChangeList;
using testing::_;
using testing::Invoke;
using testing::Pointee;
using testing::Return;
using testing::TestWithParam;
using testing::UnorderedElementsAre;
using testing::Values;

namespace {

// This class implements a very simple version of KWallet in memory.
// We only provide the parts we actually use; the real version has more.
class TestKWallet {
 public:
  typedef std::basic_string<uint8_t> Blob;  // std::string is binary-safe.

  TestKWallet() : reject_local_folders_(false) {}

  void set_reject_local_folders(bool value) { reject_local_folders_ = value; }

  // NOTE: The method names here are the same as the corresponding DBus
  // methods, and therefore have names that don't match our style guide.

  // Check for presence of a given password folder.
  bool hasFolder(const std::string& folder) const {
    return data_.find(folder) != data_.end();
  }

  // Check for presence of a given password in a given password folder.
  bool hasEntry(const std::string& folder, const std::string& key) const {
    Data::const_iterator it = data_.find(folder);
    return it != data_.end() && it->second.find(key) != it->second.end();
  }

  // Get a list of password keys in a given password folder.
  bool entryList(const std::string& folder,
                 std::vector<std::string>* entries) const {
    Data::const_iterator it = data_.find(folder);
    if (it == data_.end()) return false;
    for (Folder::const_iterator fit = it->second.begin();
         fit != it->second.end(); ++fit)
      entries->push_back(fit->first);
    return true;
  }

  // Read the password data for a given password in a given password folder.
  bool readEntry(const std::string& folder, const std::string& key,
                 Blob* value) const {
    Data::const_iterator it = data_.find(folder);
    if (it == data_.end()) return false;
    Folder::const_iterator fit = it->second.find(key);
    if (fit == it->second.end()) return false;
    *value = fit->second;
    return true;
  }

  // Create the given password folder.
  bool createFolder(const std::string& folder) {
    if (reject_local_folders_ && folder.find('(') != std::string::npos)
      return false;
    return data_.insert(make_pair(folder, Folder())).second;
  }

  // Remove the given password from the given password folder.
  bool removeEntry(const std::string& folder, const std::string& key) {
    Data::iterator it = data_.find(folder);
    if (it == data_.end()) return false;
    return it->second.erase(key) > 0;
  }

  // Write the given password data to the given password folder.
  bool writeEntry(const std::string& folder, const std::string& key,
                  const Blob& value) {
    Data::iterator it = data_.find(folder);
    if (it == data_.end()) return false;
    it->second[key] = value;
    return true;
  }

 private:
  typedef std::map<std::string, Blob> Folder;
  typedef std::map<std::string, Folder> Data;

  Data data_;
  // "Local" folders are folders containing local profile IDs in their names. We
  // can reject attempts to create them in order to make it easier to create
  // legacy shared passwords in these tests, for testing the migration code.
  bool reject_local_folders_;

  // No need to disallow copy and assign. This class is safe to copy and assign.
};

// Runs |backend->GetAutofillableLogins(forms)| and expects that the return
// value is false.
void CheckGetAutofillableLoginsFails(
    PasswordStoreX::NativeBackend* backend,
    std::vector<std::unique_ptr<PasswordForm>>* forms) {
  EXPECT_FALSE(backend->GetAutofillableLogins(forms));
}

void CheckTrue(bool result) {
  EXPECT_TRUE(result);
}

void WriteHTMLAttributes(const PasswordForm& form, base::Pickle* pickle) {
  pickle->WriteInt(form.scheme);
  pickle->WriteString(form.origin.spec());
  pickle->WriteString(form.action.spec());
  pickle->WriteString16(form.username_element);
  pickle->WriteString16(form.username_value);
  pickle->WriteString16(form.password_element);
  pickle->WriteString16(form.password_value);
  pickle->WriteString16(form.submit_element);
}

void WritePreferenceMetadata(const PasswordForm& form, base::Pickle* pickle) {
  pickle->WriteBool(form.preferred);
  pickle->WriteBool(form.blacklisted_by_user);
}

}  // anonymous namespace

// Obscure magic: we need to declare storage for this constant because we use it
// in ways that require its address in this test, but not in the actual code.
const int NativeBackendKWallet::kInvalidKWalletHandle;

// Subclass NativeBackendKWallet to promote some members to public for testing.
class NativeBackendKWalletStub : public NativeBackendKWallet {
 public:
  NativeBackendKWalletStub(LocalProfileId id,
                           base::nix::DesktopEnvironment desktop_env)
      : NativeBackendKWallet(id, desktop_env) {}
  using NativeBackendKWallet::InitWithBus;
  using NativeBackendKWallet::kInvalidKWalletHandle;
  using NativeBackendKWallet::DeserializeValue;
};

// Provide some test forms to avoid having to set them up in each test.
class NativeBackendKWalletTestBase :
    public testing::TestWithParam<base::nix::DesktopEnvironment> {
 protected:
  NativeBackendKWalletTestBase() {
    old_form_google_.origin = GURL("http://www.google.com/");
    old_form_google_.action = GURL("http://www.google.com/login");
    old_form_google_.username_element = UTF8ToUTF16("user");
    old_form_google_.username_value = UTF8ToUTF16("joeschmoe");
    old_form_google_.password_element = UTF8ToUTF16("pass");
    old_form_google_.password_value = UTF8ToUTF16("seekrit");
    old_form_google_.submit_element = UTF8ToUTF16("submit");
    old_form_google_.signon_realm = "Google";
    old_form_google_.date_created = base::Time::Now();

    form_google_ = old_form_google_;
    form_google_.times_used = 3;
    form_google_.type = PasswordForm::TYPE_GENERATED;
    form_google_.form_data.name = UTF8ToUTF16("form_name");
    form_google_.date_synced = base::Time::Now();
    form_google_.date_created = old_form_google_.date_created;
    form_google_.display_name = UTF8ToUTF16("Joe Schmoe");
    form_google_.icon_url = GURL("http://www.google.com/icon");
    form_google_.federation_origin =
        url::Origin::Create(GURL("http://www.google.com/"));
    form_google_.skip_zero_click = true;
    form_google_.generation_upload_status = PasswordForm::NEGATIVE_SIGNAL_SENT;

    form_isc_.origin = GURL("http://www.isc.org/");
    form_isc_.action = GURL("http://www.isc.org/auth");
    form_isc_.username_element = UTF8ToUTF16("id");
    form_isc_.username_value = UTF8ToUTF16("janedoe");
    form_isc_.password_element = UTF8ToUTF16("passwd");
    form_isc_.password_value = UTF8ToUTF16("ihazabukkit");
    form_isc_.submit_element = UTF8ToUTF16("login");
    form_isc_.signon_realm = "ISC";
    form_isc_.date_synced = base::Time::Now();
    form_isc_.date_created = base::Time::Now();
  }

  static void CheckPasswordForm(const PasswordForm& expected,
                                const PasswordForm& actual,
                                bool check_date_created);
  static void CheckPasswordChanges(const PasswordStoreChangeList& expected,
                                   const PasswordStoreChangeList& actual);
  static void CheckPasswordChangesWithResult(
      const PasswordStoreChangeList* expected,
      const PasswordStoreChangeList* actual,
      bool result);

  base::test::ScopedTaskEnvironment scoped_task_environment_;

  PasswordForm old_form_google_;
  PasswordForm form_google_;
  PasswordForm form_isc_;
};

// static
void NativeBackendKWalletTestBase::CheckPasswordForm(
    const PasswordForm& expected,
    const PasswordForm& actual,
    bool check_date_created) {
  EXPECT_EQ(expected.origin, actual.origin);
  EXPECT_EQ(expected.password_value, actual.password_value);
  EXPECT_EQ(expected.action, actual.action);
  EXPECT_EQ(expected.username_element, actual.username_element);
  EXPECT_EQ(expected.username_value, actual.username_value);
  EXPECT_EQ(expected.password_element, actual.password_element);
  EXPECT_EQ(expected.submit_element, actual.submit_element);
  EXPECT_EQ(expected.signon_realm, actual.signon_realm);
  EXPECT_EQ(expected.preferred, actual.preferred);
  if (check_date_created) {
    EXPECT_EQ(expected.date_created, actual.date_created);
  }
  EXPECT_EQ(expected.blacklisted_by_user, actual.blacklisted_by_user);
  EXPECT_EQ(expected.type, actual.type);
  EXPECT_EQ(expected.times_used, actual.times_used);
  EXPECT_EQ(expected.scheme, actual.scheme);
  EXPECT_EQ(expected.date_synced, actual.date_synced);
  EXPECT_EQ(expected.display_name, actual.display_name);
  EXPECT_EQ(expected.icon_url, actual.icon_url);
  EXPECT_EQ(expected.federation_origin.Serialize(),
            actual.federation_origin.Serialize());
  EXPECT_EQ(expected.skip_zero_click, actual.skip_zero_click);
  EXPECT_EQ(expected.generation_upload_status, actual.generation_upload_status);
}

// static
void NativeBackendKWalletTestBase::CheckPasswordChanges(
    const PasswordStoreChangeList& expected,
    const PasswordStoreChangeList& actual) {
  ASSERT_EQ(expected.size(), actual.size());
  for (size_t i = 0; i < expected.size(); ++i) {
    EXPECT_EQ(expected[i].type(), actual[i].type());
    CheckPasswordForm(expected[i].form(), actual[i].form(), true);
  }
}

// static
void NativeBackendKWalletTestBase::CheckPasswordChangesWithResult(
    const PasswordStoreChangeList* expected,
    const PasswordStoreChangeList* actual,
    bool result) {
  EXPECT_TRUE(result);
  CheckPasswordChanges(*expected, *actual);
}

class NativeBackendKWalletTest : public NativeBackendKWalletTestBase {
 protected:
  NativeBackendKWalletTest()
      : klauncher_ret_(0),
        klauncher_contacted_(false),
        kwallet_runnable_(true),
        kwallet_running_(true),
        kwallet_enabled_(true),
        desktop_env_(GetParam()) {}

  void SetUp() override;

  // Utilities to help verify sets of expectations.
  typedef std::vector<
              std::pair<std::string,
                        std::vector<const PasswordForm*> > > ExpectationArray;
  void CheckPasswordForms(const std::string& folder,
                          const ExpectationArray& sorted_expected);

  enum RemoveBetweenMethod {
    CREATED,
    SYNCED,
  };

  // Tests RemoveLoginsCreatedBetween or RemoveLoginsSyncedBetween.
  void TestRemoveLoginsBetween(RemoveBetweenMethod date_to_test);

  scoped_refptr<dbus::MockBus> mock_session_bus_;
  scoped_refptr<dbus::MockObjectProxy> mock_klauncher_proxy_;
  scoped_refptr<dbus::MockObjectProxy> mock_kwallet_proxy_;

  int klauncher_ret_;
  std::string klauncher_error_;
  bool klauncher_contacted_;

  bool kwallet_runnable_;
  bool kwallet_running_;
  bool kwallet_enabled_;

  // Used for switching between kwalletd and kwalletd5
  base::nix::DesktopEnvironment desktop_env_;

  TestKWallet wallet_;

  // For all method names contained in |failing_methods_|, the mocked KWallet
  // will return a null response.
  std::set<std::string> failing_methods_;

 private:
  std::unique_ptr<dbus::Response> KLauncherMethodCall(
      dbus::MethodCall* method_call, testing::Unused);

  std::unique_ptr<dbus::Response> KWalletMethodCall(
      dbus::MethodCall* method_call, testing::Unused);
};

void NativeBackendKWalletTest::SetUp() {
  dbus::Bus::Options options;
  options.bus_type = dbus::Bus::SESSION;
  mock_session_bus_ = new dbus::MockBus(options);

  mock_klauncher_proxy_ =
      new dbus::MockObjectProxy(mock_session_bus_.get(),
                                "org.kde.klauncher",
                                dbus::ObjectPath("/KLauncher"));
  EXPECT_CALL(*mock_klauncher_proxy_.get(), CallMethodAndBlock(_, _))
      .WillRepeatedly(
           Invoke(this, &NativeBackendKWalletTest::KLauncherMethodCall));

  if (desktop_env_ == base::nix::DESKTOP_ENVIRONMENT_KDE5) {
    mock_kwallet_proxy_ =
        new dbus::MockObjectProxy(mock_session_bus_.get(),
                                  "org.kde.kwalletd5",
                                  dbus::ObjectPath("/modules/kwalletd5"));
  } else {
    mock_kwallet_proxy_ =
        new dbus::MockObjectProxy(mock_session_bus_.get(),
                                  "org.kde.kwalletd",
                                  dbus::ObjectPath("/modules/kwalletd"));
  }
  EXPECT_CALL(*mock_kwallet_proxy_.get(), CallMethodAndBlock(_, _))
      .WillRepeatedly(
           Invoke(this, &NativeBackendKWalletTest::KWalletMethodCall));

  EXPECT_CALL(
      *mock_session_bus_.get(),
      GetObjectProxy("org.kde.klauncher", dbus::ObjectPath("/KLauncher")))
      .WillRepeatedly(Return(mock_klauncher_proxy_.get()));
  if (desktop_env_ == base::nix::DESKTOP_ENVIRONMENT_KDE5) {
    EXPECT_CALL(
        *mock_session_bus_.get(),
        GetObjectProxy("org.kde.kwalletd5",
                       dbus::ObjectPath("/modules/kwalletd5")))
        .WillRepeatedly(Return(mock_kwallet_proxy_.get()));
  } else {
    EXPECT_CALL(
        *mock_session_bus_.get(),
        GetObjectProxy("org.kde.kwalletd",
                       dbus::ObjectPath("/modules/kwalletd")))
        .WillRepeatedly(Return(mock_kwallet_proxy_.get()));
  }

  EXPECT_CALL(*mock_session_bus_.get(), ShutdownAndBlock()).WillOnce(Return())
      .WillRepeatedly(Return());
}

void NativeBackendKWalletTest::TestRemoveLoginsBetween(
    RemoveBetweenMethod date_to_test) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  form_google_.date_synced = base::Time();
  form_isc_.date_synced = base::Time();
  form_google_.date_created = base::Time();
  form_isc_.date_created = base::Time();
  base::Time now = base::Time::Now();
  base::Time next_day = now + base::TimeDelta::FromDays(1);
  if (date_to_test == CREATED) {
    form_google_.date_created = now;
    form_isc_.date_created = next_day;
  } else {
    form_google_.date_synced = now;
    form_isc_.date_synced = next_day;
  }

  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_isc_));

  PasswordStoreChangeList expected_changes;
  expected_changes.push_back(
      PasswordStoreChange(PasswordStoreChange::REMOVE, form_google_));
  PasswordStoreChangeList changes;
  bool (NativeBackendKWallet::*method)(
      base::Time, base::Time, password_manager::PasswordStoreChangeList*) =
      date_to_test == CREATED
          ? &NativeBackendKWalletStub::RemoveLoginsCreatedBetween
          : &NativeBackendKWalletStub::RemoveLoginsSyncedBetween;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(method, base::Unretained(&backend), base::Time(), next_day,
                 &changes),
      base::Bind(&CheckPasswordChangesWithResult, &expected_changes, &changes));

  scoped_task_environment_.RunUntilIdle();

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_isc_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_isc_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);

  // Remove form_isc_.
  expected_changes.clear();
  expected_changes.push_back(
      PasswordStoreChange(PasswordStoreChange::REMOVE, form_isc_));
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(method, base::Unretained(&backend), next_day, base::Time(),
                 &changes),
      base::Bind(&CheckPasswordChangesWithResult, &expected_changes, &changes));

  scoped_task_environment_.RunUntilIdle();

  CheckPasswordForms("Chrome Form Data (42)", ExpectationArray());
}

std::unique_ptr<dbus::Response> NativeBackendKWalletTest::KLauncherMethodCall(
    dbus::MethodCall* method_call, testing::Unused) {
  EXPECT_EQ("org.kde.KLauncher", method_call->GetInterface());
  EXPECT_EQ("start_service_by_desktop_name", method_call->GetMember());

  klauncher_contacted_ = true;

  dbus::MessageReader reader(method_call);
  std::string service_name;
  std::vector<std::string> urls;
  std::vector<std::string> envs;
  std::string startup_id;
  bool blind = false;

  EXPECT_TRUE(reader.PopString(&service_name));
  EXPECT_TRUE(reader.PopArrayOfStrings(&urls));
  EXPECT_TRUE(reader.PopArrayOfStrings(&envs));
  EXPECT_TRUE(reader.PopString(&startup_id));
  EXPECT_TRUE(reader.PopBool(&blind));

  if (desktop_env_ == base::nix::DESKTOP_ENVIRONMENT_KDE5)
    EXPECT_EQ("kwalletd5", service_name);
  else
    EXPECT_EQ("kwalletd", service_name);
  EXPECT_TRUE(urls.empty());
  EXPECT_TRUE(envs.empty());
  EXPECT_TRUE(startup_id.empty());
  EXPECT_FALSE(blind);

  if (kwallet_runnable_)
    kwallet_running_ = true;

  std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  dbus::MessageWriter writer(response.get());
  writer.AppendInt32(klauncher_ret_);
  writer.AppendString(std::string());  // dbus_name
  writer.AppendString(klauncher_error_);
  writer.AppendInt32(1234);  // pid
  return response;
}

std::unique_ptr<dbus::Response> NativeBackendKWalletTest::KWalletMethodCall(
    dbus::MethodCall* method_call, testing::Unused) {
  if (!kwallet_running_)
    return nullptr;
  EXPECT_EQ("org.kde.KWallet", method_call->GetInterface());

  if (base::ContainsKey(failing_methods_, method_call->GetMember()))
    return nullptr;
  std::unique_ptr<dbus::Response> response;
  if (method_call->GetMember() == "isEnabled") {
    response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(response.get());
    writer.AppendBool(kwallet_enabled_);
  } else if (method_call->GetMember() == "networkWallet") {
    response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(response.get());
    writer.AppendString("test_wallet");  // Should match |open| below.
  } else if (method_call->GetMember() == "open") {
    dbus::MessageReader reader(method_call);
    std::string wallet_name;
    int64_t wallet_id;
    std::string app_name;
    EXPECT_TRUE(reader.PopString(&wallet_name));
    EXPECT_TRUE(reader.PopInt64(&wallet_id));
    EXPECT_TRUE(reader.PopString(&app_name));
    EXPECT_EQ("test_wallet", wallet_name);  // Should match |networkWallet|.
    response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(response.get());
    writer.AppendInt32(1);  // Can be anything but kInvalidKWalletHandle.
  } else if (method_call->GetMember() == "hasFolder" ||
             method_call->GetMember() == "createFolder") {
    dbus::MessageReader reader(method_call);
    int handle = NativeBackendKWalletStub::kInvalidKWalletHandle;
    std::string folder_name;
    std::string app_name;
    EXPECT_TRUE(reader.PopInt32(&handle));
    EXPECT_TRUE(reader.PopString(&folder_name));
    EXPECT_TRUE(reader.PopString(&app_name));
    EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle, handle);
    response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(response.get());
    if (method_call->GetMember() == "hasFolder")
      writer.AppendBool(wallet_.hasFolder(folder_name));
    else
      writer.AppendBool(wallet_.createFolder(folder_name));
  } else if (method_call->GetMember() == "hasEntry" ||
             method_call->GetMember() == "removeEntry") {
    dbus::MessageReader reader(method_call);
    int handle = NativeBackendKWalletStub::kInvalidKWalletHandle;
    std::string folder_name;
    std::string key;
    std::string app_name;
    EXPECT_TRUE(reader.PopInt32(&handle));
    EXPECT_TRUE(reader.PopString(&folder_name));
    EXPECT_TRUE(reader.PopString(&key));
    EXPECT_TRUE(reader.PopString(&app_name));
    EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle, handle);
    response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(response.get());
    if (method_call->GetMember() == "hasEntry")
      writer.AppendBool(wallet_.hasEntry(folder_name, key));
    else
      writer.AppendInt32(wallet_.removeEntry(folder_name, key) ? 0 : 1);
  } else if (method_call->GetMember() == "entryList") {
    dbus::MessageReader reader(method_call);
    int handle = NativeBackendKWalletStub::kInvalidKWalletHandle;
    std::string folder_name;
    std::string app_name;
    EXPECT_TRUE(reader.PopInt32(&handle));
    EXPECT_TRUE(reader.PopString(&folder_name));
    EXPECT_TRUE(reader.PopString(&app_name));
    EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle, handle);
    std::vector<std::string> entries;
    if (wallet_.entryList(folder_name, &entries)) {
      response = dbus::Response::CreateEmpty();
      dbus::MessageWriter writer(response.get());
      writer.AppendArrayOfStrings(entries);
    }
  } else if (method_call->GetMember() == "readEntry") {
    dbus::MessageReader reader(method_call);
    int handle = NativeBackendKWalletStub::kInvalidKWalletHandle;
    std::string folder_name;
    std::string key;
    std::string app_name;
    EXPECT_TRUE(reader.PopInt32(&handle));
    EXPECT_TRUE(reader.PopString(&folder_name));
    EXPECT_TRUE(reader.PopString(&key));
    EXPECT_TRUE(reader.PopString(&app_name));
    EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle, handle);
    TestKWallet::Blob value;
    if (wallet_.readEntry(folder_name, key, &value)) {
      response = dbus::Response::CreateEmpty();
      dbus::MessageWriter writer(response.get());
      writer.AppendArrayOfBytes(value.data(), value.size());
    }
  } else if (method_call->GetMember() == "writeEntry") {
    dbus::MessageReader reader(method_call);
    int handle = NativeBackendKWalletStub::kInvalidKWalletHandle;
    std::string folder_name;
    std::string key;
    const uint8_t* bytes = nullptr;
    size_t length = 0;
    std::string app_name;
    EXPECT_TRUE(reader.PopInt32(&handle));
    EXPECT_TRUE(reader.PopString(&folder_name));
    EXPECT_TRUE(reader.PopString(&key));
    EXPECT_TRUE(reader.PopArrayOfBytes(&bytes, &length));
    EXPECT_TRUE(reader.PopString(&app_name));
    EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle, handle);
    response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(response.get());
    writer.AppendInt32(
        wallet_.writeEntry(folder_name, key,
                           TestKWallet::Blob(bytes, length)) ? 0 : 1);
  }

  EXPECT_TRUE(response);
  return response;
}

void NativeBackendKWalletTest::CheckPasswordForms(
    const std::string& folder, const ExpectationArray& sorted_expected) {
  EXPECT_TRUE(wallet_.hasFolder(folder));
  std::vector<std::string> entries;
  EXPECT_TRUE(wallet_.entryList(folder, &entries));
  EXPECT_EQ(sorted_expected.size(), entries.size());
  std::sort(entries.begin(), entries.end());
  for (size_t i = 0; i < entries.size() && i < sorted_expected.size(); ++i) {
    EXPECT_EQ(sorted_expected[i].first, entries[i]);
    TestKWallet::Blob value;
    EXPECT_TRUE(wallet_.readEntry(folder, entries[i], &value));
    base::Pickle pickle(reinterpret_cast<const char*>(value.data()),
                        value.size());
    std::vector<std::unique_ptr<PasswordForm>> forms =
        NativeBackendKWalletStub::DeserializeValue(entries[i], pickle);
    const std::vector<const PasswordForm*>& expect = sorted_expected[i].second;
    EXPECT_EQ(expect.size(), forms.size());
    for (size_t j = 0; j < forms.size() && j < expect.size(); ++j)
      CheckPasswordForm(*expect[j], *forms[j], true);
  }
}

TEST_P(NativeBackendKWalletTest, NotEnabled) {
  NativeBackendKWalletStub kwallet(42, desktop_env_);
  kwallet_enabled_ = false;
  EXPECT_FALSE(kwallet.InitWithBus(mock_session_bus_));
  EXPECT_FALSE(klauncher_contacted_);
}

TEST_P(NativeBackendKWalletTest, NotRunnable) {
  NativeBackendKWalletStub kwallet(42, desktop_env_);
  kwallet_runnable_ = false;
  kwallet_running_ = false;
  EXPECT_FALSE(kwallet.InitWithBus(mock_session_bus_));
  EXPECT_TRUE(klauncher_contacted_);
}

TEST_P(NativeBackendKWalletTest, NotRunningOrEnabled) {
  NativeBackendKWalletStub kwallet(42, desktop_env_);
  kwallet_running_ = false;
  kwallet_enabled_ = false;
  EXPECT_FALSE(kwallet.InitWithBus(mock_session_bus_));
  EXPECT_TRUE(klauncher_contacted_);
}

TEST_P(NativeBackendKWalletTest, NotRunning) {
  NativeBackendKWalletStub kwallet(42, desktop_env_);
  kwallet_running_ = false;
  EXPECT_TRUE(kwallet.InitWithBus(mock_session_bus_));
  EXPECT_TRUE(klauncher_contacted_);
}

TEST_P(NativeBackendKWalletTest, BasicStartup) {
  NativeBackendKWalletStub kwallet(42, desktop_env_);
  EXPECT_TRUE(kwallet.InitWithBus(mock_session_bus_));
  EXPECT_FALSE(klauncher_contacted_);
}

TEST_P(NativeBackendKWalletTest, BasicAddLogin) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::AddLogin,
                 base::Unretained(&backend), form_google_),
      base::Bind(
          &CheckPasswordChanges,
          PasswordStoreChangeList(
              1, PasswordStoreChange(PasswordStoreChange::ADD, form_google_))));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_FALSE(wallet_.hasFolder("Chrome Form Data"));

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, BasicUpdateLogin) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));

  scoped_task_environment_.RunUntilIdle();

  PasswordForm new_form_google(form_google_);
  new_form_google.times_used = 10;
  new_form_google.action = GURL("http://www.google.com/different/login");

  // Update login
  PasswordStoreChangeList changes;
  PasswordStoreChangeList expected_changes(
      1, PasswordStoreChange(PasswordStoreChange::UPDATE, new_form_google));
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::UpdateLogin,
                 base::Unretained(&backend), new_form_google, &changes),
      base::Bind(&CheckPasswordChangesWithResult, &expected_changes, &changes));

  scoped_task_environment_.RunUntilIdle();

  ASSERT_EQ(1u, changes.size());
  EXPECT_EQ(PasswordStoreChange::UPDATE, changes.front().type());
  EXPECT_EQ(new_form_google, changes.front().form());

  std::vector<const PasswordForm*> forms;
  forms.push_back(&new_form_google);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, BasicListLogins) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));

  std::vector<std::unique_ptr<PasswordForm>> form_list;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::GetAutofillableLogins,
                 base::Unretained(&backend), &form_list),
      base::Bind(&CheckTrue));

  scoped_task_environment_.RunUntilIdle();

  // Quick check that we got something back.
  EXPECT_EQ(1u, form_list.size());

  EXPECT_FALSE(wallet_.hasFolder("Chrome Form Data"));

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, BasicRemoveLogin) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_FALSE(wallet_.hasFolder("Chrome Form Data"));

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);

  PasswordStoreChangeList changes;
  PasswordStoreChangeList expected_changes(
      1, PasswordStoreChange(PasswordStoreChange::REMOVE, form_google_));
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::RemoveLogin,
                 base::Unretained(&backend), form_google_, &changes),
      base::Bind(&CheckPasswordChangesWithResult, &expected_changes, &changes));

  scoped_task_environment_.RunUntilIdle();

  expected.clear();
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, UpdateNonexistentLogin) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  // First add an unrelated login.
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));

  scoped_task_environment_.RunUntilIdle();

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);

  // Attempt to update a login that doesn't exist.
  PasswordStoreChangeList changes;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::UpdateLogin,
                 base::Unretained(&backend), form_isc_, &changes),
      base::Bind(&CheckPasswordChangesWithResult,
                 base::Owned(new PasswordStoreChangeList), &changes));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_EQ(PasswordStoreChangeList(), changes);
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, RemoveNonexistentLogin) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  // First add an unrelated login.
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_FALSE(wallet_.hasFolder("Chrome Form Data"));

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);

  // Attempt to remove a login that doesn't exist.
  PasswordStoreChangeList changes;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::RemoveLogin,
                 base::Unretained(&backend), form_isc_, &changes),
      base::Bind(&CheckPasswordChangesWithResult,
                 base::Owned(new PasswordStoreChangeList), &changes));

  // Make sure we can still get the first form back.
  std::vector<std::unique_ptr<PasswordForm>> form_list;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::GetAutofillableLogins,
                 base::Unretained(&backend), &form_list),
      base::Bind(&CheckTrue));

  scoped_task_environment_.RunUntilIdle();

  // Quick check that we got something back.
  EXPECT_EQ(1u, form_list.size());

  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, AddDuplicateLogin) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  PasswordStoreChangeList changes;
  changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD,
                                        form_google_));
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::AddLogin,
                 base::Unretained(&backend), form_google_),
      base::Bind(&NativeBackendKWalletTest::CheckPasswordChanges, changes));

  changes.clear();
  changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE,
                                        form_google_));
  form_google_.times_used++;
  form_google_.submit_element = UTF8ToUTF16("submit2");
  changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD,
                                        form_google_));

  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::AddLogin,
                 base::Unretained(&backend), form_google_),
      base::Bind(&NativeBackendKWalletTest::CheckPasswordChanges, changes));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_FALSE(wallet_.hasFolder("Chrome Form Data"));

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, AndroidCredentials) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  PasswordForm saved_android_form;
  saved_android_form.scheme = PasswordForm::SCHEME_HTML;
  saved_android_form.signon_realm =
      "android://7x7IDboo8u9YKraUsbmVkuf1-@net.rateflix.app/";
  saved_android_form.username_value = base::UTF8ToUTF16("randomusername");
  saved_android_form.password_value = base::UTF8ToUTF16("password");

  password_manager::PasswordStore::FormDigest observed_android_form(
      saved_android_form);
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::AddLogin,
                 base::Unretained(&backend), saved_android_form),
      base::Bind(&CheckPasswordChanges,
                 PasswordStoreChangeList(
                     1, PasswordStoreChange(PasswordStoreChange::ADD,
                                            saved_android_form))));

  std::vector<std::unique_ptr<PasswordForm>> form_list;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::GetLogins,
                 base::Unretained(&backend), observed_android_form, &form_list),
      base::Bind(&CheckTrue));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_EQ(1u, form_list.size());

  std::vector<const PasswordForm*> forms;
  forms.push_back(&saved_android_form);
  ExpectationArray expected;
  expected.push_back(
      make_pair(std::string(saved_android_form.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, RemoveLoginsCreatedBetween) {
  TestRemoveLoginsBetween(CREATED);
}

TEST_P(NativeBackendKWalletTest, RemoveLoginsSyncedBetween) {
  TestRemoveLoginsBetween(SYNCED);
}

TEST_P(NativeBackendKWalletTest, DisableAutoSignInForOrigins) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  form_isc_.skip_zero_click = false;
  form_google_.skip_zero_click = false;

  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWallet::AddLogin),
                     base::Unretained(&backend), form_isc_));
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWallet::AddLogin),
                     base::Unretained(&backend), form_google_));

  scoped_task_environment_.RunUntilIdle();

  // Set the canonical forms to the updated value for the following comparison.
  form_google_.skip_zero_click = true;
  PasswordStoreChangeList expected_changes;
  expected_changes.push_back(
      PasswordStoreChange(PasswordStoreChange::UPDATE, form_google_));

  PasswordStoreChangeList changes;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(
          &NativeBackendKWallet::DisableAutoSignInForOrigins,
          base::Unretained(&backend),
          base::Bind(
              static_cast<bool (*)(const GURL&, const GURL&)>(operator==),
              form_google_.origin),
          &changes),
      base::Bind(&CheckPasswordChangesWithResult, &expected_changes, &changes));

  scoped_task_environment_.RunUntilIdle();

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  forms.clear();
  forms.push_back(&form_isc_);
  expected.push_back(make_pair(std::string(form_isc_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

TEST_P(NativeBackendKWalletTest, ReadDuplicateForms) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  // Add 2 slightly different password forms.
  const char unique_string[] = "unique_unique_string";
  const char unique_string_replacement[] = "uniKue_unique_string";
  form_google_.origin =
      GURL(std::string("http://www.google.com/") + unique_string);
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));
  form_google_.origin =
      GURL(std::string("http://www.google.com/") + unique_string_replacement);
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));

  scoped_task_environment_.RunUntilIdle();

  // Read the raw value back. Change the |unique_string| to
  // |unique_string_replacement| so the forms become unique.
  TestKWallet::Blob value;
  ASSERT_TRUE(wallet_.readEntry("Chrome Form Data (42)",
                                form_google_.signon_realm, &value));
  TestKWallet::Blob sample(reinterpret_cast<const uint8_t*>(unique_string));
  size_t position = value.find(sample);
  ASSERT_NE(TestKWallet::Blob::npos, position);
  value.replace(position, sample.length(),
                reinterpret_cast<const uint8_t*>(unique_string_replacement));
  wallet_.writeEntry("Chrome Form Data (42)", form_google_.signon_realm, value);

  // Now test that GetAutofillableLogins returns only one form.
  std::vector<std::unique_ptr<PasswordForm>> form_list;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::GetAutofillableLogins,
                 base::Unretained(&backend), &form_list),
      base::Bind(&CheckTrue));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_EQ(1u, form_list.size());
  EXPECT_EQ(form_google_, *form_list[0]);

  std::vector<const PasswordForm*> forms;
  forms.push_back(&form_google_);
  ExpectationArray expected;
  expected.push_back(make_pair(std::string(form_google_.signon_realm), forms));
  CheckPasswordForms("Chrome Form Data (42)", expected);
}

// Check that if KWallet fails to respond, the backend propagates the error.
TEST_P(NativeBackendKWalletTest, GetAllLoginsErrorHandling) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));
  // Make KWallet fail on calling readEntry.
  failing_methods_.insert("readEntry");

  // Store some non-blacklisted logins to be potentially returned.
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::AddLogin,
                 base::Unretained(&backend), form_google_),
      base::Bind(
          &CheckPasswordChanges,
          PasswordStoreChangeList(
              1, PasswordStoreChange(PasswordStoreChange::ADD, form_google_))));

  // Verify that nothing is in fact returned, because KWallet fails to respond.
  std::vector<std::unique_ptr<PasswordForm>> form_list;
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE, base::BindOnce(&CheckGetAutofillableLoginsFails,
                                base::Unretained(&backend), &form_list));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_EQ(0u, form_list.size());
}

TEST_P(NativeBackendKWalletTest, GetAllLogins) {
  NativeBackendKWalletStub backend(42, desktop_env_);
  EXPECT_TRUE(backend.InitWithBus(mock_session_bus_));

  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_google_));
  backend.GetBackgroundTaskRunner()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                     base::Unretained(&backend), form_isc_));

  std::vector<std::unique_ptr<PasswordForm>> form_list;
  base::PostTaskAndReplyWithResult(
      backend.GetBackgroundTaskRunner().get(), FROM_HERE,
      base::Bind(&NativeBackendKWalletStub::GetAllLogins,
                 base::Unretained(&backend), &form_list),
      base::Bind(&CheckTrue));

  scoped_task_environment_.RunUntilIdle();

  EXPECT_EQ(2u, form_list.size());
  EXPECT_THAT(form_list,
              UnorderedElementsAre(Pointee(form_google_), Pointee(form_isc_)));
}

INSTANTIATE_TEST_CASE_P(,
                        NativeBackendKWalletTest,
                        ::testing::Values(base::nix::DESKTOP_ENVIRONMENT_KDE4,
                                          base::nix::DESKTOP_ENVIRONMENT_KDE5));

// TODO(mdm): add more basic tests here at some point.
// (For example tests for storing >1 password per realm pickle.)

class NativeBackendKWalletPickleTest : public NativeBackendKWalletTestBase {
 protected:
  // Based on |form|, fills |pickle| with data conforming to
  // |effective_version|, but marking the pickle version as |stored_version|. In
  // most cases the two versions should be the same.
  void CreateVersion1PlusPickle(const PasswordForm& form,
                                base::Pickle* pickle,
                                int stored_version,
                                int effective_version);
  // If |size_32| is true, stores the number of forms in the pickle as a 32bit
  // uint, otherwise as 64 bit size_t.
  void CreateVersion0Pickle(bool size_32,
                            const PasswordForm& form,
                            base::Pickle* pickle);
  void CheckVersion9Pickle();
  void CheckVersion8Pickle();
  void CheckVersion7Pickle();
  // As explained in http://crbug.com/494229#c11, version 6 added a new optional
  // field to version 5. This field became required in version 7. Depending on
  // |with_optional_field|, this method checks deserialization with or without
  // the optional field.
  void CheckVersion6Pickle(bool with_optional_field);
  void CheckVersion5Pickle();
  void CheckVersion3Pickle();
  void CheckVersion2Pickle();
  void CheckVersion1Pickle();
  void CheckVersion0Pickle(bool size_32, PasswordForm::Scheme scheme);
};

void NativeBackendKWalletPickleTest::CreateVersion1PlusPickle(
    const PasswordForm& form,
    base::Pickle* pickle,
    int stored_version,
    int effective_version) {
  pickle->WriteInt(stored_version);
  pickle->WriteUInt64(1);  // Number of forms in the pickle.
  WriteHTMLAttributes(form, pickle);
  if (effective_version < 9)
    pickle->WriteBool(true);  // Unused flag.
  WritePreferenceMetadata(form, pickle);
  pickle->WriteInt64(form.date_created.ToInternalValue());
  if (effective_version < 2)
    return;
  pickle->WriteInt(form.type);
  pickle->WriteInt(form.times_used);
  autofill::SerializeFormData(form.form_data, pickle);
  if (effective_version < 3)
    return;
  pickle->WriteInt64(form.date_synced.ToInternalValue());
  if (effective_version < 4)
    return;
  pickle->WriteString16(form.display_name);
  pickle->WriteString(form.icon_url.spec());
  pickle->WriteString(form.federation_origin.Serialize());
  pickle->WriteBool(form.skip_zero_click);
  if (effective_version < 7)
    return;
  pickle->WriteInt(form.generation_upload_status);
}

void NativeBackendKWalletPickleTest::CreateVersion0Pickle(
    bool size_32,
    const PasswordForm& form,
    base::Pickle* pickle) {
  pickle->WriteInt(0);
  // Write the number of forms in the pickle in the appopriate bit size.
  if (size_32)
    pickle->WriteUInt32(1);
  else
    pickle->WriteUInt64(1);
  WriteHTMLAttributes(form, pickle);
  pickle->WriteBool(true);  // Unused flag.
  WritePreferenceMetadata(form, pickle);
  // Old way to store the date.
  pickle->WriteInt64(form.date_created.ToTimeT());
}

void NativeBackendKWalletPickleTest::CheckVersion9Pickle() {
  // Pickle 9+ dropped an old flag in the middle of PasswordForm. This test
  // makes sure that the attributes after the dropped flag are deserialised
  // correctly.
  base::Pickle pickle;
  PasswordForm default_values;
  PasswordForm form = form_google_;

  CreateVersion1PlusPickle(form, &pickle, 9, 9);
  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], true);
}

void NativeBackendKWalletPickleTest::CheckVersion8Pickle() {
  base::Pickle pickle;
  PasswordForm default_values;
  PasswordForm form = form_google_;

  // Version 8 pickles deserialize with their own 'skip_zero_click' value.
  form.skip_zero_click = false;
  CreateVersion1PlusPickle(form, &pickle, 8, 8);
  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], true);
}

void NativeBackendKWalletPickleTest::CheckVersion7Pickle() {
  base::Pickle pickle;
  PasswordForm default_values;
  PasswordForm form = form_google_;

  // Version 7 pickles always deserialize with 'skip_zero_click' of 'true'.
  form.skip_zero_click = false;
  CreateVersion1PlusPickle(form, &pickle, 7, 7);
  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
  EXPECT_EQ(1u, form_list.size());
  form.skip_zero_click = true;
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], true);
}

void NativeBackendKWalletPickleTest::CheckVersion6Pickle(
    bool with_optional_field) {
  base::Pickle pickle;
  PasswordForm form = form_google_;
  if (!with_optional_field) {
    PasswordForm default_values;
    form.generation_upload_status = default_values.generation_upload_status;
  }
  CreateVersion1PlusPickle(form, &pickle, 6, with_optional_field ? 7 : 5);

  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);

  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], true);
}

void NativeBackendKWalletPickleTest::CheckVersion5Pickle() {
  base::Pickle pickle;
  PasswordForm default_values;
  PasswordForm form = form_google_;
  // Remove the field which was not present in version #5.
  form.generation_upload_status = default_values.generation_upload_status;
  CreateVersion1PlusPickle(form, &pickle, 6, 6);

  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);

  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], true);
}

void NativeBackendKWalletPickleTest::CheckVersion3Pickle() {
  base::Pickle pickle;
  PasswordForm default_values;
  PasswordForm form = form_google_;
  // Remove the fields which were not present in version #3.
  form.display_name = default_values.display_name;
  form.icon_url = default_values.icon_url;
  form.federation_origin = default_values.federation_origin;
  form.skip_zero_click = default_values.skip_zero_click;
  form.generation_upload_status = default_values.generation_upload_status;
  CreateVersion1PlusPickle(form, &pickle, 3, 3);

  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);

  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], false);
}

void NativeBackendKWalletPickleTest::CheckVersion2Pickle() {
  base::Pickle pickle;
  PasswordForm form = old_form_google_;
  form.times_used = form_google_.times_used;
  form.type = form_google_.type;
  form.form_data = form_google_.form_data;
  CreateVersion1PlusPickle(form, &pickle, 2, 2);

  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);

  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], false);
}

// Make sure that we can still read version 1 pickles.
void NativeBackendKWalletPickleTest::CheckVersion1Pickle() {
  base::Pickle pickle;
  PasswordForm form = form_google_;
  CreateVersion1PlusPickle(form, &pickle, 1, 1);

  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);

  // This will match |old_form_google_| because not all the fields present in
  // |form_google_| will be deserialized.
  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(old_form_google_, *form_list[0], false);
}

void NativeBackendKWalletPickleTest::CheckVersion0Pickle(
    bool size_32, PasswordForm::Scheme scheme) {
  base::Pickle pickle;
  PasswordForm form = old_form_google_;
  form.scheme = scheme;
  CreateVersion0Pickle(size_32, form, &pickle);
  std::vector<std::unique_ptr<PasswordForm>> form_list =
      NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
  EXPECT_EQ(1u, form_list.size());
  if (form_list.size() > 0)
    CheckPasswordForm(form, *form_list[0], false);
}

// We try both SCHEME_HTML and SCHEME_BASIC since the scheme is stored right
// after the size in the pickle, so it's what gets read as part of the count
// when reading 32-bit pickles on 64-bit systems. SCHEME_HTML is 0 (so we'll
// detect errors later) while SCHEME_BASIC is 1 (so we'll detect it then). We
// try both 32-bit and 64-bit pickles since only one will be the "other" size
// for whatever architecture we're running on, but we want to make sure we can
// read all combinations in any event.

TEST_F(NativeBackendKWalletPickleTest, ReadsOld32BitHTMLPickles) {
  CheckVersion0Pickle(true, PasswordForm::SCHEME_HTML);
}

TEST_F(NativeBackendKWalletPickleTest, ReadsOld32BitHTTPPickles) {
  CheckVersion0Pickle(true, PasswordForm::SCHEME_BASIC);
}

TEST_F(NativeBackendKWalletPickleTest, ReadsOld64BitHTMLPickles) {
  CheckVersion0Pickle(false, PasswordForm::SCHEME_HTML);
}

TEST_F(NativeBackendKWalletPickleTest, ReadsOld64BitHTTPPickles) {
  CheckVersion0Pickle(false, PasswordForm::SCHEME_BASIC);
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion1Pickle) {
  CheckVersion1Pickle();
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion2Pickle) {
  CheckVersion2Pickle();
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion3Pickle) {
  CheckVersion3Pickle();
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion5Pickle) {
  CheckVersion5Pickle();
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion6Pickle) {
  CheckVersion6Pickle(false);
  CheckVersion6Pickle(true);
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion7Pickle) {
  CheckVersion7Pickle();
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion8Pickle) {
  CheckVersion8Pickle();
}

TEST_F(NativeBackendKWalletPickleTest, CheckVersion9Pickle) {
  CheckVersion9Pickle();
}
