| Index: components/autofill/core/browser/autofill_metrics_unittest.cc
|
| diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
|
| index efea6e76cab0aafd11a2a5053fff1cb525bda757..233b3ec5464f6f77740706e1bc2d9bf504f9781d 100644
|
| --- a/components/autofill/core/browser/autofill_metrics_unittest.cc
|
| +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
|
| @@ -6,8 +6,8 @@
|
|
|
| #include <stddef.h>
|
|
|
| -#include <map>
|
| #include <memory>
|
| +#include <utility>
|
| #include <vector>
|
|
|
| #include "base/feature_list.h"
|
| @@ -54,6 +54,7 @@ using base::Bucket;
|
| using base::TimeTicks;
|
| using rappor::TestRapporServiceImpl;
|
| using ::testing::ElementsAre;
|
| +using ::testing::UnorderedElementsAre;
|
|
|
| namespace autofill {
|
| namespace {
|
| @@ -316,6 +317,18 @@ const ukm::Entry_Metric* FindMetric(
|
| return nullptr;
|
| }
|
|
|
| +// Finds all the UKM values for |name| in the specified |metrics|.
|
| +const std::vector<int64_t> FindMetricValues(
|
| + const char* name,
|
| + const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) {
|
| + std::vector<int64_t> values;
|
| + for (const auto& metric : metrics) {
|
| + if (metric.metric_hash() == base::HashMetricName(name))
|
| + values.push_back(metric.value());
|
| + }
|
| + return values;
|
| +}
|
| +
|
| } // namespace
|
|
|
| // This is defined in the autofill_metrics.cc implementation file.
|
| @@ -766,7 +779,7 @@ TEST_F(AutofillMetricsTest, QualityMetrics_BasedOnAutocomplete) {
|
| std::unique_ptr<TestFormStructure> form_structure =
|
| base::MakeUnique<TestFormStructure>(form);
|
| TestFormStructure* form_structure_ptr = form_structure.get();
|
| - form_structure->DetermineHeuristicTypes();
|
| + form_structure->DetermineHeuristicTypes(nullptr /* ukm_service */);
|
| autofill_manager_->form_structures()->push_back(std::move(form_structure));
|
|
|
| AutofillQueryResponseContents response;
|
| @@ -1434,6 +1447,8 @@ TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields_NoSubmission) {
|
|
|
| // Verify that we correctly log metrics regarding developer engagement.
|
| TEST_F(AutofillMetricsTest, DeveloperEngagement) {
|
| + ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
|
| +
|
| // Start with a non-fillable form.
|
| FormData form;
|
| form.name = ASCIIToUTF16("TestForm");
|
| @@ -1454,6 +1469,10 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
|
| autofill_manager_->OnFormsSeen(forms, TimeTicks());
|
| autofill_manager_->Reset();
|
| histogram_tester.ExpectTotalCount("Autofill.DeveloperEngagement", 0);
|
| +
|
| + // UKM must not be logged unless enabled.
|
| + EXPECT_EQ(0U, ukm_service->sources_count());
|
| + EXPECT_EQ(0U, ukm_service->entries_count());
|
| }
|
|
|
| // Add another field to the form, so that it becomes fillable.
|
| @@ -1469,6 +1488,10 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
|
| histogram_tester.ExpectUniqueSample("Autofill.DeveloperEngagement",
|
| AutofillMetrics::FILLABLE_FORM_PARSED,
|
| 1);
|
| +
|
| + // UKM must not be logged unless enabled.
|
| + EXPECT_EQ(0U, ukm_service->sources_count());
|
| + EXPECT_EQ(0U, ukm_service->entries_count());
|
| }
|
|
|
| // Add some fields with an author-specified field type to the form.
|
| @@ -1498,6 +1521,133 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
|
| histogram_tester.ExpectBucketCount(
|
| "Autofill.DeveloperEngagement",
|
| AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS, 1);
|
| +
|
| + // UKM must not be logged unless enabled.
|
| + EXPECT_EQ(0U, ukm_service->sources_count());
|
| + EXPECT_EQ(0U, ukm_service->entries_count());
|
| + }
|
| +}
|
| +
|
| +// Verify that we correctly log UKM regarding developer engagement.
|
| +TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogFillableFormParsed) {
|
| + EnableUkmLogging();
|
| + ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
|
| +
|
| + // Start with a non-fillable form.
|
| + FormData form;
|
| + form.name = ASCIIToUTF16("TestForm");
|
| + form.origin = GURL("http://example.com/form.html");
|
| + form.action = GURL("http://example.com/submit.html");
|
| +
|
| + FormFieldData field;
|
| + test::CreateTestFormField("Name", "name", "", "text", &field);
|
| + form.fields.push_back(field);
|
| + test::CreateTestFormField("Email", "email", "", "text", &field);
|
| + form.fields.push_back(field);
|
| +
|
| + std::vector<FormData> forms(1, form);
|
| +
|
| + // Ensure no metrics are logged when loading a non-fillable form.
|
| + {
|
| + autofill_manager_->OnFormsSeen(forms, TimeTicks());
|
| + autofill_manager_->Reset();
|
| +
|
| + EXPECT_EQ(0U, ukm_service->sources_count());
|
| + EXPECT_EQ(0U, ukm_service->entries_count());
|
| + }
|
| +
|
| + // Add another field to the form, so that it becomes fillable.
|
| + test::CreateTestFormField("Phone", "phone", "", "text", &field);
|
| + forms.back().fields.push_back(field);
|
| +
|
| + // Expect only the "form parsed" metric to be logged; no metrics about
|
| + // author-specified field type hints.
|
| + {
|
| + autofill_manager_->OnFormsSeen(forms, TimeTicks());
|
| + autofill_manager_->Reset();
|
| +
|
| + ASSERT_EQ(1U, ukm_service->sources_count());
|
| + const ukm::UkmSource* source =
|
| + ukm_service->GetSourceForUrl(form.origin.spec().c_str());
|
| + ASSERT_NE(nullptr, source);
|
| +
|
| + ASSERT_EQ(1U, ukm_service->entries_count());
|
| + const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
|
| + EXPECT_EQ(source->id(), entry->source_id());
|
| +
|
| + ukm::Entry entry_proto;
|
| + entry->PopulateProto(&entry_proto);
|
| + EXPECT_EQ(source->id(), entry_proto.source_id());
|
| + EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
|
| + entry_proto.event_hash());
|
| + EXPECT_THAT(FindMetricValues(internal::kUKMDeveloperEngagementMetricName,
|
| + entry_proto.metrics()),
|
| + UnorderedElementsAre(AutofillMetrics::FILLABLE_FORM_PARSED));
|
| + }
|
| +}
|
| +
|
| +// Verify that we correctly log UKM regarding developer engagement.
|
| +TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogAllMetrics) {
|
| + EnableUkmLogging();
|
| + ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
|
| +
|
| + FormData form;
|
| + form.name = ASCIIToUTF16("TestForm");
|
| + form.origin = GURL("http://example.com/form.html");
|
| + form.action = GURL("http://example.com/submit.html");
|
| +
|
| + FormFieldData field;
|
| + test::CreateTestFormField("Name", "name", "", "text", &field);
|
| + form.fields.push_back(field);
|
| + test::CreateTestFormField("Email", "email", "", "text", &field);
|
| + form.fields.push_back(field);
|
| +
|
| + std::vector<FormData> forms(1, form);
|
| +
|
| + // Add another field to the form, so that it becomes fillable.
|
| + test::CreateTestFormField("Phone", "phone", "", "text", &field);
|
| + forms.back().fields.push_back(field);
|
| +
|
| + // Add some fields with an author-specified field type to the form.
|
| + // We need to add at least three fields, because a form must have at least
|
| + // three fillable fields to be considered to be autofillable; and if at least
|
| + // one field specifies an explicit type hint, we don't apply any of our usual
|
| + // local heuristics to detect field types in the rest of the form.
|
| + test::CreateTestFormField("", "", "", "text", &field);
|
| + field.autocomplete_attribute = "given-name";
|
| + forms.back().fields.push_back(field);
|
| + test::CreateTestFormField("", "", "", "text", &field);
|
| + field.autocomplete_attribute = "email";
|
| + forms.back().fields.push_back(field);
|
| + test::CreateTestFormField("", "", "", "text", &field);
|
| + field.autocomplete_attribute = "address-line1";
|
| + forms.back().fields.push_back(field);
|
| +
|
| + // Expect both the "form parsed" metric and the author-specified field type
|
| + // hints metric to be logged.
|
| + {
|
| + autofill_manager_->OnFormsSeen(forms, TimeTicks());
|
| + autofill_manager_->Reset();
|
| +
|
| + ASSERT_EQ(1U, ukm_service->sources_count());
|
| + const ukm::UkmSource* source =
|
| + ukm_service->GetSourceForUrl(form.origin.spec().c_str());
|
| + ASSERT_NE(nullptr, source);
|
| +
|
| + ASSERT_EQ(1U, ukm_service->entries_count());
|
| + const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
|
| + EXPECT_EQ(source->id(), entry->source_id());
|
| +
|
| + ukm::Entry entry_proto;
|
| + entry->PopulateProto(&entry_proto);
|
| + EXPECT_EQ(source->id(), entry_proto.source_id());
|
| + EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
|
| + entry_proto.event_hash());
|
| + EXPECT_THAT(FindMetricValues(internal::kUKMDeveloperEngagementMetricName,
|
| + entry_proto.metrics()),
|
| + UnorderedElementsAre(
|
| + AutofillMetrics::FILLABLE_FORM_PARSED,
|
| + AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS));
|
| }
|
| }
|
|
|
| @@ -4366,15 +4516,14 @@ TEST_F(AutofillMetricsTest,
|
| }
|
| }
|
|
|
| -// Tests that logging a UKM works as expected.
|
| +// Tests that logging CardUploadDecision UKM works as expected.
|
| TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric) {
|
| EnableUkmLogging();
|
| ukm::UkmServiceTestingHarness ukm_service_test_harness;
|
| GURL url("https://www.google.com");
|
| int upload_decision = 1;
|
| - std::map<std::string, int> metrics;
|
| - metrics.insert(std::make_pair(internal::kUKMCardUploadDecisionMetricName,
|
| - upload_decision));
|
| + std::vector<std::pair<const char*, int>> metrics = {
|
| + {internal::kUKMCardUploadDecisionMetricName, upload_decision}};
|
|
|
| EXPECT_TRUE(AutofillMetrics::LogUkm(
|
| ukm_service_test_harness.test_ukm_service(), url,
|
| @@ -4389,11 +4538,11 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric) {
|
| ukm_service->GetSourceForUrl(url.spec().c_str());
|
| EXPECT_EQ(url.spec(), source->url().spec());
|
|
|
| - EXPECT_EQ(1U, ukm_service->entries_count());
|
| + ASSERT_EQ(1U, ukm_service->entries_count());
|
| const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
|
| EXPECT_EQ(source->id(), entry->source_id());
|
|
|
| - // Make sure that an card upload decision entry was logged.
|
| + // Make sure that a card upload decision entry was logged.
|
| ukm::Entry entry_proto;
|
| entry->PopulateProto(&entry_proto);
|
| EXPECT_EQ(source->id(), entry_proto.source_id());
|
| @@ -4408,13 +4557,53 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric) {
|
| EXPECT_EQ(upload_decision, metric->value());
|
| }
|
|
|
| +// Tests that logging DeveloperEngagement UKM works as expected.
|
| +TEST_F(AutofillMetricsTest, RecordDeveloperEngagementMetric) {
|
| + EnableUkmLogging();
|
| + ukm::UkmServiceTestingHarness ukm_service_test_harness;
|
| + GURL url("https://www.google.com");
|
| + int form_structure_metric = 1;
|
| + std::vector<std::pair<const char*, int>> metrics = {
|
| + {internal::kUKMDeveloperEngagementMetricName, form_structure_metric}};
|
| +
|
| + EXPECT_TRUE(AutofillMetrics::LogUkm(
|
| + ukm_service_test_harness.test_ukm_service(), url,
|
| + internal::kUKMDeveloperEngagementEntryName, metrics));
|
| +
|
| + // Make sure that the UKM was logged correctly.
|
| + ukm::TestUkmService* ukm_service =
|
| + ukm_service_test_harness.test_ukm_service();
|
| +
|
| + ASSERT_EQ(1U, ukm_service->sources_count());
|
| + const ukm::UkmSource* source =
|
| + ukm_service->GetSourceForUrl(url.spec().c_str());
|
| + EXPECT_EQ(url.spec(), source->url().spec());
|
| +
|
| + ASSERT_EQ(1U, ukm_service->entries_count());
|
| + const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
|
| + EXPECT_EQ(source->id(), entry->source_id());
|
| +
|
| + // Make sure that a developer engagement entry was logged.
|
| + ukm::Entry entry_proto;
|
| + entry->PopulateProto(&entry_proto);
|
| + EXPECT_EQ(source->id(), entry_proto.source_id());
|
| + EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
|
| + entry_proto.event_hash());
|
| + EXPECT_EQ(1, entry_proto.metrics_size());
|
| +
|
| + // Make sure that the correct developer engagement metric was logged.
|
| + const ukm::Entry_Metric* metric = FindMetric(
|
| + internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics());
|
| + ASSERT_NE(nullptr, metric);
|
| + EXPECT_EQ(form_structure_metric, metric->value());
|
| +}
|
| +
|
| // Tests that no UKM is logged when the URL is not valid.
|
| TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_InvalidUrl) {
|
| EnableUkmLogging();
|
| ukm::UkmServiceTestingHarness ukm_service_test_harness;
|
| GURL url("");
|
| - std::map<std::string, int> metrics;
|
| - metrics.insert(std::make_pair("metric", 1));
|
| + std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
|
|
|
| EXPECT_FALSE(AutofillMetrics::LogUkm(
|
| ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
|
| @@ -4426,7 +4615,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoMetrics) {
|
| EnableUkmLogging();
|
| ukm::UkmServiceTestingHarness ukm_service_test_harness;
|
| GURL url("https://www.google.com");
|
| - std::map<std::string, int> metrics;
|
| + std::vector<std::pair<const char*, int>> metrics;
|
|
|
| EXPECT_FALSE(AutofillMetrics::LogUkm(
|
| ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
|
| @@ -4438,8 +4627,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoUkmService) {
|
| EnableUkmLogging();
|
| ukm::UkmServiceTestingHarness ukm_service_test_harness;
|
| GURL url("https://www.google.com");
|
| - std::map<std::string, int> metrics;
|
| - metrics.insert(std::make_pair("metric", 1));
|
| + std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
|
|
|
| EXPECT_FALSE(AutofillMetrics::LogUkm(nullptr, url, "test_ukm", metrics));
|
| ASSERT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count());
|
| @@ -4449,8 +4637,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoUkmService) {
|
| TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_FeatureDisabled) {
|
| ukm::UkmServiceTestingHarness ukm_service_test_harness;
|
| GURL url("https://www.google.com");
|
| - std::map<std::string, int> metrics;
|
| - metrics.insert(std::make_pair("metric", 1));
|
| + std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
|
|
|
| EXPECT_FALSE(AutofillMetrics::LogUkm(
|
| ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
|
|
|