chromium/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.h"

#include <optional>

#include "base/containers/contains.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/raw_ptr.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/preloading/chrome_preloading.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/cache_alias_search_prefetch_url_loader.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/field_trial_settings.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_browser_test_base.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_factory.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h"
#include "chrome/browser/preloading/preloading_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/search_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/omnibox_controller.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
#include "components/omnibox/browser/omnibox_view.h"
#include "components/prefs/pref_service.h"
#include "components/search_engines/template_url_service.h"
#include "components/security_state/content/security_state_tab_helper.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/preloading.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/preloading_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/base/network_interfaces.h"
#include "net/base/url_util.h"
#include "net/test/embedded_test_server/http_request.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "services/network/public/mojom/clear_data_filter.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration_options.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"

NavigationPredictor;

namespace {

constexpr char kOmniboxSuggestPrefetchQuery[] =;
constexpr char kOmniboxSuggestNonPrefetchQuery[] =;
constexpr char kOmniboxErrorQuery[] =;
constexpr char kLoadInSubframe[] =;
constexpr char kClientHintsURL[] =;
constexpr char kThrottleHeader[] =;
constexpr char kThrottleHeaderValue[] =;
constexpr char kServiceWorkerUrl[] =;

UkmEntry;
Preloading_Attempt;
Preloading_Prediction;
static const auto kMockElapsedTime =;

// Since the result can be set upon Mojo disconnection, we have to wait until
// it to be reported.
void CheckCorrectForwardingResultMetric(
    base::HistogramTester& histogram_tester,
    StreamingSearchPrefetchURLLoader::ForwardingResult result,
    int count) {}

}  // namespace

// A delegate to cancel prefetch requests by setting |defer| to true.
class DeferringThrottle : public blink::URLLoaderThrottle {};

class ThrottleAllContentBrowserClient : public ChromeContentBrowserClient {};

// A delegate to cancel prefetch requests by calling cancel on |delegate_|.
class CancellingThrottle : public blink::URLLoaderThrottle {};

class CancelAllContentBrowserClient : public ChromeContentBrowserClient {};

// A delegate to add a custom header to prefetches.
class AddHeaderModifyingThrottle : public blink::URLLoaderThrottle {};

class AddHeaderContentBrowserClient : public ChromeContentBrowserClient {};

// A delegate to add a custom header to prefetches.
class AddQueryParamModifyingThrottle : public blink::URLLoaderThrottle {};

class AddQueryParamContentBrowserClient : public ChromeContentBrowserClient {};

// A delegate to add a custom header to prefetches.
class ChangeQueryModifyingThrottle : public blink::URLLoaderThrottle {};

class ChangeQueryContentBrowserClient : public ChromeContentBrowserClient {};

content::PreloadingFailureReason ToPreloadingFailureReason(
    SearchPrefetchServingReason reason) {}

class SearchPrefetchWithoutPrefetchingBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchWithoutPrefetchingBrowserTest,
                       NoFetchWhenPrefetchDisabled) {}

class SearchPrefetchHoldbackBrowserTest : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchHoldbackBrowserTest,
                       NoFetchInPrefetchHoldback) {}

// General test for standard behavior.  The interface bool represents whether
// the response can be served before headers.
class SearchPrefetchServiceEnabledBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ServiceNotCreatedWhenIncognito) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       BasicPrefetchFunctionality) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchThrottled) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchCancelledByThrottle) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchThrottleAddsHeader) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       QueryParamAddedInThrottle) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ChangeQueryCancelsPrefetch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest, SlowNetwork) {}

class HeaderObserverContentBrowserClient : public ChromeContentBrowserClient {};

std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
HeaderObserverContentBrowserClient::CreateURLLoaderThrottles(
    const network::ResourceRequest& request,
    content::BrowserContext* browser_context,
    const base::RepeatingCallback<content::WebContents*()>& wc_getter,
    content::NavigationUIData* navigation_ui_data,
    int frame_tree_node_id,
    std::optional<int64_t> navigation_id) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       HeadersNotReportedFromNetwork) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchRateLimiting) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       BasicClientHintsFunctionality) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       502PrefetchFunctionality) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       FetchSameTermsOnlyOnce) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest, BadURL) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PreloadDisabled) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       BasicPrefetchServed) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       BackPrefetchServed) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       BackPrefetchServedRefParam) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       BackPrefetchServedAfterPrefs) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       BackPrefetchServedAfterPrefsNoOverflow) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       EvictedCacheFallsback) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       RegularSearchQueryWhenNoPrefetch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NonMatchingPrefetchURL) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ErrorCausesNoFetch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       OmniboxEditTriggersPrefetch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       OmniboxURLHasPfParam) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       OmniboxEditDoesNotTriggersPrefetch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       OmniboxNavigateToMatchingEntryStreaming) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       HungRequestCanBeServed) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchServedBeforeHeaders) {}

// After search prefetch is activated, it can fallback to a real navigation
// request after it receives an invalid prefetch response.
IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchFallbackFromError) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchSecureSecurityState) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       PrefetchFallbackSecureSecurityState) {}

// Test LoadFromPrefs() when "cache_size" of kSearchPrefetchServicePrefetching
// is modified. The function should load at most N entries specified by the
// parameter regardless of the number of the entries actually stored in the
// prefs.
IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       SearchPrefetchMaxCacheEntries) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ClearCacheRemovesPrefetch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ClearCacheSearchRemovesPrefetch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ClearCacheOtherSavesCache) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ChangeDSESameOriginClearsPrefetches) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ChangeDSECrossOriginClearsPrefetches) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       ChangeDSESameDoesntClearPrefetches) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NoPrefetchWhenJSDisabled) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NoPrefetchWhenJSDisabledOnDSE) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NoServeWhenJSDisabled) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NoServeWhenJSDisabledOnDSE) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NoServeLinkClick) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest, NoServeReload) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest, NoServePost) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NoServeSideSearch) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       NoServeSideSearchImage) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       OnlyStreamedResponseCanServePartialRequest) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       DontInterceptSubframes) {}

void RunFirstParam(base::RepeatingClosure closure,
                   blink::ServiceWorkerStatusCode status) {}

// crbug.com/1272805
#if BUILDFLAG(IS_MAC)
#define MAYBE_ServiceWorkerServedPrefetchWithPreload
#else
#define MAYBE_ServiceWorkerServedPrefetchWithPreload
#endif
IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       MAYBE_ServiceWorkerServedPrefetchWithPreload) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest,
                       RequestTimingIsNonNegative) {}

class SearchPrefetchServiceBFCacheTest : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceBFCacheTest,
                       BackForwardPrefetchServedFromBFCache) {}

class SearchPrefetchServiceZeroCacheTimeBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceZeroCacheTimeBrowserTest,
                       ExpireAfterDuration) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceZeroCacheTimeBrowserTest,
                       PrefetchRateLimitingClearsAfterRemoval) {}

class SearchPrefetchServiceZeroErrorTimeBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceZeroErrorTimeBrowserTest,
                       ErrorClearedAfterDuration) {}

class SearchPrefetchServiceLowMemoryDeviceBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceLowMemoryDeviceBrowserTest,
                       NoFetchWhenLowMemoryDevice) {}

class GooglePFTest : public InProcessBrowserTest {};

IN_PROC_BROWSER_TEST_F(GooglePFTest, BaseGoogleSearchHasPFForPrefetch) {}

IN_PROC_BROWSER_TEST_F(GooglePFTest, BaseGoogleSearchNoPFForNonPrefetch) {}

class GooglePFTestFieldTrialOverride : public GooglePFTest {};

IN_PROC_BROWSER_TEST_F(GooglePFTestFieldTrialOverride,
                       BaseGoogleSearchHasPFForPrefetch) {}

class GooglePFTestDefaultFieldTrialValue : public GooglePFTest {};

IN_PROC_BROWSER_TEST_F(GooglePFTestDefaultFieldTrialValue,
                       BaseGoogleSearchHasPFForPrefetch) {}

class SearchPrefetchServiceNavigationPrefetchBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceNavigationPrefetchBrowserTest,
                       NavigationPrefetchIsServedMouseDown) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceNavigationPrefetchBrowserTest,
                       NavigationPrefetchIsServedArrowDown) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceNavigationPrefetchBrowserTest,
                       NavigationPrefetchIsServedTouchDown) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceNavigationPrefetchBrowserTest,
                       NavigationPrefetchDoesNotReplaceError) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceNavigationPrefetchBrowserTest,
                       NavigationPrefetchDoesntReplaceComplete) {}

IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceNavigationPrefetchBrowserTest,
                       DSEDoesNotAllowPrefetch) {}

// Test suite to check the PreloadingAttempt with prefetch_holdback.
class SearchNavigationPrefetchHoldbackBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchNavigationPrefetchHoldbackBrowserTest,
                       NoPrefetchInsideHoldback) {}

// Test suite to check that prefetches are not cancelled.
class SearchNavigationPrefetchNoCancelBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchNavigationPrefetchNoCancelBrowserTest,
                       PrefetchIsNotCancelled) {}

class SearchNavigationPrefetchDefaultMatchBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(SearchNavigationPrefetchDefaultMatchBrowserTest,
                       NotDefaultMatch) {}

// Test suite to check the AutocompleteDictionaryPreload feature.
class AutocompleteDictionaryPreloadBrowserTest
    : public SearchPrefetchBaseBrowserTest {};

IN_PROC_BROWSER_TEST_F(AutocompleteDictionaryPreloadBrowserTest,
                       PreloadDictionayAndDiscard) {}

IN_PROC_BROWSER_TEST_F(AutocompleteDictionaryPreloadBrowserTest,
                       NonHttpFamilyAreIgnored) {}

IN_PROC_BROWSER_TEST_F(AutocompleteDictionaryPreloadBrowserTest,
                       DoNotPreloadDictionayUnderMemoryPressure) {}

IN_PROC_BROWSER_TEST_F(AutocompleteDictionaryPreloadBrowserTest,
                       PreloadedDictionayDiscardedByMemoryPressure) {}