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()); |
+} |
+ |
Randy Smith (Not in Mondays)
2016/08/25 20:58:50
Wow, I'm sorry, I guess I'm doing a poor job of ex
ananta
2016/08/25 22:20:50
Based on our discussion, keeping the test in resou
|
} // namespace content |