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..f310d6ecf746e256aa232a77e92c5a4534ac108a |
| --- /dev/null |
| +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc |
| @@ -0,0 +1,323 @@ |
| +// 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/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/common/referrer.h" |
|
engedy
2017/03/10 10:56:57
nit: Unused?
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| +#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 { |
| + async_filter_.reset(); |
| + ruleset_handle_.reset(); |
| + dealer_handle_.reset(); |
| + RunUntilIdle(); |
| + content::RenderViewHostTestHarness::TearDown(); |
| + } |
| + |
| + // content::WebContentsObserver: |
|
engedy
2017/03/10 10:56:57
nit: Could you please move these further down into
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| + 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()); |
| + } |
| + test_throttle_ = nullptr; |
| + } |
| + |
| + void InitializeRuleset() { |
| + std::vector<proto::UrlRule> rules; |
| + rules.push_back(testing::CreateWhitelistRuleForDocument( |
| + "whitelist.com", proto::ACTIVATION_TYPE_DOCUMENT, {"parent.com"})); |
|
engedy
2017/03/10 10:56:57
nit: Let's call these whitelisted.com and allow-ch
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| + 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 InitializeDocumentSubresourceFilter(const GURL& document_url) { |
| + NavigateAndCommit(document_url); |
|
engedy
2017/03/10 10:56:57
Apart from this line, this function has no effect
Charlie Harrison
2017/03/10 17:12:47
Oops, sorry about that. I've reworked the tests to
|
| + |
| + testing::TestActivationStateCallbackReceiver activation_state; |
| + async_filter_ = base::MakeUnique<AsyncDocumentSubresourceFilter>( |
| + ruleset_handle_.get(), |
| + AsyncDocumentSubresourceFilter::InitializationParams( |
| + document_url, ActivationLevel::ENABLED, |
| + false /* measure_performance */), |
| + activation_state.GetCallback(), base::OnceClosure()); |
| + RunUntilIdle(); |
| + activation_state.ExpectReceivedOnce( |
| + ActivationState(ActivationLevel::ENABLED)); |
| + } |
| + |
| + 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, |
| + const ActivationState& parent_activation_state) { |
| + parent_activation_state_ = parent_activation_state; |
| + content::RenderFrameHost* navigating_subframe = |
| + content::RenderFrameHostTester::For(main_rfh()) |
| + ->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); |
| + } |
| + |
| + const ActivationState& last_activation_state() { |
| + return last_activation_state_.value(); |
|
engedy
2017/03/10 10:56:57
nit: This essentially EXPECT's that las_ will have
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| + } |
| + |
| + 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<AsyncDocumentSubresourceFilter> async_filter_; |
| + |
| + 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_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ActivationStateComputingNavigationThrottleTest); |
|
engedy
2017/03/10 10:56:57
#include "base/macros.h"
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| +}; |
| + |
| +// Main frame tests |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, ActivateMainFrame) { |
|
engedy
2017/03/10 11:53:41
optional nit: If we had two test fixtures, Activat
Charlie Harrison
2017/03/10 17:12:47
Done. I also rewrote some of the tests to fit the
|
| + CreateTestNavigationForMainFrame(GURL("http://example.test/activate.html")); |
| + SimulateStartAndExpectToProceed(); |
| + |
| + NotifyPageActivation(ActivationState(ActivationLevel::ENABLED)); |
|
engedy
2017/03/10 10:56:57
nit for follow-up CL: Ultimately we should have a
Charlie Harrison
2017/03/10 17:12:47
Would this be before WillStartRequest but after Di
engedy
2017/03/10 18:33:42
Exactly, the overall navigation will be in the Wil
|
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| +} |
| + |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, |
| + DoNotActivateMainFrameForInactivePage) { |
| + CreateTestNavigationForMainFrame(GURL("http://example.test/inactivate.html")); |
|
engedy
2017/03/10 10:56:57
nit: Let's remove the paths in all these URL, thei
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed( |
| + GURL("http://example.test/inactivate.html?v=1")); |
| + |
| + // Never send NotifyPageActivation. |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, |
| + DoNotActivateMainFrameForInactivePage2) { |
| + CreateTestNavigationForMainFrame(GURL("http://example.test/inactivate.html")); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed( |
| + GURL("http://example.test/inactivate.html?v=1")); |
| + |
| + // Notify that the page level state is explicitly disabled. Should be |
|
engedy
2017/03/10 10:56:57
nit: s/level state/(level) activation/
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| + // equivalent to not sending the message at all. |
| + NotifyPageActivation(ActivationState(ActivationLevel::DISABLED)); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, |
|
engedy
2017/03/10 10:56:57
Let's also have a test where the main frame is act
engedy
2017/03/10 10:56:57
In addition to (or instead of) this test, let's ha
Charlie Harrison
2017/03/10 17:12:46
Done.
Charlie Harrison
2017/03/10 17:12:46
Done.
|
| + ActivateMainFrameWhitelistedSubframe) { |
|
engedy
2017/03/10 10:56:57
nit: s/ActivateMainFrameWhitelistedSubframe/MainFr
Charlie Harrison
2017/03/10 17:12:46
Done.
|
| + InitializeDocumentSubresourceFilter(GURL("http://parent.com/")); |
| + // Not really a child frame, so whitelist should not apply. |
| + CreateTestNavigationForMainFrame(GURL("http://whitelist.com/")); |
| + 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); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| +} |
| + |
| +// Subframe tests |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, ActivateSubframe) { |
| + InitializeDocumentSubresourceFilter(GURL("http://example.test")); |
| + CreateSubframeAndInitTestNavigation( |
| + GURL("http://example.test/activate.html"), |
| + ActivationState(ActivationLevel::ENABLED)); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed( |
| + GURL("http://example.test/activate.html?v=1")); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| +} |
| + |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, |
| + DoNotActivateWhitelistedSubframe) { |
|
engedy
2017/03/10 10:56:57
We should also a version to verify that proto::ACT
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| + InitializeDocumentSubresourceFilter(GURL("http://parent.com/")); |
| + CreateSubframeAndInitTestNavigation( |
| + GURL("http://whitelist.com/"), ActivationState(ActivationLevel::ENABLED)); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_TRUE(state.filtering_disabled_for_document); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| +} |
| + |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, |
| + EnsureDryRunIsPropagated) { |
|
engedy
2017/03/10 10:56:57
We should also have a version to verify that page
Charlie Harrison
2017/03/10 17:12:47
This test now verifies that with the refactoring I
|
| + InitializeDocumentSubresourceFilter(GURL("http://example.test")); |
| + CreateSubframeAndInitTestNavigation(GURL("http://example.test/activate.html"), |
| + ActivationState(ActivationLevel::DRYRUN)); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed( |
| + GURL("http://example.test/activate.html?v=1")); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::DRYRUN, state.activation_level); |
|
engedy
2017/03/10 10:56:57
nit:
EXPECT_FALSE(state.filtering_disabled_for_do
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| +} |
| + |
| +TEST_F(ActivationStateComputingNavigationThrottleTest, |
| + DisabledStatePropagatedDocument) { |
| + InitializeDocumentSubresourceFilter(GURL("http://example.test")); |
| + ActivationState parent_activation(ActivationLevel::ENABLED); |
| + parent_activation.filtering_disabled_for_document = true; |
| + CreateSubframeAndInitTestNavigation(GURL("http://example.test/activate.html"), |
| + parent_activation); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed( |
| + GURL("http://example.test/activate.html?v=1")); |
| + 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(ActivationStateComputingNavigationThrottleTest, |
| + DisabledStatePropagatedGeneric) { |
|
engedy
2017/03/10 10:56:57
We should have a test (a new one or extend an exis
Charlie Harrison
2017/03/10 17:12:47
Done.
|
| + InitializeDocumentSubresourceFilter(GURL("http://example.test")); |
| + ActivationState parent_activation(ActivationLevel::ENABLED); |
| + parent_activation.generic_blocking_rules_disabled = true; |
| + CreateSubframeAndInitTestNavigation(GURL("http://example.test/activate.html"), |
| + parent_activation); |
| + SimulateStartAndExpectToProceed(); |
| + SimulateRedirectAndExpectToProceed( |
| + GURL("http://example.test/activate.html?v=1")); |
| + SimulateCommitAndExpectToProceed(); |
| + |
| + ActivationState state = last_activation_state(); |
| + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| + EXPECT_FALSE(state.filtering_disabled_for_document); |
| + EXPECT_TRUE(state.generic_blocking_rules_disabled); |
| +} |
| + |
| +} // namespace subresource_filter |