| Index: content/browser/download/download_manager_impl_unittest.cc
|
| diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc
|
| index 52933cae98f519541ead80fdd16eaca27e349a28..52ae849946ec979255b04d2567d8631ec310fbdb 100644
|
| --- a/content/browser/download/download_manager_impl_unittest.cc
|
| +++ b/content/browser/download/download_manager_impl_unittest.cc
|
| @@ -18,28 +18,42 @@
|
| #include "base/macros.h"
|
| #include "base/memory/weak_ptr.h"
|
| #include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| #include "base/stl_util.h"
|
| #include "base/strings/string16.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "build/build_config.h"
|
| #include "content/browser/byte_stream.h"
|
| +#include "content/browser/child_process_security_policy_impl.h"
|
| #include "content/browser/download/download_create_info.h"
|
| #include "content/browser/download/download_file_factory.h"
|
| #include "content/browser/download/download_item_factory.h"
|
| #include "content/browser/download/download_item_impl.h"
|
| #include "content/browser/download/download_item_impl_delegate.h"
|
| #include "content/browser/download/download_request_handle.h"
|
| +#include "content/browser/download/download_resource_handler.h"
|
| #include "content/browser/download/mock_download_file.h"
|
| +#include "content/browser/loader/resource_dispatcher_host_impl.h"
|
| #include "content/public/browser/browser_context.h"
|
| #include "content/public/browser/download_interrupt_reasons.h"
|
| #include "content/public/browser/download_item.h"
|
| #include "content/public/browser/download_manager_delegate.h"
|
| +#include "content/public/browser/render_frame_host.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#include "content/public/browser/resource_context.h"
|
| +#include "content/public/browser/site_instance.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/browser/web_contents_observer.h"
|
| #include "content/public/browser/zoom_level_delegate.h"
|
| #include "content/public/test/mock_download_item.h"
|
| #include "content/public/test/test_browser_context.h"
|
| #include "content/public/test/test_browser_thread.h"
|
| +#include "content/public/test/test_browser_thread_bundle.h"
|
| #include "net/log/net_log.h"
|
| +#include "net/url_request/url_request_job_factory.h"
|
| +#include "net/url_request/url_request_test_job.h"
|
| +#include "net/url_request/url_request_test_util.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gmock_mutant.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -793,4 +807,205 @@ TEST_F(DownloadManagerTest, RemoveDownloadsByURL) {
|
| EXPECT_EQ(remove_count, 1);
|
| }
|
|
|
| +// For verifying notifications sent to the WebContents.
|
| +class TestDownloadWebContentsObserver : public WebContentsObserver {
|
| + public:
|
| + explicit TestDownloadWebContentsObserver(WebContents* web_contents)
|
| + : WebContentsObserver(web_contents),
|
| + resource_request_redirect_count_(0),
|
| + resource_response_start_count_(0) {}
|
| +
|
| + void DidGetRedirectForResourceRequest(
|
| + RenderFrameHost* render_frame_host,
|
| + const ResourceRedirectDetails& details) override {
|
| + ++resource_request_redirect_count_;
|
| + }
|
| +
|
| + void DidGetResourceResponseStart(
|
| + const ResourceRequestDetails& details) override {
|
| + ++resource_response_start_count_;
|
| + }
|
| +
|
| + int resource_request_redirect_count() {
|
| + return resource_request_redirect_count_;
|
| + }
|
| +
|
| + int resource_response_start_count() { return resource_response_start_count_; }
|
| +
|
| + private:
|
| + int resource_request_redirect_count_;
|
| + int resource_response_start_count_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestDownloadWebContentsObserver);
|
| +};
|
| +
|
| +// Intercepts URLRequests and returns an instance of URLRequestTestJob for
|
| +// handling these requests if the scheme is a supported scheme.
|
| +class TestDownloadURLRequestFactory : public net::URLRequestJobFactory {
|
| + public:
|
| + explicit TestDownloadURLRequestFactory() {}
|
| +
|
| + void HandleScheme(const std::string& scheme) {
|
| + supported_schemes_.insert(scheme);
|
| + }
|
| +
|
| + net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
|
| + const std::string& scheme,
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate) const override {
|
| + if (!IsHandledProtocol(scheme))
|
| + return nullptr;
|
| + return new net::URLRequestTestJob(request, network_delegate, false);
|
| + }
|
| +
|
| + net::URLRequestJob* MaybeInterceptRedirect(
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate,
|
| + const GURL& location) const override {
|
| + return nullptr;
|
| + }
|
| +
|
| + net::URLRequestJob* MaybeInterceptResponse(
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate) const override {
|
| + return nullptr;
|
| + }
|
| +
|
| + bool IsHandledProtocol(const std::string& scheme) const override {
|
| + return supported_schemes_.count(scheme) > 0;
|
| + }
|
| +
|
| + bool IsHandledURL(const GURL& url) const override {
|
| + return supported_schemes_.count(url.scheme()) > 0;
|
| + }
|
| +
|
| + bool IsSafeRedirectTarget(const GURL& location) const override {
|
| + return false;
|
| + }
|
| +
|
| + private:
|
| + std::set<std::string> supported_schemes_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestDownloadURLRequestFactory);
|
| +};
|
| +
|
| +// This class provides functionality for testing downloads initiated via URL
|
| +// navigations.
|
| +class DownloadRequestTest : public testing::Test {
|
| + public:
|
| + DownloadRequestTest()
|
| + : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
|
| + host_(base::Bind(&DownloadResourceHandler::Create)) {
|
| + browser_context_.reset(new TestBrowserContext());
|
| + BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + ~DownloadRequestTest() override {}
|
| +
|
| + // testing::Test overrides.
|
| + void SetUp() override {
|
| + // Boiler plate code necessary to initiate end to end navigations.
|
| + ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
|
| + scoped_refptr<SiteInstance> site_instance =
|
| + SiteInstance::Create(browser_context_.get());
|
| + web_contents_.reset(
|
| + WebContents::Create(WebContents::CreateParams(browser_context_.get())));
|
| + web_contents_observer_.reset(
|
| + new TestDownloadWebContentsObserver(web_contents_.get()));
|
| + child_ids_.insert(web_contents_->GetRenderProcessHost()->GetID());
|
| + net::URLRequestContext* request_context =
|
| + browser_context_->GetResourceContext()->GetRequestContext();
|
| + job_factory_.reset(new TestDownloadURLRequestFactory());
|
| + request_context->set_job_factory(job_factory_.get());
|
| + request_context->set_network_delegate(&network_delegate_);
|
| + HandleScheme("test");
|
| + }
|
| +
|
| + void TearDown() override {
|
| + web_contents_observer_.reset();
|
| + web_contents_.reset();
|
| +
|
| + for (std::set<int>::iterator it = child_ids_.begin();
|
| + it != child_ids_.end(); ++it) {
|
| + host_.CancelRequestsForProcess(*it);
|
| + }
|
| +
|
| + host_.Shutdown();
|
| +
|
| + ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
|
| +
|
| + // Flush the message loop to make application verifiers happy.
|
| + if (ResourceDispatcherHostImpl::Get()) {
|
| + ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
|
| + browser_context_->GetResourceContext());
|
| + }
|
| +
|
| + browser_context_.reset();
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + // Intercepts requests for the given protocol.
|
| + void HandleScheme(const std::string& scheme) {
|
| + job_factory_->HandleScheme(scheme);
|
| + ChildProcessSecurityPolicyImpl* policy =
|
| + ChildProcessSecurityPolicyImpl::GetInstance();
|
| + if (!policy->IsWebSafeScheme(scheme))
|
| + policy->RegisterWebSafeScheme(scheme);
|
| + }
|
| +
|
| + void InitiateDownloadRequest(int request_id, const GURL& url) {
|
| + net::URLRequestContext* request_context =
|
| + browser_context_->GetResourceContext()->GetRequestContext();
|
| + std::unique_ptr<net::URLRequest> request(
|
| + request_context->CreateRequest(url, net::DEFAULT_PRIORITY, NULL));
|
| +
|
| + DownloadManagerImpl::BeginDownloadRequest(
|
| + std::move(request), Referrer(), browser_context_->GetResourceContext(),
|
| + false, // is_content_initiated
|
| + web_contents_->GetRenderProcessHost()->GetID(),
|
| + web_contents_->GetRoutingID(),
|
| + web_contents_->GetMainFrame()->GetRoutingID(), false);
|
| + }
|
| +
|
| + protected:
|
| + // The thread_bundle_ needs to be the first in the list of members to
|
| + // ensure that the BrowserThread globals are initialized.
|
| + content::TestBrowserThreadBundle thread_bundle_;
|
| + ResourceDispatcherHostImpl host_;
|
| + std::unique_ptr<TestBrowserContext> browser_context_;
|
| + std::unique_ptr<TestDownloadURLRequestFactory> job_factory_;
|
| + net::TestNetworkDelegate network_delegate_;
|
| + std::unique_ptr<WebContents> web_contents_;
|
| + std::unique_ptr<TestDownloadWebContentsObserver> web_contents_observer_;
|
| + // List of child ids granted access via policy.
|
| + std::set<int> child_ids_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DownloadRequestTest);
|
| +};
|
| +
|
| +// Confirm that resource response started notifications for downloads are not
|
| +// transmitted to the WebContents.
|
| +TEST_F(DownloadRequestTest, TransferResponseStartedDownload) {
|
| + int initial_count(web_contents_observer_->resource_response_start_count());
|
| +
|
| + InitiateDownloadRequest(1, net::URLRequestTestJob::test_url_1());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(initial_count,
|
| + web_contents_observer_->resource_response_start_count());
|
| +}
|
| +
|
| +// Confirm that request redirected notifications for downloads are not
|
| +// transmitted to the WebContents.
|
| +TEST_F(DownloadRequestTest, TransferRequestRedirectedDownload) {
|
| + int initial_count(web_contents_observer_->resource_request_redirect_count());
|
| +
|
| + InitiateDownloadRequest(1,
|
| + net::URLRequestTestJob::test_url_redirect_to_url_2());
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(initial_count,
|
| + web_contents_observer_->resource_request_redirect_count());
|
| +}
|
| +
|
| } // namespace content
|
|
|