// 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 "chrome/browser/password_manager/password_store_mac.h"

#include <stddef.h>

#include <string>

#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/scoped_observer.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/password_manager/password_store_mac_internal.h"
#include "chrome/common/chrome_paths.h"
#include "components/os_crypt/os_crypt_mocker.h"
#include "components/password_manager/core/browser/login_database.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
#include "components/password_manager/core/browser/password_store_origin_unittest.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_utils.h"
#include "crypto/mock_apple_keychain.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h"

using autofill::PasswordForm;
using base::ASCIIToUTF16;
using base::WideToUTF16;
using content::BrowserThread;
using crypto::MockAppleKeychain;
using internal_keychain_helpers::FormsMatchForMerge;
using internal_keychain_helpers::STRICT_FORM_MATCH;
using password_manager::CreatePasswordFormFromDataForTesting;
using password_manager::LoginDatabase;
using password_manager::PasswordFormData;
using password_manager::PasswordStore;
using password_manager::PasswordStoreChange;
using password_manager::PasswordStoreChangeList;
using password_manager::PasswordStoreConsumer;
using testing::_;
using testing::DoAll;
using testing::Invoke;
using testing::IsEmpty;
using testing::SizeIs;
using testing::WithArg;

namespace {

ACTION(QuitUIMessageLoop) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  base::MessageLoop::current()->QuitWhenIdle();
}

// From the mock's argument #0 of type const std::vector<PasswordForm*>& takes
// the first form and copies it to the form pointed to by |target_form_ptr|.
ACTION_P(SaveACopyOfFirstForm, target_form_ptr) {
  ASSERT_FALSE(arg0.empty());
  *target_form_ptr = *arg0[0];
}

void Noop() {
}

class MockPasswordStoreConsumer : public PasswordStoreConsumer {
 public:
  MOCK_METHOD1(OnGetPasswordStoreResultsConstRef,
               void(const std::vector<PasswordForm*>&));

  // GMock cannot mock methods with move-only args.
  void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override {
    OnGetPasswordStoreResultsConstRef(results.get());
  }
};

// A LoginDatabase that simulates an Init() method that takes a long time.
class SlowToInitLoginDatabase : public password_manager::LoginDatabase {
 public:
  // Creates an instance whose Init() method will block until |event| is
  // signaled. |event| must outlive |this|.
  SlowToInitLoginDatabase(const base::FilePath& db_path,
                          base::WaitableEvent* event)
      : password_manager::LoginDatabase(db_path), event_(event) {}
  ~SlowToInitLoginDatabase() override {}

  // LoginDatabase:
  bool Init() override {
    event_->Wait();
    return password_manager::LoginDatabase::Init();
  }

 private:
  base::WaitableEvent* event_;

  DISALLOW_COPY_AND_ASSIGN(SlowToInitLoginDatabase);
};

#pragma mark -

// Macro to simplify calling CheckFormsAgainstExpectations with a useful label.
#define CHECK_FORMS(forms, expectations, i) \
    CheckFormsAgainstExpectations(forms, expectations, #forms, i)

// Ensures that the data in |forms| match |expectations|, causing test failures
// for any discrepencies.
// TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't
// matter if |forms| and |expectations| are scrambled.
void CheckFormsAgainstExpectations(
    const std::vector<PasswordForm*>& forms,
    const std::vector<PasswordFormData*>& expectations,

    const char* forms_label, unsigned int test_number) {
  EXPECT_EQ(expectations.size(), forms.size()) << forms_label << " in test "
                                               << test_number;
  if (expectations.size() != forms.size())
    return;

  for (unsigned int i = 0; i < expectations.size(); ++i) {
    SCOPED_TRACE(testing::Message() << forms_label << " in test " << test_number
                                    << ", item " << i);
    PasswordForm* form = forms[i];
    PasswordFormData* expectation = expectations[i];
    EXPECT_EQ(expectation->scheme, form->scheme);
    EXPECT_EQ(std::string(expectation->signon_realm), form->signon_realm);
    EXPECT_EQ(GURL(expectation->origin), form->origin);
    EXPECT_EQ(GURL(expectation->action), form->action);
    EXPECT_EQ(WideToUTF16(expectation->submit_element), form->submit_element);
    EXPECT_EQ(WideToUTF16(expectation->username_element),
              form->username_element);
    EXPECT_EQ(WideToUTF16(expectation->password_element),
              form->password_element);
    if (expectation->username_value) {
      EXPECT_EQ(WideToUTF16(expectation->username_value), form->username_value);
      EXPECT_EQ(WideToUTF16(expectation->username_value), form->display_name);
      EXPECT_TRUE(form->skip_zero_click);
      if (expectation->password_value &&
          wcscmp(expectation->password_value,
                 password_manager::kTestingFederatedLoginMarker) == 0) {
        EXPECT_TRUE(form->password_value.empty());
        EXPECT_EQ(
            url::Origin(GURL(password_manager::kTestingFederationUrlSpec)),
            form->federation_origin);
      } else {
        EXPECT_EQ(WideToUTF16(expectation->password_value),
                  form->password_value);
        EXPECT_TRUE(form->federation_origin.unique());
      }
    } else {
      EXPECT_TRUE(form->blacklisted_by_user);
    }
    EXPECT_EQ(expectation->preferred, form->preferred);
    EXPECT_EQ(expectation->ssl_valid, form->ssl_valid);
    EXPECT_DOUBLE_EQ(expectation->creation_time,
                     form->date_created.ToDoubleT());
    base::Time created = base::Time::FromDoubleT(expectation->creation_time);
    EXPECT_EQ(
        created + base::TimeDelta::FromDays(
                      password_manager::kTestingDaysAfterPasswordsAreSynced),
        form->date_synced);
    EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url);
  }
}

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

class PasswordStoreMacTestDelegate {
 public:
  PasswordStoreMacTestDelegate();
  ~PasswordStoreMacTestDelegate();

  PasswordStoreMac* store() { return store_.get(); }

  static void FinishAsyncProcessing();

 private:
  void Initialize();

  void ClosePasswordStore();

  base::FilePath test_login_db_file_path() const;

  base::MessageLoopForUI message_loop_;
  base::ScopedTempDir db_dir_;
  std::unique_ptr<LoginDatabase> login_db_;
  scoped_refptr<PasswordStoreMac> store_;

  DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate);
};

PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate() {
  Initialize();
}

PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() {
  ClosePasswordStore();
}

void PasswordStoreMacTestDelegate::FinishAsyncProcessing() {
  base::MessageLoop::current()->RunUntilIdle();
}

void PasswordStoreMacTestDelegate::Initialize() {
  ASSERT_TRUE(db_dir_.CreateUniqueTempDir());

  // Ensure that LoginDatabase will use the mock keychain if it needs to
  // encrypt/decrypt a password.
  OSCryptMocker::SetUpWithSingleton();
  login_db_.reset(new LoginDatabase(test_login_db_file_path()));
  ASSERT_TRUE(login_db_->Init());

  // Create and initialize the password store.
  store_ = new PasswordStoreMac(base::ThreadTaskRunnerHandle::Get(),
                                base::ThreadTaskRunnerHandle::Get(),
                                base::WrapUnique(new MockAppleKeychain));
  store_->set_login_metadata_db(login_db_.get());
  store_->login_metadata_db()->set_clear_password_values(false);
}

void PasswordStoreMacTestDelegate::ClosePasswordStore() {
  store_->ShutdownOnUIThread();
  FinishAsyncProcessing();
  OSCryptMocker::TearDown();
}

base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const {
  return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
}

}  // namespace

namespace password_manager {

INSTANTIATE_TYPED_TEST_CASE_P(Mac,
                              PasswordStoreOriginTest,
                              PasswordStoreMacTestDelegate);

}  // namespace password_manager

#pragma mark -

class PasswordStoreMacInternalsTest : public testing::Test {
 public:
  void SetUp() override {
    MockAppleKeychain::KeychainTestData test_data[] = {
        // Basic HTML form.
        {kSecAuthenticationTypeHTMLForm,
         "some.domain.com",
         kSecProtocolTypeHTTP,
         NULL,
         0,
         NULL,
         "20020601171500Z",
         "joe_user",
         "sekrit",
         false},
        // HTML form with path.
        {kSecAuthenticationTypeHTMLForm,
         "some.domain.com",
         kSecProtocolTypeHTTP,
         "/insecure.html",
         0,
         NULL,
         "19991231235959Z",
         "joe_user",
         "sekrit",
         false},
        // Secure HTML form with path.
        {kSecAuthenticationTypeHTMLForm,
         "some.domain.com",
         kSecProtocolTypeHTTPS,
         "/secure.html",
         0,
         NULL,
         "20100908070605Z",
         "secure_user",
         "password",
         false},
        // True negative item.
        {kSecAuthenticationTypeHTMLForm,
         "dont.remember.com",
         kSecProtocolTypeHTTP,
         NULL,
         0,
         NULL,
         "20000101000000Z",
         "",
         "",
         true},
        // De-facto negative item, type one.
        {kSecAuthenticationTypeHTMLForm,
         "dont.remember.com",
         kSecProtocolTypeHTTP,
         NULL,
         0,
         NULL,
         "20000101000000Z",
         "Password Not Stored",
         "",
         false},
        // De-facto negative item, type two.
        {kSecAuthenticationTypeHTMLForm,
         "dont.remember.com",
         kSecProtocolTypeHTTPS,
         NULL,
         0,
         NULL,
         "20000101000000Z",
         "Password Not Stored",
         " ",
         false},
        // HTTP auth basic, with port and path.
        {kSecAuthenticationTypeHTTPBasic,
         "some.domain.com",
         kSecProtocolTypeHTTP,
         "/insecure.html",
         4567,
         "low_security",
         "19980330100000Z",
         "basic_auth_user",
         "basic",
         false},
        // HTTP auth digest, secure.
        {kSecAuthenticationTypeHTTPDigest,
         "some.domain.com",
         kSecProtocolTypeHTTPS,
         NULL,
         0,
         "high_security",
         "19980330100000Z",
         "digest_auth_user",
         "digest",
         false},
        // An FTP password with an invalid date, for edge-case testing.
        {kSecAuthenticationTypeDefault,
         "a.server.com",
         kSecProtocolTypeFTP,
         NULL,
         0,
         NULL,
         "20010203040",
         "abc",
         "123",
         false},
        // Password for an Android application.
        {kSecAuthenticationTypeHTMLForm,
         "android://hash@com.domain.some/",
         kSecProtocolTypeHTTPS,
         "",
         0,
         NULL,
         "20150515141312Z",
         "joe_user",
         "secret",
         false},
    };

    keychain_ = new MockAppleKeychain();

    for (unsigned int i = 0; i < arraysize(test_data); ++i) {
      keychain_->AddTestItem(test_data[i]);
    }
  }

  void TearDown() override {
    ExpectCreatesAndFreesBalanced();
    ExpectCreatorCodesSet();
    delete keychain_;
  }

 protected:
  // Causes a test failure unless everything returned from keychain_'s
  // ItemCopyAttributesAndData, SearchCreateFromAttributes, and SearchCopyNext
  // was correctly freed.
  void ExpectCreatesAndFreesBalanced() {
    EXPECT_EQ(0, keychain_->UnfreedSearchCount());
    EXPECT_EQ(0, keychain_->UnfreedKeychainItemCount());
    EXPECT_EQ(0, keychain_->UnfreedAttributeDataCount());
  }

  // Causes a test failure unless any Keychain items added during the test have
  // their creator code set.
  void ExpectCreatorCodesSet() {
    EXPECT_TRUE(keychain_->CreatorCodesSetForAddedItems());
  }

  MockAppleKeychain* keychain_;
};

#pragma mark -

TEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) {
  typedef struct {
    const PasswordForm::Scheme scheme;
    const char* signon_realm;
    const char* origin;
    const wchar_t* username;  // Set to NULL to check for a blacklist entry.
    const wchar_t* password;
    const bool ssl_valid;
    const int creation_year;
    const int creation_month;
    const int creation_day;
    const int creation_hour;
    const int creation_minute;
    const int creation_second;
  } TestExpectations;

  TestExpectations expected[] = {
    { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
      "http://some.domain.com/", L"joe_user", L"sekrit", false,
      2002,  6,  1, 17, 15,  0 },
    { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
      "http://some.domain.com/insecure.html", L"joe_user", L"sekrit", false,
      1999, 12, 31, 23, 59, 59 },
    { PasswordForm::SCHEME_HTML, "https://some.domain.com/",
      "https://some.domain.com/secure.html", L"secure_user", L"password", true,
      2010,  9,  8,  7,  6,  5 },
    { PasswordForm::SCHEME_HTML, "http://dont.remember.com/",
      "http://dont.remember.com/", NULL, NULL, false,
      2000,  1,  1,  0,  0,  0 },
    { PasswordForm::SCHEME_HTML, "http://dont.remember.com/",
      "http://dont.remember.com/", NULL, NULL, false,
      2000,  1,  1,  0,  0,  0 },
    { PasswordForm::SCHEME_HTML, "https://dont.remember.com/",
      "https://dont.remember.com/", NULL, NULL, true,
      2000,  1,  1,  0,  0,  0 },
    { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security",
      "http://some.domain.com:4567/insecure.html", L"basic_auth_user", L"basic",
      false, 1998, 03, 30, 10, 00, 00 },
    { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security",
      "https://some.domain.com/", L"digest_auth_user", L"digest", true,
      1998,  3, 30, 10,  0,  0 },
    // This one gives us an invalid date, which we will treat as a "NULL" date
    // which is 1601.
    { PasswordForm::SCHEME_OTHER, "http://a.server.com/",
      "http://a.server.com/", L"abc", L"123", false,
      1601,  1,  1,  0,  0,  0 },
    { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
      "", L"joe_user", L"secret", true,
      2015,  5,  15, 14, 13, 12 },
  };

  for (unsigned int i = 0; i < arraysize(expected); ++i) {
    // Create our fake KeychainItemRef; see MockAppleKeychain docs.
    SecKeychainItemRef keychain_item =
        reinterpret_cast<SecKeychainItemRef>(i + 1);
    PasswordForm form;
    bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
        *keychain_, keychain_item, &form, true);

    EXPECT_TRUE(parsed) << "In iteration " << i;

    EXPECT_EQ(expected[i].scheme, form.scheme) << "In iteration " << i;
    EXPECT_EQ(GURL(expected[i].origin), form.origin) << "In iteration " << i;
    EXPECT_EQ(expected[i].ssl_valid, form.ssl_valid) << "In iteration " << i;
    EXPECT_EQ(std::string(expected[i].signon_realm), form.signon_realm)
        << "In iteration " << i;
    if (expected[i].username) {
      EXPECT_EQ(WideToUTF16(expected[i].username), form.username_value)
          << "In iteration " << i;
      EXPECT_EQ(WideToUTF16(expected[i].password), form.password_value)
          << "In iteration " << i;
      EXPECT_FALSE(form.blacklisted_by_user) << "In iteration " << i;
    } else {
      EXPECT_TRUE(form.blacklisted_by_user) << "In iteration " << i;
    }
    base::Time::Exploded exploded_time;
    form.date_created.UTCExplode(&exploded_time);
    EXPECT_EQ(expected[i].creation_year, exploded_time.year)
         << "In iteration " << i;
    EXPECT_EQ(expected[i].creation_month, exploded_time.month)
        << "In iteration " << i;
    EXPECT_EQ(expected[i].creation_day, exploded_time.day_of_month)
        << "In iteration " << i;
    EXPECT_EQ(expected[i].creation_hour, exploded_time.hour)
        << "In iteration " << i;
    EXPECT_EQ(expected[i].creation_minute, exploded_time.minute)
        << "In iteration " << i;
    EXPECT_EQ(expected[i].creation_second, exploded_time.second)
        << "In iteration " << i;
  }

  {
    // Use an invalid ref, to make sure errors are reported.
    SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(99);
    PasswordForm form;
    bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
        *keychain_, keychain_item, &form, true);
    EXPECT_FALSE(parsed);
  }
}

TEST_F(PasswordStoreMacInternalsTest, TestKeychainSearch) {
  struct TestDataAndExpectation {
    const PasswordFormData data;
    const size_t expected_fill_matches;
    const size_t expected_merge_matches;
  };
  // Most fields are left blank because we don't care about them for searching.
  /* clang-format off */
  TestDataAndExpectation test_data[] = {
    // An HTML form we've seen.
    { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        NULL, NULL, NULL, NULL, NULL, L"joe_user", NULL, false, false, 0 },
      2, 2 },
    { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        NULL, NULL, NULL, NULL, NULL, L"wrong_user", NULL, false, false, 0 },
      2, 0 },
    // An HTML form we haven't seen
    { { PasswordForm::SCHEME_HTML, "http://www.unseendomain.com/",
        NULL, NULL, NULL, NULL, NULL, L"joe_user", NULL, false, false, 0 },
      0, 0 },
    // Basic auth that should match.
    { { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security",
        NULL, NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, false, false,
        0 },
      1, 1 },
    // Basic auth with the wrong port.
    { { PasswordForm::SCHEME_BASIC, "http://some.domain.com:1111/low_security",
        NULL, NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, false, false,
        0 },
      0, 0 },
    // Digest auth we've saved under https, visited with http.
    { { PasswordForm::SCHEME_DIGEST, "http://some.domain.com/high_security",
        NULL, NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, false, false,
        0 },
      0, 0 },
    // Digest auth that should match.
    { { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security",
        NULL, NULL, NULL, NULL, NULL, L"wrong_user", NULL, false, true, 0 },
      1, 0 },
    // Digest auth with the wrong domain.
    { { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/other_domain",
        NULL, NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, false, true,
        0 },
      0, 0 },
    // Android credentials (both legacy ones with origin, and without).
    { { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
        "android://hash@com.domain.some/", NULL, NULL, NULL, NULL, L"joe_user",
        NULL, false, true, 0 },
      1, 1 },
    { { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
        NULL, NULL, NULL, NULL, NULL, L"joe_user", NULL, false, true, 0 },
      1, 1 },
    // Federated logins do not have a corresponding Keychain entry, and should
    // not match the username/password stored for the same application. Note
    // that it will match for filling, however, because that part does not know
    // that it is a federated login.
    { { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
        NULL, NULL, NULL, NULL, NULL, L"joe_user",
        password_manager::kTestingFederatedLoginMarker, false, true, 0 },
      1, 0 },
    /// Garbage forms should have no matches.
    { { PasswordForm::SCHEME_HTML, "foo/bar/baz",
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 },
  };
  /* clang-format on */

  MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
  MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
  owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
  for (unsigned int i = 0; i < arraysize(test_data); ++i) {
    std::unique_ptr<PasswordForm> query_form =
        CreatePasswordFormFromDataForTesting(test_data[i].data);

    // Check matches treating the form as a fill target.
    ScopedVector<autofill::PasswordForm> matching_items =
        keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
                                              query_form->scheme);
    EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size());

    // Check matches treating the form as a merging target.
    EXPECT_EQ(test_data[i].expected_merge_matches > 0,
              keychain_adapter.HasPasswordsMergeableWithForm(*query_form));
    std::vector<SecKeychainItemRef> keychain_items;
    std::vector<internal_keychain_helpers::ItemFormPair> item_form_pairs =
        internal_keychain_helpers::
            ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items,
                                                              *keychain_);
    matching_items =
        internal_keychain_helpers::ExtractPasswordsMergeableWithForm(
            *keychain_, item_form_pairs, *query_form);
    EXPECT_EQ(test_data[i].expected_merge_matches, matching_items.size());
    STLDeleteContainerPairSecondPointers(item_form_pairs.begin(),
                                         item_form_pairs.end());
    for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin();
         i != keychain_items.end(); ++i) {
      keychain_->Free(*i);
    }

    // None of the pre-seeded items are owned by us, so none should match an
    // owned-passwords-only search.
    matching_items = owned_keychain_adapter.PasswordsFillingForm(
        query_form->signon_realm, query_form->scheme);
    EXPECT_EQ(0U, matching_items.size());
  }
}

// Changes just the origin path of |form|.
static void SetPasswordFormPath(PasswordForm* form, const char* path) {
  GURL::Replacements replacement;
  std::string new_value(path);
  replacement.SetPathStr(new_value);
  form->origin = form->origin.ReplaceComponents(replacement);
}

// Changes just the signon_realm port of |form|.
static void SetPasswordFormPort(PasswordForm* form, const char* port) {
  GURL::Replacements replacement;
  std::string new_value(port);
  replacement.SetPortStr(new_value);
  GURL signon_gurl = GURL(form->signon_realm);
  form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec();
}

// Changes just the signon_ream auth realm of |form|.
static void SetPasswordFormRealm(PasswordForm* form, const char* realm) {
  GURL::Replacements replacement;
  std::string new_value(realm);
  replacement.SetPathStr(new_value);
  GURL signon_gurl = GURL(form->signon_realm);
  form->signon_realm = signon_gurl.ReplaceComponents(replacement).spec();
}

TEST_F(PasswordStoreMacInternalsTest, TestKeychainExactSearch) {
  MacKeychainPasswordFormAdapter keychain_adapter(keychain_);

  PasswordFormData base_form_data[] = {
    { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
      "http://some.domain.com/insecure.html",
      NULL, NULL, NULL, NULL, L"joe_user", NULL, true, false, 0 },
    { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security",
      "http://some.domain.com:4567/insecure.html",
      NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 },
    { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security",
      "https://some.domain.com",
      NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 },
  };

  for (unsigned int i = 0; i < arraysize(base_form_data); ++i) {
    // Create a base form and make sure we find a match.
    std::unique_ptr<PasswordForm> base_form =
        CreatePasswordFormFromDataForTesting(base_form_data[i]);
    EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form));
    EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form));

    // Make sure that the matching isn't looser than it should be by checking
    // that slightly altered forms don't match.
    ScopedVector<autofill::PasswordForm> modified_forms;

    modified_forms.push_back(new PasswordForm(*base_form));
    modified_forms.back()->username_value = ASCIIToUTF16("wrong_user");

    modified_forms.push_back(new PasswordForm(*base_form));
    SetPasswordFormPath(modified_forms.back(), "elsewhere.html");

    modified_forms.push_back(new PasswordForm(*base_form));
    modified_forms.back()->scheme = PasswordForm::SCHEME_OTHER;

    modified_forms.push_back(new PasswordForm(*base_form));
    SetPasswordFormPort(modified_forms.back(), "1234");

    modified_forms.push_back(new PasswordForm(*base_form));
    modified_forms.back()->blacklisted_by_user = true;

    if (base_form->scheme == PasswordForm::SCHEME_BASIC ||
        base_form->scheme == PasswordForm::SCHEME_DIGEST) {
      modified_forms.push_back(new PasswordForm(*base_form));
      SetPasswordFormRealm(modified_forms.back(), "incorrect");
    }

    for (unsigned int j = 0; j < modified_forms.size(); ++j) {
      bool match = keychain_adapter.HasPasswordExactlyMatchingForm(
          *modified_forms[j]);
      EXPECT_FALSE(match) << "In modified version " << j
          << " of base form " << i;
    }
  }
}

TEST_F(PasswordStoreMacInternalsTest, TestKeychainAdd) {
  struct TestDataAndExpectation {
    PasswordFormData data;
    bool should_succeed;
  };
  /* clang-format off */
  TestDataAndExpectation test_data[] = {
    // Test a variety of scheme/port/protocol/path variations.
    { { PasswordForm::SCHEME_HTML, "http://web.site.com/",
        "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
        L"anonymous", L"knock-knock", false, false, 0 }, true },
    { { PasswordForm::SCHEME_HTML, "https://web.site.com/",
        "https://web.site.com/", NULL, NULL, NULL, NULL,
        L"admin", L"p4ssw0rd", false, false, 0 }, true },
    { { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm",
        "http://a.site.com:2222/", NULL, NULL, NULL, NULL,
        L"username", L"password", false, false, 0 }, true },
    { { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm",
        "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL,
        L"testname", L"testpass", false, false, 0 }, true },
    // Test that Android credentials can be stored. Also check the legacy form
    // when |origin| was still filled with the Android URI (and not left empty).
    { { PasswordForm::SCHEME_HTML, "android://hash@com.example.alpha/",
        "", NULL, NULL, NULL, NULL,
        L"joe_user", L"password", false, true, 0 }, true },
    { { PasswordForm::SCHEME_HTML, "android://hash@com.example.beta/",
        "android://hash@com.example.beta/", NULL, NULL, NULL, NULL,
        L"jane_user", L"password2", false, true, 0 }, true },
    // Make sure that garbage forms are rejected.
    { { PasswordForm::SCHEME_HTML, "gobbledygook",
        "gobbledygook", NULL, NULL, NULL, NULL,
        L"anonymous", L"knock-knock", false, false, 0 }, false },
    // Test that failing to update a duplicate (forced using the magic failure
    // password; see MockAppleKeychain::ItemModifyAttributesAndData) is
    // reported.
    { { PasswordForm::SCHEME_HTML, "http://some.domain.com",
        "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL,
        L"joe_user", L"fail_me", false, false, 0 }, false },
  };
  /* clang-format on */

  MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
  owned_keychain_adapter.SetFindsOnlyOwnedItems(true);

  for (unsigned int i = 0; i < arraysize(test_data); ++i) {
    std::unique_ptr<PasswordForm> in_form =
        CreatePasswordFormFromDataForTesting(test_data[i].data);
    bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form);
    EXPECT_EQ(test_data[i].should_succeed, add_succeeded);
    if (add_succeeded) {
      EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm(
          *in_form));
      EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm(
          *in_form));
    }
  }

  // Test that adding duplicate item updates the existing item.
  // TODO(engedy): Add a test to verify that updating Android credentials work.
  // See: https://crbug.com/476851.
  {
    PasswordFormData data = {
      PasswordForm::SCHEME_HTML, "http://some.domain.com",
      "http://some.domain.com/insecure.html", NULL,
      NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0
    };
    std::unique_ptr<PasswordForm> update_form =
        CreatePasswordFormFromDataForTesting(data);
    MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
    EXPECT_TRUE(keychain_adapter.AddPassword(*update_form));
    SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2);
    PasswordForm stored_form;
    internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_,
                                                                keychain_item,
                                                                &stored_form,
                                                                true);
    EXPECT_EQ(update_form->password_value, stored_form.password_value);
  }
}

TEST_F(PasswordStoreMacInternalsTest, TestKeychainRemove) {
  struct TestDataAndExpectation {
    PasswordFormData data;
    bool should_succeed;
  };
  /* clang-format off */
  TestDataAndExpectation test_data[] = {
    // Test deletion of an item that we add.
    { { PasswordForm::SCHEME_HTML, "http://web.site.com/",
        "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
        L"anonymous", L"knock-knock", false, false, 0 }, true },
    // Test that Android credentials can be removed. Also check the legacy case
    // when |origin| was still filled with the Android URI (and not left empty).
    { { PasswordForm::SCHEME_HTML, "android://hash@com.example.alpha/",
        "", NULL, NULL, NULL, NULL,
        L"joe_user", L"secret", false, true, 0 }, true },
    { { PasswordForm::SCHEME_HTML, "android://hash@com.example.beta/",
        "android://hash@com.example.beta/", NULL, NULL, NULL, NULL,
        L"jane_user", L"secret", false, true, 0 }, true },
    // Make sure we don't delete items we don't own.
    { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL,
        L"joe_user", NULL, true, false, 0 }, false },
  };
  /* clang-format on */

  MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
  owned_keychain_adapter.SetFindsOnlyOwnedItems(true);

  // Add our test items (except the last one) so that we can delete them.
  for (unsigned int i = 0; i + 1 < arraysize(test_data); ++i) {
    std::unique_ptr<PasswordForm> add_form =
        CreatePasswordFormFromDataForTesting(test_data[i].data);
    EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form));
  }

  for (unsigned int i = 0; i < arraysize(test_data); ++i) {
    std::unique_ptr<PasswordForm> form =
        CreatePasswordFormFromDataForTesting(test_data[i].data);
    EXPECT_EQ(test_data[i].should_succeed,
              owned_keychain_adapter.RemovePassword(*form));

    MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
    bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form);
    EXPECT_EQ(test_data[i].should_succeed, !match);
  }
}

TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) {
  PasswordForm base_form;
  base_form.signon_realm = std::string("http://some.domain.com/");
  base_form.origin = GURL("http://some.domain.com/page.html");
  base_form.username_value = ASCIIToUTF16("joe_user");

  {
    // Check that everything unimportant can be changed.
    PasswordForm different_form(base_form);
    different_form.username_element = ASCIIToUTF16("username");
    different_form.submit_element = ASCIIToUTF16("submit");
    different_form.username_element = ASCIIToUTF16("password");
    different_form.password_value = ASCIIToUTF16("sekrit");
    different_form.action = GURL("http://some.domain.com/action.cgi");
    different_form.ssl_valid = true;
    different_form.preferred = true;
    different_form.date_created = base::Time::Now();
    EXPECT_TRUE(
        FormsMatchForMerge(base_form, different_form, STRICT_FORM_MATCH));

    // Check that path differences don't prevent a match.
    base_form.origin = GURL("http://some.domain.com/other_page.html");
    EXPECT_TRUE(
        FormsMatchForMerge(base_form, different_form, STRICT_FORM_MATCH));
  }

  // Check that any one primary key changing is enough to prevent matching.
  {
    PasswordForm different_form(base_form);
    different_form.scheme = PasswordForm::SCHEME_DIGEST;
    EXPECT_FALSE(
        FormsMatchForMerge(base_form, different_form, STRICT_FORM_MATCH));
  }
  {
    PasswordForm different_form(base_form);
    different_form.signon_realm = std::string("http://some.domain.com:8080/");
    EXPECT_FALSE(
        FormsMatchForMerge(base_form, different_form, STRICT_FORM_MATCH));
  }
  {
    PasswordForm different_form(base_form);
    different_form.username_value = ASCIIToUTF16("john.doe");
    EXPECT_FALSE(
        FormsMatchForMerge(base_form, different_form, STRICT_FORM_MATCH));
  }
  {
    PasswordForm different_form(base_form);
    different_form.blacklisted_by_user = true;
    EXPECT_FALSE(
        FormsMatchForMerge(base_form, different_form, STRICT_FORM_MATCH));
  }

  // Blacklist forms should *never* match for merging, even when identical
  // (and certainly not when only one is a blacklist entry).
  {
    PasswordForm form_a(base_form);
    form_a.blacklisted_by_user = true;
    PasswordForm form_b(form_a);
    EXPECT_FALSE(FormsMatchForMerge(form_a, form_b, STRICT_FORM_MATCH));
  }

  // Federated login forms should never match for merging either.
  {
    PasswordForm form_b(base_form);
    form_b.federation_origin =
        url::Origin(GURL(password_manager::kTestingFederationUrlSpec));
    EXPECT_FALSE(FormsMatchForMerge(base_form, form_b, STRICT_FORM_MATCH));
    EXPECT_FALSE(FormsMatchForMerge(form_b, base_form, STRICT_FORM_MATCH));
    EXPECT_FALSE(FormsMatchForMerge(form_b, form_b, STRICT_FORM_MATCH));
  }
}

TEST_F(PasswordStoreMacInternalsTest, TestFormMerge) {
  // Set up a bunch of test data to use in varying combinations.
  /* clang-format off */
  PasswordFormData keychain_user_1 =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/", "", L"", L"", L"", L"joe_user", L"sekrit",
        false, false, 1010101010 };
  PasswordFormData keychain_user_1_with_path =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/page.html",
        "", L"", L"", L"", L"joe_user", L"otherpassword",
        false, false, 1010101010 };
  PasswordFormData keychain_user_2 =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/", "", L"", L"", L"", L"john.doe", L"sesame",
        false, false, 958739876 };
  PasswordFormData keychain_blacklist =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/", "", L"", L"", L"", NULL, NULL,
        false, false, 1010101010 };
  PasswordFormData keychain_android =
      { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
        "", "", L"", L"", L"", L"joe_user", L"secret",
        false, true, 1234567890 };

  PasswordFormData db_user_1 =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/", "http://some.domain.com/action.cgi",
        L"submit", L"username", L"password", L"joe_user", L"",
        true, false, 1212121212 };
  PasswordFormData db_user_1_with_path =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/page.html",
        "http://some.domain.com/handlepage.cgi",
        L"submit", L"username", L"password", L"joe_user", L"",
        true, false, 1234567890 };
  PasswordFormData db_user_3_with_path =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/page.html",
        "http://some.domain.com/handlepage.cgi",
        L"submit", L"username", L"password", L"second-account", L"",
        true, false, 1240000000 };
  PasswordFormData database_blacklist_with_path =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/path.html", "http://some.domain.com/action.cgi",
        L"submit", L"username", L"password", NULL, NULL,
        true, false, 1212121212 };
  PasswordFormData db_android =
      { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
        "android://hash@com.domain.some/", "", L"", L"", L"", L"joe_user", L"",
        false, true, 1234567890 };
  PasswordFormData db_federated =
      { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
        "android://hash@com.domain.some/", "", L"", L"", L"", L"joe_user",
        password_manager::kTestingFederatedLoginMarker,
        false, true, 3434343434 };

  PasswordFormData merged_user_1 =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/", "http://some.domain.com/action.cgi",
        L"submit", L"username", L"password", L"joe_user", L"sekrit",
        true, false, 1212121212 };
  PasswordFormData merged_user_1_with_db_path =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/page.html",
        "http://some.domain.com/handlepage.cgi",
        L"submit", L"username", L"password", L"joe_user", L"sekrit",
        true, false, 1234567890 };
  PasswordFormData merged_user_1_with_both_paths =
      { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/page.html",
        "http://some.domain.com/handlepage.cgi",
        L"submit", L"username", L"password", L"joe_user", L"otherpassword",
        true, false, 1234567890 };
  PasswordFormData merged_android =
      { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
        "android://hash@com.domain.some/", "", L"", L"", L"", L"joe_user",
        L"secret", false, true, 1234567890 };
  /* clang-format on */

  // Build up the big multi-dimensional array of data sets that will actually
  // drive the test. Use vectors rather than arrays so that initialization is
  // simple.
  enum {
    KEYCHAIN_INPUT = 0,
    DATABASE_INPUT,
    MERGE_OUTPUT,
    KEYCHAIN_OUTPUT,
    DATABASE_OUTPUT,
    MERGE_IO_ARRAY_COUNT  // termination marker
  };
  const unsigned int kTestCount = 5;
  std::vector< std::vector< std::vector<PasswordFormData*> > > test_data(
      MERGE_IO_ARRAY_COUNT, std::vector< std::vector<PasswordFormData*> >(
          kTestCount, std::vector<PasswordFormData*>()));
  unsigned int current_test = 0;

  // Test a merge with a few accounts in both systems, with partial overlap.
  CHECK(current_test < kTestCount);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_2);
  test_data[DATABASE_INPUT][current_test].push_back(&db_user_1);
  test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path);
  test_data[DATABASE_INPUT][current_test].push_back(&db_user_3_with_path);
  test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1);
  test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1_with_db_path);
  test_data[KEYCHAIN_OUTPUT][current_test].push_back(&keychain_user_2);
  test_data[DATABASE_OUTPUT][current_test].push_back(&db_user_3_with_path);

  // Test a merge where Chrome has a blacklist entry, and the keychain has
  // a stored account.
  ++current_test;
  CHECK(current_test < kTestCount);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1);
  test_data[DATABASE_INPUT][current_test].push_back(
      &database_blacklist_with_path);
  // We expect both to be present because a blacklist could be specific to a
  // subpath, and we want access to the password on other paths.
  test_data[MERGE_OUTPUT][current_test].push_back(
      &database_blacklist_with_path);
  test_data[KEYCHAIN_OUTPUT][current_test].push_back(&keychain_user_1);

  // Test a merge where Chrome has an account, and Keychain has a blacklist
  // (from another browser) and the Chrome password data.
  ++current_test;
  CHECK(current_test < kTestCount);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_blacklist);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1);
  test_data[DATABASE_INPUT][current_test].push_back(&db_user_1);
  test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1);
  test_data[KEYCHAIN_OUTPUT][current_test].push_back(&keychain_blacklist);

  // Test that matches are done using exact path when possible.
  ++current_test;
  CHECK(current_test < kTestCount);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_user_1_with_path);
  test_data[DATABASE_INPUT][current_test].push_back(&db_user_1);
  test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path);
  test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1);
  test_data[MERGE_OUTPUT][current_test].push_back(
      &merged_user_1_with_both_paths);

  // Test that Android credentails are matched correctly and that federated
  // credentials are not tried to be matched with a Keychain item.
  ++current_test;
  CHECK(current_test < kTestCount);
  test_data[KEYCHAIN_INPUT][current_test].push_back(&keychain_android);
  test_data[DATABASE_INPUT][current_test].push_back(&db_federated);
  test_data[DATABASE_INPUT][current_test].push_back(&db_android);
  test_data[MERGE_OUTPUT][current_test].push_back(&db_federated);
  test_data[MERGE_OUTPUT][current_test].push_back(&merged_android);

  for (unsigned int test_case = 0; test_case <= current_test; ++test_case) {
    ScopedVector<autofill::PasswordForm> keychain_forms;
    for (std::vector<PasswordFormData*>::iterator i =
             test_data[KEYCHAIN_INPUT][test_case].begin();
         i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) {
      keychain_forms.push_back(
          CreatePasswordFormFromDataForTesting(*(*i)).release());
    }
    ScopedVector<autofill::PasswordForm> database_forms;
    for (std::vector<PasswordFormData*>::iterator i =
             test_data[DATABASE_INPUT][test_case].begin();
         i != test_data[DATABASE_INPUT][test_case].end(); ++i) {
      database_forms.push_back(
          CreatePasswordFormFromDataForTesting(*(*i)).release());
    }

    ScopedVector<autofill::PasswordForm> merged_forms;
    internal_keychain_helpers::MergePasswordForms(&keychain_forms,
                                                  &database_forms,
                                                  &merged_forms);

    CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case],
                test_case);
    CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case],
                test_case);
    CHECK_FORMS(merged_forms.get(), test_data[MERGE_OUTPUT][test_case],
                test_case);
  }
}

TEST_F(PasswordStoreMacInternalsTest, TestPasswordBulkLookup) {
  PasswordFormData db_data[] = {
    { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
      "http://some.domain.com/", "http://some.domain.com/action.cgi",
      L"submit", L"username", L"password", L"joe_user", L"",
      true, false, 1212121212 },
    { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
      "http://some.domain.com/page.html",
      "http://some.domain.com/handlepage.cgi",
      L"submit", L"username", L"password", L"joe_user", L"",
      true, false, 1234567890 },
    { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
      "http://some.domain.com/page.html",
      "http://some.domain.com/handlepage.cgi",
      L"submit", L"username", L"password", L"second-account", L"",
      true, false, 1240000000 },
    { PasswordForm::SCHEME_HTML, "http://dont.remember.com/",
      "http://dont.remember.com/",
      "http://dont.remember.com/handlepage.cgi",
      L"submit", L"username", L"password", L"joe_user", L"",
      true, false, 1240000000 },
    { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
      "http://some.domain.com/path.html", "http://some.domain.com/action.cgi",
      L"submit", L"username", L"password", NULL, NULL,
      true, false, 1212121212 },
  };
  ScopedVector<autofill::PasswordForm> database_forms;
  for (unsigned int i = 0; i < arraysize(db_data); ++i) {
    database_forms.push_back(
        CreatePasswordFormFromDataForTesting(db_data[i]).release());
  }
  ScopedVector<autofill::PasswordForm> merged_forms;
  internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
                                                  &merged_forms);
  EXPECT_EQ(2U, database_forms.size());
  ASSERT_EQ(3U, merged_forms.size());
  EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value);
  EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value);
  EXPECT_TRUE(merged_forms[2]->blacklisted_by_user);
}

TEST_F(PasswordStoreMacInternalsTest, TestBlacklistedFiltering) {
  PasswordFormData db_data[] = {
    { PasswordForm::SCHEME_HTML, "http://dont.remember.com/",
      "http://dont.remember.com/",
      "http://dont.remember.com/handlepage.cgi",
      L"submit", L"username", L"password", L"joe_user", L"non_empty_password",
      true, false, 1240000000 },
    { PasswordForm::SCHEME_HTML, "https://dont.remember.com/",
      "https://dont.remember.com/",
      "https://dont.remember.com/handlepage_secure.cgi",
      L"submit", L"username", L"password", L"joe_user", L"non_empty_password",
      true, false, 1240000000 },
  };
  ScopedVector<autofill::PasswordForm> database_forms;
  for (unsigned int i = 0; i < arraysize(db_data); ++i) {
    database_forms.push_back(
        CreatePasswordFormFromDataForTesting(db_data[i]).release());
  }
  ScopedVector<autofill::PasswordForm> merged_forms;
  internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
                                                  &merged_forms);
  EXPECT_EQ(2U, database_forms.size());
  ASSERT_EQ(0U, merged_forms.size());
}

TEST_F(PasswordStoreMacInternalsTest, TestFillPasswordFormFromKeychainItem) {
  // When |extract_password_data| is false, the password field must be empty,
  // and |blacklisted_by_user| must be false.
  SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(1);
  PasswordForm form_without_extracted_password;
  bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
      *keychain_,
      keychain_item,
      &form_without_extracted_password,
      false);  // Do not extract password.
  EXPECT_TRUE(parsed);
  ASSERT_TRUE(form_without_extracted_password.password_value.empty());
  ASSERT_FALSE(form_without_extracted_password.blacklisted_by_user);

  // When |extract_password_data| is true and the keychain entry has a non-empty
  // password, the password field must be non-empty, and the value of
  // |blacklisted_by_user| must be false.
  keychain_item = reinterpret_cast<SecKeychainItemRef>(1);
  PasswordForm form_with_extracted_password;
  parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
      *keychain_,
      keychain_item,
      &form_with_extracted_password,
      true);  // Extract password.
  EXPECT_TRUE(parsed);
  ASSERT_EQ(ASCIIToUTF16("sekrit"),
            form_with_extracted_password.password_value);
  ASSERT_FALSE(form_with_extracted_password.blacklisted_by_user);

  // When |extract_password_data| is true and the keychain entry has an empty
  // username and password (""), the password field must be empty, and the value
  // of |blacklisted_by_user| must be true.
  keychain_item = reinterpret_cast<SecKeychainItemRef>(4);
  PasswordForm negative_form;
  parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
      *keychain_,
      keychain_item,
      &negative_form,
      true);  // Extract password.
  EXPECT_TRUE(parsed);
  ASSERT_TRUE(negative_form.username_value.empty());
  ASSERT_TRUE(negative_form.password_value.empty());
  ASSERT_TRUE(negative_form.blacklisted_by_user);

  // When |extract_password_data| is true and the keychain entry has an empty
  // password (""), the password field must be empty (""), and the value of
  // |blacklisted_by_user| must be true.
  keychain_item = reinterpret_cast<SecKeychainItemRef>(5);
  PasswordForm form_with_empty_password_a;
  parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
      *keychain_,
      keychain_item,
      &form_with_empty_password_a,
      true);  // Extract password.
  EXPECT_TRUE(parsed);
  ASSERT_TRUE(form_with_empty_password_a.password_value.empty());
  ASSERT_TRUE(form_with_empty_password_a.blacklisted_by_user);

  // When |extract_password_data| is true and the keychain entry has a single
  // space password (" "), the password field must be a single space (" "), and
  // the value of |blacklisted_by_user| must be true.
  keychain_item = reinterpret_cast<SecKeychainItemRef>(6);
  PasswordForm form_with_empty_password_b;
  parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
      *keychain_,
      keychain_item,
      &form_with_empty_password_b,
      true);  // Extract password.
  EXPECT_TRUE(parsed);
  ASSERT_EQ(ASCIIToUTF16(" "),
            form_with_empty_password_b.password_value);
  ASSERT_TRUE(form_with_empty_password_b.blacklisted_by_user);
}

TEST_F(PasswordStoreMacInternalsTest, TestPasswordGetAll) {
  MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
  MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
  owned_keychain_adapter.SetFindsOnlyOwnedItems(true);

  // Add a few passwords of various types so that we own some.
  PasswordFormData owned_password_data[] = {
    { PasswordForm::SCHEME_HTML, "http://web.site.com/",
      "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
      L"anonymous", L"knock-knock", false, false, 0 },
    { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm",
      "http://a.site.com:2222/", NULL, NULL, NULL, NULL,
      L"username", L"password", false, false, 0 },
    { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm",
      "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL,
      L"testname", L"testpass", false, false, 0 },
  };
  for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) {
    std::unique_ptr<PasswordForm> form =
        CreatePasswordFormFromDataForTesting(owned_password_data[i]);
    owned_keychain_adapter.AddPassword(*form);
  }

  ScopedVector<autofill::PasswordForm> all_passwords =
      keychain_adapter.GetAllPasswordFormPasswords();
  EXPECT_EQ(9 + arraysize(owned_password_data), all_passwords.size());

  ScopedVector<autofill::PasswordForm> owned_passwords =
      owned_keychain_adapter.GetAllPasswordFormPasswords();
  EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
}

#pragma mark -

class PasswordStoreMacTest : public testing::Test {
 public:
  PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {}

  void SetUp() override {
    ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
    histogram_tester_.reset(new base::HistogramTester);

    // Ensure that LoginDatabase will use the mock keychain if it needs to
    // encrypt/decrypt a password.
    OSCryptMocker::SetUpWithSingleton();
    login_db_.reset(
        new password_manager::LoginDatabase(test_login_db_file_path()));
    thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
    ASSERT_TRUE(thread_->Start());
    ASSERT_TRUE(thread_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&PasswordStoreMacTest::InitLoginDatabase,
                              base::Unretained(login_db_.get()))));
    CreateAndInitPasswordStore(login_db_.get());
    // Make sure deferred initialization is performed before some tests start
    // accessing the |login_db| directly.
    FinishAsyncProcessing();
  }

  void TearDown() override {
    ClosePasswordStore();
    thread_.reset();
    login_db_.reset();
    // Whatever a test did, PasswordStoreMac stores only empty password values
    // in LoginDatabase. The empty valus do not require encryption and therefore
    // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the
    // internet passwords.
    if (histogram_tester_) {
      histogram_tester_->ExpectTotalCount("OSX.Keychain.Access", 0);
    }
    OSCryptMocker::TearDown();
  }

  static void InitLoginDatabase(password_manager::LoginDatabase* login_db) {
    ASSERT_TRUE(login_db->Init());
  }

  void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) {
    store_ = new PasswordStoreMac(
        base::ThreadTaskRunnerHandle::Get(), nullptr,
        base::WrapUnique<AppleKeychain>(new MockAppleKeychain));
    ASSERT_TRUE(thread_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_,
                              thread_->task_runner())));

    ASSERT_TRUE(thread_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_,
                              base::Unretained(login_db))));
  }

  void ClosePasswordStore() {
    if (!store_)
      return;

    store_->ShutdownOnUIThread();
    store_ = nullptr;
  }

  // Verifies that the given |form| can be properly stored so that it can be
  // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it
  // can be properly removed.
  void VerifyCredentialLifecycle(const PasswordForm& form) {
    // Run everything twice to make sure no garbage is left behind that would
    // prevent storing the form a second time.
    for (size_t iteration = 0; iteration < 2; ++iteration) {
      SCOPED_TRACE(testing::Message("Iteration: ") << iteration);

      MockPasswordStoreConsumer mock_consumer;
      EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()))
          .WillOnce(QuitUIMessageLoop());
      store()->GetAutofillableLogins(&mock_consumer);
      base::MessageLoop::current()->Run();
      ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);

      store()->AddLogin(form);
      FinishAsyncProcessing();

      PasswordForm returned_form;
      EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
          .WillOnce(
              DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));

      // The query operations will also do some housekeeping: they will remove
      // dangling credentials in the LoginDatabase without a matching Keychain
      // item when one is expected. If the logic that stores the Keychain item
      // is incorrect, this will wipe the newly added form before the second
      // query.
      store()->GetAutofillableLogins(&mock_consumer);
      base::MessageLoop::current()->Run();
      ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
      EXPECT_EQ(form, returned_form);

      PasswordForm query_form = form;
      query_form.password_value.clear();
      query_form.username_value.clear();
      EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
          .WillOnce(
              DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
      store()->GetLogins(query_form, &mock_consumer);
      base::MessageLoop::current()->Run();
      ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
      EXPECT_EQ(form, returned_form);

      store()->RemoveLogin(form);
    }
  }

  base::FilePath test_login_db_file_path() const {
    return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
  }

  password_manager::LoginDatabase* login_db() const {
    return store_->login_metadata_db();
  }

  MockAppleKeychain* keychain() {
    return static_cast<MockAppleKeychain*>(store_->keychain());
  }

  void FinishAsyncProcessing() {
    scoped_refptr<content::MessageLoopRunner> runner =
        new content::MessageLoopRunner;
    ASSERT_TRUE(thread_->task_runner()->PostTaskAndReply(
        FROM_HERE, base::Bind(&Noop), runner->QuitClosure()));
    runner->Run();
  }

  PasswordStoreMac* store() { return store_.get(); }

 protected:
  base::MessageLoopForUI message_loop_;
  content::TestBrowserThread ui_thread_;
  // Thread that the synchronous methods are run on.
  std::unique_ptr<base::Thread> thread_;

  base::ScopedTempDir db_dir_;
  std::unique_ptr<password_manager::LoginDatabase> login_db_;
  scoped_refptr<PasswordStoreMac> store_;
  std::unique_ptr<base::HistogramTester> histogram_tester_;
};

TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
  // Insert a password into both the database and the keychain.
  // This is done manually, rather than through store_->AddLogin, because the
  // Mock Keychain isn't smart enough to be able to support update generically,
  // so some.domain.com triggers special handling to test it that make inserting
  // fail.
  PasswordFormData joint_data = {
    PasswordForm::SCHEME_HTML, "http://some.domain.com/",
    "http://some.domain.com/insecure.html", "login.cgi",
    L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
  };
  std::unique_ptr<PasswordForm> joint_form =
      CreatePasswordFormFromDataForTesting(joint_data);
  EXPECT_EQ(AddChangeForForm(*joint_form), login_db()->AddLogin(*joint_form));
  MockAppleKeychain::KeychainTestData joint_keychain_data = {
    kSecAuthenticationTypeHTMLForm, "some.domain.com",
    kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z",
    "joe_user", "sekrit", false };
  keychain()->AddTestItem(joint_keychain_data);

  // Insert a password into the keychain only.
  MockAppleKeychain::KeychainTestData keychain_only_data = {
    kSecAuthenticationTypeHTMLForm, "keychain.only.com",
    kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z",
    "keychain", "only", false
  };
  keychain()->AddTestItem(keychain_only_data);

  struct UpdateData {
    PasswordFormData form_data;
    const char* password;  // NULL indicates no entry should be present.
  };

  // Make a series of update calls.
  UpdateData updates[] = {
    // Update the keychain+db passwords (the normal password update case).
    { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
        "http://some.domain.com/insecure.html", "login.cgi",
        L"username", L"password", L"submit", L"joe_user", L"53krit",
        true, false, 2 },
      "53krit",
    },
    // Update the keychain-only password; this simulates the initial use of a
    // password stored by another browsers.
    { { PasswordForm::SCHEME_HTML, "http://keychain.only.com/",
        "http://keychain.only.com/login.html", "login.cgi",
        L"username", L"password", L"submit", L"keychain", L"only",
        true, false, 2 },
      "only",
    },
    // Update a password that doesn't exist in either location. This tests the
    // case where a form is filled, then the stored login is removed, then the
    // form is submitted.
    { { PasswordForm::SCHEME_HTML, "http://different.com/",
        "http://different.com/index.html", "login.cgi",
        L"username", L"password", L"submit", L"abc", L"123",
        true, false, 2 },
      NULL,
    },
  };
  for (unsigned int i = 0; i < arraysize(updates); ++i) {
    std::unique_ptr<PasswordForm> form =
        CreatePasswordFormFromDataForTesting(updates[i].form_data);
    store_->UpdateLogin(*form);
  }

  FinishAsyncProcessing();

  MacKeychainPasswordFormAdapter keychain_adapter(keychain());
  for (unsigned int i = 0; i < arraysize(updates); ++i) {
    std::unique_ptr<PasswordForm> query_form =
        CreatePasswordFormFromDataForTesting(updates[i].form_data);

    ScopedVector<autofill::PasswordForm> matching_items =
        keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
                                              query_form->scheme);
    if (updates[i].password) {
      EXPECT_GT(matching_items.size(), 0U) << "iteration " << i;
      if (matching_items.size() >= 1)
        EXPECT_EQ(ASCIIToUTF16(updates[i].password),
                  matching_items[0]->password_value) << "iteration " << i;
    } else {
      EXPECT_EQ(0U, matching_items.size()) << "iteration " << i;
    }

    EXPECT_TRUE(login_db()->GetLogins(*query_form, &matching_items));
    EXPECT_EQ(updates[i].password ? 1U : 0U, matching_items.size())
        << "iteration " << i;
  }
}

TEST_F(PasswordStoreMacTest, TestDBKeychainAssociation) {
  // Tests that association between the keychain and login database parts of a
  // password added by fuzzy (PSL) matching works.
  // 1. Add a password for www.facebook.com
  // 2. Get a password for m.facebook.com. This fuzzy matches and returns the
  //    www.facebook.com password.
  // 3. Add the returned password for m.facebook.com.
  // 4. Remove both passwords.
  //    -> check: that both are gone from the login DB and the keychain
  // This test should in particular ensure that we don't keep passwords in the
  // keychain just before we think we still have other (fuzzy-)matching entries
  // for them in the login database. (For example, here if we deleted the
  // www.facebook.com password from the login database, we should not be blocked
  // from deleting it from the keystore just becaus the m.facebook.com password
  // fuzzy-matches the www.facebook.com one.)

  // 1. Add a password for www.facebook.com
  PasswordFormData www_form_data = {
    PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
    "http://www.facebook.com/index.html", "login",
    L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
  };
  std::unique_ptr<PasswordForm> www_form =
      CreatePasswordFormFromDataForTesting(www_form_data);
  EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form));
  MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain());
  owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
  owned_keychain_adapter.AddPassword(*www_form);

  // 2. Get a password for m.facebook.com.
  PasswordForm m_form(*www_form);
  m_form.signon_realm = "http://m.facebook.com";
  m_form.origin = GURL("http://m.facebook.com/index.html");

  MockPasswordStoreConsumer consumer;
  store_->GetLogins(m_form, &consumer);
  PasswordForm returned_form;
  EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
      .WillOnce(
          DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
  base::MessageLoop::current()->Run();

  // 3. Add the returned password for m.facebook.com.
  returned_form.signon_realm = "http://m.facebook.com";
  returned_form.origin = GURL("http://m.facebook.com/index.html");
  EXPECT_EQ(AddChangeForForm(returned_form),
            login_db()->AddLogin(returned_form));
  owned_keychain_adapter.AddPassword(m_form);

  // 4. Remove both passwords.
  store_->RemoveLogin(*www_form);
  store_->RemoveLogin(m_form);
  FinishAsyncProcessing();

  // No trace of www.facebook.com.
  ScopedVector<autofill::PasswordForm> matching_items =
      owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm,
                                                  www_form->scheme);
  EXPECT_EQ(0u, matching_items.size());
  EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
  EXPECT_EQ(0u, matching_items.size());
  // No trace of m.facebook.com.
  matching_items = owned_keychain_adapter.PasswordsFillingForm(
      m_form.signon_realm, m_form.scheme);
  EXPECT_EQ(0u, matching_items.size());
  EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items));
  EXPECT_EQ(0u, matching_items.size());
}

namespace {

class PasswordsChangeObserver
    : public password_manager::PasswordStore::Observer {
 public:
  explicit PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) {
    observer_.Add(store);
  }

  void WaitAndVerify(PasswordStoreMacTest* test) {
    test->FinishAsyncProcessing();
    ::testing::Mock::VerifyAndClearExpectations(this);
  }

  // password_manager::PasswordStore::Observer:
  MOCK_METHOD1(OnLoginsChanged,
               void(const password_manager::PasswordStoreChangeList& changes));

 private:
  ScopedObserver<password_manager::PasswordStore, PasswordsChangeObserver>
      observer_;
};

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

// Tests RemoveLoginsCreatedBetween or RemoveLoginsSyncedBetween depending on
// |check_created|.
void CheckRemoveLoginsBetween(PasswordStoreMacTest* test, bool check_created) {
  PasswordFormData www_form_data_facebook = {
      PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
      "http://www.facebook.com/index.html", "login", L"submit", L"username",
      L"password", L"joe_user", L"sekrit", true, false, 0 };
  // The old form doesn't have elements names.
  PasswordFormData www_form_data_facebook_old = {
      PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
      "http://www.facebook.com/index.html", "login", L"", L"",
      L"", L"joe_user", L"oldsekrit", true, false, 0 };
  PasswordFormData www_form_data_other = {
      PasswordForm::SCHEME_HTML, "http://different.com/",
      "http://different.com/index.html", "login", L"submit", L"username",
      L"password", L"different_joe_user", L"sekrit", true, false, 0 };
  std::unique_ptr<PasswordForm> form_facebook =
      CreatePasswordFormFromDataForTesting(www_form_data_facebook);
  std::unique_ptr<PasswordForm> form_facebook_old =
      CreatePasswordFormFromDataForTesting(www_form_data_facebook_old);
  std::unique_ptr<PasswordForm> form_other =
      CreatePasswordFormFromDataForTesting(www_form_data_other);
  base::Time now = base::Time::Now();
  base::Time next_day = now + base::TimeDelta::FromDays(1);
  if (check_created) {
    form_facebook_old->date_created = now;
    form_facebook->date_created = next_day;
    form_other->date_created = next_day;
  } else {
    form_facebook_old->date_synced = now;
    form_facebook->date_synced = next_day;
    form_other->date_synced = next_day;
  }

  PasswordsChangeObserver observer(test->store());
  test->store()->AddLogin(*form_facebook_old);
  test->store()->AddLogin(*form_facebook);
  test->store()->AddLogin(*form_other);
  EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook_old)));
  EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook)));
  EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_other)));
  observer.WaitAndVerify(test);

  // Check the keychain content.
  MacKeychainPasswordFormAdapter owned_keychain_adapter(test->keychain());
  owned_keychain_adapter.SetFindsOnlyOwnedItems(false);
  ScopedVector<PasswordForm> matching_items(
      owned_keychain_adapter.PasswordsFillingForm(form_facebook->signon_realm,
                                                  form_facebook->scheme));
  EXPECT_EQ(1u, matching_items.size());
  matching_items = owned_keychain_adapter.PasswordsFillingForm(
      form_other->signon_realm, form_other->scheme);
  EXPECT_EQ(1u, matching_items.size());

  // Remove facebook.
  if (check_created) {
    test->store()->RemoveLoginsCreatedBetween(base::Time(), next_day,
                                              base::Closure());
  } else {
    test->store()->RemoveLoginsSyncedBetween(base::Time(), next_day);
  }
  password_manager::PasswordStoreChangeList list;
  form_facebook_old->password_value.clear();
  form_facebook->password_value.clear();
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::REMOVE, *form_facebook_old));
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::REMOVE, *form_facebook));
  EXPECT_CALL(observer, OnLoginsChanged(list));
  list.clear();
  observer.WaitAndVerify(test);

  matching_items = owned_keychain_adapter.PasswordsFillingForm(
      form_facebook->signon_realm, form_facebook->scheme);
  EXPECT_EQ(0u, matching_items.size());
  matching_items = owned_keychain_adapter.PasswordsFillingForm(
      form_other->signon_realm, form_other->scheme);
  EXPECT_EQ(1u, matching_items.size());

  // Remove form_other.
  if (check_created) {
    test->store()->RemoveLoginsCreatedBetween(next_day, base::Time(),
                                              base::Closure());
  } else {
    test->store()->RemoveLoginsSyncedBetween(next_day, base::Time());
  }
  form_other->password_value.clear();
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::REMOVE, *form_other));
  EXPECT_CALL(observer, OnLoginsChanged(list));
  observer.WaitAndVerify(test);
  matching_items = owned_keychain_adapter.PasswordsFillingForm(
      form_other->signon_realm, form_other->scheme);
  EXPECT_EQ(0u, matching_items.size());
}

}  // namespace

TEST_F(PasswordStoreMacTest, TestRemoveLoginsCreatedBetween) {
  CheckRemoveLoginsBetween(this, true);
}

TEST_F(PasswordStoreMacTest, TestRemoveLoginsSyncedBetween) {
  CheckRemoveLoginsBetween(this, false);
}

TEST_F(PasswordStoreMacTest, TestDisableAutoSignInForAllLogins) {
  PasswordFormData www_form_data_facebook = {
      PasswordForm::SCHEME_HTML,
      "http://www.facebook.com/",
      "http://www.facebook.com/index.html",
      "login",
      L"submit",
      L"username",
      L"password",
      L"joe_user",
      L"sekrit",
      true,
      false,
      0};
  std::unique_ptr<PasswordForm> form_facebook =
      CreatePasswordFormFromDataForTesting(www_form_data_facebook);
  form_facebook->skip_zero_click = false;

  // Add the zero-clickable form to the database.
  PasswordsChangeObserver observer(store());
  store()->AddLogin(*form_facebook);
  EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook)));
  observer.WaitAndVerify(this);

  ScopedVector<autofill::PasswordForm> forms;
  EXPECT_TRUE(login_db()->GetAutoSignInLogins(&forms));
  EXPECT_EQ(1u, forms.size());
  EXPECT_FALSE(forms[0]->skip_zero_click);

  store()->DisableAutoSignInForAllLogins(base::Closure());
  FinishAsyncProcessing();

  EXPECT_TRUE(login_db()->GetAutoSignInLogins(&forms));
  EXPECT_EQ(0u, forms.size());
}

TEST_F(PasswordStoreMacTest, TestRemoveLoginsMultiProfile) {
  // Make sure that RemoveLoginsCreatedBetween does affect only the correct
  // profile.

  // Add a third-party password.
  MockAppleKeychain::KeychainTestData keychain_data = {
      kSecAuthenticationTypeHTMLForm, "some.domain.com",
      kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z",
      "joe_user", "sekrit", false };
  keychain()->AddTestItem(keychain_data);

  // Add a password through the adapter. It has the "Chrome" creator tag.
  // However, it's not referenced by the password database.
  MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain());
  owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
  PasswordFormData www_form_data1 = {
      PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
      "http://www.facebook.com/index.html", "login", L"username", L"password",
      L"submit", L"joe_user", L"sekrit", true, false, 1 };
  std::unique_ptr<PasswordForm> www_form =
      CreatePasswordFormFromDataForTesting(www_form_data1);
  EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form));

  // Add a password from the current profile.
  PasswordFormData www_form_data2 = {
      PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
      "http://www.facebook.com/index.html", "login", L"username", L"password",
      L"submit", L"not_joe_user", L"12345", true, false, 1 };
  www_form = CreatePasswordFormFromDataForTesting(www_form_data2);
  store_->AddLogin(*www_form);
  FinishAsyncProcessing();

  ScopedVector<PasswordForm> matching_items;
  EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
  EXPECT_EQ(1u, matching_items.size());

  store_->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
                                     base::Closure());
  FinishAsyncProcessing();

  // Check the second facebook form is gone.
  EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
  EXPECT_EQ(0u, matching_items.size());

  // Check the first facebook form is still there.
  matching_items = owned_keychain_adapter.PasswordsFillingForm(
      www_form->signon_realm, www_form->scheme);
  ASSERT_EQ(1u, matching_items.size());
  EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value);

  // Check the third-party password is still there.
  owned_keychain_adapter.SetFindsOnlyOwnedItems(false);
  matching_items = owned_keychain_adapter.PasswordsFillingForm(
      "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML);
  ASSERT_EQ(1u, matching_items.size());
}

// Add a facebook form to the store but not to the keychain. The form is to be
// implicitly deleted. However, the observers shouldn't get notified about
// deletion of non-existent forms like m.facebook.com.
TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) {
  testing::StrictMock<password_manager::MockPasswordStoreObserver>
      mock_observer;
  store()->AddObserver(&mock_observer);

  // 1. Add a password for www.facebook.com to the LoginDatabase.
  PasswordFormData www_form_data = {
    PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
    "http://www.facebook.com/index.html", "login",
    L"username", L"password", L"submit", L"joe_user", L"", true, false, 1
  };
  std::unique_ptr<PasswordForm> www_form(
      CreatePasswordFormFromDataForTesting(www_form_data));
  EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form));

  // 2. Get a PSL-matched password for m.facebook.com. The observer isn't
  // notified because the form isn't in the database.
  PasswordForm m_form(*www_form);
  m_form.signon_realm = "http://m.facebook.com";
  m_form.origin = GURL("http://m.facebook.com/index.html");

  MockPasswordStoreConsumer consumer;
  ON_CALL(consumer, OnGetPasswordStoreResultsConstRef(_))
      .WillByDefault(QuitUIMessageLoop());
  EXPECT_CALL(mock_observer, OnLoginsChanged(_)).Times(0);
  // The PSL-matched form isn't returned because there is no actual password in
  // the keychain.
  EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
  store_->GetLogins(m_form, &consumer);
  base::MessageLoop::current()->Run();
  ScopedVector<autofill::PasswordForm> all_forms;
  EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms));
  EXPECT_EQ(1u, all_forms.size());
  ::testing::Mock::VerifyAndClearExpectations(&mock_observer);

  // 3. Get a password for www.facebook.com. The form is implicitly removed and
  // the observer is notified.
  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::REMOVE, *www_form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
  store_->GetLogins(*www_form, &consumer);
  base::MessageLoop::current()->Run();
  EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms));
  EXPECT_EQ(0u, all_forms.size());
}

// Verify that Android app passwords can be stored, retrieved, and deleted.
// Regression test for http://crbug.com/455551
TEST_F(PasswordStoreMacTest, StoringAndRetrievingAndroidCredentials) {
  PasswordForm form;
  form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/";
  form.username_value = base::UTF8ToUTF16("randomusername");
  form.password_value = base::UTF8ToUTF16("password");

  VerifyCredentialLifecycle(form);
}

// Verify that federated credentials can be stored, retrieved and deleted.
TEST_F(PasswordStoreMacTest, StoringAndRetrievingFederatedCredentials) {
  PasswordForm form;
  form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/";
  form.federation_origin =
      url::Origin(GURL(password_manager::kTestingFederationUrlSpec));
  form.username_value = base::UTF8ToUTF16("randomusername");
  form.password_value = base::UTF8ToUTF16("");  // No password.

  VerifyCredentialLifecycle(form);
}

void CheckMigrationResult(PasswordStoreMac::MigrationResult expected_result,
                          PasswordStoreMac::MigrationResult result) {
  EXPECT_EQ(expected_result, result);
  QuitUIMessageLoop();
}

// Import the passwords from the Keychain to LoginDatabase.
TEST_F(PasswordStoreMacTest, ImportFromKeychain) {
  PasswordForm form1;
  form1.origin = GURL("http://accounts.google.com/LoginAuth");
  form1.signon_realm = "http://accounts.google.com/";
  form1.username_value = ASCIIToUTF16("my_username");
  form1.password_value = ASCIIToUTF16("my_password");

  PasswordForm form2;
  form2.origin = GURL("http://facebook.com/Login");
  form2.signon_realm = "http://facebook.com/";
  form2.username_value = ASCIIToUTF16("my_username");
  form2.password_value = ASCIIToUTF16("my_password");

  PasswordForm blacklisted_form;
  blacklisted_form.origin = GURL("http://badsite.com/Login");
  blacklisted_form.signon_realm = "http://badsite.com/";
  blacklisted_form.blacklisted_by_user = true;

  store()->AddLogin(form1);
  store()->AddLogin(form2);
  store()->AddLogin(blacklisted_form);
  FinishAsyncProcessing();

  ASSERT_TRUE(base::PostTaskAndReplyWithResult(
      thread_->task_runner().get(), FROM_HERE,
      base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
      base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
  FinishAsyncProcessing();

  // The password should be stored in the database by now.
  ScopedVector<PasswordForm> matching_items;
  EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
  ASSERT_EQ(1u, matching_items.size());
  EXPECT_EQ(form1, *matching_items[0]);

  EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items));
  ASSERT_EQ(1u, matching_items.size());
  EXPECT_EQ(form2, *matching_items[0]);

  EXPECT_TRUE(login_db()->GetLogins(blacklisted_form, &matching_items));
  ASSERT_EQ(1u, matching_items.size());
  EXPECT_EQ(blacklisted_form, *matching_items[0]);

  // The passwords are encrypted using a key from the Keychain.
  EXPECT_TRUE(histogram_tester_->GetHistogramSamplesSinceCreation(
                                     "OSX.Keychain.Access")->TotalCount());
  histogram_tester_.reset();
}

// Import a federated credential while the Keychain is locked.
TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) {
  keychain()->set_locked(true);
  PasswordForm form1;
  form1.origin = GURL("http://example.com/Login");
  form1.signon_realm = "http://example.com/";
  form1.username_value = ASCIIToUTF16("my_username");
  form1.federation_origin = url::Origin(GURL("https://accounts.google.com/"));

  store()->AddLogin(form1);
  FinishAsyncProcessing();
  ASSERT_TRUE(base::PostTaskAndReplyWithResult(
      thread_->task_runner().get(), FROM_HERE,
      base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
      base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
  FinishAsyncProcessing();

  ScopedVector<PasswordForm> matching_items;
  EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
  ASSERT_EQ(1u, matching_items.size());
  EXPECT_EQ(form1, *matching_items[0]);
}

// Try to import while the Keychain is locked but the encryption key had been
// read earlier.
TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) {
  PasswordForm form1;
  form1.origin = GURL("http://accounts.google.com/LoginAuth");
  form1.signon_realm = "http://accounts.google.com/";
  form1.username_value = ASCIIToUTF16("my_username");
  form1.password_value = ASCIIToUTF16("my_password");
  store()->AddLogin(form1);
  FinishAsyncProcessing();

  // Add a second keychain item matching the Database entry.
  PasswordForm form2 = form1;
  form2.origin = GURL("http://accounts.google.com/Login");
  form2.password_value = ASCIIToUTF16("1234");
  MacKeychainPasswordFormAdapter adapter(keychain());
  EXPECT_TRUE(adapter.AddPassword(form2));

  keychain()->set_locked(true);
  ASSERT_TRUE(base::PostTaskAndReplyWithResult(
      thread_->task_runner().get(), FROM_HERE,
      base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
      base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED)));
  FinishAsyncProcessing();

  ScopedVector<PasswordForm> matching_items;
  EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
  ASSERT_EQ(1u, matching_items.size());
  EXPECT_EQ(base::string16(), matching_items[0]->password_value);

  histogram_tester_->ExpectUniqueSample(
      "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1);
  histogram_tester_->ExpectUniqueSample(
      "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1);
  histogram_tester_->ExpectUniqueSample(
      "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords",
      2, 1);
  // Don't test the encryption key access.
  histogram_tester_.reset();
}
