123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- // Copyright 2022 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/browsing_topics/browsing_topics_page_load_data_tracker.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/memory/raw_ptr.h"
- #include "base/test/bind.h"
- #include "base/test/scoped_feature_list.h"
- #include "components/browsing_topics/test_util.h"
- #include "components/history/content/browser/history_context_helper.h"
- #include "components/history/core/browser/history_database_params.h"
- #include "components/history/core/browser/history_service.h"
- #include "components/history/core/test/test_history_database.h"
- #include "components/ukm/test_ukm_recorder.h"
- #include "content/public/browser/navigation_entry.h"
- #include "content/public/test/back_forward_cache_util.h"
- #include "content/public/test/browsing_topics_test_util.h"
- #include "content/public/test/navigation_simulator.h"
- #include "content/public/test/test_utils.h"
- #include "content/public/test/web_contents_tester.h"
- #include "content/test/test_render_view_host.h"
- #include "services/metrics/public/cpp/metrics_utils.h"
- #include "services/metrics/public/cpp/ukm_builders.h"
- namespace browsing_topics {
- class BrowsingTopicsPageLoadDataTrackerTest
- : public content::RenderViewHostTestHarness {
- public:
- BrowsingTopicsPageLoadDataTrackerTest() {
- scoped_feature_list_.InitWithFeatures(
- /*enabled_features=*/{blink::features::kBrowsingTopics},
- /*disabled_features=*/{});
- EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
- history_service_ = std::make_unique<history::HistoryService>();
- history_service_->Init(
- history::TestHistoryDatabaseParamsForPath(temp_dir_.GetPath()));
- }
- ~BrowsingTopicsPageLoadDataTrackerTest() override = default;
- void SetUp() override {
- content::RenderViewHostTestHarness::SetUp();
- // The test assumes pages gets deleted after navigation, triggering metrics
- // recording. Disable back/forward cache to ensure that pages don't get
- // preserved in the cache.
- content::DisableBackForwardCacheForTesting(
- web_contents(), content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
- }
- void TearDown() override {
- DCHECK(history_service_);
- base::RunLoop run_loop;
- history_service_->SetOnBackendDestroyTask(run_loop.QuitClosure());
- history_service_.reset();
- run_loop.Run();
- content::RenderViewHostTestHarness::TearDown();
- }
- void NavigateToPage(const GURL& url,
- bool publicly_routable,
- bool browsing_topics_permissions_policy_allowed,
- bool interest_cohort_permissions_policy_allowed) {
- auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
- url, web_contents());
- simulator->SetTransition(ui::PageTransition::PAGE_TRANSITION_TYPED);
- if (!publicly_routable) {
- net::IPAddress address;
- EXPECT_TRUE(address.AssignFromIPLiteral("0.0.0.0"));
- simulator->SetSocketAddress(net::IPEndPoint(address, /*port=*/0));
- }
- blink::ParsedPermissionsPolicy policy;
- if (!browsing_topics_permissions_policy_allowed) {
- policy.emplace_back(
- blink::mojom::PermissionsPolicyFeature::kBrowsingTopics,
- /*values=*/std::vector<url::Origin>(), /*matches_all_origins=*/false,
- /*matches_opaque_src=*/false);
- }
- if (!interest_cohort_permissions_policy_allowed) {
- policy.emplace_back(blink::mojom::PermissionsPolicyFeature::
- kBrowsingTopicsBackwardCompatible,
- /*values=*/std::vector<url::Origin>(),
- /*matches_all_origins=*/false,
- /*matches_opaque_src=*/false);
- }
- simulator->SetPermissionsPolicyHeader(std::move(policy));
- simulator->Commit();
- history_service_->AddPage(
- url, base::Time::Now(),
- history::ContextIDForWebContents(web_contents()),
- web_contents()->GetController().GetLastCommittedEntry()->GetUniqueID(),
- /*referrer=*/GURL(),
- /*redirects=*/{}, ui::PageTransition::PAGE_TRANSITION_TYPED,
- history::VisitSource::SOURCE_BROWSED,
- /*did_replace_entry=*/false);
- }
- BrowsingTopicsPageLoadDataTracker* GetBrowsingTopicsPageLoadDataTracker() {
- return BrowsingTopicsPageLoadDataTracker::GetOrCreateForPage(
- web_contents()->GetPrimaryMainFrame()->GetPage());
- }
- content::BrowsingTopicsSiteDataManager* topics_site_data_manager() {
- return web_contents()
- ->GetPrimaryMainFrame()
- ->GetProcess()
- ->GetStoragePartition()
- ->GetBrowsingTopicsSiteDataManager();
- }
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
- std::unique_ptr<history::HistoryService> history_service_;
- base::ScopedTempDir temp_dir_;
- };
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, OneUsage) {
- GURL url("https://foo.com");
- NavigateToPage(url, /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- EXPECT_FALSE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- EXPECT_TRUE(
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager()).empty());
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- EXPECT_TRUE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- std::vector<ApiUsageContext> api_usage_contexts =
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager());
- EXPECT_EQ(api_usage_contexts.size(), 1u);
- EXPECT_EQ(api_usage_contexts[0].hashed_main_frame_host,
- HashMainFrameHostForStorage("foo.com"));
- EXPECT_EQ(api_usage_contexts[0].hashed_context_domain, HashedDomain(123));
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, TwoUsages) {
- GURL url("https://foo.com");
- NavigateToPage(url, /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(456), history_service_.get());
- EXPECT_TRUE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- std::vector<ApiUsageContext> api_usage_contexts =
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager());
- EXPECT_EQ(api_usage_contexts.size(), 2u);
- EXPECT_EQ(api_usage_contexts[0].hashed_main_frame_host,
- HashMainFrameHostForStorage("foo.com"));
- EXPECT_EQ(api_usage_contexts[0].hashed_context_domain, HashedDomain(123));
- EXPECT_EQ(api_usage_contexts[1].hashed_main_frame_host,
- HashMainFrameHostForStorage("foo.com"));
- EXPECT_EQ(api_usage_contexts[1].hashed_context_domain, HashedDomain(456));
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, OneUsage_PageLoadUkm) {
- ukm::TestAutoSetUkmRecorder ukm_recorder;
- NavigateToPage(GURL("https://foo.com"), /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- NavigateToPage(GURL(url::kAboutBlankURL), /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- auto entries = ukm_recorder.GetEntriesByName(
- ukm::builders::BrowsingTopics_PageLoad::kEntryName);
- EXPECT_EQ(1u, entries.size());
- ASSERT_EQ(1, ukm::GetExponentialBucketMinForCounts1000(1));
- ukm_recorder.ExpectEntryMetric(entries.back(),
- ukm::builders::BrowsingTopics_PageLoad::
- kTopicsRequestingContextDomainsCountName,
- 1);
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, OneThousandUsages_PageLoadUkm) {
- ukm::TestAutoSetUkmRecorder ukm_recorder;
- NavigateToPage(GURL("https://foo.com"), /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- for (int i = 0; i < 1000; ++i) {
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(i), history_service_.get());
- }
- NavigateToPage(GURL(url::kAboutBlankURL), /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- auto entries = ukm_recorder.GetEntriesByName(
- ukm::builders::BrowsingTopics_PageLoad::kEntryName);
- EXPECT_EQ(1u, entries.size());
- ASSERT_EQ(943, ukm::GetExponentialBucketMinForCounts1000(1000));
- ukm_recorder.ExpectEntryMetric(entries.back(),
- ukm::builders::BrowsingTopics_PageLoad::
- kTopicsRequestingContextDomainsCountName,
- 943);
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, TwoThousandUsages_PageLoadUkm) {
- ukm::TestAutoSetUkmRecorder ukm_recorder;
- NavigateToPage(GURL("https://foo.com"), /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- for (int i = 0; i < 2000; ++i) {
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(i), history_service_.get());
- }
- NavigateToPage(GURL(url::kAboutBlankURL), /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- auto entries = ukm_recorder.GetEntriesByName(
- ukm::builders::BrowsingTopics_PageLoad::kEntryName);
- EXPECT_EQ(1u, entries.size());
- ASSERT_EQ(943, ukm::GetExponentialBucketMinForCounts1000(1000));
- ASSERT_EQ(1896, ukm::GetExponentialBucketMinForCounts1000(2000));
- ukm_recorder.ExpectEntryMetric(entries.back(),
- ukm::builders::BrowsingTopics_PageLoad::
- kTopicsRequestingContextDomainsCountName,
- 943);
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, DuplicateDomains) {
- GURL url("https://foo.com");
- NavigateToPage(url, /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(456), history_service_.get());
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- EXPECT_TRUE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- std::vector<ApiUsageContext> api_usage_contexts =
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager());
- EXPECT_EQ(api_usage_contexts.size(), 2u);
- EXPECT_EQ(api_usage_contexts[0].hashed_main_frame_host,
- HashMainFrameHostForStorage("foo.com"));
- EXPECT_EQ(api_usage_contexts[0].hashed_context_domain, HashedDomain(123));
- EXPECT_EQ(api_usage_contexts[1].hashed_main_frame_host,
- HashMainFrameHostForStorage("foo.com"));
- EXPECT_EQ(api_usage_contexts[1].hashed_context_domain, HashedDomain(456));
- // The second HashedDomain(123) shouldn't update the database. Verify this by
- // verifying that the timestamp for HashedDomain(123) is no greater than the
- // timestamp for HashedDomain(456).
- EXPECT_LE(api_usage_contexts[0].time, api_usage_contexts[1].time);
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, NumberOfDomainsExceedsLimit) {
- GURL url("https://foo.com");
- NavigateToPage(url, /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- for (int i = 0; i < 31; ++i) {
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(i), history_service_.get());
- }
- EXPECT_TRUE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- std::vector<ApiUsageContext> api_usage_contexts =
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager());
- EXPECT_EQ(api_usage_contexts.size(), 30u);
- for (int i = 0; i < 30; ++i) {
- EXPECT_EQ(api_usage_contexts[i].hashed_main_frame_host,
- HashMainFrameHostForStorage("foo.com"));
- EXPECT_EQ(api_usage_contexts[i].hashed_context_domain, HashedDomain(i));
- }
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest, NotPubliclyRoutable) {
- GURL url("https://foo.com");
- NavigateToPage(url, /*publicly_routable=*/false,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/true);
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- EXPECT_FALSE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- EXPECT_TRUE(
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager()).empty());
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest,
- BrowsingTopicsPermissionsPolicyNotAllowed) {
- GURL url("https://foo.com");
- NavigateToPage(url, /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/false,
- /*interest_cohort_permissions_policy_allowed=*/true);
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- EXPECT_FALSE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- EXPECT_TRUE(
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager()).empty());
- }
- TEST_F(BrowsingTopicsPageLoadDataTrackerTest,
- InterestCohortPermissionsPolicyNotAllowed) {
- GURL url("https://foo.com");
- NavigateToPage(url, /*publicly_routable=*/true,
- /*browsing_topics_permissions_policy_allowed=*/true,
- /*interest_cohort_permissions_policy_allowed=*/false);
- GetBrowsingTopicsPageLoadDataTracker()->OnBrowsingTopicsApiUsed(
- HashedDomain(123), history_service_.get());
- EXPECT_FALSE(BrowsingTopicsEligibleForURLVisit(history_service_.get(), url));
- EXPECT_TRUE(
- content::GetBrowsingTopicsApiUsage(topics_site_data_manager()).empty());
- }
- } // namespace browsing_topics
|