Index: chrome/browser/renderer_host/ignore_navigation_resource_throttle_unittest.cc |
diff --git a/chrome/browser/renderer_host/ignore_navigation_resource_throttle_unittest.cc b/chrome/browser/renderer_host/ignore_navigation_resource_throttle_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..43aa3fe44fa4a7281a50803337e1183518d1e730 |
--- /dev/null |
+++ b/chrome/browser/renderer_host/ignore_navigation_resource_throttle_unittest.cc |
@@ -0,0 +1,255 @@ |
+// Copyright (c) 2012 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/bind_helpers.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/memory/scoped_vector.h" |
+#include "chrome/browser/renderer_host/ignore_navigation_resource_throttle.h" |
+#include "chrome/test/base/chrome_render_view_host_test_harness.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/resource_context.h" |
+#include "content/public/browser/resource_dispatcher_host.h" |
+#include "content/public/browser/resource_dispatcher_host_delegate.h" |
+#include "content/public/browser/resource_request_info.h" |
+#include "content/public/browser/resource_throttle.h" |
+#include "content/public/browser/resource_throttle_controller.h" |
+#include "content/public/browser/web_contents.h" |
+#include "content/public/browser/web_contents_delegate.h" |
+#include "content/test/mock_resource_context.h" |
+#include "content/test/test_browser_thread.h" |
+#include "content/test/net/url_request_user_data_helper.h" |
+#include "net/url_request/url_request.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using namespace content; |
+using namespace ::testing; |
+ |
+namespace { |
+ |
+const char* kTestUrl = "http://www.test.com/"; |
+ |
+void ContinueTestCase() { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ MessageLoop::QuitClosure()); |
+} |
+ |
+} // namespace |
+ |
+// MockWebContentsDelegate ---------------------------------------------------- |
+ |
+class MockWebContentsDelegate : public content::WebContentsDelegate { |
+ public: |
+ MOCK_METHOD4(ShouldIgnoreNavigation, bool(WebContents* source, |
+ const GURL& url, |
+ const content::Referrer& referrer, |
+ bool is_content_initiated)); |
+}; |
+ |
+// MockResourceThrottleController |
+class MockResourceThrottleController |
+ : public content::ResourceThrottleController { |
+ public: |
+ enum Status { |
+ UNKNOWN, |
+ RESUMED, |
+ CANCELLED |
+ }; |
+ |
+ MockResourceThrottleController() |
+ : status_(UNKNOWN) { |
+ } |
+ |
+ Status status() const { return status_; } |
+ |
+ // content::ResourceThrottleController |
+ virtual void Cancel() { |
+ DCHECK(status_ == UNKNOWN); |
+ status_ = CANCELLED; |
+ ContinueTestCase(); |
+ } |
+ virtual void Resume() { |
+ DCHECK(status_ == UNKNOWN); |
+ status_ = RESUMED; |
+ ContinueTestCase(); |
+ } |
+ |
+ private: |
+ Status status_; |
+}; |
+ |
+// TestIOThreadState ---------------------------------------------------------- |
+ |
+class TestIOThreadState { |
+ public: |
+ TestIOThreadState(int render_process_id, int render_view_id) |
+ : request_(GURL(kTestUrl), NULL), |
+ throttle_(&request_) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ ResourceRequestInfo::AllocateForTesting(&request_, |
+ ResourceType::MAIN_FRAME, |
+ &resource_context_); |
+ if (render_process_id != MSG_ROUTING_NONE && |
+ render_view_id != MSG_ROUTING_NONE) { |
+ URLRequestUserDataHelper::AssociateWithRenderView( |
+ &request_, render_process_id, render_view_id); |
+ } else { |
+ URLRequestUserDataHelper::DissasociateFromRenderView(&request_); |
+ } |
+ throttle_.set_controller_for_testing(&throttle_controller_); |
+ } |
+ |
+ void ThrottleWillStartRequest(bool* defer) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ throttle_.WillStartRequest(defer); |
+ } |
+ |
+ bool request_resumed() const { |
+ return throttle_controller_.status() == |
+ MockResourceThrottleController::RESUMED; |
+ } |
+ |
+ bool request_cancelled() const { |
+ return throttle_controller_.status() == |
+ MockResourceThrottleController::CANCELLED; |
+ } |
+ |
+ private: |
+ content::MockResourceContext resource_context_; |
+ net::URLRequest request_; |
+ IgnoreNavigationResourceThrottle throttle_; |
+ MockResourceThrottleController throttle_controller_; |
+}; |
+ |
+// IgnoreNavigationResourceThrottleTest --------------------------------------- |
+ |
+class IgnoreNavigationResourceThrottleTest |
+ : public ChromeRenderViewHostTestHarness { |
+ public: |
+ IgnoreNavigationResourceThrottleTest() |
+ : ui_thread_(BrowserThread::UI, &message_loop_), |
+ io_thread_(BrowserThread::IO), |
+ io_thread_state_(NULL) { |
+ } |
+ |
+ virtual void SetUp() OVERRIDE { |
+ ChromeRenderViewHostTestHarness::SetUp(); |
+ |
+ io_thread_.StartIOThread(); |
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ web_contents()->SetDelegate(NULL); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&base::DeletePointer<TestIOThreadState>, io_thread_state_)); |
+ |
+ ChromeRenderViewHostTestHarness::TearDown(); |
+ } |
+ |
+ void SetIOThreadState(TestIOThreadState* io_thread_state) { |
+ io_thread_state_ = io_thread_state; |
+ } |
+ |
+ void RunThrottleWillStartRequestOnIOThread( |
+ int render_process_id, |
+ int render_view_id, |
+ bool* defer) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ TestIOThreadState* io_thread_state = |
+ new TestIOThreadState(render_process_id, render_view_id); |
+ |
+ SetIOThreadState(io_thread_state); |
+ io_thread_state->ThrottleWillStartRequest(defer); |
+ |
+ if (!*defer) { |
+ ContinueTestCase(); |
+ } |
+ } |
+ |
+ protected: |
+ enum ShouldIgnoreNavigationCallbackAction { |
+ IgnoreNavigation, |
+ DontIgnoreNavigation |
+ }; |
+ |
+ void SetUpWebContentsDelegateAndRunMessageLoop( |
+ ShouldIgnoreNavigationCallbackAction callback_action, |
+ bool* defer) { |
+ scoped_ptr<MockWebContentsDelegate> web_contents_delegate( |
+ new MockWebContentsDelegate()); |
+ EXPECT_FALSE(web_contents()->GetDelegate()); |
+ web_contents()->SetDelegate(web_contents_delegate.get()); |
+ |
+ ON_CALL(*web_contents_delegate, |
+ ShouldIgnoreNavigation(_, Eq(GURL(kTestUrl)), _, _)) |
+ .WillByDefault(Return(callback_action == IgnoreNavigation)); |
+ EXPECT_CALL(*web_contents_delegate, |
+ ShouldIgnoreNavigation(_, Eq(GURL(kTestUrl)), _, _)) |
+ .Times(1); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind( |
+ &IgnoreNavigationResourceThrottleTest:: |
+ RunThrottleWillStartRequestOnIOThread, |
+ base::Unretained(this), |
+ contents()->GetRenderViewHost()->GetProcess()->GetID(), |
+ contents()->GetRenderViewHost()->GetRoutingID(), |
+ base::Unretained(defer))); |
+ |
+ // Wait for the request to finish processing. |
+ message_loop_.Run(); |
+ } |
+ |
+ content::TestBrowserThread ui_thread_; |
+ content::TestBrowserThread io_thread_; |
+ TestIOThreadState* io_thread_state_; |
+}; |
+ |
+TEST_F(IgnoreNavigationResourceThrottleTest, |
+ RequestDeferredAndResumedIfNavigationNotIgnored) { |
+ bool defer = false; |
+ SetUpWebContentsDelegateAndRunMessageLoop(DontIgnoreNavigation, &defer); |
+ |
+ EXPECT_TRUE(defer); |
+ EXPECT_TRUE(io_thread_state_); |
+ EXPECT_TRUE(io_thread_state_->request_resumed()); |
+} |
+ |
+TEST_F(IgnoreNavigationResourceThrottleTest, |
+ RequestDeferredAndCancelledIfNavigationIgnored) { |
+ bool defer = false; |
+ SetUpWebContentsDelegateAndRunMessageLoop(IgnoreNavigation, &defer); |
+ |
+ EXPECT_TRUE(defer); |
+ EXPECT_TRUE(io_thread_state_); |
+ EXPECT_TRUE(io_thread_state_->request_cancelled()); |
+} |
+ |
+TEST_F(IgnoreNavigationResourceThrottleTest, |
+ RequestNotDeferredForRequestNotAssociatedWithARenderView) { |
+ bool defer = false; |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind( |
+ &IgnoreNavigationResourceThrottleTest:: |
+ RunThrottleWillStartRequestOnIOThread, |
+ base::Unretained(this), |
+ MSG_ROUTING_NONE, |
+ MSG_ROUTING_NONE, |
+ base::Unretained(&defer))); |
+ |
+ // Wait for the request to finish processing. |
+ message_loop_.Run(); |
+ |
+ EXPECT_FALSE(defer); |
+} |