blob: 97998a41649695dffc56234af07c32dc92820d62 [file] [log] [blame]
// Copyright 2021 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/history_clusters/core/on_device_clustering_util.h"
#include "base/test/task_environment.h"
#include "components/history_clusters/core/clustering_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace history_clusters {
namespace {
using ::testing::UnorderedElementsAre;
using OnDeviceClusteringUtilTest = ::testing::Test;
TEST_F(OnDeviceClusteringUtilTest, MergeDuplicateVisitIntoCanonicalVisit) {
// canonical_visit has the same normalized URL as duplicated_visit.
history::ClusterVisit duplicate_visit = testing::CreateClusterVisit(
testing::CreateDefaultAnnotatedVisit(
1, GURL("https://example.com/normalized?q=whatever")),
GURL("https://example.com/normalized"));
duplicate_visit.annotated_visit.content_annotations.related_searches = {
"xyz"};
duplicate_visit.annotated_visit.context_annotations.omnibox_url_copied = true;
duplicate_visit.annotated_visit.context_annotations.is_existing_bookmark =
true;
duplicate_visit.annotated_visit.context_annotations
.is_existing_part_of_tab_group = true;
duplicate_visit.annotated_visit.context_annotations.is_new_bookmark = true;
duplicate_visit.annotated_visit.context_annotations.is_placed_in_tab_group =
true;
duplicate_visit.annotated_visit.context_annotations.is_ntp_custom_link = true;
duplicate_visit.annotated_visit.context_annotations
.total_foreground_duration = base::Seconds(20);
history::ClusterVisit canonical_visit =
testing::CreateClusterVisit(testing::CreateDefaultAnnotatedVisit(
2, GURL("https://example.com/normalized")));
canonical_visit.annotated_visit.content_annotations.related_searches = {
"abc", "xyz"};
canonical_visit.annotated_visit.context_annotations.omnibox_url_copied =
false;
canonical_visit.annotated_visit.context_annotations.is_existing_bookmark =
false;
canonical_visit.annotated_visit.context_annotations
.is_existing_part_of_tab_group = false;
canonical_visit.annotated_visit.context_annotations.is_new_bookmark = false;
canonical_visit.annotated_visit.context_annotations.is_placed_in_tab_group =
false;
canonical_visit.annotated_visit.context_annotations.is_ntp_custom_link =
false;
canonical_visit.annotated_visit.context_annotations
.total_foreground_duration = base::Seconds(20);
MergeDuplicateVisitIntoCanonicalVisit(duplicate_visit, canonical_visit);
EXPECT_TRUE(
canonical_visit.annotated_visit.context_annotations.omnibox_url_copied);
EXPECT_TRUE(
canonical_visit.annotated_visit.context_annotations.is_existing_bookmark);
EXPECT_TRUE(canonical_visit.annotated_visit.context_annotations
.is_existing_part_of_tab_group);
EXPECT_TRUE(
canonical_visit.annotated_visit.context_annotations.is_new_bookmark);
EXPECT_TRUE(canonical_visit.annotated_visit.context_annotations
.is_placed_in_tab_group);
EXPECT_TRUE(
canonical_visit.annotated_visit.context_annotations.is_ntp_custom_link);
EXPECT_THAT(
canonical_visit.annotated_visit.content_annotations.related_searches,
UnorderedElementsAre("abc", "xyz"));
EXPECT_EQ(canonical_visit.annotated_visit.visit_row.visit_duration,
base::Seconds(10 * 2));
EXPECT_EQ(canonical_visit.annotated_visit.context_annotations
.total_foreground_duration,
base::Seconds(20 * 2));
}
TEST_F(OnDeviceClusteringUtilTest, CalculateAllDuplicateVisitsForCluster) {
history::ClusterVisit visit = testing::CreateClusterVisit(
testing::CreateDefaultAnnotatedVisit(1, GURL("https://google.com/")));
history::ClusterVisit visit2 = testing::CreateClusterVisit(
testing::CreateDefaultAnnotatedVisit(2, GURL("https://foo.com/")));
visit2.duplicate_visit_ids = {1};
history::Cluster cluster;
cluster.visits = {visit, visit2};
EXPECT_THAT(CalculateAllDuplicateVisitsForCluster(cluster),
UnorderedElementsAre(1));
}
TEST_F(OnDeviceClusteringUtilTest, SortClusters) {
std::vector<history::Cluster> clusters;
// This first cluster is meant to validate that the higher scoring "visit 1"
// gets sorted to the top, even though "visit 1" is older than "visit 2".
// It's to validate the within-cluster sorting.
clusters.push_back(history::Cluster(
0,
{
testing::CreateClusterVisit(
testing::CreateDefaultAnnotatedVisit(2, GURL("https://two.com/"),
base::Time::FromTimeT(10)),
absl::nullopt, 0.5),
testing::CreateClusterVisit(
testing::CreateDefaultAnnotatedVisit(1, GURL("https://one.com/"),
base::Time::FromTimeT(5)),
absl::nullopt, 0.9),
},
{}));
// The second cluster is lower scoring, but newer, because the top visit is
// newer. It should be sorted above the first cluster because of reverse
// chronological between-cluster sorting.
clusters.push_back(history::Cluster(
0,
{
testing::CreateClusterVisit(
testing::CreateDefaultAnnotatedVisit(2, GURL("https://two.com/"),
base::Time::FromTimeT(10)),
absl::nullopt, 0.1),
},
{}));
SortClusters(&clusters);
ASSERT_EQ(clusters.size(), 2u);
auto& visits = clusters[0].visits;
ASSERT_EQ(visits.size(), 1u);
EXPECT_EQ(visits[0].annotated_visit.url_row.url(), "https://two.com/");
EXPECT_FLOAT_EQ(visits[0].score, 0.1);
visits = clusters[1].visits;
ASSERT_EQ(visits.size(), 2u);
EXPECT_EQ(visits[0].annotated_visit.url_row.url(), "https://one.com/");
EXPECT_FLOAT_EQ(visits[0].score, 0.9);
EXPECT_EQ(visits[1].annotated_visit.url_row.url(), "https://two.com/");
EXPECT_FLOAT_EQ(visits[1].score, 0.5);
}
} // namespace
} // namespace history_clusters