chromium/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_unittest.cc

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

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <memory>
#include <set>
#include <utility>

#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/with_feature_override.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/loading_predictor_factory.h"
#include "chrome/browser/predictors/loading_test_util.h"
#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_unit_test_utils.h"
#include "chrome/browser/preloading/preloading_prefs.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_contents.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_field_trial.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_handle.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_link_manager.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
#include "components/no_state_prefetch/common/no_state_prefetch_origin.h"
#include "components/no_state_prefetch/common/no_state_prefetch_utils.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "net/base/network_change_notifier.h"
#include "net/http/http_cache.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"

Time;
TimeTicks;
Referrer;

namespace prerender {

namespace {

class TestNetworkBytesChangedObserver
    : public prerender::NoStatePrefetchHandle::Observer {};

const gfx::Size kDefaultViewSize(640, 480);

}  // namespace

class MockNetworkChangeNotifier4GMetered : public net::NetworkChangeNotifier {};

class MockNetworkChangeNotifier4GUnmetered : public net::NetworkChangeNotifier {};

class MockNetworkChangeNotifierWifiMetered : public net::NetworkChangeNotifier {};

class NoStatePrefetchTest : public testing::Test {};

TEST_F(NoStatePrefetchTest, RespectsThirdPartyCookiesPref) {}

class NoStatePrefetchGWSPrefetchHoldbackTest : public NoStatePrefetchTest {};

TEST_F(NoStatePrefetchGWSPrefetchHoldbackTest,
       GWSPrefetchHoldbackNonGWSSReferrer) {}

TEST_F(NoStatePrefetchGWSPrefetchHoldbackTest, GWSPrefetchHoldbackGWSReferrer) {}

class NoStatePrefetchGWSPrefetchHoldbackOffTest : public NoStatePrefetchTest {};

TEST_F(NoStatePrefetchGWSPrefetchHoldbackOffTest,
       GWSPrefetchHoldbackOffNonGWSReferrer) {}

TEST_F(NoStatePrefetchGWSPrefetchHoldbackOffTest,
       GWSPrefetchHoldbackOffGWSReferrer) {}

class PrerendererNavigationPredictorPrefetchHoldbackTest
    : public NoStatePrefetchTest {};

TEST_F(PrerendererNavigationPredictorPrefetchHoldbackTest,
       PredictorPrefetchHoldbackNonPredictorReferrer) {}

// Verify that link-rel:next URLs are not prefetched.
TEST_F(NoStatePrefetchTest, LinkRelNextWithNSPDisabled) {}

class PrerendererNavigationPredictorPrefetchHoldbackDisabledTest
    : public NoStatePrefetchTest {};

TEST_F(PrerendererNavigationPredictorPrefetchHoldbackDisabledTest,
       PredictorPrefetchHoldbackOffNonPredictorReferrer) {}

// Flaky on Android and Mac, crbug.com/1087876.
TEST_F(NoStatePrefetchTest, DISABLED_PrerenderDisabledOnLowEndDevice) {}

TEST_F(NoStatePrefetchTest, FoundTest) {}

// Flaky on Android, crbug.com/1088454.
// Make sure that if queue a request, and a second prerender request for the
// same URL comes in, that the second request attaches to the first prerender,
// and we don't use the second prerender contents.
// This test is the same as the "DuplicateTest" above, but for NoStatePrefetch.
TEST_F(NoStatePrefetchTest, DISABLED_DuplicateTest_NoStatePrefetch) {}

// Ensure that we expire a prerendered page after the max. permitted time.
TEST_F(NoStatePrefetchTest, ExpireTest) {}

// Ensure that we don't launch prerenders of bad urls (in this case, a mailto:
// url)
TEST_F(NoStatePrefetchTest, BadURLTest) {}

// When the user navigates away from a page, the prerenders it launched should
// have their time to expiry shortened from the default time to live.
TEST_F(NoStatePrefetchTest, LinkManagerNavigateAwayExpire) {}

// But when we navigate away very close to the original expiry of a prerender,
// we shouldn't expect it to be extended.
TEST_F(NoStatePrefetchTest, LinkManagerNavigateAwayNearExpiry) {}

// When the user navigates away from a page, and then launches a new prerender,
// the new prerender should preempt the abandoned prerender even if the
// abandoned prerender hasn't expired.
TEST_F(NoStatePrefetchTest, LinkManagerNavigateAwayLaunchAnother) {}

// Prefetching the same URL twice during |time_to_live| results in a duplicate
// and is aborted.
TEST_F(NoStatePrefetchTest, NoStatePrefetchDuplicate) {}

// Make sure that if we prerender more requests than we support, that we launch
// them in the order given up until we reach MaxConcurrency, at which point we
// queue them and launch them in the order given. As well, insure that limits
// are enforced for the system as a whole and on a per launcher basis.
TEST_F(NoStatePrefetchTest, MaxConcurrencyTest) {}

// Flaky on Android: https://crbug.com/1105908
TEST_F(NoStatePrefetchTest, DISABLED_AliasURLTest) {}

// Tests that prerendering is cancelled when the source render view does not
// exist.  On failure, the DCHECK in CreateNoStatePrefetchContents() above
// should be triggered.
TEST_F(NoStatePrefetchTest, SourceRenderViewClosed) {}

// Tests that prerendering is cancelled when we launch a second prerender of
// the same target within a short time interval.
TEST_F(NoStatePrefetchTest, RecentlyVisited) {}

TEST_F(NoStatePrefetchTest, NotSoRecentlyVisited) {}

// Tests that the prerender manager matches include the fragment.
TEST_F(NoStatePrefetchTest, FragmentMatchesTest) {}

// Tests that the prerender manager uses fragment references when matching
// prerender URLs in the case a different fragment is in both URLs.
TEST_F(NoStatePrefetchTest, FragmentsDifferTest) {}

// Make sure that clearing works as expected.
TEST_F(NoStatePrefetchTest, ClearTest) {}

// Make sure canceling works as expected.
TEST_F(NoStatePrefetchTest, CancelAllTest) {}

class NoStatePrefetchFallbackToPreconnectTest
    : public base::test::WithFeatureOverride,
      public NoStatePrefetchTest {};

INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE();

// Test that when prefetch fails and ...
// - the kPrerenderFallbackToPreconnect experiment is not enabled, a prefetch
//   initiated by <link rel=prerender> does not result in a preconnect.
// - the kPrerenderFallbackToPreconnect experiment is enabled, a prefetch
//   initiated by <link rel=prerender> actually results in preconnect.
TEST_P(NoStatePrefetchFallbackToPreconnectTest, LinkRelPrerender) {}

TEST_F(NoStatePrefetchTest, LinkRelStillAllowedWhenDisabled) {}

TEST_F(NoStatePrefetchTest, LinkRelAllowedOnCellular) {}

TEST_F(NoStatePrefetchTest, LinkManagerCancel) {}

TEST_F(NoStatePrefetchTest, LinkManagerAbandon) {}

TEST_F(NoStatePrefetchTest, LinkManagerAbandonThenCancel) {}

// Flaky on Android, crbug.com/1087876.
// Flaky on Mac and Linux, crbug.com/1087735.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
    BUILDFLAG(IS_CHROMEOS)
#define MAYBE_LinkManagerAddTwiceCancelTwice
#else
#define MAYBE_LinkManagerAddTwiceCancelTwice
#endif
TEST_F(NoStatePrefetchTest, MAYBE_LinkManagerAddTwiceCancelTwice) {}

// TODO(gavinp): Update this test after abandon has an effect on Prerenders,
// like shortening the timeouts.
// Flaky on Android and Linux, crbug.com/1087876 & crbug.com/1087736.
TEST_F(NoStatePrefetchTest, DISABLED_LinkManagerAddTwiceAbandonTwiceUseTwice) {}

// TODO(gavinp): After abandon shortens the expire time on a Prerender,
// add a series of tests testing advancing the time by either the abandon
// or normal expire, and verifying the expected behaviour with groups
// of links.
TEST_F(NoStatePrefetchTest, LinkManagerExpireThenCancel) {}

TEST_F(NoStatePrefetchTest, LinkManagerExpireThenAddAgain) {}

// Flaky on Android, crbug.com/1087876.
TEST_F(NoStatePrefetchTest, DISABLED_LinkManagerCancelThenAddAgain) {}

// Creates two prerenders, one of which should be blocked by the
// max_link_concurrency; abandons both of them and waits to make sure both
// are cleared from the NoStatePrefetchLinkManager.
TEST_F(NoStatePrefetchTest, DISABLED_LinkManagerAbandonInactivePrerender) {}

// Creates two prerenders, one of which should be blocked by the
// max_link_concurrency; uses one after the max wait to launch, and
// ensures the second prerender does not start.
TEST_F(NoStatePrefetchTest, LinkManagerWaitToLaunchNotLaunched) {}

// Creates two prerenders, one of which should start when the first one expires.
TEST_F(NoStatePrefetchTest, LinkManagerExpireRevealingLaunch) {}

TEST_F(NoStatePrefetchTest, NoStatePrefetchContentsIsValidHttpMethod) {}

TEST_F(NoStatePrefetchTest, NoPrerenderInSingleProcess) {}

}  // namespace prerender