blob: 7e7067f2ae8fce57b83069b741c33cdb8ea76f2f [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/policy/content/proceed_until_response_navigation_throttle.h"
#include "base/memory/raw_ptr.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_navigation_throttle_inserter.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class EventExpectation final {
public:
EventExpectation() = default;
EventExpectation(const EventExpectation&) = delete;
EventExpectation& operator=(const EventExpectation&) = delete;
~EventExpectation() = default;
content::NavigationThrottle::ThrottleCheckResult WillStartRequest() {
EXPECT_TRUE(expect_will_start_request_);
visit_will_start_request_ = true;
return action_on_will_start_request_;
}
content::NavigationThrottle::ThrottleCheckResult WillRedirectRequest() {
EXPECT_TRUE(expect_will_redirect_request_);
visit_will_redirect_request_ = true;
return action_on_will_redirect_request_;
}
content::NavigationThrottle::ThrottleCheckResult WillProcessResponse() {
EXPECT_TRUE(expect_will_process_response_);
visit_will_process_response_ = true;
return action_on_will_process_response_;
}
void SetDeferredResultCallback(
const ProceedUntilResponseNavigationThrottle::DeferredResultCallback&
deferred_result_callback) {
deferred_result_callback_ = deferred_result_callback;
}
void ExpectWillStartRequest(
content::NavigationThrottle::ThrottleAction action =
content::NavigationThrottle::ThrottleAction::PROCEED) {
action_on_will_start_request_ = action;
expect_will_start_request_ = true;
}
void ExpectWillRedirectRequest(
content::NavigationThrottle::ThrottleAction action =
content::NavigationThrottle::ThrottleAction::PROCEED) {
action_on_will_redirect_request_ = action;
expect_will_redirect_request_ = true;
}
void ExpectWillProcessResponse(
content::NavigationThrottle::ThrottleAction action =
content::NavigationThrottle::ThrottleAction::PROCEED) {
action_on_will_process_response_ = action;
expect_will_process_response_ = true;
}
void CheckExpectations() {
EXPECT_EQ(expect_will_start_request_, visit_will_start_request_);
EXPECT_EQ(expect_will_redirect_request_, visit_will_redirect_request_);
EXPECT_EQ(expect_will_process_response_, visit_will_process_response_);
}
void Resolve(bool proceed,
std::optional<content::NavigationThrottle::ThrottleCheckResult>
result = std::nullopt) {
deferred_result_callback_.Run(proceed, result);
}
private:
bool expect_will_start_request_ = false;
bool expect_will_redirect_request_ = false;
bool expect_will_process_response_ = false;
bool visit_will_start_request_ = false;
bool visit_will_redirect_request_ = false;
bool visit_will_process_response_ = false;
content::NavigationThrottle::ThrottleAction action_on_will_start_request_ =
content::NavigationThrottle::ThrottleAction::PROCEED;
content::NavigationThrottle::ThrottleAction action_on_will_redirect_request_ =
content::NavigationThrottle::ThrottleAction::PROCEED;
content::NavigationThrottle::ThrottleAction action_on_will_process_response_ =
content::NavigationThrottle::ThrottleAction::PROCEED;
ProceedUntilResponseNavigationThrottle::DeferredResultCallback
deferred_result_callback_;
};
class EventMonitorNavigationThrottleClient final
: public ProceedUntilResponseNavigationThrottle::Client {
public:
EventMonitorNavigationThrottleClient(
content::NavigationThrottleRegistry& registry,
raw_ptr<EventExpectation> event_expectation)
: ProceedUntilResponseNavigationThrottle::Client(registry),
event_expectation_(event_expectation) {}
private:
// NavigationThrottle implementation:
ThrottleCheckResult WillStartRequest() override {
return event_expectation_->WillStartRequest();
}
ThrottleCheckResult WillRedirectRequest() override {
return event_expectation_->WillRedirectRequest();
}
ThrottleCheckResult WillProcessResponse() override {
return event_expectation_->WillProcessResponse();
}
const char* GetNameForLogging() override {
return "EventMonitorNavigationThrottle";
}
// ProceedUntilResponseNavigationThrottle::Client implementation:
void SetDeferredResultCallback(
const ProceedUntilResponseNavigationThrottle::DeferredResultCallback&
deferred_result_callback) override {
event_expectation_->SetDeferredResultCallback(deferred_result_callback);
}
raw_ptr<EventExpectation> event_expectation_;
};
} // namespace
class ProceedUntilResponseNavigationThrottleTest
: public content::RenderViewHostTestHarness {
public:
ProceedUntilResponseNavigationThrottleTest() = default;
ProceedUntilResponseNavigationThrottleTest(
const ProceedUntilResponseNavigationThrottleTest&) = delete;
ProceedUntilResponseNavigationThrottleTest& operator=(
const ProceedUntilResponseNavigationThrottleTest&) = delete;
~ProceedUntilResponseNavigationThrottleTest() override = default;
protected:
std::unique_ptr<content::NavigationSimulator> StartNavigation(
const GURL& url) {
auto navigation_simulator =
content::NavigationSimulator::CreateRendererInitiated(url, main_rfh());
auto throttle_inserter = std::make_unique<
content::TestNavigationThrottleInserter>(
web_contents(),
base::BindRepeating(
&ProceedUntilResponseNavigationThrottleTest::CreateAndAddThrottle,
base::Unretained(this)));
navigation_simulator->SetAutoAdvance(false);
navigation_simulator->Start();
return navigation_simulator;
}
EventExpectation& event_expectation() { return event_expectation_; }
private:
// content::RenderViewHostTestHarness implementation:
void SetUp() override {
content::RenderViewHostTestHarness::SetUp();
}
void CreateAndAddThrottle(content::NavigationThrottleRegistry& registry) {
std::unique_ptr<ProceedUntilResponseNavigationThrottle::Client>
monitor_throttle =
std::make_unique<EventMonitorNavigationThrottleClient>(
registry, &event_expectation_);
registry.AddThrottle(
std::make_unique<ProceedUntilResponseNavigationThrottle>(
registry, std::move(monitor_throttle), std::nullopt));
}
EventExpectation event_expectation_;
};
// Test a simple case, the internal throttle doesn't ask DEFER.
TEST_F(ProceedUntilResponseNavigationThrottleTest, Proceed) {
// Proceed on WillStartRequest.
event_expectation().ExpectWillStartRequest();
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Proceed on WillRedirectRequest.
event_expectation().ExpectWillRedirectRequest();
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Proceed on WillProcessResponse.
event_expectation().ExpectWillProcessResponse();
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_FALSE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a simplest case, the internal throttle doesn't ask DEFER, but CANCEL
// on WillStartRequest.
TEST_F(ProceedUntilResponseNavigationThrottleTest, CancelOnStartRequest) {
// Cancel on WillStartRequest.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::CANCEL);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a simplest case, the internal throttle doesn't ask DEFER, but CANCEL
// on WillRedirectRequest.
TEST_F(ProceedUntilResponseNavigationThrottleTest, CancelOnRedirectRequest) {
// Proceed on WillStartRequest.
event_expectation().ExpectWillStartRequest();
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Cancel on WillRedirectRequest.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::CANCEL);
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a simplest case, the internal throttle doesn't ask DEFER, but CANCEL
// on WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest, CancelOnProcessResponse) {
// Proceed on WillStartRequest.
event_expectation().ExpectWillStartRequest();
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Proceed on WillRedirectRequest.
event_expectation().ExpectWillRedirectRequest();
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Proceed on WillProcessResponse.
event_expectation().ExpectWillProcessResponse(
content::NavigationThrottle::CANCEL);
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request before WillRedirectRequest. It asks DEFER on WillRedirectRequest
// again and resumes the request before WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest, DeferOnStartAndRedirect) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().Resolve(/*proceed=*/true);
// Defer on WillRedirectRequest.
// This will be observed as PROCEED again in the throttle runner.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to proceed.
event_expectation().Resolve(/*proceed=*/true);
// Proceed on WillProcessResponse.
event_expectation().ExpectWillProcessResponse();
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_FALSE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request before WillRedirectRequest with a junk action, but intended to
// proceed.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndResolveToProceedWithJunkAction) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed, but with a junk action, `CANCEL`.
// If the `proceed` is true, the given action should be ignored.
event_expectation().Resolve(/*proceed=*/true,
content::NavigationThrottle::CANCEL);
// Proceed on WillProcessResponse.
event_expectation().ExpectWillProcessResponse();
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_FALSE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request to cancel before WillRedirectRequest.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndResolveToCancelOnRedirect) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to cancel.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
// Cancel on WillRedirectRequest without calling the internal throttle.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request to cancel before WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndResolveToCancelOnResponse) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to cancel.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
// Cancel on WillProcessResponse without calling the internal throttle.
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request before WillRedirectRequest. It asks DEFER on WillRedirectRequest
// again and resumes the request to cancel before WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndRedirectAndResolveRedirectToCancelBeforeResponse) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().Resolve(/*proceed=*/true);
// Defer on WillRedirectRequest.
// This will be observed as PROCEED again in the throttle runner.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to cancel.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
// Proceed on WillProcessResponse.
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request before WillRedirectRequest. It asks DEFER on WillRedirectRequest
// again and resumes the request after WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndRedirectAndResolveRedirectAfterResponse) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().Resolve(/*proceed=*/true);
// Defer on WillRedirectRequest.
// This will be observed as PROCEED again in the throttle runner.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Proceed later on WillProcessResponse, observed as DEFER without calling the
// internal throttle.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request.
event_expectation().ExpectWillProcessResponse(
content::NavigationThrottle::PROCEED);
event_expectation().Resolve(/*proceed=*/true);
EXPECT_FALSE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request before WillRedirectRequest. It asks DEFER on WillRedirectRequest
// again and resumes the request to cancel after WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndRedirectAndResolveRedirectToCancelAfterResponse) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().Resolve(/*proceed=*/true);
// Defer on WillRedirectRequest.
// This will be observed as PROCEED again in the throttle runner.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Proceed later on WillProcessResponse, observed as DEFER without calling the
// internal throttle.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to cancel.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request before WillRedirectRequest. It asks DEFER on WillRedirectRequest
// again and resumes the request after WillProcessResponse that will cancel.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndRedirectAndResolveRedirectAfterResponseToBeCanceled) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().Resolve(/*proceed=*/true);
// Defer on WillRedirectRequest.
// This will be observed as PROCEED again in the throttle runner.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Proceed later on WillProcessResponse, observed as DEFER without calling the
// internal throttle.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request, and the throttle cancel on
// WillProcessResponse.
event_expectation().ExpectWillProcessResponse(
content::NavigationThrottle::CANCEL);
event_expectation().Resolve(/*proceed=*/true);
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request to cancel after WillRedirectRequest.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndResolveToCancelAfterRedirect) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest without calling the internal throttle.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to cancel.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request after WillRedirectRequest that will cancel the request.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndResolveAfterRedirectToBeCanceled) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest without calling the internal throttle.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::CANCEL);
event_expectation().Resolve(/*proceed=*/true);
// Deferred cancel on the redirect will be resolved.
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request to cancel after WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndResolveToCancelAfterResponse) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillProcessResponse without calling the internal throttle.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to cancel.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and resumes
// the request after WillProcessResponse that will cancel the request.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferOnStartAndResolveAfterResponseToBeCanceled) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillProcessResponse without calling the internal throttle.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillProcessResponse(
content::NavigationThrottle::CANCEL);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and
// WillRedirectRequest again before it resumes the request. It resumes the
// request again before WillProcessResponse to proceed.
TEST_F(ProceedUntilResponseNavigationThrottleTest, DeferWithPending) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest again.
// This will be observed also as DEFER in the throttle runner.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to proceed.
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Proceed on WillProcessResponse.
event_expectation().ExpectWillProcessResponse();
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_FALSE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and
// WillRedirectRequest again before it resumes the request. It resumes the
// request again before WillProcessResponse to cancel.
TEST_F(ProceedUntilResponseNavigationThrottleTest, DeferWithPendingAndCancel) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest again.
// This will be observed also as DEFER in the throttle runner.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to proceed.
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Proceed on WillProcessResponse.
event_expectation().ExpectWillProcessResponse(
content::NavigationThrottle::CANCEL);
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::CANCEL,
navigation_simulator->GetLastThrottleCheckResult());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and
// WillRedirectRequest again before it resumes the request. It resumes the
// request to cancel again before WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferWithPendingAndResolveToCancel) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest again.
// This will be observed also as DEFER in the throttle runner.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to proceed.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Proceed on WillProcessResponse.
navigation_simulator->ReadyToCommit();
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and
// WillRedirectRequest again before it resumes the request. It resumes the
// request again after WillProcessResponse to proceed.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferWithPendingAndDeferResponse) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest again.
// This will be observed also as DEFER in the throttle runner.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Defer on WillProcessResponse.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to proceed.
event_expectation().ExpectWillProcessResponse();
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_FALSE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and
// WillRedirectRequest again before it resumes the request. It resumes the
// request again after WillProcessResponse to cancel.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferWithPendingAndResolveResponseToCancel) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest again.
// This will be observed also as DEFER in the throttle runner.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Defer on WillProcessResponse.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to proceed.
event_expectation().ExpectWillProcessResponse(
content::NavigationThrottle::CANCEL);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}
// Test a case, the internal throttle asks DEFER on WillStartRequest and
// WillRedirectRequest again before it resumes the request. It resumes the
// request to cancel again after WillProcessResponse.
TEST_F(ProceedUntilResponseNavigationThrottleTest,
DeferWithPendingAndResolveResponseAndCancel) {
// Defer on WillStartRequest.
// This will be observed as PROCEED in the throttle runner.
event_expectation().ExpectWillStartRequest(
content::NavigationThrottle::DEFER);
auto navigation_simulator = StartNavigation(GURL("http://example.com/"));
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_EQ(content::NavigationThrottle::PROCEED,
navigation_simulator->GetLastThrottleCheckResult());
event_expectation().CheckExpectations();
// Defer on WillRedirectRequest again.
// This will be observed also as DEFER in the throttle runner.
navigation_simulator->Redirect(GURL("http://alt.example.com/"));
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred request to proceed.
event_expectation().ExpectWillRedirectRequest(
content::NavigationThrottle::DEFER);
event_expectation().Resolve(/*proceed=*/true);
ASSERT_FALSE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Defer on WillProcessResponse.
navigation_simulator->ReadyToCommit();
ASSERT_TRUE(navigation_simulator->IsDeferred());
event_expectation().CheckExpectations();
// Resolve the deferred redirect request to cancel.
event_expectation().Resolve(/*proceed=*/false,
content::NavigationThrottle::CANCEL);
ASSERT_FALSE(navigation_simulator->IsDeferred());
EXPECT_TRUE(navigation_simulator->HasFailed());
event_expectation().CheckExpectations();
}