| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "ios/chrome/browser/optimization_guide/optimization_guide_service.h" |
| |
| #import "base/command_line.h" |
| #import "base/test/metrics/histogram_tester.h" |
| #import "base/test/scoped_command_line.h" |
| #import "base/test/scoped_feature_list.h" |
| #import "components/optimization_guide/core/hints_component_util.h" |
| #import "components/optimization_guide/core/hints_manager.h" |
| #import "components/optimization_guide/core/optimization_guide_features.h" |
| #import "components/optimization_guide/core/optimization_guide_navigation_data.h" |
| #import "components/optimization_guide/core/optimization_guide_switches.h" |
| #import "components/optimization_guide/core/optimization_guide_test_util.h" |
| #import "components/optimization_guide/core/optimization_hints_component_update_listener.h" |
| #import "components/optimization_guide/core/test_hints_component_creator.h" |
| #import "components/sync_preferences/pref_service_syncable.h" |
| #import "components/sync_preferences/testing_pref_service_syncable.h" |
| #import "components/ukm/test_ukm_recorder.h" |
| #import "components/unified_consent/pref_names.h" |
| #import "components/unified_consent/unified_consent_service.h" |
| #import "ios/chrome/browser/optimization_guide/optimization_guide_service_factory.h" |
| #import "ios/chrome/browser/optimization_guide/optimization_guide_test_utils.h" |
| #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" |
| #import "ios/chrome/browser/shared/model/prefs/browser_prefs.h" |
| #import "ios/web/public/navigation/navigation_manager.h" |
| #import "ios/web/public/test/fakes/fake_navigation_context.h" |
| #import "ios/web/public/test/web_task_environment.h" |
| #import "services/metrics/public/cpp/ukm_builders.h" |
| #import "services/metrics/public/cpp/ukm_source.h" |
| #import "testing/gtest/include/gtest/gtest.h" |
| #import "testing/platform_test.h" |
| #import "url/gurl.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| // These tests are roughly similarly to the tests in |
| // optimization_guide_keyed_service_browsertest.cc |
| |
| namespace { |
| |
| constexpr char kHintsURL[] = "https://hints.com/with_hints.html"; |
| constexpr char kNoHintsURL[] = "https://nohints.com/no_hints.html"; |
| constexpr char kRedirectURL[] = "https://hints.com/redirect.html"; |
| |
| // Wraps the NavigationContext and OptimizationGuideNavigationData together for |
| // tests. |
| class NavigationContextAndData { |
| public: |
| explicit NavigationContextAndData(const std::string& url) { |
| navigation_context_ = std::make_unique<web::FakeNavigationContext>(); |
| navigation_context_->SetUrl(GURL(url)); |
| navigation_data_ = std::make_unique<OptimizationGuideNavigationData>( |
| navigation_context_->GetNavigationId(), |
| /*navigation_start=*/base::TimeTicks::Now()); |
| navigation_data_->set_navigation_url(navigation_context_->GetUrl()); |
| } |
| |
| std::unique_ptr<web::FakeNavigationContext> navigation_context_; |
| std::unique_ptr<OptimizationGuideNavigationData> navigation_data_; |
| }; |
| |
| } // namespace |
| |
| class OptimizationGuideServiceTest : public PlatformTest { |
| public: |
| OptimizationGuideServiceTest() { |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| optimization_guide::switches::kPurgeHintsStore); |
| |
| // The tests are run in the same process and share the same |
| // OptimizationHintsComponentUpdateListener due to the global object usage |
| // in GetInstance(). So reset the state for each test. |
| optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() |
| ->ResetStateForTesting(); |
| } |
| |
| ~OptimizationGuideServiceTest() override = default; |
| |
| void SetUp() override { |
| PlatformTest::SetUp(); |
| auto testing_prefs = |
| std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); |
| RegisterBrowserStatePrefs(testing_prefs->registry()); |
| |
| std::vector<base::test::FeatureRef> enabled_features; |
| enabled_features.push_back( |
| optimization_guide::features::kOptimizationHints); |
| enabled_features.push_back( |
| optimization_guide::features::kRemoteOptimizationGuideFetching); |
| if (url_keyed_anonymized_data_collection_enabled_) { |
| enabled_features.push_back( |
| optimization_guide::features:: |
| kRemoteOptimizationGuideFetchingAnonymousDataConsent); |
| testing_prefs->SetBoolean( |
| unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, |
| true); |
| } |
| scoped_feature_list_.InitWithFeatures(enabled_features, {}); |
| |
| TestChromeBrowserState::Builder builder; |
| builder.AddTestingFactory( |
| OptimizationGuideServiceFactory::GetInstance(), |
| OptimizationGuideServiceFactory::GetDefaultFactory()); |
| builder.SetPrefService(std::move(testing_prefs)); |
| browser_state_ = builder.Build(); |
| optimization_guide_service_ = |
| OptimizationGuideServiceFactory::GetForBrowserState( |
| browser_state_.get()); |
| optimization_guide_service_->DoFinalInit( |
| BackgroundDownloadServiceFactory::GetForBrowserState( |
| browser_state_.get())); |
| } |
| |
| void CreateOTRBrowserState() { |
| ChromeBrowserState* otr_browser_state = |
| browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories( |
| {std::make_pair( |
| OptimizationGuideServiceFactory::GetInstance(), |
| OptimizationGuideServiceFactory::GetDefaultFactory())}); |
| OptimizationGuideServiceFactory::GetForBrowserState(otr_browser_state) |
| ->DoFinalInit(); |
| } |
| |
| void PushHintsComponentAndWaitForCompletion() { |
| RetryForHistogramUntilCountReached( |
| histogram_tester(), |
| "OptimizationGuide.HintsManager.HintCacheInitialized", 1); |
| |
| base::RunLoop run_loop; |
| optimization_guide_service() |
| ->GetHintsManager() |
| ->ListenForNextUpdateForTesting(run_loop.QuitClosure()); |
| GURL hints_url(kHintsURL); |
| |
| const optimization_guide::HintsComponentInfo& component_info = |
| test_hints_component_creator_.CreateHintsComponentInfoWithPageHints( |
| optimization_guide::proto::NOSCRIPT, {hints_url.host()}, |
| hints_url.path().substr(1)); |
| |
| optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance() |
| ->MaybeUpdateHintsComponent(component_info); |
| |
| run_loop.Run(); |
| RunUntilIdle(); |
| } |
| |
| void SimulateNavigation( |
| NavigationContextAndData* context_and_data, |
| const absl::optional<GURL> redirect_url = absl::nullopt) { |
| return SimulateNavigationInBrowserState( |
| context_and_data, optimization_guide_service_, redirect_url); |
| } |
| |
| void SimulateNavigationInBrowserState( |
| NavigationContextAndData* context_and_data, |
| OptimizationGuideService* optimization_guide_service, |
| const absl::optional<GURL> redirect_url = absl::nullopt) { |
| std::vector<GURL> navigation_redirect_chain; |
| navigation_redirect_chain.push_back( |
| context_and_data->navigation_context_->GetUrl()); |
| |
| optimization_guide_service->OnNavigationStartOrRedirect( |
| context_and_data->navigation_data_.get()); |
| RunUntilIdle(); |
| |
| if (redirect_url) { |
| context_and_data->navigation_data_->set_navigation_url(*redirect_url); |
| optimization_guide_service->OnNavigationStartOrRedirect( |
| context_and_data->navigation_data_.get()); |
| navigation_redirect_chain.push_back(*redirect_url); |
| RunUntilIdle(); |
| } |
| |
| optimization_guide_service->OnNavigationFinish(navigation_redirect_chain); |
| RunUntilIdle(); |
| } |
| |
| void RegisterWithKeyedService() { |
| optimization_guide_service()->RegisterOptimizationTypes( |
| {optimization_guide::proto::NOSCRIPT}); |
| } |
| |
| // Calls the `CanApplyOptimizationAsync` and expects `expected_decision` when |
| // the decision is returned. `on_decision_callback` is called when the |
| // decision is called. |
| void VerifyCanApplyOptimizationAsyncDecision( |
| NavigationContextAndData* context_and_data, |
| base::OnceClosure on_decision_callback, |
| optimization_guide::OptimizationGuideDecision expected_decision) { |
| optimization_guide_service()->CanApplyOptimizationAsync( |
| context_and_data->navigation_context_.get(), |
| optimization_guide::proto::NOSCRIPT, |
| base::BindOnce( |
| [](base::OnceClosure on_decision_callback, |
| optimization_guide::OptimizationGuideDecision expected_decision, |
| optimization_guide::OptimizationGuideDecision decision, |
| const optimization_guide::OptimizationMetadata& metadata) { |
| EXPECT_EQ(expected_decision, decision); |
| std::move(on_decision_callback).Run(); |
| }, |
| std::move(on_decision_callback), expected_decision)); |
| } |
| |
| void SetUrlKeyedAnonymizedDataCollectionEnabled(bool enabled) { |
| url_keyed_anonymized_data_collection_enabled_ = enabled; |
| } |
| |
| void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } |
| |
| OptimizationGuideService* optimization_guide_service() { |
| return optimization_guide_service_; |
| } |
| |
| base::HistogramTester* histogram_tester() { return &histogram_tester_; } |
| |
| TestChromeBrowserState* browser_state() { return browser_state_.get(); } |
| |
| protected: |
| web::WebTaskEnvironment task_environment_; |
| base::HistogramTester histogram_tester_; |
| std::unique_ptr<TestChromeBrowserState> browser_state_; |
| OptimizationGuideService* optimization_guide_service_; |
| base::test::ScopedFeatureList scoped_feature_list_; |
| optimization_guide::testing::TestHintsComponentCreator |
| test_hints_component_creator_; |
| bool url_keyed_anonymized_data_collection_enabled_ = false; |
| }; |
| |
| TEST_F(OptimizationGuideServiceTest, RemoteFetchingDisabled) { |
| histogram_tester()->ExpectUniqueSample( |
| "OptimizationGuide.RemoteFetchingEnabled", false, 1); |
| // TODO(crbug.com/1240912): Verify the optimization guide fetching synthetic |
| // field trial is recorded. |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, |
| NavigateToPageWithHintsButNoRegistrationDoesNotAttemptToLoadHint) { |
| ukm::TestAutoSetUkmRecorder ukm_recorder; |
| |
| PushHintsComponentAndWaitForCompletion(); |
| |
| NavigationContextAndData context_and_data(kHintsURL); |
| SimulateNavigation(&context_and_data); |
| |
| histogram_tester()->ExpectTotalCount("OptimizationGuide.LoadedHint.Result", |
| 0); |
| |
| // Navigate away so UKM get recorded. |
| context_and_data = NavigationContextAndData(kHintsURL); |
| SimulateNavigation(&context_and_data); |
| |
| auto entries = ukm_recorder.GetEntriesByName( |
| ukm::builders::OptimizationGuide::kEntryName); |
| EXPECT_EQ(0u, entries.size()); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, |
| NavigateToPageWithAsyncCallbackReturnsAnswerRedirect) { |
| PushHintsComponentAndWaitForCompletion(); |
| RegisterWithKeyedService(); |
| |
| auto run_loop = std::make_unique<base::RunLoop>(); |
| NavigationContextAndData context_and_data(kRedirectURL); |
| |
| VerifyCanApplyOptimizationAsyncDecision( |
| &context_and_data, run_loop->QuitClosure(), |
| optimization_guide::OptimizationGuideDecision::kFalse); |
| |
| SimulateNavigation(&context_and_data, |
| /*redirect_url=*/GURL(kNoHintsURL)); |
| run_loop->Run(); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, |
| NavigateToPageWithAsyncCallbackReturnsAnswer) { |
| PushHintsComponentAndWaitForCompletion(); |
| RegisterWithKeyedService(); |
| |
| auto run_loop = std::make_unique<base::RunLoop>(); |
| NavigationContextAndData context_and_data(kHintsURL); |
| |
| VerifyCanApplyOptimizationAsyncDecision( |
| &context_and_data, run_loop->QuitClosure(), |
| optimization_guide::OptimizationGuideDecision::kTrue); |
| |
| SimulateNavigation(&context_and_data); |
| run_loop->Run(); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, |
| NavigateToPageWithAsyncCallbackReturnsAnswerEventually) { |
| PushHintsComponentAndWaitForCompletion(); |
| RegisterWithKeyedService(); |
| |
| auto run_loop = std::make_unique<base::RunLoop>(); |
| NavigationContextAndData context_and_data(kNoHintsURL); |
| |
| VerifyCanApplyOptimizationAsyncDecision( |
| &context_and_data, run_loop->QuitClosure(), |
| optimization_guide::OptimizationGuideDecision::kFalse); |
| |
| SimulateNavigation(&context_and_data); |
| run_loop->Run(); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, NavigateToPageWithHintsLoadsHint) { |
| PushHintsComponentAndWaitForCompletion(); |
| RegisterWithKeyedService(); |
| |
| ukm::TestAutoSetUkmRecorder ukm_recorder; |
| base::HistogramTester histogram_tester; |
| |
| NavigationContextAndData context_and_data(kHintsURL); |
| SimulateNavigation(&context_and_data); |
| |
| auto decision = optimization_guide_service()->CanApplyOptimization( |
| GURL(kHintsURL), optimization_guide::proto::NOSCRIPT, |
| /*optimization_metadata=*/nullptr); |
| RetryForHistogramUntilCountReached(&histogram_tester, |
| "OptimizationGuide.LoadedHint.Result", 1); |
| |
| // There is a hint that matches this URL, so there should be an attempt to |
| // load a hint that succeeds. |
| histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result", |
| true, 1); |
| // We had a hint and it was loaded. |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kTrue, decision); |
| |
| // Navigate away so UKM get recorded. |
| context_and_data = NavigationContextAndData(kHintsURL); |
| SimulateNavigation(&context_and_data); |
| |
| // Expect that UKM is recorded. |
| auto entries = ukm_recorder.GetEntriesByName( |
| ukm::builders::OptimizationGuide::kEntryName); |
| ASSERT_EQ(1u, entries.size()); |
| auto* entry = entries[0]; |
| EXPECT_TRUE(ukm_recorder.EntryHasMetric( |
| entry, |
| ukm::builders::OptimizationGuide::kRegisteredOptimizationTypesName)); |
| // NOSCRIPT = 1, so bit mask is 10, which equals 2. |
| ukm_recorder.ExpectEntryMetric( |
| entry, ukm::builders::OptimizationGuide::kRegisteredOptimizationTypesName, |
| 2); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, |
| RecordsMetricsWhenNavigationDataDestroyed) { |
| PushHintsComponentAndWaitForCompletion(); |
| RegisterWithKeyedService(); |
| |
| ukm::TestAutoSetUkmRecorder ukm_recorder; |
| base::HistogramTester histogram_tester; |
| |
| auto context_and_data = std::make_unique<NavigationContextAndData>(kHintsURL); |
| SimulateNavigation(context_and_data.get()); |
| auto decision = optimization_guide_service()->CanApplyOptimization( |
| GURL(kHintsURL), optimization_guide::proto::NOSCRIPT, |
| /*optimization_metadata=*/nullptr); |
| |
| RetryForHistogramUntilCountReached(&histogram_tester, |
| "OptimizationGuide.LoadedHint.Result", 1); |
| |
| // There is a hint that matches this URL, so there should be an attempt to |
| // load a hint that succeeds. |
| histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result", |
| true, 1); |
| // We had a hint and it was loaded. |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kTrue, decision); |
| |
| // Make sure metrics get recorded when navigation data is destroyed. |
| context_and_data.reset(); |
| RunUntilIdle(); |
| |
| // Expect that the optimization guide UKM is recorded. |
| auto entries = ukm_recorder.GetEntriesByName( |
| ukm::builders::OptimizationGuide::kEntryName); |
| EXPECT_EQ(1u, entries.size()); |
| auto* entry = entries[0]; |
| EXPECT_TRUE(ukm_recorder.EntryHasMetric( |
| entry, |
| ukm::builders::OptimizationGuide::kRegisteredOptimizationTypesName)); |
| // NOSCRIPT = 1, so bit mask is 10, which equals 2. |
| ukm_recorder.ExpectEntryMetric( |
| entry, ukm::builders::OptimizationGuide::kRegisteredOptimizationTypesName, |
| 2); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, |
| NavigateToPageThatRedirectsToUrlWithHintsShouldAttemptTwoLoads) { |
| PushHintsComponentAndWaitForCompletion(); |
| RegisterWithKeyedService(); |
| |
| base::HistogramTester histogram_tester; |
| |
| NavigationContextAndData context_and_data(kRedirectURL); |
| SimulateNavigation(&context_and_data, |
| /*redirect_url=*/GURL(kHintsURL)); |
| auto decision = optimization_guide_service()->CanApplyOptimization( |
| GURL(kHintsURL), optimization_guide::proto::NOSCRIPT, |
| /*optimization_metadata=*/nullptr); |
| |
| RetryForHistogramUntilCountReached(&histogram_tester, |
| "OptimizationGuide.LoadedHint.Result", 2); |
| |
| // Should attempt and succeed to load a hint once for the initial navigation |
| // and redirect. |
| histogram_tester.ExpectBucketCount("OptimizationGuide.LoadedHint.Result", |
| true, 2); |
| // Hint is still applicable so we expect it to be allowed to be applied. |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kTrue, decision); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, NavigateToPageWithoutHint) { |
| PushHintsComponentAndWaitForCompletion(); |
| RegisterWithKeyedService(); |
| |
| base::HistogramTester histogram_tester; |
| |
| NavigationContextAndData context_and_data(kNoHintsURL); |
| SimulateNavigation(&context_and_data); |
| auto decision = optimization_guide_service()->CanApplyOptimization( |
| GURL(kNoHintsURL), optimization_guide::proto::NOSCRIPT, |
| /*optimization_metadata=*/nullptr); |
| |
| RetryForHistogramUntilCountReached(&histogram_tester, |
| "OptimizationGuide.LoadedHint.Result", 1); |
| |
| // There were no hints that match this URL, but there should still be an |
| // attempt to load a hint but still fail. |
| histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result", |
| false, 1); |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kFalse, decision); |
| histogram_tester.ExpectUniqueSample( |
| "OptimizationGuide.ApplyDecision.NoScript", |
| static_cast<int>( |
| optimization_guide::OptimizationTypeDecision::kNoHintAvailable), |
| 1); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, CheckForBlocklistFilter) { |
| PushHintsComponentAndWaitForCompletion(); |
| |
| OptimizationGuideService* ogks = |
| OptimizationGuideServiceFactory::GetForBrowserState(browser_state()); |
| |
| { |
| base::HistogramTester histogram_tester; |
| |
| // Register an optimization type with an optimization filter. |
| ogks->RegisterOptimizationTypes( |
| {optimization_guide::proto::FAST_HOST_HINTS}); |
| // Wait until filter is loaded. This histogram will record twice: once when |
| // the config is found and once when the filter is created. |
| RetryForHistogramUntilCountReached( |
| &histogram_tester, |
| "OptimizationGuide.OptimizationFilterStatus.FastHostHints", 2); |
| histogram_tester.ExpectBucketCount( |
| "OptimizationGuide.OptimizationFilterStatus.FastHostHints", |
| optimization_guide::OptimizationFilterStatus::kFoundServerFilterConfig, |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "OptimizationGuide.OptimizationFilterStatus.FastHostHints", |
| optimization_guide::OptimizationFilterStatus::kCreatedServerFilter, 1); |
| |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kFalse, |
| ogks->CanApplyOptimization( |
| GURL("https://blockedhost.com/whatever"), |
| optimization_guide::proto::FAST_HOST_HINTS, nullptr)); |
| histogram_tester.ExpectUniqueSample( |
| "OptimizationGuide.ApplyDecision.FastHostHints", |
| static_cast<int>(optimization_guide::OptimizationTypeDecision:: |
| kNotAllowedByOptimizationFilter), |
| 1); |
| } |
| |
| // Register another type with optimization filter. |
| { |
| base::HistogramTester histogram_tester; |
| ogks->RegisterOptimizationTypes( |
| {optimization_guide::proto::LITE_PAGE_REDIRECT}); |
| // Wait until filter is loaded. This histogram will record twice: once when |
| // the config is found and once when the filter is created. |
| RetryForHistogramUntilCountReached( |
| &histogram_tester, |
| "OptimizationGuide.OptimizationFilterStatus.LitePageRedirect", 2); |
| histogram_tester.ExpectBucketCount( |
| "OptimizationGuide.OptimizationFilterStatus.LitePageRedirect", |
| optimization_guide::OptimizationFilterStatus::kCreatedServerFilter, 1); |
| histogram_tester.ExpectBucketCount( |
| "OptimizationGuide.OptimizationFilterStatus.LitePageRedirect", |
| optimization_guide::OptimizationFilterStatus::kFoundServerFilterConfig, |
| 1); |
| |
| // The previously loaded filter should still be loaded and give the same |
| // result. |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kFalse, |
| ogks->CanApplyOptimization( |
| GURL("https://blockedhost.com/whatever"), |
| optimization_guide::proto::FAST_HOST_HINTS, nullptr)); |
| histogram_tester.ExpectUniqueSample( |
| "OptimizationGuide.ApplyDecision.FastHostHints", |
| static_cast<int>(optimization_guide::OptimizationTypeDecision:: |
| kNotAllowedByOptimizationFilter), |
| 1); |
| } |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, IncognitoCanStillReadFromComponentHints) { |
| // Wait until initialization logic finishes running and component pushed to |
| // both incognito and regular browsers. |
| PushHintsComponentAndWaitForCompletion(); |
| |
| // Set up incognito browser state and incognito OptimizationGuideService |
| // consumer. |
| CreateOTRBrowserState(); |
| ChromeBrowserState* otr_browser_state = |
| browser_state_->GetOffTheRecordChromeBrowserState(); |
| |
| // Instantiate off the record Optimization Guide Service. |
| OptimizationGuideService* otr_ogs = |
| OptimizationGuideServiceFactory::GetForBrowserState(otr_browser_state); |
| otr_ogs->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT}); |
| // Wait until initialization has stabilized. |
| RunUntilIdle(); |
| |
| // Navigate to a URL that has a hint from a component and wait for that hint |
| // to have loaded. |
| base::HistogramTester histogram_tester; |
| NavigationContextAndData context_and_data(kHintsURL); |
| SimulateNavigationInBrowserState(&context_and_data, otr_ogs); |
| RetryForHistogramUntilCountReached(&histogram_tester, |
| "OptimizationGuide.LoadedHint.Result", 1); |
| |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kTrue, |
| otr_ogs->CanApplyOptimization( |
| GURL(kHintsURL), optimization_guide::proto::NOSCRIPT, nullptr)); |
| } |
| |
| TEST_F(OptimizationGuideServiceTest, IncognitoStillProcessesBloomFilter) { |
| PushHintsComponentAndWaitForCompletion(); |
| |
| // Set up incognito browser and incognito OptimizationGuideService |
| // consumer. |
| CreateOTRBrowserState(); |
| ChromeBrowserState* otr_browser_state = |
| browser_state_->GetOffTheRecordChromeBrowserState(); |
| |
| // Instantiate off the record Optimization Guide Service. |
| OptimizationGuideService* otr_ogs = |
| OptimizationGuideServiceFactory::GetForBrowserState(otr_browser_state); |
| base::HistogramTester histogram_tester; |
| |
| // Register an optimization type with an optimization filter. |
| otr_ogs->RegisterOptimizationTypes( |
| {optimization_guide::proto::FAST_HOST_HINTS}); |
| // Wait until filter is loaded. This histogram will record twice: once when |
| // the config is found and once when the filter is created. |
| RetryForHistogramUntilCountReached( |
| &histogram_tester, |
| "OptimizationGuide.OptimizationFilterStatus.FastHostHints", 2); |
| |
| EXPECT_EQ(optimization_guide::OptimizationGuideDecision::kFalse, |
| otr_ogs->CanApplyOptimization( |
| GURL("https://blockedhost.com/whatever"), |
| optimization_guide::proto::FAST_HOST_HINTS, nullptr)); |
| histogram_tester.ExpectUniqueSample( |
| "OptimizationGuide.ApplyDecision.FastHostHints", |
| static_cast<int>(optimization_guide::OptimizationTypeDecision:: |
| kNotAllowedByOptimizationFilter), |
| 1); |
| } |
| |
| class OptimizationGuideServiceMSBBUserTest |
| : public OptimizationGuideServiceTest { |
| public: |
| void SetUp() override { |
| SetUrlKeyedAnonymizedDataCollectionEnabled(true); |
| OptimizationGuideServiceTest::SetUp(); |
| } |
| }; |
| |
| TEST_F(OptimizationGuideServiceMSBBUserTest, RemoteFetchingEnabled) { |
| histogram_tester()->ExpectUniqueSample( |
| "OptimizationGuide.RemoteFetchingEnabled", true, 1); |
| // TODO(crbug.com/1240912): Verify the optimization guide fetching synthetic |
| // field trial is recorded. |
| } |