blob: 89bf250acf140162b42fb13c9690182c30adfa35 [file] [log] [blame]
// Copyright 2016 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 "base/bind.h"
#include "base/run_loop.h"
#include "components/web_restrictions/browser/mock_web_restrictions_client.h"
#include "components/web_restrictions/browser/web_restrictions_client.h"
#include "components/web_restrictions/browser/web_restrictions_resource_throttle.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/net_errors.h"
#include "net/url_request/redirect_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace web_restrictions {
namespace {
class TestResourceThrottleDelegate
: public content::ResourceThrottle::Delegate {
public:
TestResourceThrottleDelegate(const base::Closure& quit_closure)
: resume_called_(false),
cancel_with_error_called_(false),
error_code_(0),
quit_closure_(quit_closure) {}
void Cancel() override {}
void CancelWithError(int error_code) override {
cancel_with_error_called_ = true;
error_code_ = error_code;
quit_closure_.Run();
}
void Resume() override {
resume_called_ = true;
quit_closure_.Run();
}
bool CancelWithErrorCalled() const { return cancel_with_error_called_; }
int GetErrorCode() const { return error_code_; }
bool ResumeCalled() const { return resume_called_; }
private:
bool resume_called_;
bool cancel_with_error_called_;
int error_code_;
base::Closure quit_closure_;
};
} // namespace
class WebRestrictionsResourceThrottleTest : public testing::Test {
protected:
WebRestrictionsResourceThrottleTest()
: throttle_(&provider_, GURL("http://example.com"), true),
delegate_(run_loop_.QuitClosure()) {
throttle_.set_delegate_for_testing(&delegate_);
}
void SetAuthority(std::string authority) {
provider_.SetAuthorityTask(authority);
}
void StartProvider() {
SetAuthority("Good");
bool defer;
throttle_.WillStartRequest(&defer);
run_loop_.Run();
}
// Mock the Java WebRestrictionsClient. The real version
// would need a content provider to do anything.
web_restrictions::MockWebRestrictionsClient mock_;
content::TestBrowserThreadBundle thread_bundle_;
WebRestrictionsClient provider_;
WebRestrictionsResourceThrottle throttle_;
base::RunLoop run_loop_;
TestResourceThrottleDelegate delegate_;
};
TEST_F(WebRestrictionsResourceThrottleTest, WillStartRequest_NoAuthority) {
WebRestrictionsResourceThrottle throttle(&provider_,
GURL("http://example.com"), true);
bool defer;
throttle.WillStartRequest(&defer);
// If there is no authority the request won't be deferred.
EXPECT_FALSE(defer);
}
TEST_F(WebRestrictionsResourceThrottleTest, WillStartRequest_DeferredAllow) {
// Test deferring with a resource provider, and that the correct results
// are received.
SetAuthority("Good");
bool defer;
throttle_.WillStartRequest(&defer);
EXPECT_TRUE(defer);
run_loop_.Run();
EXPECT_TRUE(delegate_.ResumeCalled());
EXPECT_FALSE(delegate_.CancelWithErrorCalled());
}
TEST_F(WebRestrictionsResourceThrottleTest, WillStartRequest_DeferredForbid) {
SetAuthority("Bad");
bool defer;
throttle_.WillStartRequest(&defer);
EXPECT_TRUE(defer);
run_loop_.Run();
EXPECT_FALSE(delegate_.ResumeCalled());
EXPECT_TRUE(delegate_.CancelWithErrorCalled());
EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR, delegate_.GetErrorCode());
}
#if defined(OS_ANDROID)
// Flaky on android: https://crbug.com/718066
#define MAYBE_WillStartRequest_Subresource DISABLED_WillStartRequest_Subresource
#else
#define MAYBE_WillStartRequest_Subresource WillStartRequest_Subresource
#endif
TEST_F(WebRestrictionsResourceThrottleTest,
MAYBE_WillStartRequest_Subresource) {
// Only the main frame should be deferred.
// Initialization of the delegate is asynchronous, and this will only work
// correctly if the provider is initialized. Run a main frame through this
// first to ensure that everything is initialized.
StartProvider();
// Now the real test.
WebRestrictionsResourceThrottle throttle(
&provider_, GURL("http://example.com/sub"), false);
base::RunLoop test_run_loop;
TestResourceThrottleDelegate test_delegate(test_run_loop.QuitClosure());
throttle.set_delegate_for_testing(&test_delegate);
bool defer;
throttle.WillStartRequest(&defer);
ASSERT_FALSE(defer);
}
TEST_F(WebRestrictionsResourceThrottleTest, WillRedirectRequest_KnownUrl) {
// Set up a cached url.
StartProvider();
// Using the same URL should not be deferred
net::RedirectInfo redirect;
redirect.new_url = GURL("http://example.com");
bool defer;
throttle_.WillRedirectRequest(redirect, &defer);
ASSERT_FALSE(defer);
}
TEST_F(WebRestrictionsResourceThrottleTest, WillRedirectRequest_NewUrl) {
// Set up a cached url.
StartProvider();
// Using a different URL should be deferred
net::RedirectInfo redirect;
redirect.new_url = GURL("http://example.com/2");
base::RunLoop test_run_loop;
TestResourceThrottleDelegate test_delegate(test_run_loop.QuitClosure());
throttle_.set_delegate_for_testing(&test_delegate);
bool defer;
throttle_.WillRedirectRequest(redirect, &defer);
ASSERT_TRUE(defer);
// If we don't wait for the callback it may happen after the exit, which
// results in accesses the redirect_url after the stack frame is freed.
test_run_loop.Run();
}
} // namespace web_restrictions