Commit cc2fd272 authored by Vidhan's avatar Vidhan Committed by Commit Bot

[Autofill] Refactoring form_structure_unittest.cc

This CL improves the readability of form_structure_unittest.cc by
reducing the redundant code and introducing form field factory.

Bug: 1127001
Change-Id: I172d738847af114d16a11f68356cc5fb01e68f8c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2332704
Commit-Queue: Vidhan Jain <vidhanj@google.com>
Reviewed-by: default avatarChristoph Schwering <schwering@google.com>
Reviewed-by: default avatarMatthias Körber <koerber@google.com>
Cr-Commit-Position: refs/heads/master@{#806149}
parent 46daf5f3
......@@ -428,6 +428,8 @@ static_library("browser") {
static_library("test_support") {
testonly = true
sources = [
"autofill_form_test_utils.cc",
"autofill_form_test_utils.h",
"autofill_test_utils.cc",
"autofill_test_utils.h",
"data_driven_test.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/autofill_form_test_utils.h"
#include "base/optional.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/form_structure.h"
using base::ASCIIToUTF16;
namespace autofill {
namespace test {
testing::Message DescribeFormData(const FormData& form_data) {
testing::Message result;
result << "Form contains " << form_data.fields.size() << " fields:\n";
for (const FormFieldData& field : form_data.fields) {
result << "type=" << field.form_control_type << ", name=" << field.name
<< ", label=" << field.label << "\n";
}
return result;
}
FormFieldData CreateFieldByRole(ServerFieldType role) {
FormFieldData field;
switch (role) {
case ServerFieldType::USERNAME:
field.label = ASCIIToUTF16("Username");
field.name = ASCIIToUTF16("username");
break;
case ServerFieldType::NAME_FULL:
field.label = ASCIIToUTF16("Full name");
field.name = ASCIIToUTF16("fullname");
break;
case ServerFieldType::NAME_FIRST:
field.label = ASCIIToUTF16("First Name");
field.name = ASCIIToUTF16("firstName");
break;
case ServerFieldType::NAME_LAST:
field.label = ASCIIToUTF16("Last Name");
field.name = ASCIIToUTF16("lastName");
break;
case ServerFieldType::EMAIL_ADDRESS:
field.label = ASCIIToUTF16("E-mail address");
field.name = ASCIIToUTF16("email");
break;
case ServerFieldType::ADDRESS_HOME_CITY:
field.label = ASCIIToUTF16("City");
field.name = ASCIIToUTF16("city");
break;
case ServerFieldType::ADDRESS_HOME_STATE:
field.label = ASCIIToUTF16("State");
field.name = ASCIIToUTF16("state");
break;
case ServerFieldType::ADDRESS_HOME_COUNTRY:
field.label = ASCIIToUTF16("Country");
field.name = ASCIIToUTF16("country");
break;
case ServerFieldType::ADDRESS_HOME_ZIP:
field.label = ASCIIToUTF16("Zip Code");
field.name = ASCIIToUTF16("zipCode");
break;
case ServerFieldType::PHONE_HOME_NUMBER:
field.label = ASCIIToUTF16("Phone");
field.name = ASCIIToUTF16("phone");
break;
case ServerFieldType::COMPANY_NAME:
field.label = ASCIIToUTF16("Company");
field.name = ASCIIToUTF16("company");
break;
case ServerFieldType::CREDIT_CARD_NUMBER:
field.label = ASCIIToUTF16("Card Number");
field.name = ASCIIToUTF16("cardNumber");
break;
case ServerFieldType::EMPTY_TYPE:
default:
break;
}
return field;
}
FormData GetFormData(const FormAttributes& form_attributes) {
FormData form_data;
form_data.url = GURL(form_attributes.form_url);
for (const FieldDataDescription& field_description : form_attributes.fields) {
FormFieldData field = CreateFieldByRole(field_description.role);
field.form_control_type = field_description.form_control_type;
field.is_focusable = field_description.is_focusable;
if (field_description.autocomplete_attribute)
field.autocomplete_attribute = field_description.autocomplete_attribute;
if (ASCIIToUTF16(field_description.label) != ASCIIToUTF16(kLabelText))
field.label = ASCIIToUTF16(field_description.label);
if (ASCIIToUTF16(field_description.name) != ASCIIToUTF16(kNameText))
field.name = ASCIIToUTF16(field_description.name);
field.should_autocomplete = field_description.should_autocomplete;
form_data.fields.push_back(field);
}
form_data.is_formless_checkout = form_attributes.is_formless_checkout;
form_data.is_form_tag = form_attributes.is_form_tag;
return form_data;
}
// static
void FormStructureTest::CheckFormStructureTestData(
const std::vector<FormStructureTestCase>& test_cases) {
for (const FormStructureTestCase& test_case : test_cases) {
const FormData form = GetFormData(test_case.form_attributes);
SCOPED_TRACE(testing::Message("Test description: ")
<< test_case.form_attributes.description_for_logging);
auto form_structure = std::make_unique<FormStructure>(form);
if (test_case.form_flags.determine_heuristic_type)
form_structure->DetermineHeuristicTypes();
if (test_case.form_flags.is_autofillable)
EXPECT_TRUE(form_structure->IsAutofillable());
if (test_case.form_flags.should_be_parsed)
EXPECT_TRUE(form_structure->ShouldBeParsed());
if (test_case.form_flags.should_be_queried)
EXPECT_TRUE(form_structure->ShouldBeQueried());
if (test_case.form_flags.should_be_uploaded)
EXPECT_TRUE(form_structure->ShouldBeUploaded());
if (test_case.form_flags.has_author_specified_types)
EXPECT_TRUE(form_structure->has_author_specified_types());
if (test_case.form_flags.has_author_specified_upi_vpa_hint)
EXPECT_TRUE(form_structure->has_author_specified_upi_vpa_hint());
if (test_case.form_flags.is_complete_credit_card_form.first) {
if (test_case.form_flags.is_complete_credit_card_form.second)
EXPECT_TRUE(form_structure->IsCompleteCreditCardForm());
else
EXPECT_FALSE(form_structure->IsCompleteCreditCardForm());
}
if (test_case.form_flags.field_count)
ASSERT_EQ(*test_case.form_flags.field_count,
static_cast<int>(form_structure->field_count()));
if (test_case.form_flags.autofill_count)
ASSERT_EQ(*test_case.form_flags.autofill_count,
static_cast<int>(form_structure->autofill_count()));
if (test_case.form_flags.section_count) {
std::set<std::string> section_names;
for (size_t i = 0; i < 9; ++i) {
section_names.insert(form_structure->field(i)->section);
}
EXPECT_EQ(*test_case.form_flags.section_count,
static_cast<int>(section_names.size()));
}
if (!test_case.expected_field_types.expected_html_type.empty()) {
for (size_t i = 0;
i < test_case.expected_field_types.expected_html_type.size(); i++)
EXPECT_EQ(test_case.expected_field_types.expected_html_type[i],
form_structure->field(i)->html_type());
}
if (!test_case.expected_field_types.expected_phone_part.empty()) {
for (size_t i = 0;
i < test_case.expected_field_types.expected_phone_part.size(); i++)
EXPECT_EQ(test_case.expected_field_types.expected_phone_part[i],
form_structure->field(i)->phone_part());
}
if (!test_case.expected_field_types.expected_heuristic_type.empty()) {
for (size_t i = 0;
i < test_case.expected_field_types.expected_heuristic_type.size();
i++)
EXPECT_EQ(test_case.expected_field_types.expected_heuristic_type[i],
form_structure->field(i)->heuristic_type());
}
if (!test_case.expected_field_types.expected_overall_type.empty()) {
for (size_t i = 0;
i < test_case.expected_field_types.expected_overall_type.size(); i++)
EXPECT_EQ(test_case.expected_field_types.expected_overall_type[i],
form_structure->field(i)->Type().GetStorableType());
}
}
}
} // namespace test
} // namespace autofill
// Copyright 2020 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.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_FORM_TEST_UTILS_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_FORM_TEST_UTILS_H_
#include <vector>
#include "base/optional.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace test {
namespace {
// Default label assigned to fields.
constexpr char kLabelText[] = "label";
// Default name attribute assigned to fields.
constexpr char kNameText[] = "name";
// Default form url.
constexpr char kFormUrl[] = "http://www.foo.com/";
} // namespace
namespace internal {
// Expected FormFieldData are constructed based on these descriptions.
template <typename = void>
struct FieldDataDescription {
ServerFieldType role = ServerFieldType::EMPTY_TYPE;
bool is_focusable = true;
const char* label = kLabelText;
const char* name = kNameText;
const char* autocomplete_attribute = nullptr;
const char* form_control_type = "text";
bool should_autocomplete = true;
};
// Attributes provided to the test form.
template <typename = void>
struct FormAttributes {
const char* description_for_logging = "";
std::vector<FieldDataDescription<>> fields = {};
const char* form_url = kFormUrl;
bool is_formless_checkout = false;
bool is_form_tag = true;
};
// Flags determining whether the corresponding check should be run on the test
// form.
template <typename = void>
struct FormFlags {
// false means the function is not to be called.
bool determine_heuristic_type = false;
bool parse_query_response = false;
// false means the corresponding check is not supposed to run.
bool is_autofillable = false;
bool should_be_parsed = false;
bool should_be_queried = false;
bool should_be_uploaded = false;
bool has_author_specified_types = false;
bool has_author_specified_upi_vpa_hint = false;
// first value denotes whether the comparison is to be done while second
// denotes EXPECT_TRUE for true and EXPECT_FALSE for false.
std::pair<bool, bool> is_complete_credit_card_form = {false, false};
// base::nullopt means no checking.
base::Optional<int> field_count = base::nullopt;
base::Optional<int> autofill_count = base::nullopt;
base::Optional<int> section_count = base::nullopt;
base::Optional<int> response_field_count = base::nullopt;
};
// Expected field type values to be verified with the test form.
template <typename = void>
struct ExpectedFieldTypeValues {
std::vector<HtmlFieldType> expected_html_type = {};
std::vector<AutofillField::PhonePart> expected_phone_part = {};
std::vector<ServerFieldType> expected_heuristic_type = {};
std::vector<ServerFieldType> expected_overall_type = {};
};
// Describes a test case for the parser.
template <typename = void>
struct FormStructureTestCase {
FormAttributes<> form_attributes;
FormFlags<> form_flags;
ExpectedFieldTypeValues<> expected_field_types;
};
} // namespace internal
using FieldDataDescription = internal::FieldDataDescription<>;
using FormAttributes = internal::FormAttributes<>;
using FormStructureTestCase = internal::FormStructureTestCase<>;
// Describes the |form_data|. Use this in SCOPED_TRACE if other logging
// messages might refer to the form.
testing::Message DescribeFormData(const FormData& form_data);
// Returns the form field relevant to the |role|.
FormFieldData CreateFieldByRole(ServerFieldType role);
// Creates a FormData to be fed to the parser.
FormData GetFormData(const FormAttributes& form_attributes);
class FormStructureTest : public testing::Test {
protected:
// Iterates over |test_cases|, creates a FormData for each, runs the parser
// and checks the results.
static void CheckFormStructureTestData(
const std::vector<FormStructureTestCase>& test_cases);
};
} // namespace test
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_FORM_TEST_UTILS_H_
......@@ -403,12 +403,12 @@ class FormStructure {
private:
friend class AutofillMergeTest;
friend class FormStructureTest;
friend class FormStructureTestImpl;
FRIEND_TEST_ALL_PREFIXES(AutofillDownloadTest, QueryAndUploadTest);
FRIEND_TEST_ALL_PREFIXES(FormStructureTest, FindLongestCommonPrefix);
FRIEND_TEST_ALL_PREFIXES(FormStructureTest, FindLongestCommonAffixLength);
FRIEND_TEST_ALL_PREFIXES(FormStructureTest, IsValidParseableName);
FRIEND_TEST_ALL_PREFIXES(FormStructureTest,
FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, FindLongestCommonPrefix);
FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, FindLongestCommonAffixLength);
FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, IsValidParseableName);
FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl,
RationalizePhoneNumber_RunsOncePerSection);
class SectionedFieldsIndexes {
......@@ -559,7 +559,7 @@ class FormStructure {
// Tries to set |parseable_name| fields by stripping the given offsets from
// both sides of the |name| fields.
// Sets |parseable_name| to |name| if the sum of offsets is bigger than
// Sets |parseable_name| to |name| if the sum of offsets is bigger than
// |name|.
// Sets all |parseable_name| to |name| without modification and returns
// false if a name fails the |IsValidParseableName()| check after stripping.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment