// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <memory>

#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "components/autofill/content/renderer/field_data_manager.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "components/autofill/content/renderer/password_form_conversion_utils.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "content/public/test/render_view_test.h"
#include "google_apis/gaia/gaia_urls.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_form_control_element.h"
#include "third_party/blink/public/web/web_form_element.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_local_frame.h"

using blink::WebFormControlElement;
using blink::WebFormElement;
using blink::WebLocalFrame;
using blink::WebInputElement;
using blink::WebVector;

namespace autofill {
namespace {

const char kTestFormActionURL[] = "http://cnn.com";

// A builder to produce HTML code for a password form composed of the desired
// number and kinds of username and password fields.
class PasswordFormBuilder {
 public:
  // Creates a builder to start composing a new form. The form will have the
  // specified |action| URL.
  explicit PasswordFormBuilder(const char* action) {
    base::StringAppendF(
        &html_, "<FORM name=\"Test\" action=\"%s\" method=\"post\">", action);
  }

  // Appends a new text-type field at the end of the form, having the specified
  // |name_and_id|, |value|, and |autocomplete| attributes. The |autocomplete|
  // argument can take two special values, namely:
  //  1.) nullptr, causing no autocomplete attribute to be added,
  //  2.) "", causing an empty attribute (i.e. autocomplete="") to be added.
  void AddTextField(const char* name_and_id,
                    const char* value,
                    const char* autocomplete) {
    std::string autocomplete_attribute(autocomplete ?
        base::StringPrintf("autocomplete=\"%s\"", autocomplete) : "");
    base::StringAppendF(
        &html_,
        "<INPUT type=\"text\" name=\"%s\" id=\"%s\" value=\"%s\" %s/>",
        name_and_id, name_and_id, value, autocomplete_attribute.c_str());
  }

  // Add a text field with name, id, value, label and placeholder,
  // without autocomplete.
  void AddTextFieldWithoutAutocomplete(const char* name,
                                       const char* id,
                                       const char* value,
                                       const char* label,
                                       const char* placeholder) {
    base::StringAppendF(&html_,
                        "<LABEL for=\"%s\">%s</LABEL>"
                        "<INPUT type=\"text\" name=\"%s\" id=\"%s\" "
                        "value=\"%s\" placeholder=\"%s\"/>",
                        id, label, name, id, value, placeholder);
  }

  // Appends a new password-type field at the end of the form, having the
  // specified |name_and_id|, |value|, and |autocomplete| attributes. Special
  // values for |autocomplete| are the same as in AddTextField.
  void AddPasswordField(const char* name_and_id,
                        const char* value,
                        const char* autocomplete) {
    std::string autocomplete_attribute(
        autocomplete ? base::StringPrintf("autocomplete=\"%s\"", autocomplete)
                     : "");
    base::StringAppendF(
        &html_,
        "<INPUT type=\"password\" name=\"%s\" id=\"%s\" value=\"%s\" %s/>",
        name_and_id, name_and_id, value, autocomplete_attribute.c_str());
  }

  // Appends a disabled text-type field at the end of the form.
  void AddDisabledUsernameField() {
    html_ += "<INPUT name=\"disabled field\" type=\"text\" disabled/>";
  }

  // Appends a disabled password-type field at the end of the form.
  void AddDisabledPasswordField() {
    html_ += "<INPUT name=\"disabled field\" type=\"password\" disabled/>";
  }

  // Appends a hidden field at the end of the form.
  void AddHiddenField() { html_ += "<INPUT type=\"hidden\"/>"; }

  // Appends a new hidden-type field at the end of the form, having the
  // specified |name_and_id| and |value| attributes.
  void AddHiddenField(const char* name_and_id, const char* value) {
    base::StringAppendF(
        &html_, "<INPUT type=\"hidden\" name=\"%s\" id=\"%s\" value=\"%s\" />",
        name_and_id, name_and_id, value);
  }

  // Append a text field with "display: none".
  void AddNonDisplayedTextField(const char* name_and_id, const char* value) {
    base::StringAppendF(
        &html_,
        "<INPUT type=\"text\" name=\"%s\" id=\"%s\" value=\"%s\""
        "style=\"display: none;\"/>",
        name_and_id, name_and_id, value);
  }

  // Append a password field with "display: none".
  void AddNonDisplayedPasswordField(const char* name_and_id,
                                    const char* value) {
    base::StringAppendF(
        &html_,
        "<INPUT type=\"password\" name=\"%s\" id=\"%s\" value=\"%s\""
        "style=\"display: none;\"/>",
        name_and_id, name_and_id, value);
  }

  // Append a text field with "visibility: hidden".
  void AddNonVisibleTextField(const char* name_and_id, const char* value) {
    base::StringAppendF(
        &html_,
        "<INPUT type=\"text\" name=\"%s\" id=\"%s\" value=\"%s\""
        "style=\"visibility: hidden;\"/>",
        name_and_id, name_and_id, value);
  }

  // Append a password field with "visibility: hidden".
  void AddNonVisiblePasswordField(const char* name_and_id, const char* value) {
    base::StringAppendF(
        &html_,
        "<INPUT type=\"password\" name=\"%s\" id=\"%s\" value=\"%s\""
        "style=\"visibility: hidden;\"/>",
        name_and_id, name_and_id, value);
  }

  // Add a field with a given type. Useful to add non-text fields.
  void AddFieldWithType(const char* name_and_id, const char* type) {
    base::StringAppendF(&html_, "<INPUT type=\"%s\" name=\"%s\" id=\"%s\"/>",
                        type, name_and_id, name_and_id);
  }

  // Appends a new submit-type field at the end of the form with the specified
  // |name|.
  void AddSubmitButton(const char* name) {
    base::StringAppendF(
        &html_, "<INPUT type=\"submit\" name=\"%s\" value=\"Submit\"/>", name);
  }

  // Returns the HTML code for the form containing the fields that have been
  // added so far.
  std::string ProduceHTML() const { return html_ + "</FORM>"; }

  // Appends a field of |type| without name or id attribute at the end of the
  // form.
  void AddAnonymousInputField(const char* type) {
    std::string type_attribute(type ? base::StringPrintf("type=\"%s\"", type)
                                    : "");
    base::StringAppendF(&html_, "<INPUT %s/>", type_attribute.c_str());
  }

 private:
  std::string html_;

  DISALLOW_COPY_AND_ASSIGN(PasswordFormBuilder);
};

class PasswordFormConversionUtilsTest : public content::RenderViewTest {
 public:
  PasswordFormConversionUtilsTest() = default;
  ~PasswordFormConversionUtilsTest() override = default;

 protected:
  // Loads the given |html|, retrieves the sole WebFormElement from it, and then
  // calls CreatePasswordForm(), passing it the |predictions| to convert it to
  // a PasswordForm. If |with_user_input| == true it's considered that all
  // values in the form elements came from the user input.
  std::unique_ptr<PasswordForm> LoadHTMLAndConvertForm(
      const std::string& html,
      FormsPredictionsMap* predictions,
      bool with_user_input) {
    WebFormElement form;
    LoadWebFormFromHTML(html, &form, nullptr);

    WebVector<WebFormControlElement> control_elements;
    form.GetFormControlElements(control_elements);
    FieldDataManager field_data_manager;
    for (size_t i = 0; i < control_elements.size(); ++i) {
      WebInputElement* input_element = ToWebInputElement(&control_elements[i]);
      if (input_element->HasAttribute("set-activated-submit"))
        input_element->SetActivatedSubmit(true);
      if (with_user_input) {
        field_data_manager.UpdateFieldDataMap(control_elements[i],
                                              input_element->Value().Utf16(),
                                              FieldPropertiesFlags::USER_TYPED);
      }
    }

    return CreatePasswordFormFromWebForm(
        form, with_user_input ? &field_data_manager : nullptr, predictions,
        &username_detector_cache_);
  }

  // Iterates on the form generated by the |html| and adds the fields and type
  // predictions corresponding to |predictions_positions| to |predictions|.
  void SetPredictions(const std::string& html,
                      FormsPredictionsMap* predictions,
                      const std::map<int, PasswordFormFieldPredictionType>&
                          predictions_positions) {
    WebFormElement form;
    LoadWebFormFromHTML(html, &form, nullptr);

    FormData form_data;
    ASSERT_TRUE(form_util::WebFormElementToFormData(
        form, WebFormControlElement(), nullptr, form_util::EXTRACT_NONE,
        &form_data, nullptr));

    FormStructure form_structure(form_data);

    int field_index = 0;
    for (auto field = form_structure.begin(); field != form_structure.end();
         ++field, ++field_index) {
      if (predictions_positions.find(field_index) !=
          predictions_positions.end()) {
        (*predictions)[form_data][*(*field)] =
            predictions_positions.find(field_index)->second;
      }
    }
  }

  void GetFirstForm(WebFormElement* form) {
    WebLocalFrame* frame = GetMainFrame();
    ASSERT_TRUE(frame);

    WebVector<WebFormElement> forms;
    frame->GetDocument().Forms(forms);
    ASSERT_LE(1U, forms.size());

    *form = forms[0];
  }

  // Loads the given |html| and retrieves the sole WebFormElement from it.
  void LoadWebFormFromHTML(const std::string& html,
                           WebFormElement* form,
                           const char* origin) {
    if (origin)
      LoadHTMLWithUrlOverride(html.c_str(), origin);
    else
      LoadHTML(html.c_str());

    GetFirstForm(form);
  }

  bool ExtractFormDataForFirstForm(FormData* data) {
    WebFormElement form;
    GetFirstForm(&form);
    return form_util::ExtractFormData(form, data);
  }

  void TearDown() override {
    username_detector_cache_.clear();
    content::RenderViewTest::TearDown();
  }

  UsernameDetectorCache username_detector_cache_;

 private:
  DISALLOW_COPY_AND_ASSIGN(PasswordFormConversionUtilsTest);
};

}  // namespace

TEST_F(PasswordFormConversionUtilsTest, BasicFormAttributes) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username", "johnsmith", nullptr);
  builder.AddSubmitButton("inactive_submit");
  builder.AddSubmitButton("active_submit");
  builder.AddSubmitButton("inactive_submit2");
  builder.AddPasswordField("password", "secret", nullptr);
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);

  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ("data:", password_form->signon_realm);
  EXPECT_EQ(GURL(kTestFormActionURL), password_form->action);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
  EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form->scheme);
  EXPECT_FALSE(password_form->preferred);
  EXPECT_FALSE(password_form->blacklisted_by_user);
  EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type);
}

TEST_F(PasswordFormConversionUtilsTest, DisabledFieldsAreIgnored) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username", "johnsmith", nullptr);
  builder.AddDisabledUsernameField();
  builder.AddDisabledPasswordField();
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
}

// When not enough fields are enabled to parse the form, the result should still
// be not null. It must contain only minimal information, so that it is not used
// for fill on load, for example. It must contain the full FormData, so that the
// new parser can be run as well.
TEST_F(PasswordFormConversionUtilsTest, OnlyDisabledFields) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddDisabledUsernameField();
  builder.AddDisabledPasswordField();
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_TRUE(password_form->username_element.empty());
  EXPECT_TRUE(password_form->password_element.empty());
  EXPECT_TRUE(password_form->new_password_element.empty());
  EXPECT_EQ(2u, password_form->form_data.fields.size());
}

TEST_F(PasswordFormConversionUtilsTest, HTMLDetector_DeveloperGroupAttributes) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      password_manager::features::kHtmlBasedUsernameDetector);

  // Each test case consists of a set of parameters to be plugged into the
  // PasswordFormBuilder below, plus the corresponding expectations.
  // The test data contains cases that are identified by HTML detector, and not
  // by base heuristic. Thus, username field does not necessarely have to be
  // right before password field.
  // These tests basically check searching in developer group (i.e. name and id
  // attribute, concatenated, with "$" guard in between).
  struct TestCase {
    // Field parameters represent, in order of appearance, field name, field id
    // and field value.
    const char* first_text_field_parameters[3];
    const char* second_text_field_parameters[3];
    const char* expected_username_element;
    const char* expected_username_value;
  } cases[] = {
      // There are both field name and id.
      {{"username", "id", "johnsmith"},
       {"email", "id", "js@google.com"},
       "username",
       "johnsmith"},
      // there is no field id.
      {{"username", "", "johnsmith"},
       {"email", "", "js@google.com"},
       "username",
       "johnsmith"},
      // Upper or mixed case shouldn't matter.
      {{"uSeRnAmE", "id", "johnsmith"},
       {"email", "id", "js@google.com"},
       "uSeRnAmE",
       "johnsmith"},
      // Check removal of special characters.
      {{"u1_s2-e3~r4/n5(a)6m#e", "", "johnsmith"},
       {"email", "", "js@google.com"},
       "u1_s2-e3~r4/n5(a)6m#e",
       "johnsmith"},
      // Check guard between field name and field id.
      {{"us", "ername", "johnsmith"},
       {"email", "", "js@google.com"},
       "email",
       "js@google.com"},
      // Check removal of fields with latin negative words in developer group.
      {{"email", "", "js@google.com"},
       {"fake_username", "", "johnsmith"},
       "email",
       "js@google.com"},
      {{"email", "mail", "js@google.com"},
       {"user_name", "fullname", "johnsmith"},
       "email",
       "js@google.com"},
      // Identify latin translations of "username".
      {{"benutzername", "", "johnsmith"},
       {"email", "", "js@google.com"},
       "benutzername",
       "johnsmith"},
      // Identify latin translations of "user".
      {{"utilizator", "", "johnsmith"},
       {"email", "", "js@google.com"},
       "utilizator",
       "johnsmith"},
      // Identify technical words.
      {{"loginid", "", "johnsmith"},
       {"email", "", "js@google.com"},
       "loginid",
       "johnsmith"},
      // Identify weak words.
      {{"usrname", "", "johnsmith"},
       {"email", "", "js@google.com"},
       "email",
       "js@google.com"},
      // If a word matches in maximum 2 fields, it is accepted.
      // First encounter is selected as username.
      {{"username", "", "johnsmith"},
       {"repeat_username", "", "johnsmith"},
       "username",
       "johnsmith"},
      // A short word should be enclosed between delimiters. Otherwise, an
      // Occurrence doesn't count.
      {{"identity_name", "idn", "johnsmith"},
       {"id", "id", "123"},
       "id",
       "123"}};

  for (size_t i = 0; i < base::size(cases); ++i) {
    SCOPED_TRACE(testing::Message() << "Iteration " << i);

    PasswordFormBuilder builder(kTestFormActionURL);
    builder.AddTextFieldWithoutAutocomplete(
        cases[i].first_text_field_parameters[0],
        cases[i].first_text_field_parameters[1],
        cases[i].first_text_field_parameters[2], "", "");
    builder.AddTextFieldWithoutAutocomplete(
        cases[i].second_text_field_parameters[0],
        cases[i].second_text_field_parameters[1],
        cases[i].second_text_field_parameters[2], "", "");
    builder.AddPasswordField("password", "secret", nullptr);
    builder.AddSubmitButton("submit");
    std::string html = builder.ProduceHTML();

    username_detector_cache_.clear();
    std::unique_ptr<PasswordForm> password_form =
        LoadHTMLAndConvertForm(html, nullptr, false);

    ASSERT_TRUE(password_form);

    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element),
              password_form->username_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value),
              password_form->username_value);
    // Check that the username field was found by HTML detector.
    ASSERT_EQ(1u, username_detector_cache_.size());
    ASSERT_FALSE(username_detector_cache_.begin()->second.empty());
    EXPECT_EQ(
        cases[i].expected_username_element,
        username_detector_cache_.begin()->second[0].NameForAutofill().Utf8());
  }
}

TEST_F(PasswordFormConversionUtilsTest, HTMLDetector_SeveralDetections) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      password_manager::features::kHtmlBasedUsernameDetector);

  // If word matches in more than 2 fields, we don't match on it.
  // We search for match with another word.
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextFieldWithoutAutocomplete("address", "user", "someaddress", "",
                                          "");
  builder.AddTextFieldWithoutAutocomplete("loginid", "user", "johnsmith", "",
                                          "");
  builder.AddTextFieldWithoutAutocomplete("tel", "user", "sometel", "", "");
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  DCHECK(username_detector_cache_.empty());
  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);

  ASSERT_TRUE(password_form);

  EXPECT_EQ(base::UTF8ToUTF16("loginid"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
  // Check that the username field was found by HTML detector.
  ASSERT_EQ(1u, username_detector_cache_.size());
  ASSERT_EQ(1u, username_detector_cache_.begin()->second.size());
  EXPECT_EQ(
      "loginid",
      username_detector_cache_.begin()->second[0].NameForAutofill().Utf8());
}

TEST_F(PasswordFormConversionUtilsTest, HTMLDetector_UserGroupAttributes) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      password_manager::features::kHtmlBasedUsernameDetector);

  // Each test case consists of a set of parameters to be plugged into the
  // PasswordFormBuilder below, plus the corresponding expectations.
  // The test data contains cases that are identified by HTML detector, and not
  // by base heuristic. Thus, username field does not necessarely have to be
  // right before password field.
  // These tests basically check searching in user group.
  struct TestCase {
    // Field parameters represent, in order of appearance, field name, field
    // id, field value and field label or placeholder.
    // Field name and field id don't contain any significant information.
    const char* first_text_field_parameters[4];
    const char* second_text_field_parameters[4];
    const char* expected_username_element;
    const char* expected_username_value;
  } cases[] = {
      // Label information will decide username.
      {{"name1", "id1", "johnsmith", "Username:"},
       {"name2", "id2", "js@google.com", "Email:"},
       "name1",
       "johnsmith"},
      // Placeholder information will decide username.
      {{"name1", "id1", "js@google.com", "Email:"},
       {"name2", "id2", "johnsmith", "Username:"},
       "name2",
       "johnsmith"},
      // Check removal of special characters.
      {{"name1", "id1", "johnsmith", "U s er n a m e:"},
       {"name2", "id2", "js@google.com", "Email:"},
       "name1",
       "johnsmith"},
      // Check removal of fields with latin negative words in user group.
      {{"name1", "id1", "johnsmith", "Username password:"},
       {"name2", "id2", "js@google.com", "Email:"},
       "name2",
       "js@google.com"},
      // Check removal of fields with non-latin negative words in user group.
      {{"name1", "id1", "js@google.com", "Email:"},
       {"name2", "id2", "johnsmith", "የይለፍቃልየይለፍቃል:"},
       "name1",
       "js@google.com"},
      // Identify latin translations of "username".
      {{"name1", "id1", "johnsmith", "Username:"},
       {"name2", "id2", "js@google.com", "Email:"},
       "name1",
       "johnsmith"},
      // Identify non-latin translations of "username".
      {{"name1", "id1", "johnsmith", "用户名:"},
       {"name2", "id2", "js@google.com", "Email:"},
       "name1",
       "johnsmith"},
      // Identify latin translations of "user".
      {{"name1", "id1", "johnsmith", "Wosuta:"},
       {"name2", "id2", "js@google.com", "Email:"},
       "name1",
       "johnsmith"},
      // Identify non-latin translations of "user".
      {{"name1", "id1", "johnsmith", "истифода:"},
       {"name2", "id2", "js@google.com", "Email:"},
       "name1",
       "johnsmith"},
      // Identify weak words.
      {{"name1", "id1", "johnsmith", "Insert your login details:"},
       {"name2", "id2", "js@google.com", "Insert your email:"},
       "name1",
       "johnsmith"},
      // Check user group priority, compared to developer group.
      // User group should have higher priority than developer group.
      {{"email", "", "js@google.com", "Username:"},
       {"username", "", "johnsmith", "Email:"},
       "email",
       "js@google.com"},
      // Check treatment for short dictionary words. "uid" has higher priority,
      // but its occurrence is ignored because it is a part of another word.
      {{"name1", "", "johnsmith", "Insert your id:"},
       {"name2", "uidentical", "js@google.com", "Insert something:"},
       "name1",
       "johnsmith"}};

  for (size_t i = 0; i < base::size(cases); ++i) {
    SCOPED_TRACE(testing::Message() << "Iteration " << i);

    PasswordFormBuilder builder(kTestFormActionURL);
    builder.AddTextFieldWithoutAutocomplete(
        cases[i].first_text_field_parameters[0],
        cases[i].first_text_field_parameters[1],
        cases[i].first_text_field_parameters[2],
        cases[i].first_text_field_parameters[3], "");
    builder.AddTextFieldWithoutAutocomplete(
        cases[i].second_text_field_parameters[0],
        cases[i].second_text_field_parameters[1],
        cases[i].second_text_field_parameters[2], "",
        cases[i].second_text_field_parameters[3]);
    builder.AddPasswordField("password", "secret", nullptr);
    builder.AddSubmitButton("submit");
    std::string html = builder.ProduceHTML();

    username_detector_cache_.clear();
    std::unique_ptr<PasswordForm> password_form =
        LoadHTMLAndConvertForm(html, nullptr, false);

    ASSERT_TRUE(password_form);

    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element),
              password_form->username_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value),
              password_form->username_value);
    // Check that the username field was found by HTML detector.
    ASSERT_EQ(1u, username_detector_cache_.size());
    ASSERT_FALSE(username_detector_cache_.begin()->second.empty());
    EXPECT_EQ(
        cases[i].expected_username_element,
        username_detector_cache_.begin()->second[0].NameForAutofill().Utf8());
  }
}

TEST_F(PasswordFormConversionUtilsTest, HTMLDetectorCache) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      password_manager::features::kHtmlBasedUsernameDetector);

  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("unknown", "12345", nullptr);
  builder.AddTextField("something", "smith", nullptr);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();
  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);
  UsernameDetectorCache detector_cache;

  // No signals from HTML attributes. The classifier found nothing and cached
  // it.
  base::HistogramTester histogram_tester;
  std::unique_ptr<PasswordForm> password_form =
      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
  EXPECT_TRUE(password_form);
  ASSERT_EQ(1u, detector_cache.size());
  EXPECT_EQ(form, detector_cache.begin()->first);
  EXPECT_TRUE(detector_cache.begin()->second.empty());
  histogram_tester.ExpectUniqueSample("PasswordManager.UsernameDetectionMethod",
                                      UsernameDetectionMethod::BASE_HEURISTIC,
                                      1);

  // Changing attributes would change the classifier's output. But the output
  // will be the same because it was cached in |username_detector_cache|.
  WebVector<WebFormControlElement> control_elements;
  form.GetFormControlElements(control_elements);
  control_elements[0].SetAttribute("name", "id");
  password_form =
      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
  EXPECT_TRUE(password_form);
  ASSERT_EQ(1u, detector_cache.size());
  EXPECT_EQ(form, detector_cache.begin()->first);
  EXPECT_TRUE(detector_cache.begin()->second.empty());
  histogram_tester.ExpectUniqueSample("PasswordManager.UsernameDetectionMethod",
                                      UsernameDetectionMethod::BASE_HEURISTIC,
                                      2);

  // Clear the cache. The classifier will find username field and cache it.
  detector_cache.clear();
  ASSERT_EQ(4u, control_elements.size());
  password_form =
      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
  EXPECT_TRUE(password_form);
  ASSERT_EQ(1u, detector_cache.size());
  EXPECT_EQ(form, detector_cache.begin()->first);
  ASSERT_EQ(1u, detector_cache.begin()->second.size());
  EXPECT_EQ("id", detector_cache.begin()->second[0].NameForAutofill().Utf8());
  EXPECT_THAT(
      histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"),
      testing::UnorderedElementsAre(
          base::Bucket(UsernameDetectionMethod::BASE_HEURISTIC, 2),
          base::Bucket(UsernameDetectionMethod::HTML_BASED_CLASSIFIER, 1)));

  // Change the attributes again ("username" is stronger signal than "login"),
  // but keep the cache. The classifier's output should be the same.
  control_elements[1].SetAttribute("name", "username");
  password_form =
      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
  EXPECT_TRUE(password_form);
  ASSERT_EQ(1u, detector_cache.size());
  EXPECT_EQ(form, detector_cache.begin()->first);
  ASSERT_EQ(1u, detector_cache.begin()->second.size());
  EXPECT_EQ("id", detector_cache.begin()->second[0].NameForAutofill().Utf8());
  EXPECT_THAT(
      histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"),
      testing::UnorderedElementsAre(
          base::Bucket(UsernameDetectionMethod::BASE_HEURISTIC, 2),
          base::Bucket(UsernameDetectionMethod::HTML_BASED_CLASSIFIER, 2)));
}

TEST_F(PasswordFormConversionUtilsTest, HTMLDetectorCache_SkipSomePredictions) {
  // The cache of HTML based username detector may contain several predictions
  // (in the order of decreasing reliability) for the given form, but the
  // detector should consider only |possible_usernames| passed to
  // GetUsernameFieldBasedOnHtmlAttributes. For example, if a field has no user
  // input while others has, the field cannot be an username field.

  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username", "12345", nullptr);
  builder.AddTextField("email", "smith@google.com", nullptr);
  builder.AddTextField("id", "12345", nullptr);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();
  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);
  WebVector<WebFormControlElement> control_elements;
  form.GetFormControlElements(control_elements);
  ASSERT_FALSE(control_elements.empty());

  // Add predictions for "email" and "id" fields to the cache.
  UsernameDetectorCache username_detector_cache;
  username_detector_cache[control_elements[0].Form()] = {
      *ToWebInputElement(&control_elements[1]),   // email
      *ToWebInputElement(&control_elements[2])};  // id

  // A user typed only into "id" and "password" fields. So, the prediction for
  // "email" field should be ignored despite it is more reliable than prediction
  // for "id" field.
  FieldDataManager field_data_manager;
  field_data_manager.UpdateFieldDataMap(
      control_elements[2], control_elements[2].Value().Utf16(),
      FieldPropertiesFlags::USER_TYPED);  // id
  field_data_manager.UpdateFieldDataMap(
      control_elements[3], control_elements[3].Value().Utf16(),
      FieldPropertiesFlags::USER_TYPED);  // password

  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
      form, &field_data_manager, nullptr, &username_detector_cache);

  ASSERT_TRUE(password_form);
  EXPECT_EQ(base::UTF8ToUTF16("id"), password_form->username_element);
}

TEST_F(PasswordFormConversionUtilsTest,
       IdentifyingUsernameFieldsWithBaseHeuristic) {
  // Each test case consists of a set of parameters to be plugged into the
  // PasswordFormBuilder below, plus the corresponding expectations.
  // The test data should not contain field names that are identified by the
  // HTML based username detector, because with these tests only the base
  // heuristic (i.e. select as username the field before the password field)
  // is tested.
  struct TestCase {
    const char* autocomplete[3];
    const char* expected_username_element;
    const char* expected_username_value;
    const char* expected_other_possible_usernames;
  } cases[] = {
      // When no elements are marked with autocomplete='username', the text-type
      // input field before the first password element should get selected as
      // the username, and the rest should be marked as alternatives.
      {{nullptr, nullptr, nullptr},
       "usrname2",
       "William",
       "John+usrname1, Smith+usrname3"},
      // When a sole element is marked with autocomplete='username', it should
      // be treated as the username, but other text fields should be added to
      // |other_possible_usernames|.
      {{"username", nullptr, nullptr},
       "usrname1",
       "John",
       "William+usrname2, Smith+usrname3"},
      {{nullptr, "username", nullptr},
       "usrname2",
       "William",
       "John+usrname1, Smith+usrname3"},
      {{nullptr, nullptr, "username"},
       "usrname3",
       "Smith",
       "John+usrname1, William+usrname2"},
      // When >=2 elements have the attribute, the first should be selected as
      // the username, and the rest should go to |other_possible_usernames|.
      {{"username", "username", nullptr},
       "usrname1",
       "John",
       "William+usrname2, Smith+usrname3"},
      {{nullptr, "username", "username"},
       "usrname2",
       "William",
       "John+usrname1, Smith+usrname3"},
      {{"username", nullptr, "username"},
       "usrname1",
       "John",
       "William+usrname2, Smith+usrname3"},
      {{"username", "username", "username"},
       "usrname1",
       "John",
       "William+usrname2, Smith+usrname3"},
      // When there is an empty autocomplete attribute (i.e. autocomplete=""),
      // it should have the same effect as having no attribute whatsoever.
      {{"", "", ""}, "usrname2", "William", "John+usrname1, Smith+usrname3"},
      {{"", "", "username"},
       "usrname3",
       "Smith",
       "John+usrname1, William+usrname2"},
      {{"username", "", "username"},
       "usrname1",
       "John",
       "William+usrname2, Smith+usrname3"},
      // It should not matter if attribute values are upper or mixed case.
      {{"USERNAME", nullptr, "uSeRNaMe"},
       "usrname1",
       "John",
       "William+usrname2, Smith+usrname3"},
      {{"uSeRNaMe", nullptr, "USERNAME"},
       "usrname1",
       "John",
       "William+usrname2, Smith+usrname3"}};

  for (size_t i = 0; i < base::size(cases); ++i) {
    for (size_t nonempty_username_fields = 0; nonempty_username_fields < 2;
         ++nonempty_username_fields) {
      SCOPED_TRACE(testing::Message()
                   << "Iteration " << i << " "
                   << (nonempty_username_fields ? "nonempty" : "empty"));

      // Repeat each test once with empty, and once with non-empty usernames.
      // In the former case, no empty other_possible_usernames should be saved.
      const char* names[3];
      if (nonempty_username_fields) {
        names[0] = "John";
        names[1] = "William";
        names[2] = "Smith";
      } else {
        names[0] = names[1] = names[2] = "";
      }

      PasswordFormBuilder builder(kTestFormActionURL);
      builder.AddTextField("usrname1", names[0], cases[i].autocomplete[0]);
      builder.AddTextField("usrname2", names[1], cases[i].autocomplete[1]);
      builder.AddPasswordField("password", "secret", nullptr);
      builder.AddTextField("usrname3", names[2], cases[i].autocomplete[2]);
      builder.AddPasswordField("password2", "othersecret", nullptr);
      builder.AddSubmitButton("submit");
      std::string html = builder.ProduceHTML();

      std::unique_ptr<PasswordForm> password_form =
          LoadHTMLAndConvertForm(html, nullptr, false);
      ASSERT_TRUE(password_form);

      EXPECT_FALSE(password_form->only_for_fallback_saving);
      EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element),
                password_form->username_element);

      if (nonempty_username_fields) {
        EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value),
                  password_form->username_value);
        EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_other_possible_usernames),
                  ValueElementVectorToString(
                      password_form->other_possible_usernames));
      } else {
        EXPECT_TRUE(password_form->username_value.empty());
        EXPECT_TRUE(password_form->other_possible_usernames.empty());
      }

      // Do a basic sanity check that we are still having a password field.
      EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
      EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
    }
  }
}

TEST_F(PasswordFormConversionUtilsTest, IdentifyingTwoPasswordFields) {
  // Each test case consists of a set of parameters to be plugged into the
  // PasswordFormBuilder below, plus the corresponding expectations.
  struct TestCase {
    const char* password_values[2];
    const char* expected_password_element;
    const char* expected_password_value;
    const char* expected_new_password_element;
    const char* expected_new_password_value;
    const char* expected_confirmation_element;
  } cases[] = {
      // Two non-empty fields with the same value should be treated as a new
      // password field plus a confirmation field for the new password.
      {{"alpha", "alpha"}, "", "", "password1", "alpha", "password2"},
      // The same goes if the fields are yet empty: we speculate that we will
      // identify them as new password fields once they are filled out, and we
      // want to keep our abstract interpretation of the form less flaky.
      {{"", ""}, "password1", "", "password2", "", ""},
      // Two different values should be treated as a password change form, one
      // that also asks for the current password, but only once for the new.
      {{"alpha", ""}, "password1", "alpha", "password2", "", ""},
      {{"", "beta"}, "password1", "", "password2", "beta", ""},
      {{"alpha", "beta"}, "password1", "alpha", "password2", "beta", ""}};

  for (size_t i = 0; i < base::size(cases); ++i) {
    SCOPED_TRACE(testing::Message() << "Iteration " << i);

    PasswordFormBuilder builder(kTestFormActionURL);
    builder.AddTextField("usrname1", "William", nullptr);
    builder.AddPasswordField("password1", cases[i].password_values[0], nullptr);
    builder.AddTextField("usrname2", "Smith", nullptr);
    builder.AddPasswordField("password2", cases[i].password_values[1], nullptr);
    builder.AddSubmitButton("submit");
    std::string html = builder.ProduceHTML();

    std::unique_ptr<PasswordForm> password_form =
        LoadHTMLAndConvertForm(html, nullptr, false);
    ASSERT_TRUE(password_form);

    EXPECT_FALSE(password_form->only_for_fallback_saving);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element),
              password_form->password_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value),
              password_form->password_value);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element),
              password_form->new_password_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value),
              password_form->new_password_value);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_confirmation_element),
              password_form->confirmation_password_element);

    // Do a basic sanity check that we are still selecting the right username.
    EXPECT_EQ(base::UTF8ToUTF16("usrname1"), password_form->username_element);
    EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value);
    EXPECT_THAT(
        password_form->other_possible_usernames,
        testing::ElementsAre(ValueElementPair(base::UTF8ToUTF16("Smith"),
                                              base::UTF8ToUTF16("usrname2"))));
  }
}

TEST_F(PasswordFormConversionUtilsTest, IdentifyingThreePasswordFields) {
  // Each test case consists of a set of parameters to be plugged into the
  // PasswordFormBuilder below, plus the corresponding expectations.
  struct TestCase {
    const char* password_values[3];
    const char* expected_password_element;
    const char* expected_password_value;
    const char* expected_new_password_element;
    const char* expected_new_password_value;
    const char* expected_confirmation_element;
  } cases[] = {
      // Two fields with the same value, and one different: we should treat this
      // as a password change form with confirmation for the new password. Note
      // that we only recognize (current + new + new) and (new + new + current)
      // without autocomplete attributes.
      {{"alpha", "", ""}, "password1", "alpha", "password2", "", "password3"},
      {{"", "beta", "beta"}, "password1", "", "password2", "beta", "password3"},
      {{"alpha", "beta", "beta"},
       "password1",
       "alpha",
       "password2",
       "beta",
       "password3"},
      // If confirmed password comes first, assume that the third password
      // field is related to security question, SSN, or credit card and ignore
      // it.
      {{"beta", "beta", "alpha"}, "", "", "password1", "beta", "password2"},
      // If the fields are yet empty, we speculate that we will identify them as
      // (current + new + new) once they are filled out, so we should classify
      // them the same for now to keep our abstract interpretation less flaky.
      {{"", "", ""}, "password1", "", "password2", "", "password3"}};

  for (size_t i = 0; i < base::size(cases); ++i) {
    SCOPED_TRACE(testing::Message() << "Iteration " << i);

    PasswordFormBuilder builder(kTestFormActionURL);
    builder.AddTextField("usrname1", "William", nullptr);
    builder.AddPasswordField("password1", cases[i].password_values[0], nullptr);
    builder.AddPasswordField("password2", cases[i].password_values[1], nullptr);
    builder.AddTextField("usrname2", "Smith", nullptr);
    builder.AddPasswordField("password3", cases[i].password_values[2], nullptr);
    builder.AddSubmitButton("submit");
    std::string html = builder.ProduceHTML();

    std::unique_ptr<PasswordForm> password_form =
        LoadHTMLAndConvertForm(html, nullptr, false);
    ASSERT_TRUE(password_form);

    EXPECT_FALSE(password_form->only_for_fallback_saving);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element),
              password_form->password_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value),
              password_form->password_value);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element),
              password_form->new_password_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value),
              password_form->new_password_value);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_confirmation_element),
              password_form->confirmation_password_element);

    // Do a basic sanity check that we are still selecting the right username.
    EXPECT_EQ(base::UTF8ToUTF16("usrname1"), password_form->username_element);
    EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value);
    EXPECT_THAT(
        password_form->other_possible_usernames,
        testing::ElementsAre(ValueElementPair(base::UTF8ToUTF16("Smith"),
                                              base::UTF8ToUTF16("usrname2"))));
  }
}

TEST_F(PasswordFormConversionUtilsTest,
       IdentifyingPasswordFieldsWithAutocompleteAttributes) {
  // Each test case consists of a set of parameters to be plugged into the
  // PasswordFormBuilder below, plus the corresponding expectations.
  // The test data should not contain field names that are identified by the
  // HTML based username detector, because with these tests only the base
  // heuristic (i.e. select as username the field before the password field)
  // is tested.
  struct TestCase {
    const char* autocomplete[3];
    const char* expected_password_element;
    const char* expected_password_value;
    const char* expected_new_password_element;
    const char* expected_new_password_value;
    bool expected_new_password_marked_by_site;
    const char* expected_username_element;
    const char* expected_username_value;
  } cases[] = {
      // When there are elements marked with autocomplete='current-password',
      // but no elements with 'new-password', we should treat the first of the
      // former kind as the current password, and ignore all other password
      // fields, assuming they are not intentionally not marked. They might be
      // for other purposes, such as PINs, OTPs, and the like. Actual values in
      // the password fields should be ignored in all cases below.
      // Username is the element just before the first 'current-password' (even
      // if 'new-password' comes earlier). If no 'current-password', then the
      // element just before the first 'new-passwords'.
      {{"current-password", nullptr, nullptr},
       "password1",
       "alpha",
       "",
       "",
       false,
       "usrname1",
       "William"},
      {{nullptr, "current-password", nullptr},
       "password2",
       "beta",
       "",
       "",
       false,
       "usrname2",
       "Smith"},
      {{nullptr, nullptr, "current-password"},
       "password3",
       "gamma",
       "",
       "",
       false,
       "usrname2",
       "Smith"},
      {{nullptr, "current-password", "current-password"},
       "password2",
       "beta",
       "",
       "",
       false,
       "usrname2",
       "Smith"},
      {{"current-password", nullptr, "current-password"},
       "password1",
       "alpha",
       "",
       "",
       false,
       "usrname1",
       "William"},
      {{"current-password", "current-password", nullptr},
       "password1",
       "alpha",
       "",
       "",
       false,
       "usrname1",
       "William"},
      {{"current-password", "current-password", "current-password"},
       "password1",
       "alpha",
       "",
       "",
       false,
       "usrname1",
       "William"},
      // The same goes vice versa for autocomplete='new-password'.
      {{"new-password", nullptr, nullptr},
       "",
       "",
       "password1",
       "alpha",
       true,
       "usrname1",
       "William"},
      {{nullptr, "new-password", nullptr},
       "",
       "",
       "password2",
       "beta",
       true,
       "usrname2",
       "Smith"},
      {{nullptr, nullptr, "new-password"},
       "",
       "",
       "password3",
       "gamma",
       true,
       "usrname2",
       "Smith"},
      {{nullptr, "new-password", "new-password"},
       "",
       "",
       "password2",
       "beta",
       true,
       "usrname2",
       "Smith"},
      {{"new-password", nullptr, "new-password"},
       "",
       "",
       "password1",
       "alpha",
       true,
       "usrname1",
       "William"},
      {{"new-password", "new-password", nullptr},
       "",
       "",
       "password1",
       "alpha",
       true,
       "usrname1",
       "William"},
      {{"new-password", "new-password", "new-password"},
       "",
       "",
       "password1",
       "alpha",
       true,
       "usrname1",
       "William"},
      // When there is one element marked with autocomplete='current-password',
      // and one with 'new-password', just comply. Ignore the unmarked password
      // field(s) for the same reason as above.
      {{"current-password", "new-password", nullptr},
       "password1",
       "alpha",
       "password2",
       "beta",
       true,
       "usrname1",
       "William"},
      {{"current-password", nullptr, "new-password"},
       "password1",
       "alpha",
       "password3",
       "gamma",
       true,
       "usrname1",
       "William"},
      {{nullptr, "current-password", "new-password"},
       "password2",
       "beta",
       "password3",
       "gamma",
       true,
       "usrname2",
       "Smith"},
      {{"new-password", "current-password", nullptr},
       "password2",
       "beta",
       "password1",
       "alpha",
       true,
       "usrname2",
       "Smith"},
      {{"new-password", nullptr, "current-password"},
       "password3",
       "gamma",
       "password1",
       "alpha",
       true,
       "usrname2",
       "Smith"},
      {{nullptr, "new-password", "current-password"},
       "password3",
       "gamma",
       "password2",
       "beta",
       true,
       "usrname2",
       "Smith"},
      // In case of duplicated elements of either kind, go with the first one of
      // its kind.
      {{"current-password", "current-password", "new-password"},
       "password1",
       "alpha",
       "password3",
       "gamma",
       true,
       "usrname1",
       "William"},
      {{"current-password", "new-password", "current-password"},
       "password1",
       "alpha",
       "password2",
       "beta",
       true,
       "usrname1",
       "William"},
      {{"new-password", "current-password", "current-password"},
       "password2",
       "beta",
       "password1",
       "alpha",
       true,
       "usrname2",
       "Smith"},
      {{"current-password", "new-password", "new-password"},
       "password1",
       "alpha",
       "password2",
       "beta",
       true,
       "usrname1",
       "William"},
      {{"new-password", "current-password", "new-password"},
       "password2",
       "beta",
       "password1",
       "alpha",
       true,
       "usrname2",
       "Smith"},
      {{"new-password", "new-password", "current-password"},
       "password3",
       "gamma",
       "password1",
       "alpha",
       true,
       "usrname2",
       "Smith"},
      // When there is an empty autocomplete attribute (i.e. autocomplete=""),
      // it should have the same effect as having no attribute whatsoever.
      {{"current-password", "", ""},
       "password1",
       "alpha",
       "",
       "",
       false,
       "usrname1",
       "William"},
      {{"", "", "new-password"},
       "",
       "",
       "password3",
       "gamma",
       true,
       "usrname2",
       "Smith"},
      {{"", "new-password", ""},
       "",
       "",
       "password2",
       "beta",
       true,
       "usrname2",
       "Smith"},
      {{"", "current-password", "current-password"},
       "password2",
       "beta",
       "",
       "",
       false,
       "usrname2",
       "Smith"},
      {{"new-password", "", "new-password"},
       "",
       "",
       "password1",
       "alpha",
       true,
       "usrname1",
       "William"},
      {{"new-password", "", "current-password"},
       "password3",
       "gamma",
       "password1",
       "alpha",
       true,
       "usrname2",
       "Smith"},
      // It should not matter if attribute values are upper or mixed case.
      {{nullptr, "current-password", nullptr},
       "password2",
       "beta",
       "",
       "",
       false,
       "usrname2",
       "Smith"},
      {{nullptr, "CURRENT-PASSWORD", nullptr},
       "password2",
       "beta",
       "",
       "",
       false,
       "usrname2",
       "Smith"},
      {{nullptr, "new-password", nullptr},
       "",
       "",
       "password2",
       "beta",
       true,
       "usrname2",
       "Smith"},
      {{nullptr, "nEw-PaSsWoRd", nullptr},
       "",
       "",
       "password2",
       "beta",
       true,
       "usrname2",
       "Smith"}};

  for (size_t i = 0; i < base::size(cases); ++i) {
    SCOPED_TRACE(testing::Message() << "Iteration " << i);

    PasswordFormBuilder builder(kTestFormActionURL);
    builder.AddPasswordField("pin1", "123456", nullptr);
    builder.AddPasswordField("pin2", "789101", nullptr);
    builder.AddTextField("usrname1", "William", nullptr);
    builder.AddPasswordField("password1", "alpha", cases[i].autocomplete[0]);
    builder.AddTextField("usrname2", "Smith", nullptr);
    builder.AddPasswordField("password2", "beta", cases[i].autocomplete[1]);
    builder.AddPasswordField("password3", "gamma", cases[i].autocomplete[2]);
    builder.AddSubmitButton("submit");
    std::string html = builder.ProduceHTML();

    std::unique_ptr<PasswordForm> password_form =
        LoadHTMLAndConvertForm(html, nullptr, false);
    ASSERT_TRUE(password_form);

    EXPECT_FALSE(password_form->only_for_fallback_saving);
    // In the absence of username autocomplete attributes, the username should
    // be the text input field just before 'current-password' or before
    // 'new-password', if there is no 'current-password'.
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element),
              password_form->username_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value),
              password_form->username_value);
    if (strcmp(cases[i].expected_username_value, "William") == 0) {
      EXPECT_THAT(
          password_form->other_possible_usernames,
          testing::ElementsAre(ValueElementPair(
              base::UTF8ToUTF16("Smith"), base::UTF8ToUTF16("usrname2"))));
    } else {
      EXPECT_THAT(
          password_form->other_possible_usernames,
          testing::ElementsAre(ValueElementPair(
              base::UTF8ToUTF16("William"), base::UTF8ToUTF16("usrname1"))));
    }
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element),
              password_form->password_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value),
              password_form->password_value);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element),
              password_form->new_password_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value),
              password_form->new_password_value);
    EXPECT_EQ(cases[i].expected_new_password_marked_by_site,
              password_form->new_password_marked_by_site);
  }
}

TEST_F(PasswordFormConversionUtilsTest,
       UsernameDetection_AutocompleteAttribute) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username", "JohnSmith", "username");
  builder.AddTextField("Full name", "John A. Smith", nullptr);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  base::HistogramTester histogram_tester;
  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("JohnSmith"), password_form->username_value);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.UsernameDetectionMethod",
      UsernameDetectionMethod::AUTOCOMPLETE_ATTRIBUTE, 1);
}

TEST_F(PasswordFormConversionUtilsTest, IgnoreInvisibledTextFields) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddNonDisplayedTextField("nondisplayed1", "nodispalyed_value1");
  builder.AddNonVisibleTextField("nonvisible1", "nonvisible_value1");
  builder.AddTextField("username", "johnsmith", nullptr);
  builder.AddNonDisplayedTextField("nondisplayed2", "nodispalyed_value2");
  builder.AddNonVisiblePasswordField("nonvisible2", "nonvisible_value2");
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->new_password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->new_password_value);
}

TEST_F(PasswordFormConversionUtilsTest, IgnoreInvisiblLoginPairs) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddNonDisplayedTextField("nondisplayed1", "nodispalyed_value1");
  builder.AddNonDisplayedPasswordField("nondisplayed2", "nodispalyed_value2");
  builder.AddNonVisibleTextField("nonvisible1", "nonvisible_value1");
  builder.AddNonVisiblePasswordField("nonvisible2", "nonvisible_value2");
  builder.AddTextField("username", "johnsmith", nullptr);
  builder.AddNonVisibleTextField("nonvisible3", "nonvisible_value3");
  builder.AddNonVisiblePasswordField("nonvisible4", "nonvisible_value4");
  builder.AddNonDisplayedTextField("nondisplayed3", "nodispalyed_value3");
  builder.AddNonDisplayedPasswordField("nondisplayed4", "nodispalyed_value4");
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->new_password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->new_password_value);
}

TEST_F(PasswordFormConversionUtilsTest, OnlyNonDisplayedLoginPair) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddNonDisplayedTextField("username", "William");
  builder.AddNonDisplayedPasswordField("password", "secret");
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"),
            password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("William"),
            password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"),
            password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"),
            password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest, OnlyNonVisibleLoginPair) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddNonVisibleTextField("username", "William");
  builder.AddNonVisiblePasswordField("password", "secret");
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest, VisiblePasswordAndInvisibleUsername) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddNonDisplayedTextField("username", "William");
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest,
       InvisiblePassword_LatestUsernameIsVisible) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddNonDisplayedTextField("search", "query");
  builder.AddTextField("username", "William", nullptr);
  builder.AddNonDisplayedPasswordField("password", "secret");
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest,
       InvisiblePassword_LatestUsernameIsInvisible) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddTextField("search", "query", nullptr);
  builder.AddNonDisplayedTextField("username", "William");
  builder.AddNonDisplayedPasswordField("password", "secret");
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
}

// Checks that username/password fields are detected based on user input even if
// visibility heuristics disagree.
TEST_F(PasswordFormConversionUtilsTest, UserInput) {
  PasswordFormBuilder builder(kTestFormActionURL);

  builder.AddNonVisibleTextField("nonvisible_text", "actual_username");
  builder.AddTextField("visible_text", "fake_username", nullptr);

  builder.AddNonVisiblePasswordField("nonvisible_password", "actual_password");
  builder.AddPasswordField("visible_password", "fake_password", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);

  FieldDataManager field_data_manager;
  WebVector<WebFormControlElement> control_elements;
  form.GetFormControlElements(control_elements);
  ASSERT_EQ("nonvisible_text", control_elements[0].NameForAutofill().Utf8());
  field_data_manager.UpdateFieldDataMap(control_elements[0],
                                        control_elements[0].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);
  ASSERT_EQ("nonvisible_password",
            control_elements[2].NameForAutofill().Utf8());
  field_data_manager.UpdateFieldDataMap(control_elements[2],
                                        control_elements[2].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);

  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
      form, &field_data_manager, nullptr, nullptr);

  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("nonvisible_text"),
            password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("actual_username"),
            password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("nonvisible_password"),
            password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("actual_password"),
            password_form->password_value);
  EXPECT_EQ(base::UTF8ToUTF16(""), password_form->new_password_element);
  EXPECT_EQ(base::UTF8ToUTF16(""), password_form->new_password_value);
}

TEST_F(PasswordFormConversionUtilsTest, TypedPasswordAndUsernameCachedOnPage) {
  PasswordFormBuilder builder(kTestFormActionURL);
  // The heuristics should consider only password field with user input (i.e.
  // password_with_user_input?) and visible username fields (i.e. nickname,
  // visible_text, captcha) since there is no username field with user input.
  builder.AddNonDisplayedPasswordField("nondisplayed1", "fake_password");
  builder.AddNonDisplayedTextField("nondisplayed1", "fake_username1");
  builder.AddTextField("nickname", "bob", nullptr);
  builder.AddTextField("visible_text", "cached_username",
                       nullptr);  // Username.
  builder.AddNonVisibleTextField("nonvisible_text", "fake_username2");
  builder.AddNonVisiblePasswordField("nonvisible_password", "not_password");
  builder.AddNonVisibleTextField("nonvisible_text", "fake_username2");
  builder.AddPasswordField("password_wo_user_input", "", nullptr);
  builder.AddNonVisibleTextField("nonvisible_text", "");
  builder.AddPasswordField("password_with_user_input1", "actual_password",
                           nullptr);  // Password to save.
  builder.AddPasswordField("password_with_user_input2", "actual_password",
                           nullptr);
  builder.AddTextField("captcha", "12345", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);

  FieldDataManager field_data_manager;
  WebVector<WebFormControlElement> control_elements;
  form.GetFormControlElements(control_elements);
  ASSERT_EQ("password_with_user_input1",
            control_elements[9].NameForAutofill().Utf8());
  field_data_manager.UpdateFieldDataMap(control_elements[9],
                                        control_elements[9].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);
  ASSERT_EQ("password_with_user_input2",
            control_elements[10].NameForAutofill().Utf8());
  field_data_manager.UpdateFieldDataMap(control_elements[10],
                                        control_elements[10].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);

  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
      form, &field_data_manager, nullptr, nullptr);

  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);

  EXPECT_EQ(base::UTF8ToUTF16("visible_text"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("cached_username"),
            password_form->username_value);

  EXPECT_EQ(base::string16(), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_value);

  EXPECT_EQ(base::UTF8ToUTF16("password_with_user_input1"),
            password_form->new_password_element);
  EXPECT_EQ(base::UTF8ToUTF16("actual_password"),
            password_form->new_password_value);
}

TEST_F(PasswordFormConversionUtilsTest, TypedPasswordAndInvisibleUsername) {
  PasswordFormBuilder builder(kTestFormActionURL);
  // The heuristics should consider only password field with user input (i.e.
  // password_with_user_input?) and invisible username fields since all username
  // fields have no user input and are invisible.
  builder.AddNonDisplayedPasswordField("nondisplayed1", "fake_password");
  builder.AddNonDisplayedTextField("nondisplayed1", "fake_username1");
  builder.AddNonVisibleTextField("nickname", "bob");
  builder.AddNonVisibleTextField("this_is_username", "invisible_username");
  builder.AddNonVisiblePasswordField("nonvisible_password", "not_password");
  builder.AddPasswordField("password_wo_user_input", "", nullptr);
  builder.AddNonVisiblePasswordField("nonvisible_password2", "");
  builder.AddPasswordField("password_with_user_input1", "actual_password",
                           nullptr);  // Password to save.
  builder.AddNonVisibleTextField("nonvisible_text3", "---H09-$%");
  builder.AddPasswordField("password_with_user_input2", "actual_password",
                           nullptr);
  builder.AddNonVisibleTextField("nonvisible_text3", "debug_info");
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);

  FieldDataManager field_data_manager;
  WebVector<WebFormControlElement> control_elements;
  form.GetFormControlElements(control_elements);
  ASSERT_EQ("password_with_user_input1",
            control_elements[7].NameForAutofill().Utf8());
  field_data_manager.UpdateFieldDataMap(control_elements[7],
                                        control_elements[7].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);
  ASSERT_EQ("password_with_user_input2",
            control_elements[9].NameForAutofill().Utf8());
  field_data_manager.UpdateFieldDataMap(control_elements[9],
                                        control_elements[9].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);

  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
      form, &field_data_manager, nullptr, nullptr);

  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);

  EXPECT_EQ(base::UTF8ToUTF16("this_is_username"),
            password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("invisible_username"),
            password_form->username_value);

  EXPECT_EQ(base::string16(), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_value);

  EXPECT_EQ(base::UTF8ToUTF16("password_with_user_input1"),
            password_form->new_password_element);
  EXPECT_EQ(base::UTF8ToUTF16("actual_password"),
            password_form->new_password_value);
}

TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToBadActionURL) {
  PasswordFormBuilder builder("invalid_target");
  builder.AddTextField("username", "JohnSmith", nullptr);
  builder.AddSubmitButton("submit");
  builder.AddPasswordField("password", "secret", nullptr);
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  EXPECT_FALSE(password_form);
}

TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToNoPasswordFields) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username1", "John", nullptr);
  builder.AddTextField("username2", "Smith", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  EXPECT_FALSE(password_form);
}

TEST_F(PasswordFormConversionUtilsTest, ConfusingPasswordFields) {
  // Each test case consists of a set of parameters to be plugged into the
  // PasswordFormBuilder below.
  const char* cases[][3] = {
      // No autocomplete attributes to guide us, and we see:
      //  * three password values that are all different,
      //  * three password values that are all the same;
      //  * three password values with the first and last matching.
      // In any case, we should just give up on this form.
      {"alpha", "beta", "gamma"},
      {"alpha", "alpha", "alpha"},
      {"alpha", "beta", "alpha"}};

  for (size_t i = 0; i < base::size(cases); ++i) {
    SCOPED_TRACE(testing::Message() << "Iteration " << i);

    PasswordFormBuilder builder(kTestFormActionURL);
    builder.AddTextField("username1", "John", nullptr);
    builder.AddPasswordField("password1", cases[i][0], nullptr);
    builder.AddPasswordField("password2", cases[i][1], nullptr);
    builder.AddPasswordField("password3", cases[i][2], nullptr);
    builder.AddSubmitButton("submit");
    std::string html = builder.ProduceHTML();

    std::unique_ptr<PasswordForm> password_form =
        LoadHTMLAndConvertForm(html, nullptr, false);
    ASSERT_TRUE(password_form);
    EXPECT_FALSE(password_form->only_for_fallback_saving);
    EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element);
    EXPECT_EQ(base::UTF8ToUTF16("John"), password_form->username_value);
    EXPECT_EQ(base::UTF8ToUTF16("password1"), password_form->password_element);
    EXPECT_EQ(base::UTF8ToUTF16(cases[i][0]), password_form->password_value);
  }
}

TEST_F(PasswordFormConversionUtilsTest,
       ManyPasswordFieldsWithoutAutocompleteAttributes) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username1", "John", nullptr);
  builder.AddPasswordField("password1", "alpha", nullptr);
  builder.AddPasswordField("password2", "alpha", nullptr);
  builder.AddPasswordField("password3", "alpha", nullptr);
  builder.AddPasswordField("password4", "alpha", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("John"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password1"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("alpha"), password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest, SetOtherPossiblePasswords) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username1", "John", nullptr);
  builder.AddPasswordField("password1", "alpha1", nullptr);
  builder.AddPasswordField("password2", "alpha2", nullptr);
  builder.AddPasswordField("password3", "alpha3", nullptr);
  builder.AddPasswordField("password4", "alpha4", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->form_has_autofilled_value);

  // Make sure we have all possible passwords along with the username info.
  EXPECT_EQ(base::ASCIIToUTF16("username1"), password_form->username_element);
  EXPECT_EQ(base::ASCIIToUTF16("John"), password_form->username_value);
  EXPECT_EQ(base::ASCIIToUTF16("alpha1"), password_form->password_value);
  EXPECT_THAT(
      password_form->all_possible_passwords,
      testing::ElementsAre(ValueElementPair(base::ASCIIToUTF16("alpha1"),
                                            base::ASCIIToUTF16("password1")),
                           ValueElementPair(base::ASCIIToUTF16("alpha2"),
                                            base::ASCIIToUTF16("password2")),
                           ValueElementPair(base::ASCIIToUTF16("alpha3"),
                                            base::ASCIIToUTF16("password3")),
                           ValueElementPair(base::ASCIIToUTF16("alpha4"),
                                            base::ASCIIToUTF16("password4"))));
  EXPECT_EQ(base::ASCIIToUTF16("alpha1+password1, alpha2+password2, "
                               "alpha3+password3, alpha4+password4"),
            ValueElementVectorToString(password_form->all_possible_passwords));
}

TEST_F(PasswordFormConversionUtilsTest,
       AllPossiblePasswordsIncludeAutofilledValue) {
  for (bool autofilled_value_was_modified_by_user : {false, true}) {
    PasswordFormBuilder builder(kTestFormActionURL);
    builder.AddTextField("username1", "John", nullptr);
    builder.AddPasswordField("old-password", "autofilled_value", nullptr);
    builder.AddPasswordField("new-password", "user_value", nullptr);
    builder.AddSubmitButton("submit");
    std::string html = builder.ProduceHTML();

    WebFormElement form;
    LoadWebFormFromHTML(html, &form, nullptr);
    WebVector<WebFormControlElement> control_elements;
    form.GetFormControlElements(control_elements);

    FieldDataManager field_data_manager;
    FieldPropertiesMask mask = FieldPropertiesFlags::AUTOFILLED;
    if (autofilled_value_was_modified_by_user)
      mask |= FieldPropertiesFlags::USER_TYPED;
    field_data_manager.UpdateFieldDataMap(
        control_elements[1], base::ASCIIToUTF16("autofilled_value"), mask);
    field_data_manager.UpdateFieldDataMap(control_elements[2],
                                          base::ASCIIToUTF16("user_value"),
                                          FieldPropertiesFlags::USER_TYPED);

    std::unique_ptr<PasswordForm> password_form(CreatePasswordFormFromWebForm(
        form, &field_data_manager, nullptr, nullptr));
    ASSERT_TRUE(password_form);
    EXPECT_TRUE(password_form->form_has_autofilled_value);
  }
}

TEST_F(PasswordFormConversionUtilsTest, CreditCardNumberWithTypePasswordForm) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr);
  builder.AddPasswordField("Credit-card-number", "0000 0000 0000 0000",
                           nullptr);
  builder.AddTextField("cvc", "000", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::map<int, PasswordFormFieldPredictionType> predictions_positions;
  predictions_positions[1] = PREDICTION_NOT_PASSWORD;

  FormsPredictionsMap predictions;
  SetPredictions(html, &predictions, predictions_positions);

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, &predictions, false);
  EXPECT_TRUE(password_form);
  EXPECT_TRUE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("Credit-card-owner-name"),
            password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("John Smith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"),
            password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"),
            password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest, UsernamePredictionFromServer) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username", "JohnSmith", nullptr);
  // 'autocomplete' attribute cannot override server's prediction.
  builder.AddTextField("Full name", "John A. Smith", "username");
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::map<int, PasswordFormFieldPredictionType> predictions_positions;
  predictions_positions[0] = PREDICTION_USERNAME;
  FormsPredictionsMap predictions;
  SetPredictions(html, &predictions, predictions_positions);

  base::HistogramTester histogram_tester;
  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, &predictions, false);
  ASSERT_TRUE(password_form);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("JohnSmith"), password_form->username_value);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.UsernameDetectionMethod",
      UsernameDetectionMethod::SERVER_SIDE_PREDICTION, 1);
}

TEST_F(PasswordFormConversionUtilsTest,
       UsernamePredictionFromServerToEmptyField) {
  // Tests that if a form has user input and the username prediction by the
  // server points to an empty field, then the prediction is ignored.
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("empty-field", "", "");  // The prediction points here.
  builder.AddTextField("full-name", "John A. Smith", nullptr);
  builder.AddTextField("username", "JohnSmith", nullptr);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::map<int, PasswordFormFieldPredictionType> predictions_positions;
  predictions_positions[0] = PREDICTION_USERNAME;
  FormsPredictionsMap predictions;
  SetPredictions(html, &predictions, predictions_positions);

  // The password field has user input.
  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);
  WebVector<WebFormControlElement> control_elements;
  form.GetFormControlElements(control_elements);
  FieldDataManager field_data_manager;
  field_data_manager.UpdateFieldDataMap(control_elements[3],
                                        control_elements[3].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);

  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
      form, &field_data_manager, &predictions, &username_detector_cache_);
  ASSERT_TRUE(password_form);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("JohnSmith"), password_form->username_value);
}

TEST_F(PasswordFormConversionUtilsTest,
       CreditCardVerificationNumberWithTypePasswordForm) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr);
  builder.AddTextField("Credit-card-number", "0000 0000 0000 0000", nullptr);
  builder.AddPasswordField("cvc", "000", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::map<int, PasswordFormFieldPredictionType> predictions_positions;
  predictions_positions[2] = PREDICTION_NOT_PASSWORD;

  FormsPredictionsMap predictions;
  SetPredictions(html, &predictions, predictions_positions);

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, &predictions, false);
  EXPECT_TRUE(password_form);
  EXPECT_TRUE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"),
            password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"),
            password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("cvc"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("000"), password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest,
       CreditCardNumberWithTypePasswordFormWithAutocomplete) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr);
  builder.AddPasswordField("Credit-card-number", "0000 0000 0000 0000",
                           "current-password");
  builder.AddTextField("cvc", "000", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::map<int, PasswordFormFieldPredictionType> predictions_positions;
  predictions_positions[1] = PREDICTION_NOT_PASSWORD;

  FormsPredictionsMap predictions;
  SetPredictions(html, &predictions, predictions_positions);

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, &predictions, false);
  EXPECT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("Credit-card-owner-name"),
            password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("John Smith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"),
            password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"),
            password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest,
       CreditCardVerificationNumberWithTypePasswordFormWithAutocomplete) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr);
  builder.AddTextField("Credit-card-number", "0000 0000 0000 0000", nullptr);
  builder.AddPasswordField("cvc", "000", "new-password");
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::map<int, PasswordFormFieldPredictionType> predictions_positions;
  predictions_positions[2] = PREDICTION_NOT_PASSWORD;

  FormsPredictionsMap predictions;
  SetPredictions(html, &predictions, predictions_positions);

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, &predictions, false);
  ASSERT_TRUE(password_form);
  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"),
            password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"),
            password_form->username_value);
  EXPECT_TRUE(password_form->password_element.empty());
  EXPECT_TRUE(password_form->password_value.empty());
  EXPECT_EQ(base::UTF8ToUTF16("cvc"), password_form->new_password_element);
  EXPECT_EQ(base::UTF8ToUTF16("000"), password_form->new_password_value);
}

TEST_F(PasswordFormConversionUtilsTest, IsGaiaReauthFormIgnored) {
  struct TestCase {
    const char* origin;
    struct KeyValue {
      KeyValue() : name(nullptr), value(nullptr) {}
      KeyValue(const char* new_name, const char* new_value)
          : name(new_name), value(new_value) {}
      const char* name;
      const char* value;
    } hidden_fields[2];
    bool expected_form_is_reauth;
  } cases[] = {
      // A common password form is parsed successfully.
      {"https://example.com",
       {TestCase::KeyValue(), TestCase::KeyValue()},
       false},
      // A common password form, even if it appears on a GAIA reauth url,
      // is parsed successfully.
      {"https://accounts.google.com",
       {TestCase::KeyValue(), TestCase::KeyValue()},
       false},
      // Not a transactional reauth.
      {"https://accounts.google.com",
       {TestCase::KeyValue("continue", "https://passwords.google.com/settings"),
        TestCase::KeyValue()},
       false},
      // A reauth form that is not for a password site is parsed successfuly.
      {"https://accounts.google.com",
       {TestCase::KeyValue("continue", "https://mail.google.com"),
        TestCase::KeyValue("rart", "")},
       false},
      // A reauth form for a password site is recognised as such.
      {"https://accounts.google.com",
       {TestCase::KeyValue("continue", "https://passwords.google.com"),
        TestCase::KeyValue("rart", "")},
       true},
      // Path, params or fragment in "continue" should not have influence.
      {"https://accounts.google.com",
       {TestCase::KeyValue("continue",
                           "https://passwords.google.com/path?param=val#frag"),
        TestCase::KeyValue("rart", "")},
       true},
      // Password site is inaccesible via HTTP, but because of HSTS the
      // following link should still continue to https://passwords.google.com.
      {"https://accounts.google.com",
       {TestCase::KeyValue("continue", "http://passwords.google.com"),
        TestCase::KeyValue("rart", "")},
       true},
      // Make sure testing sites are disabled as well.
      {"https://accounts.google.com",
       {TestCase::KeyValue(
            "continue",
            "https://passwords-ac-testing.corp.google.com/settings"),
        TestCase::KeyValue("rart", "")},
       true},
      // Specifying default port doesn't change anything.
      {"https://accounts.google.com",
       {TestCase::KeyValue("continue", "passwords.google.com:443"),
        TestCase::KeyValue("rart", "")},
       true},
      // Fully qualified domain should work as well.
      {"https://accounts.google.com",
       {TestCase::KeyValue("continue",
                           "https://passwords.google.com./settings"),
        TestCase::KeyValue("rart", "")},
       true},
      // A correctly looking form, but on a different page.
      {"https://google.com",
       {TestCase::KeyValue("continue", "https://passwords.google.com"),
        TestCase::KeyValue("rart", "")},
       false},
  };

  for (TestCase& test_case : cases) {
    SCOPED_TRACE(testing::Message("origin=")
                 << test_case.origin
                 << ", hidden_fields[0]=" << test_case.hidden_fields[0].name
                 << "/" << test_case.hidden_fields[0].value
                 << ", hidden_fields[1]=" << test_case.hidden_fields[1].name
                 << "/" << test_case.hidden_fields[1].value
                 << ", expected_form_is_reauth="
                 << test_case.expected_form_is_reauth);
    std::unique_ptr<PasswordFormBuilder> builder(new PasswordFormBuilder(""));
    builder->AddTextField("username", "", nullptr);
    builder->AddPasswordField("password", "", nullptr);
    for (TestCase::KeyValue& hidden_field : test_case.hidden_fields) {
      if (hidden_field.name)
        builder->AddHiddenField(hidden_field.name, hidden_field.value);
    }
    std::string html = builder->ProduceHTML();
    WebFormElement form;
    LoadWebFormFromHTML(html, &form, test_case.origin);
    EXPECT_EQ(test_case.expected_form_is_reauth,
              IsGaiaReauthenticationForm(form));
  }
}

TEST_F(PasswordFormConversionUtilsTest, IsGaiaWithSkipSavePasswordForm) {
  struct TestCase {
    const char* origin;
    bool expected_form_has_skip_save_password;
  } cases[] = {
      // A common password form is parsed successfully.
      {"https://example.com", false},
      // A common GAIA sign-in page, with no skip save password argument.
      {"https://accounts.google.com", false},
      // A common GAIA sign-in page, with "0" skip save password argument.
      {"https://accounts.google.com/?ssp=0", false},
      // A common GAIA sign-in page, with skip save password argument.
      {"https://accounts.google.com/?ssp=1", true},
      // The Gaia page that is used to start a Chrome sign-in flow when Desktop
      // Identity Consistency is enable.
      {GaiaUrls::GetInstance()->signin_chrome_sync_dice().spec().c_str(), true},
  };

  for (TestCase& test_case : cases) {
    SCOPED_TRACE(testing::Message("origin=")
                 << test_case.origin
                 << ", expected_form_has_skip_save_password="
                 << test_case.expected_form_has_skip_save_password);
    std::unique_ptr<PasswordFormBuilder> builder(new PasswordFormBuilder(""));
    builder->AddTextField("username", "", nullptr);
    builder->AddPasswordField("password", "", nullptr);
    std::string html = builder->ProduceHTML();
    WebFormElement form;
    LoadWebFormFromHTML(html, &form, test_case.origin);
    EXPECT_EQ(test_case.expected_form_has_skip_save_password,
              IsGaiaWithSkipSavePasswordForm(form));
  }
}

TEST_F(PasswordFormConversionUtilsTest,
       IdentifyingFieldsWithoutNameOrIdAttributes) {
  const char* kEmpty = nullptr;
  const struct {
    const char* username_fieldname;
    const char* password_fieldname;
    const char* new_password_fieldname;
    const char* expected_username_element;
    const char* expected_password_element;
    const char* expected_new_password_element;
  } test_cases[] = {
      {"username", "password", "new_password", "username", "password",
       "new_password"},
      {"username", "password", kEmpty, "username", "password",
       "anonymous_new_password"},
      {"username", kEmpty, kEmpty, "username", "anonymous_password",
       "anonymous_new_password"},
      {kEmpty, kEmpty, kEmpty, "anonymous_username", "anonymous_password",
       "anonymous_new_password"},
  };

  for (size_t i = 0; i < base::size(test_cases); ++i) {
    SCOPED_TRACE(testing::Message()
                 << "Iteration " << i << ", expected_username "
                 << test_cases[i].expected_username_element
                 << ", expected_password"
                 << test_cases[i].expected_password_element
                 << ", expected_new_password "
                 << test_cases[i].expected_new_password_element);

    PasswordFormBuilder builder(kTestFormActionURL);
    if (test_cases[i].username_fieldname == kEmpty) {
      builder.AddAnonymousInputField("text");
    } else {
      builder.AddTextField(test_cases[i].username_fieldname, "", kEmpty);
    }

    if (test_cases[i].password_fieldname == kEmpty) {
      builder.AddAnonymousInputField("password");
    } else {
      builder.AddPasswordField(test_cases[i].password_fieldname, "", kEmpty);
    }

    if (test_cases[i].new_password_fieldname == kEmpty) {
      builder.AddAnonymousInputField("password");
    } else {
      builder.AddPasswordField(test_cases[i].new_password_fieldname, "",
                               kEmpty);
    }
    std::string html = builder.ProduceHTML();

    std::unique_ptr<PasswordForm> password_form =
        LoadHTMLAndConvertForm(html, nullptr, false);
    EXPECT_TRUE(password_form);

    EXPECT_FALSE(password_form->only_for_fallback_saving);
    EXPECT_EQ(base::UTF8ToUTF16(test_cases[i].expected_username_element),
              password_form->username_element);
    EXPECT_EQ(base::UTF8ToUTF16(test_cases[i].expected_password_element),
              password_form->password_element);
    EXPECT_EQ(base::UTF8ToUTF16(test_cases[i].expected_new_password_element),
              password_form->new_password_element);
  }
}

TEST_F(PasswordFormConversionUtilsTest, TooManyFieldsToParseForm) {
  PasswordFormBuilder builder(kTestFormActionURL);
  for (size_t i = 0; i < form_util::kMaxParseableFields + 1; ++i)
    builder.AddTextField("id", "value", "autocomplete");
  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(builder.ProduceHTML(), nullptr, false);
  EXPECT_FALSE(password_form);
}

TEST_F(PasswordFormConversionUtilsTest, OnlyCreditCardFields) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("ccname", "johnsmith", "cc-name");
  builder.AddPasswordField("cc_security_code", "0123456789", "cc-csc");
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  EXPECT_TRUE(password_form);
  EXPECT_TRUE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("ccname"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("cc_security_code"),
            password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("0123456789"), password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest,
       FieldsWithAndWithoutCreditCardAttributes) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username", "johnsmith", nullptr);
  builder.AddTextField("ccname", "john_smith", "cc-name");
  builder.AddPasswordField("cc_security_code", "0123456789", "random cc-csc");
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);

  ASSERT_TRUE(password_form);

  EXPECT_FALSE(password_form->only_for_fallback_saving);
  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
}

TEST_F(PasswordFormConversionUtilsTest, ResetPasswordForm) {
  // GetPassword (including HTML classifier) should process correctly forms
  // without any text fields.
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      password_manager::features::kHtmlBasedUsernameDetector);
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();
  base::HistogramTester histogram_tester;

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);

  ASSERT_TRUE(password_form);

  EXPECT_TRUE(password_form->username_element.empty());
  EXPECT_TRUE(password_form->username_value.empty());
  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.UsernameDetectionMethod",
      UsernameDetectionMethod::NO_USERNAME_DETECTED, 1);
}

TEST_F(PasswordFormConversionUtilsTest, StickyPasswordType) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("username", "johnsmith", nullptr);
  builder.AddPasswordField("password", "secret", nullptr);
  builder.AddSubmitButton("submit");
  std::string html = builder.ProduceHTML();

  std::unique_ptr<PasswordForm> password_form =
      LoadHTMLAndConvertForm(html, nullptr, false);
  ASSERT_TRUE(password_form);

  FormData old_form_data;
  ASSERT_TRUE(ExtractFormDataForFirstForm(&old_form_data));

  // Change password field to type="text".
  ExecuteJavaScriptForTests(
      "document.getElementById(\"password\").type = \"text\";");

  // Validate that - despite the change - the old password field is still
  // recognized as a password field.
  WebFormElement new_form;
  GetFirstForm(&new_form);
  std::unique_ptr<PasswordForm> new_password_form =
      CreatePasswordFormFromWebForm(new_form, nullptr, nullptr,
                                    &username_detector_cache_);
  ASSERT_TRUE(new_password_form);

  EXPECT_EQ(*password_form, *new_password_form);

  FormData new_form_data;
  ASSERT_TRUE(ExtractFormDataForFirstForm(&new_form_data));

  EXPECT_EQ(old_form_data, new_form_data);
}

// Check that Chrome remembers the value typed by the user in cases when it gets
// overridden by the page.
TEST_F(PasswordFormConversionUtilsTest, TypedValuePreserved) {
  PasswordFormBuilder builder(kTestFormActionURL);
  builder.AddTextField("fine", "", "username");
  builder.AddPasswordField("mangled", "", "current-password");
  builder.AddTextField("completed_for_user", "", nullptr);
  std::string html = builder.ProduceHTML();

  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);

  FieldDataManager field_data_manager;
  WebVector<WebFormControlElement> control_elements;
  form.GetFormControlElements(control_elements);

  ASSERT_EQ(3u, control_elements.size());
  ASSERT_EQ("fine", control_elements[0].NameForAutofill().Utf8());
  control_elements[0].SetAutofillValue("same_value");
  field_data_manager.UpdateFieldDataMap(control_elements[0],
                                        control_elements[0].Value().Utf16(),
                                        FieldPropertiesFlags::USER_TYPED);

  ASSERT_EQ("mangled", control_elements[1].NameForAutofill().Utf8());
  control_elements[1].SetAutofillValue("mangled_value");
  field_data_manager.UpdateFieldDataMap(control_elements[1],
                                        base::UTF8ToUTF16("original_value"),
                                        FieldPropertiesFlags::USER_TYPED);

  ASSERT_EQ("completed_for_user", control_elements[2].NameForAutofill().Utf8());
  control_elements[2].SetAutofillValue("email@gmail.com");
  field_data_manager.UpdateFieldDataMap(control_elements[2],
                                        base::UTF8ToUTF16("email"),
                                        FieldPropertiesFlags::USER_TYPED);

  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
      form, &field_data_manager, nullptr, nullptr);

  ASSERT_TRUE(password_form);

  EXPECT_EQ(base::UTF8ToUTF16("same_value"), password_form->username_value);
  EXPECT_EQ(base::UTF8ToUTF16("original_value"), password_form->password_value);

  ASSERT_EQ(3u, password_form->form_data.fields.size());

  EXPECT_EQ(base::UTF8ToUTF16("same_value"),
            password_form->form_data.fields[0].value);
  EXPECT_EQ(base::string16(), password_form->form_data.fields[0].typed_value);

  EXPECT_EQ(base::UTF8ToUTF16("mangled_value"),
            password_form->form_data.fields[1].value);
  EXPECT_EQ(base::UTF8ToUTF16("original_value"),
            password_form->form_data.fields[1].typed_value);

  EXPECT_EQ(base::UTF8ToUTF16("email@gmail.com"),
            password_form->form_data.fields[2].value);
  EXPECT_EQ(base::string16(), password_form->form_data.fields[2].typed_value);
}

// Check that non-text fields are ignored.
TEST_F(PasswordFormConversionUtilsTest, NonTextFields) {
  PasswordFormBuilder builder(kTestFormActionURL);
  // Avoid calling the text fields anything related to "username" to prevent the
  // local HTML classifier from influencing the test result.
  builder.AddTextField("textField", "", "");
  builder.AddFieldWithType("radioInput", "radio");
  builder.AddPasswordField("password", "", "");
  std::string html = builder.ProduceHTML();

  WebFormElement form;
  LoadWebFormFromHTML(html, &form, nullptr);

  std::unique_ptr<PasswordForm> password_form =
      CreatePasswordFormFromWebForm(form, nullptr, nullptr, nullptr);

  ASSERT_TRUE(password_form);
  EXPECT_EQ(base::UTF8ToUTF16("textField"), password_form->username_element);
}

}  // namespace autofill
