Chromium Code Reviews| Index: components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc |
| diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..931f546dc24616c736cc507b30910e39c34615a8 |
| --- /dev/null |
| +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc |
| @@ -0,0 +1,416 @@ |
| +// Copyright 2017 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/browser/activation_state_computing_navigation_throttle.h" |
| + |
| +#include <memory> |
| +#include <utility> |
| + |
| +#include "base/callback.h" |
| +#include "base/macros.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/optional.h" |
| +#include "base/run_loop.h" |
| +#include "base/test/test_simple_task_runner.h" |
| +#include "components/subresource_filter/content/browser/async_document_subresource_filter.h" |
| +#include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h" |
| +#include "components/subresource_filter/core/common/activation_level.h" |
| +#include "components/subresource_filter/core/common/activation_state.h" |
| +#include "components/subresource_filter/core/common/proto/rules.pb.h" |
| +#include "components/subresource_filter/core/common/test_ruleset_creator.h" |
| +#include "components/subresource_filter/core/common/test_ruleset_utils.h" |
| +#include "content/public/browser/navigation_handle.h" |
| +#include "content/public/browser/web_contents_observer.h" |
| +#include "content/public/test/navigation_simulator.h" |
| +#include "content/public/test/test_renderer_host.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace subresource_filter { |
| + |
| +class ActivationStateComputingNavigationThrottleTest |
| + : public content::RenderViewHostTestHarness, |
| + public content::WebContentsObserver { |
| + public: |
| + ActivationStateComputingNavigationThrottleTest() {} |
| + ~ActivationStateComputingNavigationThrottleTest() override {} |
| + |
| + void SetUp() override { |
| + content::RenderViewHostTestHarness::SetUp(); |
| + NavigateAndCommit(GURL("https://example.first")); |
| + InitializeRuleset(); |
| + Observe(RenderViewHostTestHarness::web_contents()); |
| + } |
| + |
| + void TearDown() override { |
| + ruleset_handle_.reset(); |
| + dealer_handle_.reset(); |
| + RunUntilIdle(); |
| + content::RenderViewHostTestHarness::TearDown(); |
| + } |
| + |
| + void InitializeRuleset() { |
| + std::vector<proto::UrlRule> rules; |
| + rules.push_back(testing::CreateWhitelistRuleForDocument( |
| + "whitelisted.com", proto::ACTIVATION_TYPE_DOCUMENT, |
| + {"allow-child-to-be-whitelisted.com", |
| + "whitelisted-generic-with-disabled-child.com"})); |
| + |
| + rules.push_back(testing::CreateWhitelistRuleForDocument( |
| + "whitelisted-generic.com", proto::ACTIVATION_TYPE_GENERICBLOCK, |
| + {"allow-child-to-be-whitelisted.com"})); |
| + |
| + rules.push_back(testing::CreateWhitelistRuleForDocument( |
| + "whitelisted-generic-with-disabled-child.com", |
| + proto::ACTIVATION_TYPE_GENERICBLOCK, |
| + {"allow-child-to-be-whitelisted.com"})); |
| + |
| + rules.push_back(testing::CreateWhitelistRuleForDocument( |
| + "whitelisted-always.com", proto::ACTIVATION_TYPE_DOCUMENT)); |
| + |
| + ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules( |
| + rules, &test_ruleset_pair_)); |
| + |
| + // Make the blocking task runner run on the current task runner for the |
| + // tests, to ensure that the NavigationSimulator properly runs all necessary |
| + // tasks while waiting for throttle checks to finish. |
| + dealer_handle_ = base::MakeUnique<VerifiedRulesetDealer::Handle>( |
| + base::MessageLoop::current()->task_runner()); |
| + dealer_handle_->SetRulesetFile( |
| + testing::TestRuleset::Open(test_ruleset_pair_.indexed)); |
| + ruleset_handle_ = |
| + base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle_.get()); |
| + } |
| + |
| + void NavigateAndCommitToMainFrameWithPageActivation( |
|
engedy
2017/03/10 18:33:43
nit: NavigateAndCommitMainFrameWithPageActivationS
Charlie Harrison
2017/03/10 18:48:54
Done.
|
| + const GURL& document_url, |
| + const ActivationState& page_activation) { |
| + CreateTestNavigationForMainFrame(document_url); |
| + SimulateStartAndExpectToProceed(); |
| + |
| + NotifyPageActivation(page_activation); |
| + SimulateCommitAndExpectToProceed(); |
| + } |
| + |
| + void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } |
| + |
| + void CreateTestNavigationForMainFrame(const GURL& first_url) { |
| + navigation_simulator_ = |
| + content::NavigationSimulator::CreateRendererInitiated(first_url, |
| + main_rfh()); |
| + } |
| + |
| + void CreateSubframeAndInitTestNavigation( |
| + const GURL& first_url, |
| + content::RenderFrameHost* parent, |
| + const ActivationState& parent_activation_state) { |
| + ASSERT_TRUE(parent); |
| + parent_activation_state_ = parent_activation_state; |
| + content::RenderFrameHost* navigating_subframe = |
| + content::RenderFrameHostTester::For(parent)->AppendChild("subframe"); |
| + navigation_simulator_ = |
| + content::NavigationSimulator::CreateRendererInitiated( |
| + first_url, navigating_subframe); |
| + } |
| + |
| + void SimulateStartAndExpectToProceed() { |
| + ASSERT_TRUE(navigation_simulator_); |
| + navigation_simulator_->Start(); |
| + EXPECT_EQ(content::NavigationThrottle::PROCEED, |
| + navigation_simulator_->GetLastThrottleCheckResult()); |
| + } |
| + |
| + void SimulateRedirectAndExpectToProceed(const GURL& new_url) { |
| + navigation_simulator_->Redirect(new_url); |
| + EXPECT_EQ(content::NavigationThrottle::PROCEED, |
| + navigation_simulator_->GetLastThrottleCheckResult()); |
| + } |
| + |
| + void SimulateCommitAndExpectToProceed() { |
| + navigation_simulator_->Commit(); |
| + EXPECT_EQ(content::NavigationThrottle::PROCEED, |
| + navigation_simulator_->GetLastThrottleCheckResult()); |
| + } |
| + |
| + void NotifyPageActivation(ActivationState state) { |
| + test_throttle_->NotifyPageActivationWithRuleset( |
| + state.activation_level == ActivationLevel::DISABLED |
| + ? nullptr |
| + : ruleset_handle_.get(), |
| + state); |
| + } |
| + |
| + ActivationState last_activation_state() { |
| + EXPECT_TRUE(last_activation_state_.has_value()); |
| + return last_activation_state_.value_or( |
| + ActivationState(ActivationLevel::DISABLED)); |
| + } |
| + |
| + content::RenderFrameHost* last_committed_frame_host() { |
| + return last_committed_frame_host_; |
| + } |
| + |
| + protected: |
| + // content::WebContentsObserver: |
| + void DidStartNavigation( |
| + content::NavigationHandle* navigation_handle) override { |
| + std::unique_ptr<ActivationStateComputingNavigationThrottle> throttle = |
| + navigation_handle->IsInMainFrame() |
| + ? ActivationStateComputingNavigationThrottle::CreateForMainFrame( |
| + navigation_handle) |
| + : ActivationStateComputingNavigationThrottle::CreateForSubframe( |
| + navigation_handle, ruleset_handle_.get(), |
| + parent_activation_state_.value()); |
| + test_throttle_ = throttle.get(); |
| + navigation_handle->RegisterThrottleForTesting(std::move(throttle)); |
| + } |
| + |
| + void ReadyToCommitNavigation( |
| + content::NavigationHandle* navigation_handle) override { |
| + if (!test_throttle_) |
| + return; |
| + ASSERT_EQ(navigation_handle, test_throttle_->navigation_handle()); |
| + last_activation_state_ = test_throttle_->GetActivationState(); |
| + if (last_activation_state_.value().activation_level == |
| + ActivationLevel::DISABLED) { |
| + EXPECT_FALSE(test_throttle_->ReleaseFilter()); |
| + } else { |
| + EXPECT_TRUE(test_throttle_->ReleaseFilter()); |
| + } |
| + } |
| + |
| + void DidFinishNavigation( |
| + content::NavigationHandle* navigation_handle) override { |
| + if (!test_throttle_) |
| + return; |
| + last_committed_frame_host_ = navigation_handle->GetRenderFrameHost(); |
| + test_throttle_ = nullptr; |
| + } |
| + |
| + private: |
| + testing::TestRulesetCreator test_ruleset_creator_; |
| + testing::TestRulesetPair test_ruleset_pair_; |
| + |
| + std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_; |
| + std::unique_ptr<VerifiedRuleset::Handle> ruleset_handle_; |
| + |
| + std::unique_ptr<content::NavigationSimulator> navigation_simulator_; |
| + |
| + // Owned by the current navigation. |
| + ActivationStateComputingNavigationThrottle* test_throttle_; |
| + base::Optional<ActivationState> last_activation_state_; |
| + base::Optional<ActivationState> parent_activation_state_; |
| + |
| + // Needed for potential cross process navigations which swap hosts. |
| + content::RenderFrameHost* last_committed_frame_host_ = nullptr; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ActivationStateComputingNavigationThrottleTest); |
| +}; |
| + |
| +class ActivationStateComputingThrottleMainFrameTest |
|
engedy
2017/03/10 18:33:43
nit: Would declaring a type alias here work with G
Charlie Harrison
2017/03/10 18:48:54
Yep, changed to typedefs.
|
| + : public ActivationStateComputingNavigationThrottleTest {}; |
| +class ActivationStateComputingThrottleSubFrameTest |
| + : public ActivationStateComputingNavigationThrottleTest {}; |
| + |
| +// Main frame tests |
| +TEST_F(ActivationStateComputingThrottleMainFrameTest, Activate) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED)); |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| + NoPageStateNotification_NoActivation) { |
|
engedy
2017/03/10 18:33:42
nit: s/State/Activation/g here and in the test bel
Charlie Harrison
2017/03/10 18:48:54
Done.
|
| + CreateTestNavigationForMainFrame(GURL("http://example.test/")); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed(GURL("http://example.test/?v=1")); |
| + |
| + // Never send NotifyPageActivation. |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| + DisabledPageState_NoActivation) { |
| + // Notify that the page level activation is explicitly disabled. Should be |
| + // equivalent to not sending the message at all to the main frame throttle. |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://example.test/"), ActivationState(ActivationLevel::DISABLED)); |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| + WhitelistDoesNotApply_CausesActivation) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://allow-child-to-be-whitelisted.com/"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + |
| + // Not really a child frame, so whitelist should not apply. |
| + CreateTestNavigationForMainFrame(GURL("http://whitelisted.com/")); |
|
engedy
2017/03/10 18:33:42
nit: Lines 254--260 are equivalent to another Navi
Charlie Harrison
2017/03/10 18:48:54
Done.
|
| + SimulateStartAndExpectToProceed(); |
| + |
| + // Main frames will usually have their "parent" activation state set right |
| + // before WillProcessResponse. |
| + NotifyPageActivation(ActivationState(ActivationLevel::ENABLED)); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
|
engedy
2017/03/10 18:33:43
Let's check |generic_blocking_rules_disabled| here
Charlie Harrison
2017/03/10 18:48:54
Done.
|
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| + Whitelisted_DisablesDocumentFiltering) { |
|
engedy
2017/03/10 18:33:42
nit: s/DisablesDocumentFiltering/DisablesFiltering
Charlie Harrison
2017/03/10 18:48:54
Done.
|
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://whitelisted-always.com/"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_TRUE(state.filtering_disabled_for_document); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| +} |
| + |
| +// Subframe tests |
|
engedy
2017/03/10 18:33:43
nit: Either remove this line or make it a section
Charlie Harrison
2017/03/10 18:48:54
Done.
|
| +TEST_F(ActivationStateComputingThrottleSubFrameTest, Activate) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED)); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://example.child/"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed(GURL("http://example.child/?v=1")); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleSubFrameTest, |
| + WhitelistDoesNotApply_CausesActivation) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://disallows-child-to-be-whitelisted.com/"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleSubFrameTest, |
| + Whitelisted_DisableDocumentFiltering) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://allow-child-to-be-whitelisted.com/"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_TRUE(state.filtering_disabled_for_document); |
| + EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleSubFrameTest, |
| + Whitelisted_DisablesGenericBlocking) { |
|
engedy
2017/03/10 18:33:42
nit: DisablesGenericRules
Charlie Harrison
2017/03/10 18:48:54
Done.
|
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://allow-child-to-be-whitelisted.com/"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://whitelisted-generic.com/"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| + EXPECT_TRUE(state.generic_blocking_rules_disabled); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleSubFrameTest, DryRunIsPropagated) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://example.test/"), ActivationState(ActivationLevel::DRYRUN)); |
| + EXPECT_EQ(ActivationLevel::DRYRUN, last_activation_state().activation_level); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://example.child/"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed(GURL("http://example.child/?v=1")); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::DRYRUN, state.activation_level); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| + EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://allow-child-to-be-whitelisted.com/"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://example.test/"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_TRUE(state.filtering_disabled_for_document); |
| + EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| +} |
| + |
| +TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated2) { |
| + NavigateAndCommitToMainFrameWithPageActivation( |
| + GURL("http://allow-child-to-be-whitelisted.com/"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + |
| + CreateSubframeAndInitTestNavigation( |
| + GURL("http://whitelisted-generic-with-disabled-child.com/"), |
| + last_committed_frame_host(), last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| + EXPECT_TRUE(state.generic_blocking_rules_disabled); |
| + |
| + CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), |
| + last_committed_frame_host(), |
| + last_activation_state()); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_TRUE(state.filtering_disabled_for_document); |
| + EXPECT_TRUE(state.generic_blocking_rules_disabled); |
| +} |
| + |
| +} // namespace subresource_filter |