Chromium Code Reviews| Index: components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc |
| diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc b/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ccf041cf9cc5cf56dd8e44eeced6051682be4fd0 |
| --- /dev/null |
| +++ b/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc |
| @@ -0,0 +1,231 @@ |
| +// 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 "components/subresource_filter/content/renderer/subresource_filter_agent.h" |
| + |
| +#include <memory> |
| +#include <string> |
| +#include <utility> |
| + |
| +#include "base/macros.h" |
| +#include "components/subresource_filter/content/common/subresource_filter_messages.h" |
| +#include "components/subresource_filter/content/renderer/ruleset_dealer.h" |
| +#include "components/subresource_filter/core/common/test_ruleset_creator.h" |
| +#include "components/test_runner/test_common.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "third_party/WebKit/public/platform/WebDocumentSubresourceFilter.h" |
| +#include "third_party/WebKit/public/platform/WebURL.h" |
| +#include "third_party/WebKit/public/platform/WebURLRequest.h" |
| +#include "url/gurl.h" |
| + |
| +namespace subresource_filter { |
| + |
| +namespace { |
| + |
| +// The SubresourceFilterAgent with its dependencies on Blink mocked out. |
| +// |
| +// This approach is somewhat rudimentary, but appears to be the best compromise |
| +// considering the alternatives: |
| +// -- Passing in a TestRenderFrame would itself require bringing up a |
| +// significant number of supporting classes. |
| +// -- Using a RenderViewTest would not allow having any non-filtered resource |
| +// loads due to not having a child thread and ResourceDispatcher. |
| +// The real implementations of the mocked-out methods are exercised in: |
| +// chrome/browser/subresource_filter/subresource_filter_browsertest.cc. |
| +class SubresourceFilterAgentUnderTest : public SubresourceFilterAgent { |
| + public: |
| + explicit SubresourceFilterAgentUnderTest(RulesetDealer* ruleset_dealer) |
| + : SubresourceFilterAgent(nullptr /* RenderFrame */, ruleset_dealer) {} |
| + ~SubresourceFilterAgentUnderTest() {} |
|
pkalinnikov
2016/07/19 11:57:33
= default?
engedy
2016/07/19 12:57:29
Done.
|
| + |
| + MOCK_METHOD0(GetAncestorDocumentURLs, std::vector<GURL>()); |
| + MOCK_METHOD0(OnSetSubresourceFilterForCommittedLoadCalled, void()); |
| + void SetSubresourceFilterForCommittedLoad( |
| + std::unique_ptr<blink::WebDocumentSubresourceFilter> filter) override { |
| + last_injected_filter_ = std::move(filter); |
| + OnSetSubresourceFilterForCommittedLoadCalled(); |
| + } |
| + |
| + blink::WebDocumentSubresourceFilter* filter() { |
| + return last_injected_filter_.get(); |
| + } |
| + |
| + private: |
| + std::unique_ptr<blink::WebDocumentSubresourceFilter> last_injected_filter_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterAgentUnderTest); |
| +}; |
| + |
| +const char kTestFirstURL[] = "http://example.com/alpha"; |
| +const char kTestSecondURL[] = "http://example.com/beta"; |
| +const char kTestFirstURLPathSuffix[] = "alpha"; |
| +const char kTestSecondURLPathSuffix[] = "beta"; |
| +const char kTestBothURLsPathSuffix[] = "a"; |
| + |
| +} // namespace |
| + |
| +class SubresourceFilterAgentTest : public ::testing::Test { |
| + public: |
| + SubresourceFilterAgentTest() { test_runner::EnsureBlinkInitialized(); } |
| + |
| + protected: |
| + void SetUp() override { |
| + agent_.reset(new SubresourceFilterAgentUnderTest(&ruleset_dealer_)); |
| + ON_CALL(*agent(), GetAncestorDocumentURLs()) |
| + .WillByDefault(::testing::Return(std::vector<GURL>( |
| + {GURL("http://inner.com/"), GURL("http://outer.com/")}))); |
| + } |
| + |
| + void SetTestRulesetToDisallowURLsWithPathSuffix(const std::string& suffix) { |
| + base::File ruleset_file; |
| + ASSERT_NO_FATAL_FAILURE( |
| + test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( |
| + suffix, &ruleset_file)); |
| + ruleset_dealer_.SetRulesetFile(std::move(ruleset_file)); |
| + } |
| + |
| + void StartLoadWithoutSettingActivationState() { |
| + agent_as_rfo()->DidStartProvisionalLoad(); |
| + agent_as_rfo()->DidCommitProvisionalLoad( |
| + true /* is_new_navigation */, false /* is_same_page_navigation */); |
| + } |
| + |
| + void StartLoadAndSetActivationState(ActivationState activation_state) { |
| + agent_as_rfo()->DidStartProvisionalLoad(); |
| + EXPECT_TRUE(agent_as_rfo()->OnMessageReceived( |
| + SubresourceFilterMsg_ActivateForProvisionalLoad(0, activation_state))); |
| + agent_as_rfo()->DidCommitProvisionalLoad( |
| + true /* is_new_navigation */, false /* is_same_page_navigation */); |
| + } |
| + |
| + void FinishLoad() { agent_as_rfo()->DidFinishLoad(); } |
| + |
| + void ExpectSubresourceFilterGetsInjected() { |
| + EXPECT_CALL(*agent(), GetAncestorDocumentURLs()); |
| + EXPECT_CALL(*agent(), OnSetSubresourceFilterForCommittedLoadCalled()); |
| + } |
| + |
| + void ExpectNoSubresourceFilterGetsInjected() { |
| + EXPECT_CALL(*agent(), OnSetSubresourceFilterForCommittedLoadCalled()) |
| + .Times(0); |
| + } |
| + |
| + void ExpectLoadAllowed(const std::string& url_spec, bool allowed) { |
| + blink::WebURL url = GURL(url_spec); |
| + blink::WebURLRequest::RequestContext request_context = |
| + blink::WebURLRequest::RequestContextUnspecified; |
| + EXPECT_EQ(allowed, agent()->filter()->allowLoad(url, request_context)); |
| + } |
| + |
| + SubresourceFilterAgentUnderTest* agent() { return agent_.get(); } |
| + content::RenderFrameObserver* agent_as_rfo() { |
| + return static_cast<content::RenderFrameObserver*>(agent_.get()); |
| + } |
| + |
| + private: |
| + testing::TestRulesetCreator test_ruleset_creator_; |
| + RulesetDealer ruleset_dealer_; |
| + |
| + std::unique_ptr<SubresourceFilterAgentUnderTest> agent_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterAgentTest); |
| +}; |
| + |
| +TEST_F(SubresourceFilterAgentTest, DisabledByDefault_NoFilterIsInjected) { |
| + ASSERT_NO_FATAL_FAILURE( |
| + SetTestRulesetToDisallowURLsWithPathSuffix(kTestBothURLsPathSuffix)); |
| + ExpectNoSubresourceFilterGetsInjected(); |
| + StartLoadWithoutSettingActivationState(); |
| + FinishLoad(); |
| +} |
| + |
| +TEST_F(SubresourceFilterAgentTest, Disabled_NoFilterIsInjected) { |
| + ASSERT_NO_FATAL_FAILURE( |
| + SetTestRulesetToDisallowURLsWithPathSuffix(kTestBothURLsPathSuffix)); |
| + ExpectNoSubresourceFilterGetsInjected(); |
| + StartLoadAndSetActivationState(ActivationState::DISABLED); |
| + FinishLoad(); |
| +} |
| + |
| +TEST_F(SubresourceFilterAgentTest, |
| + EnabledButRulesetUnavailable_NoFilterIsInjected) { |
| + ExpectNoSubresourceFilterGetsInjected(); |
| + StartLoadAndSetActivationState(ActivationState::ENABLED); |
| + FinishLoad(); |
| +} |
| + |
| +TEST_F(SubresourceFilterAgentTest, Enabled_FilteringIsInEffectForOneLoad) { |
| + ASSERT_NO_FATAL_FAILURE( |
| + SetTestRulesetToDisallowURLsWithPathSuffix(kTestFirstURLPathSuffix)); |
| + ExpectSubresourceFilterGetsInjected(); |
| + StartLoadAndSetActivationState(ActivationState::ENABLED); |
| + ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent())); |
| + |
| + ExpectLoadAllowed(kTestFirstURL, false); |
| + ExpectLoadAllowed(kTestSecondURL, true); |
| + FinishLoad(); |
| + |
| + ExpectNoSubresourceFilterGetsInjected(); |
| + StartLoadWithoutSettingActivationState(); |
| + FinishLoad(); |
| +} |
| + |
| +TEST_F(SubresourceFilterAgentTest, Enabled_NewRulesetIsPickedUpAtNextLoad) { |
| + ASSERT_NO_FATAL_FAILURE( |
| + SetTestRulesetToDisallowURLsWithPathSuffix(kTestFirstURLPathSuffix)); |
| + ExpectSubresourceFilterGetsInjected(); |
| + StartLoadAndSetActivationState(ActivationState::ENABLED); |
| + ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent())); |
| + |
| + // Set the new ruleset just after the deadline for being used for the current |
| + // load, to exercises doing filtering based on obseleted rulesets. |
| + ASSERT_NO_FATAL_FAILURE( |
| + SetTestRulesetToDisallowURLsWithPathSuffix(kTestSecondURLPathSuffix)); |
| + |
| + ExpectLoadAllowed(kTestFirstURL, false); |
| + ExpectLoadAllowed(kTestSecondURL, true); |
| + FinishLoad(); |
| + |
| + ExpectSubresourceFilterGetsInjected(); |
| + StartLoadAndSetActivationState(ActivationState::ENABLED); |
| + ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent())); |
| + |
| + ExpectLoadAllowed(kTestFirstURL, true); |
| + ExpectLoadAllowed(kTestSecondURL, false); |
| + FinishLoad(); |
| +} |
| + |
| +// If a provisional load is aborted, the RenderFrameObservers might not receive |
| +// any further notifications about that load. It is thus possible that there |
| +// will be two RenderFrameObserver::DidStartProvisionalLoad in a row. Make sure |
| +// that the activation decision does not outlive the first provisional load. |
| +TEST_F(SubresourceFilterAgentTest, |
| + Enabled_FilteringNoLongerEffectAfterProvisionalLoadIsCancelled) { |
| + ASSERT_NO_FATAL_FAILURE( |
| + SetTestRulesetToDisallowURLsWithPathSuffix(kTestBothURLsPathSuffix)); |
| + ExpectNoSubresourceFilterGetsInjected(); |
| + agent_as_rfo()->DidStartProvisionalLoad(); |
| + EXPECT_TRUE(agent_as_rfo()->OnMessageReceived( |
| + SubresourceFilterMsg_ActivateForProvisionalLoad( |
| + 0, ActivationState::ENABLED))); |
| + agent_as_rfo()->DidStartProvisionalLoad(); |
| + agent_as_rfo()->DidCommitProvisionalLoad(true /* is_new_navigation */, |
| + false /* is_same_page_navigation */); |
| + FinishLoad(); |
| +} |
| + |
| +TEST_F(SubresourceFilterAgentTest, DryRun_ResourcesAreEvaluatedButNotFiltered) { |
| + ASSERT_NO_FATAL_FAILURE( |
| + SetTestRulesetToDisallowURLsWithPathSuffix(kTestFirstURLPathSuffix)); |
| + ExpectSubresourceFilterGetsInjected(); |
| + StartLoadAndSetActivationState(ActivationState::DRYRUN); |
| + ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent())); |
| + |
| + ExpectLoadAllowed(kTestFirstURL, true); |
| + ExpectLoadAllowed(kTestSecondURL, true); |
| + FinishLoad(); |
| +} |
| + |
| +} // namespace subresource_filter |