blob: a05c0a95f776d614e2e35ee162e539a8c6680b79 [file]
// Copyright 2025 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/data_model/autofill_ai/entity_type.h"
#include "base/test/scoped_feature_list.h"
#include "components/autofill/core/browser/country_type.h"
#include "components/autofill/core/browser/data_model/autofill_ai/entity_type_names.h"
#include "components/autofill/core/browser/data_model/autofill_ai/entity_type_test_api.h"
#include "components/autofill/core/common/autofill_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
namespace autofill {
namespace {
using ::testing::AnyOf;
using ::testing::Contains;
using ::testing::Each;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::IsEmpty;
using ::testing::IsSubsetOf;
using ::testing::Optional;
using ::testing::ResultOf;
using ::testing::UnorderedElementsAre;
using ::testing::ValuesIn;
class AutofillAttributeTypeTest_FieldTypeRelations
: public testing::TestWithParam<AttributeType> {};
INSTANTIATE_TEST_SUITE_P(,
AutofillAttributeTypeTest_FieldTypeRelations,
ValuesIn(DenseSet<AttributeType>::all()));
// Tests the co-domain of AttributeType::field_type().
TEST_P(AutofillAttributeTypeTest_FieldTypeRelations, FieldType) {
AttributeType at = GetParam();
EXPECT_THAT(
at.field_type(),
AnyOf(Optional(
ResultOf(&GroupTypeOfFieldType, FieldTypeGroup::kAutofillAi)),
Optional(NAME_FULL), Optional(ADDRESS_HOME_ZIP), std::nullopt));
}
// Tests the co-domain of AttributeType::field_subtypes().
TEST_P(AutofillAttributeTypeTest_FieldTypeRelations, FieldSubtypes) {
AttributeType at = GetParam();
EXPECT_THAT(
at.field_subtypes(),
AnyOf(Each(ResultOf(&GroupTypeOfFieldType, FieldTypeGroup::kAutofillAi)),
Each(ResultOf(&GroupTypeOfFieldType, FieldTypeGroup::kName)),
Each(ADDRESS_HOME_ZIP)));
if (at.field_type()) {
EXPECT_THAT(at.field_subtypes(), Contains(at.field_type()));
} else {
EXPECT_THAT(at.field_subtypes(), IsEmpty());
}
}
// Tests the co-domain of AttributeType::storable_field_types().
TEST_P(AutofillAttributeTypeTest_FieldTypeRelations, StorableFieldTypes) {
AttributeType at = GetParam();
if (at.field_type()) {
EXPECT_THAT(test_api(at).storable_field_types(),
IsSubsetOf(at.field_subtypes()));
} else {
EXPECT_THAT(test_api(at).storable_field_types(), ElementsAre(UNKNOWN_TYPE));
}
EXPECT_THAT(test_api(at).storable_field_types(),
Contains(at.field_type().value_or(UNKNOWN_TYPE)));
}
TEST(AutofillAttributeTypeTest, Relationships_PassportName) {
AttributeType a = AttributeType(AttributeTypeName::kPassportName);
EXPECT_EQ(a.entity_type(), EntityType(EntityTypeName::kPassport));
EXPECT_THAT(
a.field_subtypes(),
UnorderedElementsAre(NAME_HONORIFIC_PREFIX, NAME_FIRST, NAME_MIDDLE,
NAME_LAST, NAME_LAST_FIRST, NAME_LAST_SECOND,
NAME_LAST_CONJUNCTION, NAME_MIDDLE_INITIAL,
NAME_FULL, NAME_SUFFIX, ALTERNATIVE_FAMILY_NAME,
ALTERNATIVE_GIVEN_NAME, ALTERNATIVE_FULL_NAME));
}
TEST(AutofillAttributeTypeTest, IsObfuscated) {
AttributeType name = AttributeType(AttributeTypeName::kPassportName);
AttributeType number = AttributeType(AttributeTypeName::kPassportNumber);
EXPECT_FALSE(name.is_obfuscated());
EXPECT_TRUE(number.is_obfuscated());
}
TEST(AutofillEntityTypeTest, Attributes) {
using enum AttributeTypeName;
EntityType e = EntityType(EntityTypeName::kPassport);
EXPECT_THAT(e.attributes(),
UnorderedElementsAre(AttributeType(kPassportName),
AttributeType(kPassportNumber),
AttributeType(kPassportCountry),
AttributeType(kPassportExpirationDate),
AttributeType(kPassportIssueDate)));
ASSERT_FALSE(e.attributes().empty());
}
TEST(AutofillEntityTypeTest, ImportConstraints) {
using enum AttributeTypeName;
EntityType e = EntityType(EntityTypeName::kPassport);
EXPECT_THAT(e.import_constraints(), UnorderedElementsAre(UnorderedElementsAre(
AttributeType(kPassportNumber))));
}
TEST(AutofillEntityTypeTest, MergeConstraints) {
using enum AttributeTypeName;
EntityType e = EntityType(EntityTypeName::kPassport);
EXPECT_THAT(
e.merge_constraints(),
ElementsAre(UnorderedElementsAre(AttributeType(kPassportNumber))));
}
TEST(AutofillEntityTypeTest, StrikeKeys) {
EntityType e = EntityType(EntityTypeName::kPassport);
EXPECT_THAT(e.strike_keys(), ElementsAre(UnorderedElementsAre(AttributeType(
AttributeTypeName::kPassportNumber))));
}
TEST(AutofillEntityTypeTest, NameAsString) {
EntityType e = EntityType(EntityTypeName::kPassport);
AttributeType a = *e.attributes().begin();
EXPECT_EQ(e.name_as_string(), "Passport");
EXPECT_EQ(a.name_as_string(), "Name");
}
TEST(AutofillEntityTypeTest, DisambiguationOrder) {
using enum AttributeTypeName;
auto lt = [](AttributeTypeName lhs, AttributeTypeName rhs) {
return AttributeType::DisambiguationOrder(AttributeType(lhs),
AttributeType(rhs));
};
EXPECT_TRUE(lt(kPassportName, kPassportCountry));
EXPECT_TRUE(lt(kPassportCountry, kPassportExpirationDate));
EXPECT_TRUE(lt(kPassportCountry, kPassportIssueDate));
EXPECT_TRUE(lt(kPassportCountry, kPassportNumber));
EXPECT_FALSE(lt(kPassportNumber, kPassportIssueDate));
}
TEST(AutofillEntityTypeTest, Disabled) {
using enum EntityTypeName;
EXPECT_TRUE(EntityType(kPassport).enabled());
EXPECT_TRUE(EntityType(kDriversLicense).enabled());
EXPECT_TRUE(EntityType(kVehicle).enabled());
}
// Tests that specifying an "excluded geo-ip" disables the entity in countries
// with that geo ip.
TEST(AutofillEntityTypeTest, EnabledWithCountryCode) {
EntityType e = EntityType(EntityTypeName::kNationalIdCard);
EXPECT_TRUE(e.enabled(GeoIpCountryCode("US")));
EXPECT_TRUE(e.enabled(GeoIpCountryCode("DE")));
EXPECT_FALSE(e.enabled(GeoIpCountryCode("IN")));
}
TEST(AutofillEntityTypeTest, EntityGetNameForI18n) {
using enum EntityTypeName;
EntityType a = EntityType(kPassport);
EntityType b = EntityType(kDriversLicense);
EntityType c = EntityType(kOrder);
EntityType d = EntityType(kShipment);
EXPECT_EQ(a.GetNameForI18n(), u"Passport");
EXPECT_EQ(b.GetNameForI18n(), u"Driver's license");
EXPECT_EQ(c.GetNameForI18n(), u"Order");
EXPECT_EQ(d.GetNameForI18n(), u"Shipment");
}
TEST(AutofillEntityTypeTest, AttributeGetNameForI18n) {
using enum AttributeTypeName;
AttributeType a = AttributeType(kPassportCountry);
AttributeType b = AttributeType(kVehiclePlateNumber);
AttributeType c = AttributeType(kDriversLicenseExpirationDate);
AttributeType d = AttributeType(kOrderDate);
AttributeType e = AttributeType(kOrderAccount);
AttributeType f = AttributeType(kOrderId);
AttributeType g = AttributeType(kOrderMerchantDomain);
AttributeType h = AttributeType(kOrderMerchantName);
AttributeType i = AttributeType(kOrderProductNames);
AttributeType j = AttributeType(kShipmentTrackingNumber);
AttributeType k = AttributeType(kShipmentCarrierName);
AttributeType l = AttributeType(kShipmentCarrierDomain);
AttributeType m = AttributeType(kShipmentDeliveryZipCode);
AttributeType n = AttributeType(kShipmentEstimatedDeliveryDate);
AttributeType o = AttributeType(kShipmentOrderIds);
AttributeType p = AttributeType(kShipmentOrderDates);
AttributeType q = AttributeType(kShipmentMerchantName);
AttributeType r = AttributeType(kShipmentProductNames);
EXPECT_EQ(a.GetNameForI18n(), u"Country");
EXPECT_EQ(b.GetNameForI18n(), u"License plate");
EXPECT_EQ(c.GetNameForI18n(), u"Expiration date");
EXPECT_EQ(d.GetNameForI18n(), u"Date");
EXPECT_EQ(e.GetNameForI18n(), u"Account");
EXPECT_EQ(f.GetNameForI18n(), u"Id");
EXPECT_EQ(g.GetNameForI18n(), u"Merchant domain");
EXPECT_EQ(h.GetNameForI18n(), u"Merchant name");
EXPECT_EQ(i.GetNameForI18n(), u"Product names");
EXPECT_EQ(j.GetNameForI18n(), u"Tracking number");
EXPECT_EQ(k.GetNameForI18n(), u"Carrier name");
EXPECT_EQ(l.GetNameForI18n(), u"Carrier domain");
EXPECT_EQ(m.GetNameForI18n(), u"Delivery zip code");
EXPECT_EQ(n.GetNameForI18n(), u"Estimated delivery date");
EXPECT_EQ(o.GetNameForI18n(), u"Order ids");
EXPECT_EQ(p.GetNameForI18n(), u"Order dates");
EXPECT_EQ(q.GetNameForI18n(), u"Merchant name");
EXPECT_EQ(r.GetNameForI18n(), u"Product names");
}
TEST(AutofillEntityTypeTest, DataType) {
using enum AttributeTypeName;
AttributeType a = AttributeType(kPassportName);
AttributeType b = AttributeType(kPassportCountry);
AttributeType c = AttributeType(kDriversLicenseIssueDate);
AttributeType d = AttributeType(kDriversLicenseState);
AttributeType e = AttributeType(kVehicleMake);
EXPECT_EQ(a.data_type(), AttributeType::DataType::kName);
EXPECT_EQ(b.data_type(), AttributeType::DataType::kCountry);
EXPECT_EQ(c.data_type(), AttributeType::DataType::kDate);
EXPECT_EQ(d.data_type(), AttributeType::DataType::kState);
EXPECT_EQ(e.data_type(), AttributeType::DataType::kString);
}
TEST(AutofillEntityTypeTest, ReadOnly) {
using enum EntityTypeName;
EXPECT_FALSE(EntityType(kPassport).read_only());
EXPECT_TRUE(EntityType(kFlightReservation).read_only());
}
// Tests that `EntityType` and `AttributeType` can be used in
// `absl::flat_hash_map`.
TEST(AutofillEntityTypeTest, CanBeUsedInAbslFlatHashMap) {
absl::flat_hash_map<EntityType, int> entity_type_map;
auto passport = EntityType(EntityTypeName::kPassport);
entity_type_map[passport] = 1;
EXPECT_EQ(entity_type_map[passport], 1);
absl::flat_hash_map<AttributeType, int> attribute_type_map;
auto passport_name = AttributeType(AttributeTypeName::kPassportName);
attribute_type_map[passport_name] = 2;
EXPECT_EQ(attribute_type_map[passport_name], 2);
}
} // namespace
} // namespace autofill