chromium/components/autofill/core/browser/form_structure_rationalizer_unittest.cc

// Copyright 2022 The Chromium Authors
// 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/form_structure_rationalizer.h"

#include <string_view>
#include <tuple>
#include <utility>

#include "base/base64.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_structure_test_api.h"
#include "components/autofill/core/browser/heuristic_source.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/form_data_test_api.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

AllOf;
ElementsAre;
ElementsAreArray;
Matcher;
Pointee;
Property;

namespace autofill {
namespace {

std::string SerializeAndEncode(const AutofillQueryResponse& response) {}

// The key information from which we build FormFieldData objects and an
// AutofillQueryResponse for tests.
struct FieldTemplate {};

// These are helper functions that set a special flag in a field_template.
// They only exist because the output of clang-format for function calls is
// more compact than if we switched to designated initializer lists.
FieldTemplate ToNotFocusable(FieldTemplate field_template) {}

FieldTemplate ToSelectOne(FieldTemplate field_template) {}

FieldTemplate SetRolePresentation(FieldTemplate field_template) {}

std::pair<FormData, std::string> CreateFormAndServerClassification(
    std::vector<FieldTemplate> fields) {}

std::unique_ptr<FormStructure> BuildFormStructure(
    const std::vector<FieldTemplate>& fields,
    bool run_heuristics) {}

std::vector<FieldType> GetTypes(const FormStructure& form_structure) {}

Matcher<AutofillField> HasType(FieldType type) {}

Matcher<AutofillField> HasOffset(size_t offset) {}

Matcher<AutofillField> HasTypeAndOffset(FieldType type, size_t offset) {}

Matcher<FormStructure> AreFieldsArray(
    const std::vector<Matcher<AutofillField>>& matchers) {}

template <typename... Matchers>
Matcher<FormStructure> AreFields(Matchers... matchers) {}

class FormStructureRationalizerTest : public testing::Test {};

FormStructureRationalizerTest::FormStructureRationalizerTest() {}

TEST_F(FormStructureRationalizerTest, ParseQueryResponse_RationalizeLoneField) {}

TEST_F(FormStructureRationalizerTest, ParseQueryResponse_RationalizeCCName) {}
TEST_F(FormStructureRationalizerTest,
       ParseQueryResponse_RationalizeMultiMonth_1) {}

TEST_F(FormStructureRationalizerTest,
       ParseQueryResponse_RationalizeMultiMonth_2) {}

TEST_F(FormStructureRationalizerTest,
       RationalizePhoneNumber_RunsOncePerSection) {}

TEST_F(FormStructureRationalizerTest, RationalizeStreetAddressAndAddressLine) {}

// Tests that phone number trunk types are rationalized correctly.
TEST_F(FormStructureRationalizerTest, RationalizePhoneNumberTrunkTypes) {}

// Tests that a form that has only one address predicted as
// ADDRESS_HOME_STREET_ADDRESS is not modified by the address rationalization.
TEST_F(FormStructureRationalizerTest, RationalizeRepeatedFields_OneAddress) {}

// Tests that a form that has two address predicted as
// ADDRESS_HOME_STREET_ADDRESS is modified by the address rationalization to be
// ADDRESS_HOME_LINE1 and ADDRESS_HOME_LINE2 instead.
TEST_F(FormStructureRationalizerTest, RationalizeRepreatedFields_TwoAddresses) {}

// Tests that a form that has three address lines predicted as
// ADDRESS_HOME_STREET_ADDRESS is modified by the address rationalization to be
// ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2 and ADDRESS_HOME_LINE3 instead.
TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_ThreeAddresses) {}

// Tests that a form that has four address lines predicted as
// ADDRESS_HOME_STREET_ADDRESS is not modified by the address rationalization.
// This doesn't happen in real world, because four address lines mean multiple
// sections according to the heuristics.
TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_FourAddresses) {}

// Tests that a form that has only one address in each section predicted as
// ADDRESS_HOME_STREET_ADDRESS is not modified by the address rationalization.
TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_OneAddressEachSection) {}

// Tests a form that has multiple sections with multiple number of address
// fields predicted as ADDRESS_HOME_STREET_ADDRESS. The last section
// doesn't happen in real world, because it is in fact two sections according to
// heuristics, and is only made for testing.
TEST_F(
    FormStructureRationalizerTest,
    RationalizeRepreatedFields_SectionTwoAddress_SectionThreeAddress_SectionFourAddresses) {}

// Tests that a form that has only one address in each section predicted as
// ADDRESS_HOME_STREET_ADDRESS is not modified by the address rationalization,
// while the sections are previously determined by the heuristics.
TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_MultipleSectionsByHeuristics_OneAddressEach) {}

// Tests a form that has multiple sections with multiple number of address
// fields predicted as ADDRESS_HOME_STREET_ADDRESS, while the sections are
// identified by heuristics.
TEST_F(
    FormStructureRationalizerTest,
    RationalizeRepreatedFields_MultipleSectionsByHeuristics_TwoAddress_ThreeAddress) {}

TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_StateCountry_NoRationalization) {}

TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_CountryStateNoHeuristics) {}

TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_StateCountryWithHeuristics) {}

TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_FirstFieldRationalized) {}

TEST_F(FormStructureRationalizerTest,
       RationalizeRepreatedFields_LastFieldRationalized) {}

TEST_F(FormStructureRationalizerTest, RationalizeStandaloneCVCField) {}

TEST_F(FormStructureRationalizerTest,
       RationalizeAndKeepCVCField_OtherCreditCardFields) {}

TEST_F(FormStructureRationalizerTest,
       RationalizeAndKeepCVCField_EmailAddressField) {}

// Tests that contenteditables types are overridden with UNKNOWN_TYPE.
TEST_F(FormStructureRationalizerTest, RationalizeContentEditables) {}

// Tests the rationalization that ignores certain types on the main origin. The
// underlying assumption is that the field in the main frame misclassified
// because such fields usually do not occur on the main frame's origin due to
// PCI-DSS.
class FormStructureRationalizerTestMultiOriginCreditCardFields
    : public FormStructureRationalizerTest,
      public ::testing::WithParamInterface<FieldType> {};

INSTANTIATE_TEST_SUITE_P();

// Tests that if a sensitive type appears in both the main and a cross-origin
// iframe, the field in the main frame is rationalized to UNKNOWN_TYPE.
TEST_P(FormStructureRationalizerTestMultiOriginCreditCardFields,
       RationalizeIfSensitiveFieldsOnMainAndCrossOrigin) {}

// Tests that if there is no sensitive type in a cross-origin iframe, the
// multi-origin rationalization does *not* apply, i.e., all fields keep their
// types.
TEST_P(FormStructureRationalizerTestMultiOriginCreditCardFields,
       DoNotRationalizeIfSensitiveFieldsOnlyOnMainOrigin) {}

// Tests that if there is no sensitive field in the main frame, the multi-origin
// rationalization does *not* apply, i.e., all fields keep their types.
TEST_P(FormStructureRationalizerTestMultiOriginCreditCardFields,
       DoNotRationalizeIfSensitiveFieldsOnlyOnCrossOrigins) {}

// Tests that the offset of a cc-number field is not affected by non-adjacent
// <input maxlength=1>.
TEST_F(
    FormStructureRationalizerTest,
    RationalizeCreditCardNumberOffsets_DoNotSplitForNonAdjacentMaxlength1Field) {}

// Tests that the offset of a cc-number field is not affected by a single
// adjacent <input maxlength=1>.
TEST_F(
    FormStructureRationalizerTest,
    RationalizeCreditCardNumberOffsets_DoNotSplitForAdjacentMaxlength1Field) {}

// Tests the offsets of four adjacent <input maxlength=4> cc-number fields
// grow by 4.
TEST_F(FormStructureRationalizerTest,
       RationalizeCreditCardNumberOffsets_SplitGroupOfFours) {}

// Tests fields of different focusability are not in the same group.
TEST_F(FormStructureRationalizerTest,
       RationalizeCreditCardNumberOffsets_FocusabilityStartNewGroups) {}

// Tests fields from different host forms are not in the same group.
TEST_F(FormStructureRationalizerTest,
       RationalizeCreditCardNumberOffsets_RendererFormsStartNewGroups) {}

// Tests the offsets of three adjacent <input maxlength=4> cc-number fields
// followed by an overflow field grow by 4.
TEST_F(FormStructureRationalizerTest,
       RationalizeCreditCardNumberOffsets_SplitGroupOfFoursFollodeByOverflow) {}

// Tests the offsets of seven adjacent <input maxlength=1> cc-number fields
// followed by an overflow <input maxlength=N> grow by 1.
// A subsequent ninth cc-number field with different maxlength is in a separate
// group.
TEST_F(FormStructureRationalizerTest,
       RationalizeCreditCardNumberOffsets_SplitGroupOfOnes) {}

// Tests that in <input maxlength=4> <input maxlength=8> <input maxlength=4> the
// last <input> starts a new group. Regression test for crbug.com/1465573.
TEST_F(FormStructureRationalizerTest, RationalizeCreditCardNumberOffsets_) {}

// Tests that if there are multiple address between fields and atleast one of
// them is wrongly classified as `ADDRESS_HOME_BETWEEN_STREETS` would be
// rationalized into (`ADDRESS_HOME_BETWEEN_STREETS_1,
// `ADDRESS_HOME_BETWEEN_STREETS_2`).
TEST_F(FormStructureRationalizerTest, RationalizeAddressBetweenStreets) {}

struct RationalizeAutocompleteTestParam {};
class RationalizeAutocompleteTest
    : public testing::Test,
      public testing::WithParamInterface<RationalizeAutocompleteTestParam> {};
INSTANTIATE_TEST_SUITE_P();

TEST_P(RationalizeAutocompleteTest, RationalizeAutocompleteAttribute) {}

struct RationalizationTypeRelationshipsTestParams {};
class RationalizationFieldTypeFilterTest
    : public testing::Test,
      public testing::WithParamInterface<FieldType> {};
class RationalizationFieldTypeRelationshipsTest
    : public testing::Test,
      public testing::WithParamInterface<
          RationalizationTypeRelationshipsTestParams> {};

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// Tests that the rationalization logic will filter out fields of type |param|
// when there is no other required type.
TEST_P(RationalizationFieldTypeFilterTest, Rationalization_Rules_Filter_Out) {}

// Tests that the rationalization logic will not filter out fields of type
// |param| when there is another field with a required type.
TEST_P(RationalizationFieldTypeRelationshipsTest,
       Rationalization_Rules_Relationships) {}

}  // namespace
}  // namespace autofill