Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/subresource_filter/content/browser/activation_state_computi ng_navigation_throttle.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 #include <utility> | |
| 9 | |
| 10 #include "base/callback.h" | |
| 11 #include "base/memory/ptr_util.h" | |
| 12 #include "base/optional.h" | |
| 13 #include "base/run_loop.h" | |
| 14 #include "base/test/test_simple_task_runner.h" | |
| 15 #include "components/subresource_filter/content/browser/async_document_subresour ce_filter.h" | |
| 16 #include "components/subresource_filter/content/browser/async_document_subresour ce_filter_test_utils.h" | |
| 17 #include "components/subresource_filter/core/common/activation_level.h" | |
| 18 #include "components/subresource_filter/core/common/activation_state.h" | |
| 19 #include "components/subresource_filter/core/common/proto/rules.pb.h" | |
| 20 #include "components/subresource_filter/core/common/test_ruleset_creator.h" | |
| 21 #include "components/subresource_filter/core/common/test_ruleset_utils.h" | |
| 22 #include "content/public/browser/navigation_handle.h" | |
| 23 #include "content/public/browser/web_contents_observer.h" | |
| 24 #include "content/public/common/referrer.h" | |
|
engedy
2017/03/10 10:56:57
nit: Unused?
Charlie Harrison
2017/03/10 17:12:47
Done.
| |
| 25 #include "content/public/test/navigation_simulator.h" | |
| 26 #include "content/public/test/test_renderer_host.h" | |
| 27 #include "testing/gtest/include/gtest/gtest.h" | |
| 28 | |
| 29 namespace subresource_filter { | |
| 30 | |
| 31 class ActivationStateComputingNavigationThrottleTest | |
| 32 : public content::RenderViewHostTestHarness, | |
| 33 public content::WebContentsObserver { | |
| 34 public: | |
| 35 ActivationStateComputingNavigationThrottleTest() {} | |
| 36 ~ActivationStateComputingNavigationThrottleTest() override {} | |
| 37 | |
| 38 void SetUp() override { | |
| 39 content::RenderViewHostTestHarness::SetUp(); | |
| 40 NavigateAndCommit(GURL("https://example.first")); | |
| 41 InitializeRuleset(); | |
| 42 Observe(RenderViewHostTestHarness::web_contents()); | |
| 43 } | |
| 44 | |
| 45 void TearDown() override { | |
| 46 async_filter_.reset(); | |
| 47 ruleset_handle_.reset(); | |
| 48 dealer_handle_.reset(); | |
| 49 RunUntilIdle(); | |
| 50 content::RenderViewHostTestHarness::TearDown(); | |
| 51 } | |
| 52 | |
| 53 // 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.
| |
| 54 void DidStartNavigation( | |
| 55 content::NavigationHandle* navigation_handle) override { | |
| 56 std::unique_ptr<ActivationStateComputingNavigationThrottle> throttle = | |
| 57 navigation_handle->IsInMainFrame() | |
| 58 ? ActivationStateComputingNavigationThrottle::CreateForMainFrame( | |
| 59 navigation_handle) | |
| 60 : ActivationStateComputingNavigationThrottle::CreateForSubframe( | |
| 61 navigation_handle, ruleset_handle_.get(), | |
| 62 parent_activation_state_.value()); | |
| 63 test_throttle_ = throttle.get(); | |
| 64 navigation_handle->RegisterThrottleForTesting(std::move(throttle)); | |
| 65 } | |
| 66 | |
| 67 void ReadyToCommitNavigation( | |
| 68 content::NavigationHandle* navigation_handle) override { | |
| 69 if (!test_throttle_) | |
| 70 return; | |
| 71 ASSERT_EQ(navigation_handle, test_throttle_->navigation_handle()); | |
| 72 last_activation_state_ = test_throttle_->GetActivationState(); | |
| 73 if (last_activation_state_.value().activation_level == | |
| 74 ActivationLevel::DISABLED) { | |
| 75 EXPECT_FALSE(test_throttle_->ReleaseFilter()); | |
| 76 } else { | |
| 77 EXPECT_TRUE(test_throttle_->ReleaseFilter()); | |
| 78 } | |
| 79 test_throttle_ = nullptr; | |
| 80 } | |
| 81 | |
| 82 void InitializeRuleset() { | |
| 83 std::vector<proto::UrlRule> rules; | |
| 84 rules.push_back(testing::CreateWhitelistRuleForDocument( | |
| 85 "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.
| |
| 86 ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules( | |
| 87 rules, &test_ruleset_pair_)); | |
| 88 | |
| 89 // Make the blocking task runner run on the current task runner for the | |
| 90 // tests, to ensure that the NavigationSimulator properly runs all necessary | |
| 91 // tasks while waiting for throttle checks to finish. | |
| 92 dealer_handle_ = base::MakeUnique<VerifiedRulesetDealer::Handle>( | |
| 93 base::MessageLoop::current()->task_runner()); | |
| 94 dealer_handle_->SetRulesetFile( | |
| 95 testing::TestRuleset::Open(test_ruleset_pair_.indexed)); | |
| 96 ruleset_handle_ = | |
| 97 base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle_.get()); | |
| 98 } | |
| 99 void InitializeDocumentSubresourceFilter(const GURL& document_url) { | |
| 100 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
| |
| 101 | |
| 102 testing::TestActivationStateCallbackReceiver activation_state; | |
| 103 async_filter_ = base::MakeUnique<AsyncDocumentSubresourceFilter>( | |
| 104 ruleset_handle_.get(), | |
| 105 AsyncDocumentSubresourceFilter::InitializationParams( | |
| 106 document_url, ActivationLevel::ENABLED, | |
| 107 false /* measure_performance */), | |
| 108 activation_state.GetCallback(), base::OnceClosure()); | |
| 109 RunUntilIdle(); | |
| 110 activation_state.ExpectReceivedOnce( | |
| 111 ActivationState(ActivationLevel::ENABLED)); | |
| 112 } | |
| 113 | |
| 114 void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } | |
| 115 | |
| 116 void CreateTestNavigationForMainFrame(const GURL& first_url) { | |
| 117 navigation_simulator_ = | |
| 118 content::NavigationSimulator::CreateRendererInitiated(first_url, | |
| 119 main_rfh()); | |
| 120 } | |
| 121 | |
| 122 void CreateSubframeAndInitTestNavigation( | |
| 123 const GURL& first_url, | |
| 124 const ActivationState& parent_activation_state) { | |
| 125 parent_activation_state_ = parent_activation_state; | |
| 126 content::RenderFrameHost* navigating_subframe = | |
| 127 content::RenderFrameHostTester::For(main_rfh()) | |
| 128 ->AppendChild("subframe"); | |
| 129 navigation_simulator_ = | |
| 130 content::NavigationSimulator::CreateRendererInitiated( | |
| 131 first_url, navigating_subframe); | |
| 132 } | |
| 133 | |
| 134 void SimulateStartAndExpectToProceed() { | |
| 135 ASSERT_TRUE(navigation_simulator_); | |
| 136 navigation_simulator_->Start(); | |
| 137 EXPECT_EQ(content::NavigationThrottle::PROCEED, | |
| 138 navigation_simulator_->GetLastThrottleCheckResult()); | |
| 139 } | |
| 140 | |
| 141 void SimulateRedirectAndExpectToProceed(const GURL& new_url) { | |
| 142 navigation_simulator_->Redirect(new_url); | |
| 143 EXPECT_EQ(content::NavigationThrottle::PROCEED, | |
| 144 navigation_simulator_->GetLastThrottleCheckResult()); | |
| 145 } | |
| 146 | |
| 147 void SimulateCommitAndExpectToProceed() { | |
| 148 navigation_simulator_->Commit(); | |
| 149 EXPECT_EQ(content::NavigationThrottle::PROCEED, | |
| 150 navigation_simulator_->GetLastThrottleCheckResult()); | |
| 151 } | |
| 152 | |
| 153 void NotifyPageActivation(ActivationState state) { | |
| 154 test_throttle_->NotifyPageActivationWithRuleset( | |
| 155 state.activation_level == ActivationLevel::DISABLED | |
| 156 ? nullptr | |
| 157 : ruleset_handle_.get(), | |
| 158 state); | |
| 159 } | |
| 160 | |
| 161 const ActivationState& last_activation_state() { | |
| 162 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.
| |
| 163 } | |
| 164 | |
| 165 private: | |
| 166 testing::TestRulesetCreator test_ruleset_creator_; | |
| 167 testing::TestRulesetPair test_ruleset_pair_; | |
| 168 | |
| 169 std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_; | |
| 170 std::unique_ptr<VerifiedRuleset::Handle> ruleset_handle_; | |
| 171 | |
| 172 std::unique_ptr<AsyncDocumentSubresourceFilter> async_filter_; | |
| 173 | |
| 174 std::unique_ptr<content::NavigationSimulator> navigation_simulator_; | |
| 175 | |
| 176 // Owned by the current navigation. | |
| 177 ActivationStateComputingNavigationThrottle* test_throttle_; | |
| 178 base::Optional<ActivationState> last_activation_state_; | |
| 179 base::Optional<ActivationState> parent_activation_state_; | |
| 180 | |
| 181 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.
| |
| 182 }; | |
| 183 | |
| 184 // Main frame tests | |
| 185 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
| |
| 186 CreateTestNavigationForMainFrame(GURL("http://example.test/activate.html")); | |
| 187 SimulateStartAndExpectToProceed(); | |
| 188 | |
| 189 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
| |
| 190 SimulateCommitAndExpectToProceed(); | |
| 191 | |
| 192 ActivationState state = last_activation_state(); | |
| 193 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 194 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 195 } | |
| 196 | |
| 197 TEST_F(ActivationStateComputingNavigationThrottleTest, | |
| 198 DoNotActivateMainFrameForInactivePage) { | |
| 199 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.
| |
| 200 SimulateStartAndExpectToProceed(); | |
| 201 SimulateRedirectAndExpectToProceed( | |
| 202 GURL("http://example.test/inactivate.html?v=1")); | |
| 203 | |
| 204 // Never send NotifyPageActivation. | |
| 205 SimulateCommitAndExpectToProceed(); | |
| 206 | |
| 207 ActivationState state = last_activation_state(); | |
| 208 EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); | |
| 209 } | |
| 210 | |
| 211 TEST_F(ActivationStateComputingNavigationThrottleTest, | |
| 212 DoNotActivateMainFrameForInactivePage2) { | |
| 213 CreateTestNavigationForMainFrame(GURL("http://example.test/inactivate.html")); | |
| 214 SimulateStartAndExpectToProceed(); | |
| 215 SimulateRedirectAndExpectToProceed( | |
| 216 GURL("http://example.test/inactivate.html?v=1")); | |
| 217 | |
| 218 // 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.
| |
| 219 // equivalent to not sending the message at all. | |
| 220 NotifyPageActivation(ActivationState(ActivationLevel::DISABLED)); | |
| 221 SimulateCommitAndExpectToProceed(); | |
| 222 | |
| 223 ActivationState state = last_activation_state(); | |
| 224 EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); | |
| 225 } | |
| 226 | |
| 227 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.
| |
| 228 ActivateMainFrameWhitelistedSubframe) { | |
|
engedy
2017/03/10 10:56:57
nit: s/ActivateMainFrameWhitelistedSubframe/MainFr
Charlie Harrison
2017/03/10 17:12:46
Done.
| |
| 229 InitializeDocumentSubresourceFilter(GURL("http://parent.com/")); | |
| 230 // Not really a child frame, so whitelist should not apply. | |
| 231 CreateTestNavigationForMainFrame(GURL("http://whitelist.com/")); | |
| 232 SimulateStartAndExpectToProceed(); | |
| 233 | |
| 234 // Main frames will usually have their "parent" activation state set right | |
| 235 // before WillProcessResponse. | |
| 236 NotifyPageActivation(ActivationState(ActivationLevel::ENABLED)); | |
| 237 SimulateCommitAndExpectToProceed(); | |
| 238 | |
| 239 ActivationState state = last_activation_state(); | |
| 240 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 241 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 242 } | |
| 243 | |
| 244 // Subframe tests | |
| 245 TEST_F(ActivationStateComputingNavigationThrottleTest, ActivateSubframe) { | |
| 246 InitializeDocumentSubresourceFilter(GURL("http://example.test")); | |
| 247 CreateSubframeAndInitTestNavigation( | |
| 248 GURL("http://example.test/activate.html"), | |
| 249 ActivationState(ActivationLevel::ENABLED)); | |
| 250 SimulateStartAndExpectToProceed(); | |
| 251 SimulateRedirectAndExpectToProceed( | |
| 252 GURL("http://example.test/activate.html?v=1")); | |
| 253 SimulateCommitAndExpectToProceed(); | |
| 254 | |
| 255 ActivationState state = last_activation_state(); | |
| 256 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 257 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 258 } | |
| 259 | |
| 260 TEST_F(ActivationStateComputingNavigationThrottleTest, | |
| 261 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.
| |
| 262 InitializeDocumentSubresourceFilter(GURL("http://parent.com/")); | |
| 263 CreateSubframeAndInitTestNavigation( | |
| 264 GURL("http://whitelist.com/"), ActivationState(ActivationLevel::ENABLED)); | |
| 265 SimulateStartAndExpectToProceed(); | |
| 266 SimulateCommitAndExpectToProceed(); | |
| 267 | |
| 268 ActivationState state = last_activation_state(); | |
| 269 EXPECT_TRUE(state.filtering_disabled_for_document); | |
| 270 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 271 } | |
| 272 | |
| 273 TEST_F(ActivationStateComputingNavigationThrottleTest, | |
| 274 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
| |
| 275 InitializeDocumentSubresourceFilter(GURL("http://example.test")); | |
| 276 CreateSubframeAndInitTestNavigation(GURL("http://example.test/activate.html"), | |
| 277 ActivationState(ActivationLevel::DRYRUN)); | |
| 278 SimulateStartAndExpectToProceed(); | |
| 279 SimulateRedirectAndExpectToProceed( | |
| 280 GURL("http://example.test/activate.html?v=1")); | |
| 281 SimulateCommitAndExpectToProceed(); | |
| 282 | |
| 283 ActivationState state = last_activation_state(); | |
| 284 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.
| |
| 285 } | |
| 286 | |
| 287 TEST_F(ActivationStateComputingNavigationThrottleTest, | |
| 288 DisabledStatePropagatedDocument) { | |
| 289 InitializeDocumentSubresourceFilter(GURL("http://example.test")); | |
| 290 ActivationState parent_activation(ActivationLevel::ENABLED); | |
| 291 parent_activation.filtering_disabled_for_document = true; | |
| 292 CreateSubframeAndInitTestNavigation(GURL("http://example.test/activate.html"), | |
| 293 parent_activation); | |
| 294 SimulateStartAndExpectToProceed(); | |
| 295 SimulateRedirectAndExpectToProceed( | |
| 296 GURL("http://example.test/activate.html?v=1")); | |
| 297 SimulateCommitAndExpectToProceed(); | |
| 298 | |
| 299 ActivationState state = last_activation_state(); | |
| 300 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 301 EXPECT_TRUE(state.filtering_disabled_for_document); | |
| 302 EXPECT_FALSE(state.generic_blocking_rules_disabled); | |
| 303 } | |
| 304 | |
| 305 TEST_F(ActivationStateComputingNavigationThrottleTest, | |
| 306 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.
| |
| 307 InitializeDocumentSubresourceFilter(GURL("http://example.test")); | |
| 308 ActivationState parent_activation(ActivationLevel::ENABLED); | |
| 309 parent_activation.generic_blocking_rules_disabled = true; | |
| 310 CreateSubframeAndInitTestNavigation(GURL("http://example.test/activate.html"), | |
| 311 parent_activation); | |
| 312 SimulateStartAndExpectToProceed(); | |
| 313 SimulateRedirectAndExpectToProceed( | |
| 314 GURL("http://example.test/activate.html?v=1")); | |
| 315 SimulateCommitAndExpectToProceed(); | |
| 316 | |
| 317 ActivationState state = last_activation_state(); | |
| 318 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 319 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 320 EXPECT_TRUE(state.generic_blocking_rules_disabled); | |
| 321 } | |
| 322 | |
| 323 } // namespace subresource_filter | |
| OLD | NEW |