| // Copyright 2015 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 "components/navigation_interception/intercept_navigation_throttle.h" |
| #include "components/navigation_interception/navigation_params.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/test/test_renderer_host.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using content::NavigationThrottle; |
| using testing::_; |
| using testing::Eq; |
| using testing::Ne; |
| using testing::Property; |
| using testing::Return; |
| |
| namespace navigation_interception { |
| |
| namespace { |
| |
| const char kTestUrl[] = "http://www.test.com/"; |
| |
| // The MS C++ compiler complains about not being able to resolve which url() |
| // method (const or non-const) to use if we use the Property matcher to check |
| // the return value of the NavigationParams::url() method. |
| // It is possible to suppress the error by specifying the types directly but |
| // that results in very ugly syntax, which is why these custom matchers are |
| // used instead. |
| MATCHER(NavigationParamsUrlIsTest, "") { |
| return arg.url() == GURL(kTestUrl); |
| } |
| |
| } // namespace |
| |
| // MockInterceptCallbackReceiver ---------------------------------------------- |
| |
| class MockInterceptCallbackReceiver { |
| public: |
| MOCK_METHOD2(ShouldIgnoreNavigation, |
| bool(content::WebContents* source, |
| const NavigationParams& navigation_params)); |
| }; |
| |
| // InterceptNavigationThrottleTest ------------------------------------ |
| |
| class InterceptNavigationThrottleTest |
| : public content::RenderViewHostTestHarness { |
| public: |
| InterceptNavigationThrottleTest() |
| : mock_callback_receiver_(new MockInterceptCallbackReceiver()) {} |
| |
| NavigationThrottle::ThrottleCheckResult |
| SimulateWillStart(const GURL& url, const GURL& sanitized_url, bool is_post) { |
| scoped_ptr<content::NavigationHandle> test_handle = |
| content::NavigationHandle::CreateNavigationHandleForTesting( |
| url, main_rfh()); |
| test_handle->RegisterThrottleForTesting( |
| scoped_ptr<NavigationThrottle>( |
| new InterceptNavigationThrottle( |
| test_handle.get(), |
| base::Bind( |
| &MockInterceptCallbackReceiver::ShouldIgnoreNavigation, |
| base::Unretained(mock_callback_receiver_.get())))) |
| .Pass()); |
| return test_handle->CallWillStartRequestForTesting( |
| is_post, content::Referrer(), false, ui::PAGE_TRANSITION_LINK, false); |
| } |
| |
| NavigationThrottle::ThrottleCheckResult Simulate302() { |
| scoped_ptr<content::NavigationHandle> test_handle = |
| content::NavigationHandle::CreateNavigationHandleForTesting( |
| GURL(kTestUrl), main_rfh()); |
| test_handle->RegisterThrottleForTesting( |
| scoped_ptr<NavigationThrottle>( |
| new InterceptNavigationThrottle( |
| test_handle.get(), |
| base::Bind( |
| &MockInterceptCallbackReceiver::ShouldIgnoreNavigation, |
| base::Unretained(mock_callback_receiver_.get())))) |
| .Pass()); |
| test_handle->CallWillStartRequestForTesting( |
| true, content::Referrer(), false, ui::PAGE_TRANSITION_LINK, false); |
| return test_handle->CallWillRedirectRequestForTesting(GURL(kTestUrl), false, |
| GURL(), false); |
| } |
| |
| scoped_ptr<MockInterceptCallbackReceiver> mock_callback_receiver_; |
| }; |
| |
| TEST_F(InterceptNavigationThrottleTest, |
| RequestDeferredAndResumedIfNavigationNotIgnored) { |
| ON_CALL(*mock_callback_receiver_, ShouldIgnoreNavigation(_, _)) |
| .WillByDefault(Return(false)); |
| EXPECT_CALL( |
| *mock_callback_receiver_, |
| ShouldIgnoreNavigation(web_contents(), NavigationParamsUrlIsTest())); |
| NavigationThrottle::ThrottleCheckResult result = |
| SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), false); |
| |
| EXPECT_EQ(NavigationThrottle::PROCEED, result); |
| } |
| |
| TEST_F(InterceptNavigationThrottleTest, |
| RequestDeferredAndCancelledIfNavigationIgnored) { |
| ON_CALL(*mock_callback_receiver_, ShouldIgnoreNavigation(_, _)) |
| .WillByDefault(Return(true)); |
| EXPECT_CALL( |
| *mock_callback_receiver_, |
| ShouldIgnoreNavigation(web_contents(), NavigationParamsUrlIsTest())); |
| NavigationThrottle::ThrottleCheckResult result = |
| SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), false); |
| |
| EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, result); |
| } |
| |
| TEST_F(InterceptNavigationThrottleTest, CallbackIsPostFalseForGet) { |
| EXPECT_CALL(*mock_callback_receiver_, |
| ShouldIgnoreNavigation( |
| _, AllOf(NavigationParamsUrlIsTest(), |
| Property(&NavigationParams::is_post, Eq(false))))) |
| .WillOnce(Return(false)); |
| |
| NavigationThrottle::ThrottleCheckResult result = |
| SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), false); |
| |
| EXPECT_EQ(NavigationThrottle::PROCEED, result); |
| } |
| |
| TEST_F(InterceptNavigationThrottleTest, CallbackIsPostTrueForPost) { |
| EXPECT_CALL(*mock_callback_receiver_, |
| ShouldIgnoreNavigation( |
| _, AllOf(NavigationParamsUrlIsTest(), |
| Property(&NavigationParams::is_post, Eq(true))))) |
| .WillOnce(Return(false)); |
| NavigationThrottle::ThrottleCheckResult result = |
| SimulateWillStart(GURL(kTestUrl), GURL(kTestUrl), true); |
| |
| EXPECT_EQ(NavigationThrottle::PROCEED, result); |
| } |
| |
| TEST_F(InterceptNavigationThrottleTest, |
| CallbackIsPostFalseForPostConvertedToGetBy302) { |
| EXPECT_CALL(*mock_callback_receiver_, |
| ShouldIgnoreNavigation( |
| _, AllOf(NavigationParamsUrlIsTest(), |
| Property(&NavigationParams::is_post, Eq(true))))) |
| .WillOnce(Return(false)); |
| EXPECT_CALL(*mock_callback_receiver_, |
| ShouldIgnoreNavigation( |
| _, AllOf(NavigationParamsUrlIsTest(), |
| Property(&NavigationParams::is_post, Eq(false))))) |
| .WillOnce(Return(false)); |
| NavigationThrottle::ThrottleCheckResult result = Simulate302(); |
| |
| EXPECT_EQ(NavigationThrottle::PROCEED, result); |
| } |
| |
| } // namespace navigation_interception |