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/macros.h" | |
| 12 #include "base/memory/ptr_util.h" | |
| 13 #include "base/optional.h" | |
| 14 #include "base/run_loop.h" | |
| 15 #include "base/test/test_simple_task_runner.h" | |
| 16 #include "components/subresource_filter/content/browser/async_document_subresour ce_filter.h" | |
| 17 #include "components/subresource_filter/content/browser/async_document_subresour ce_filter_test_utils.h" | |
| 18 #include "components/subresource_filter/core/common/activation_level.h" | |
| 19 #include "components/subresource_filter/core/common/activation_state.h" | |
| 20 #include "components/subresource_filter/core/common/proto/rules.pb.h" | |
| 21 #include "components/subresource_filter/core/common/test_ruleset_creator.h" | |
| 22 #include "components/subresource_filter/core/common/test_ruleset_utils.h" | |
| 23 #include "content/public/browser/navigation_handle.h" | |
| 24 #include "content/public/browser/web_contents_observer.h" | |
| 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 ruleset_handle_.reset(); | |
| 47 dealer_handle_.reset(); | |
| 48 RunUntilIdle(); | |
| 49 content::RenderViewHostTestHarness::TearDown(); | |
| 50 } | |
| 51 | |
| 52 void InitializeRuleset() { | |
| 53 std::vector<proto::UrlRule> rules; | |
| 54 rules.push_back(testing::CreateWhitelistRuleForDocument( | |
| 55 "whitelisted.com", proto::ACTIVATION_TYPE_DOCUMENT, | |
| 56 {"allow-child-to-be-whitelisted.com", | |
| 57 "whitelisted-generic-with-disabled-child.com"})); | |
| 58 | |
| 59 rules.push_back(testing::CreateWhitelistRuleForDocument( | |
| 60 "whitelisted-generic.com", proto::ACTIVATION_TYPE_GENERICBLOCK, | |
| 61 {"allow-child-to-be-whitelisted.com"})); | |
| 62 | |
| 63 rules.push_back(testing::CreateWhitelistRuleForDocument( | |
| 64 "whitelisted-generic-with-disabled-child.com", | |
| 65 proto::ACTIVATION_TYPE_GENERICBLOCK, | |
| 66 {"allow-child-to-be-whitelisted.com"})); | |
| 67 | |
| 68 rules.push_back(testing::CreateWhitelistRuleForDocument( | |
| 69 "whitelisted-always.com", proto::ACTIVATION_TYPE_DOCUMENT)); | |
| 70 | |
| 71 ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules( | |
| 72 rules, &test_ruleset_pair_)); | |
| 73 | |
| 74 // Make the blocking task runner run on the current task runner for the | |
| 75 // tests, to ensure that the NavigationSimulator properly runs all necessary | |
| 76 // tasks while waiting for throttle checks to finish. | |
| 77 dealer_handle_ = base::MakeUnique<VerifiedRulesetDealer::Handle>( | |
| 78 base::MessageLoop::current()->task_runner()); | |
| 79 dealer_handle_->SetRulesetFile( | |
| 80 testing::TestRuleset::Open(test_ruleset_pair_.indexed)); | |
| 81 ruleset_handle_ = | |
| 82 base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle_.get()); | |
| 83 } | |
| 84 | |
| 85 void NavigateAndCommitToMainFrameWithPageActivation( | |
|
engedy
2017/03/10 18:33:43
nit: NavigateAndCommitMainFrameWithPageActivationS
Charlie Harrison
2017/03/10 18:48:54
Done.
| |
| 86 const GURL& document_url, | |
| 87 const ActivationState& page_activation) { | |
| 88 CreateTestNavigationForMainFrame(document_url); | |
| 89 SimulateStartAndExpectToProceed(); | |
| 90 | |
| 91 NotifyPageActivation(page_activation); | |
| 92 SimulateCommitAndExpectToProceed(); | |
| 93 } | |
| 94 | |
| 95 void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } | |
| 96 | |
| 97 void CreateTestNavigationForMainFrame(const GURL& first_url) { | |
| 98 navigation_simulator_ = | |
| 99 content::NavigationSimulator::CreateRendererInitiated(first_url, | |
| 100 main_rfh()); | |
| 101 } | |
| 102 | |
| 103 void CreateSubframeAndInitTestNavigation( | |
| 104 const GURL& first_url, | |
| 105 content::RenderFrameHost* parent, | |
| 106 const ActivationState& parent_activation_state) { | |
| 107 ASSERT_TRUE(parent); | |
| 108 parent_activation_state_ = parent_activation_state; | |
| 109 content::RenderFrameHost* navigating_subframe = | |
| 110 content::RenderFrameHostTester::For(parent)->AppendChild("subframe"); | |
| 111 navigation_simulator_ = | |
| 112 content::NavigationSimulator::CreateRendererInitiated( | |
| 113 first_url, navigating_subframe); | |
| 114 } | |
| 115 | |
| 116 void SimulateStartAndExpectToProceed() { | |
| 117 ASSERT_TRUE(navigation_simulator_); | |
| 118 navigation_simulator_->Start(); | |
| 119 EXPECT_EQ(content::NavigationThrottle::PROCEED, | |
| 120 navigation_simulator_->GetLastThrottleCheckResult()); | |
| 121 } | |
| 122 | |
| 123 void SimulateRedirectAndExpectToProceed(const GURL& new_url) { | |
| 124 navigation_simulator_->Redirect(new_url); | |
| 125 EXPECT_EQ(content::NavigationThrottle::PROCEED, | |
| 126 navigation_simulator_->GetLastThrottleCheckResult()); | |
| 127 } | |
| 128 | |
| 129 void SimulateCommitAndExpectToProceed() { | |
| 130 navigation_simulator_->Commit(); | |
| 131 EXPECT_EQ(content::NavigationThrottle::PROCEED, | |
| 132 navigation_simulator_->GetLastThrottleCheckResult()); | |
| 133 } | |
| 134 | |
| 135 void NotifyPageActivation(ActivationState state) { | |
| 136 test_throttle_->NotifyPageActivationWithRuleset( | |
| 137 state.activation_level == ActivationLevel::DISABLED | |
| 138 ? nullptr | |
| 139 : ruleset_handle_.get(), | |
| 140 state); | |
| 141 } | |
| 142 | |
| 143 ActivationState last_activation_state() { | |
| 144 EXPECT_TRUE(last_activation_state_.has_value()); | |
| 145 return last_activation_state_.value_or( | |
| 146 ActivationState(ActivationLevel::DISABLED)); | |
| 147 } | |
| 148 | |
| 149 content::RenderFrameHost* last_committed_frame_host() { | |
| 150 return last_committed_frame_host_; | |
| 151 } | |
| 152 | |
| 153 protected: | |
| 154 // content::WebContentsObserver: | |
| 155 void DidStartNavigation( | |
| 156 content::NavigationHandle* navigation_handle) override { | |
| 157 std::unique_ptr<ActivationStateComputingNavigationThrottle> throttle = | |
| 158 navigation_handle->IsInMainFrame() | |
| 159 ? ActivationStateComputingNavigationThrottle::CreateForMainFrame( | |
| 160 navigation_handle) | |
| 161 : ActivationStateComputingNavigationThrottle::CreateForSubframe( | |
| 162 navigation_handle, ruleset_handle_.get(), | |
| 163 parent_activation_state_.value()); | |
| 164 test_throttle_ = throttle.get(); | |
| 165 navigation_handle->RegisterThrottleForTesting(std::move(throttle)); | |
| 166 } | |
| 167 | |
| 168 void ReadyToCommitNavigation( | |
| 169 content::NavigationHandle* navigation_handle) override { | |
| 170 if (!test_throttle_) | |
| 171 return; | |
| 172 ASSERT_EQ(navigation_handle, test_throttle_->navigation_handle()); | |
| 173 last_activation_state_ = test_throttle_->GetActivationState(); | |
| 174 if (last_activation_state_.value().activation_level == | |
| 175 ActivationLevel::DISABLED) { | |
| 176 EXPECT_FALSE(test_throttle_->ReleaseFilter()); | |
| 177 } else { | |
| 178 EXPECT_TRUE(test_throttle_->ReleaseFilter()); | |
| 179 } | |
| 180 } | |
| 181 | |
| 182 void DidFinishNavigation( | |
| 183 content::NavigationHandle* navigation_handle) override { | |
| 184 if (!test_throttle_) | |
| 185 return; | |
| 186 last_committed_frame_host_ = navigation_handle->GetRenderFrameHost(); | |
| 187 test_throttle_ = nullptr; | |
| 188 } | |
| 189 | |
| 190 private: | |
| 191 testing::TestRulesetCreator test_ruleset_creator_; | |
| 192 testing::TestRulesetPair test_ruleset_pair_; | |
| 193 | |
| 194 std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_; | |
| 195 std::unique_ptr<VerifiedRuleset::Handle> ruleset_handle_; | |
| 196 | |
| 197 std::unique_ptr<content::NavigationSimulator> navigation_simulator_; | |
| 198 | |
| 199 // Owned by the current navigation. | |
| 200 ActivationStateComputingNavigationThrottle* test_throttle_; | |
| 201 base::Optional<ActivationState> last_activation_state_; | |
| 202 base::Optional<ActivationState> parent_activation_state_; | |
| 203 | |
| 204 // Needed for potential cross process navigations which swap hosts. | |
| 205 content::RenderFrameHost* last_committed_frame_host_ = nullptr; | |
| 206 | |
| 207 DISALLOW_COPY_AND_ASSIGN(ActivationStateComputingNavigationThrottleTest); | |
| 208 }; | |
| 209 | |
| 210 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.
| |
| 211 : public ActivationStateComputingNavigationThrottleTest {}; | |
| 212 class ActivationStateComputingThrottleSubFrameTest | |
| 213 : public ActivationStateComputingNavigationThrottleTest {}; | |
| 214 | |
| 215 // Main frame tests | |
| 216 TEST_F(ActivationStateComputingThrottleMainFrameTest, Activate) { | |
| 217 NavigateAndCommitToMainFrameWithPageActivation( | |
| 218 GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED)); | |
| 219 ActivationState state = last_activation_state(); | |
| 220 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 221 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 222 } | |
| 223 | |
| 224 TEST_F(ActivationStateComputingThrottleMainFrameTest, | |
| 225 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.
| |
| 226 CreateTestNavigationForMainFrame(GURL("http://example.test/")); | |
| 227 SimulateStartAndExpectToProceed(); | |
| 228 SimulateRedirectAndExpectToProceed(GURL("http://example.test/?v=1")); | |
| 229 | |
| 230 // Never send NotifyPageActivation. | |
| 231 SimulateCommitAndExpectToProceed(); | |
| 232 | |
| 233 ActivationState state = last_activation_state(); | |
| 234 EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); | |
| 235 } | |
| 236 | |
| 237 TEST_F(ActivationStateComputingThrottleMainFrameTest, | |
| 238 DisabledPageState_NoActivation) { | |
| 239 // Notify that the page level activation is explicitly disabled. Should be | |
| 240 // equivalent to not sending the message at all to the main frame throttle. | |
| 241 NavigateAndCommitToMainFrameWithPageActivation( | |
| 242 GURL("http://example.test/"), ActivationState(ActivationLevel::DISABLED)); | |
| 243 ActivationState state = last_activation_state(); | |
| 244 EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); | |
| 245 } | |
| 246 | |
| 247 TEST_F(ActivationStateComputingThrottleMainFrameTest, | |
| 248 WhitelistDoesNotApply_CausesActivation) { | |
| 249 NavigateAndCommitToMainFrameWithPageActivation( | |
| 250 GURL("http://allow-child-to-be-whitelisted.com/"), | |
| 251 ActivationState(ActivationLevel::ENABLED)); | |
| 252 | |
| 253 // Not really a child frame, so whitelist should not apply. | |
| 254 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.
| |
| 255 SimulateStartAndExpectToProceed(); | |
| 256 | |
| 257 // Main frames will usually have their "parent" activation state set right | |
| 258 // before WillProcessResponse. | |
| 259 NotifyPageActivation(ActivationState(ActivationLevel::ENABLED)); | |
| 260 SimulateCommitAndExpectToProceed(); | |
| 261 | |
| 262 ActivationState state = last_activation_state(); | |
| 263 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.
| |
| 264 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 265 } | |
| 266 | |
| 267 TEST_F(ActivationStateComputingThrottleMainFrameTest, | |
| 268 Whitelisted_DisablesDocumentFiltering) { | |
|
engedy
2017/03/10 18:33:42
nit: s/DisablesDocumentFiltering/DisablesFiltering
Charlie Harrison
2017/03/10 18:48:54
Done.
| |
| 269 NavigateAndCommitToMainFrameWithPageActivation( | |
| 270 GURL("http://whitelisted-always.com/"), | |
| 271 ActivationState(ActivationLevel::ENABLED)); | |
| 272 | |
| 273 ActivationState state = last_activation_state(); | |
| 274 EXPECT_TRUE(state.filtering_disabled_for_document); | |
| 275 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 276 } | |
| 277 | |
| 278 // 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.
| |
| 279 TEST_F(ActivationStateComputingThrottleSubFrameTest, Activate) { | |
| 280 NavigateAndCommitToMainFrameWithPageActivation( | |
| 281 GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED)); | |
| 282 | |
| 283 CreateSubframeAndInitTestNavigation(GURL("http://example.child/"), | |
| 284 last_committed_frame_host(), | |
| 285 last_activation_state()); | |
| 286 SimulateStartAndExpectToProceed(); | |
| 287 SimulateRedirectAndExpectToProceed(GURL("http://example.child/?v=1")); | |
| 288 SimulateCommitAndExpectToProceed(); | |
| 289 | |
| 290 ActivationState state = last_activation_state(); | |
| 291 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 292 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 293 } | |
| 294 | |
| 295 TEST_F(ActivationStateComputingThrottleSubFrameTest, | |
| 296 WhitelistDoesNotApply_CausesActivation) { | |
| 297 NavigateAndCommitToMainFrameWithPageActivation( | |
| 298 GURL("http://disallows-child-to-be-whitelisted.com/"), | |
| 299 ActivationState(ActivationLevel::ENABLED)); | |
| 300 | |
| 301 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), | |
| 302 last_committed_frame_host(), | |
| 303 last_activation_state()); | |
| 304 SimulateStartAndExpectToProceed(); | |
| 305 SimulateCommitAndExpectToProceed(); | |
| 306 | |
| 307 ActivationState state = last_activation_state(); | |
| 308 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 309 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 310 } | |
| 311 | |
| 312 TEST_F(ActivationStateComputingThrottleSubFrameTest, | |
| 313 Whitelisted_DisableDocumentFiltering) { | |
| 314 NavigateAndCommitToMainFrameWithPageActivation( | |
| 315 GURL("http://allow-child-to-be-whitelisted.com/"), | |
| 316 ActivationState(ActivationLevel::ENABLED)); | |
| 317 | |
| 318 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), | |
| 319 last_committed_frame_host(), | |
| 320 last_activation_state()); | |
| 321 SimulateStartAndExpectToProceed(); | |
| 322 SimulateCommitAndExpectToProceed(); | |
| 323 | |
| 324 ActivationState state = last_activation_state(); | |
| 325 EXPECT_TRUE(state.filtering_disabled_for_document); | |
| 326 EXPECT_FALSE(state.generic_blocking_rules_disabled); | |
| 327 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 328 } | |
| 329 | |
| 330 TEST_F(ActivationStateComputingThrottleSubFrameTest, | |
| 331 Whitelisted_DisablesGenericBlocking) { | |
|
engedy
2017/03/10 18:33:42
nit: DisablesGenericRules
Charlie Harrison
2017/03/10 18:48:54
Done.
| |
| 332 NavigateAndCommitToMainFrameWithPageActivation( | |
| 333 GURL("http://allow-child-to-be-whitelisted.com/"), | |
| 334 ActivationState(ActivationLevel::ENABLED)); | |
| 335 | |
| 336 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted-generic.com/"), | |
| 337 last_committed_frame_host(), | |
| 338 last_activation_state()); | |
| 339 SimulateStartAndExpectToProceed(); | |
| 340 SimulateCommitAndExpectToProceed(); | |
| 341 | |
| 342 ActivationState state = last_activation_state(); | |
| 343 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 344 EXPECT_TRUE(state.generic_blocking_rules_disabled); | |
| 345 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 346 } | |
| 347 | |
| 348 TEST_F(ActivationStateComputingThrottleSubFrameTest, DryRunIsPropagated) { | |
| 349 NavigateAndCommitToMainFrameWithPageActivation( | |
| 350 GURL("http://example.test/"), ActivationState(ActivationLevel::DRYRUN)); | |
| 351 EXPECT_EQ(ActivationLevel::DRYRUN, last_activation_state().activation_level); | |
| 352 | |
| 353 CreateSubframeAndInitTestNavigation(GURL("http://example.child/"), | |
| 354 last_committed_frame_host(), | |
| 355 last_activation_state()); | |
| 356 SimulateStartAndExpectToProceed(); | |
| 357 SimulateRedirectAndExpectToProceed(GURL("http://example.child/?v=1")); | |
| 358 SimulateCommitAndExpectToProceed(); | |
| 359 | |
| 360 ActivationState state = last_activation_state(); | |
| 361 EXPECT_EQ(ActivationLevel::DRYRUN, state.activation_level); | |
| 362 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 363 EXPECT_FALSE(state.generic_blocking_rules_disabled); | |
| 364 } | |
| 365 | |
| 366 TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated) { | |
| 367 NavigateAndCommitToMainFrameWithPageActivation( | |
| 368 GURL("http://allow-child-to-be-whitelisted.com/"), | |
| 369 ActivationState(ActivationLevel::ENABLED)); | |
| 370 | |
| 371 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com"), | |
| 372 last_committed_frame_host(), | |
| 373 last_activation_state()); | |
| 374 SimulateStartAndExpectToProceed(); | |
| 375 SimulateCommitAndExpectToProceed(); | |
| 376 | |
| 377 CreateSubframeAndInitTestNavigation(GURL("http://example.test/"), | |
| 378 last_committed_frame_host(), | |
| 379 last_activation_state()); | |
| 380 SimulateStartAndExpectToProceed(); | |
| 381 SimulateCommitAndExpectToProceed(); | |
| 382 | |
| 383 ActivationState state = last_activation_state(); | |
| 384 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 385 EXPECT_TRUE(state.filtering_disabled_for_document); | |
| 386 EXPECT_FALSE(state.generic_blocking_rules_disabled); | |
| 387 } | |
| 388 | |
| 389 TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated2) { | |
| 390 NavigateAndCommitToMainFrameWithPageActivation( | |
| 391 GURL("http://allow-child-to-be-whitelisted.com/"), | |
| 392 ActivationState(ActivationLevel::ENABLED)); | |
| 393 | |
| 394 CreateSubframeAndInitTestNavigation( | |
| 395 GURL("http://whitelisted-generic-with-disabled-child.com/"), | |
| 396 last_committed_frame_host(), last_activation_state()); | |
| 397 SimulateStartAndExpectToProceed(); | |
| 398 SimulateCommitAndExpectToProceed(); | |
| 399 | |
| 400 ActivationState state = last_activation_state(); | |
| 401 EXPECT_FALSE(state.filtering_disabled_for_document); | |
| 402 EXPECT_TRUE(state.generic_blocking_rules_disabled); | |
| 403 | |
| 404 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), | |
| 405 last_committed_frame_host(), | |
| 406 last_activation_state()); | |
| 407 SimulateStartAndExpectToProceed(); | |
| 408 SimulateCommitAndExpectToProceed(); | |
| 409 | |
| 410 state = last_activation_state(); | |
| 411 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); | |
| 412 EXPECT_TRUE(state.filtering_disabled_for_document); | |
| 413 EXPECT_TRUE(state.generic_blocking_rules_disabled); | |
| 414 } | |
| 415 | |
| 416 } // namespace subresource_filter | |
| OLD | NEW |