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 NavigateAndCommitMainFrameWithPageActivationState( |
| 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 typedef ActivationStateComputingNavigationThrottleTest |
| 211 ActivationStateComputingThrottleMainFrameTest; |
| 212 typedef ActivationStateComputingNavigationThrottleTest |
| 213 ActivationStateComputingThrottleSubFrameTest; |
| 214 |
| 215 TEST_F(ActivationStateComputingThrottleMainFrameTest, Activate) { |
| 216 NavigateAndCommitMainFrameWithPageActivationState( |
| 217 GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED)); |
| 218 ActivationState state = last_activation_state(); |
| 219 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 220 EXPECT_FALSE(state.filtering_disabled_for_document); |
| 221 } |
| 222 |
| 223 TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| 224 NoPageActivationNotification_NoActivation) { |
| 225 CreateTestNavigationForMainFrame(GURL("http://example.test/")); |
| 226 SimulateStartAndExpectToProceed(); |
| 227 SimulateRedirectAndExpectToProceed(GURL("http://example.test/?v=1")); |
| 228 |
| 229 // Never send NotifyPageActivation. |
| 230 SimulateCommitAndExpectToProceed(); |
| 231 |
| 232 ActivationState state = last_activation_state(); |
| 233 EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); |
| 234 } |
| 235 |
| 236 TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| 237 DisabledPageActivation_NoActivation) { |
| 238 // Notify that the page level activation is explicitly disabled. Should be |
| 239 // equivalent to not sending the message at all to the main frame throttle. |
| 240 NavigateAndCommitMainFrameWithPageActivationState( |
| 241 GURL("http://example.test/"), ActivationState(ActivationLevel::DISABLED)); |
| 242 ActivationState state = last_activation_state(); |
| 243 EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); |
| 244 } |
| 245 |
| 246 TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| 247 WhitelistDoesNotApply_CausesActivation) { |
| 248 NavigateAndCommitMainFrameWithPageActivationState( |
| 249 GURL("http://allow-child-to-be-whitelisted.com/"), |
| 250 ActivationState(ActivationLevel::ENABLED)); |
| 251 |
| 252 NavigateAndCommitMainFrameWithPageActivationState( |
| 253 GURL("http://whitelisted.com/"), |
| 254 ActivationState(ActivationLevel::ENABLED)); |
| 255 |
| 256 ActivationState state = last_activation_state(); |
| 257 EXPECT_FALSE(state.filtering_disabled_for_document); |
| 258 EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| 259 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 260 } |
| 261 |
| 262 TEST_F(ActivationStateComputingThrottleMainFrameTest, |
| 263 Whitelisted_DisablesFiltering) { |
| 264 NavigateAndCommitMainFrameWithPageActivationState( |
| 265 GURL("http://whitelisted-always.com/"), |
| 266 ActivationState(ActivationLevel::ENABLED)); |
| 267 |
| 268 ActivationState state = last_activation_state(); |
| 269 EXPECT_TRUE(state.filtering_disabled_for_document); |
| 270 EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| 271 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 272 } |
| 273 |
| 274 TEST_F(ActivationStateComputingThrottleSubFrameTest, Activate) { |
| 275 NavigateAndCommitMainFrameWithPageActivationState( |
| 276 GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED)); |
| 277 |
| 278 CreateSubframeAndInitTestNavigation(GURL("http://example.child/"), |
| 279 last_committed_frame_host(), |
| 280 last_activation_state()); |
| 281 SimulateStartAndExpectToProceed(); |
| 282 SimulateRedirectAndExpectToProceed(GURL("http://example.child/?v=1")); |
| 283 SimulateCommitAndExpectToProceed(); |
| 284 |
| 285 ActivationState state = last_activation_state(); |
| 286 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 287 EXPECT_FALSE(state.filtering_disabled_for_document); |
| 288 EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| 289 } |
| 290 |
| 291 TEST_F(ActivationStateComputingThrottleSubFrameTest, |
| 292 WhitelistDoesNotApply_CausesActivation) { |
| 293 NavigateAndCommitMainFrameWithPageActivationState( |
| 294 GURL("http://disallows-child-to-be-whitelisted.com/"), |
| 295 ActivationState(ActivationLevel::ENABLED)); |
| 296 |
| 297 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), |
| 298 last_committed_frame_host(), |
| 299 last_activation_state()); |
| 300 SimulateStartAndExpectToProceed(); |
| 301 SimulateCommitAndExpectToProceed(); |
| 302 |
| 303 ActivationState state = last_activation_state(); |
| 304 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 305 EXPECT_FALSE(state.filtering_disabled_for_document); |
| 306 EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| 307 } |
| 308 |
| 309 TEST_F(ActivationStateComputingThrottleSubFrameTest, |
| 310 Whitelisted_DisableDocumentFiltering) { |
| 311 NavigateAndCommitMainFrameWithPageActivationState( |
| 312 GURL("http://allow-child-to-be-whitelisted.com/"), |
| 313 ActivationState(ActivationLevel::ENABLED)); |
| 314 |
| 315 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), |
| 316 last_committed_frame_host(), |
| 317 last_activation_state()); |
| 318 SimulateStartAndExpectToProceed(); |
| 319 SimulateCommitAndExpectToProceed(); |
| 320 |
| 321 ActivationState state = last_activation_state(); |
| 322 EXPECT_TRUE(state.filtering_disabled_for_document); |
| 323 EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| 324 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 325 } |
| 326 |
| 327 TEST_F(ActivationStateComputingThrottleSubFrameTest, |
| 328 Whitelisted_DisablesGenericRules) { |
| 329 NavigateAndCommitMainFrameWithPageActivationState( |
| 330 GURL("http://allow-child-to-be-whitelisted.com/"), |
| 331 ActivationState(ActivationLevel::ENABLED)); |
| 332 |
| 333 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted-generic.com/"), |
| 334 last_committed_frame_host(), |
| 335 last_activation_state()); |
| 336 SimulateStartAndExpectToProceed(); |
| 337 SimulateCommitAndExpectToProceed(); |
| 338 |
| 339 ActivationState state = last_activation_state(); |
| 340 EXPECT_FALSE(state.filtering_disabled_for_document); |
| 341 EXPECT_TRUE(state.generic_blocking_rules_disabled); |
| 342 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 343 } |
| 344 |
| 345 TEST_F(ActivationStateComputingThrottleSubFrameTest, DryRunIsPropagated) { |
| 346 NavigateAndCommitMainFrameWithPageActivationState( |
| 347 GURL("http://example.test/"), ActivationState(ActivationLevel::DRYRUN)); |
| 348 EXPECT_EQ(ActivationLevel::DRYRUN, last_activation_state().activation_level); |
| 349 |
| 350 CreateSubframeAndInitTestNavigation(GURL("http://example.child/"), |
| 351 last_committed_frame_host(), |
| 352 last_activation_state()); |
| 353 SimulateStartAndExpectToProceed(); |
| 354 SimulateRedirectAndExpectToProceed(GURL("http://example.child/?v=1")); |
| 355 SimulateCommitAndExpectToProceed(); |
| 356 |
| 357 ActivationState state = last_activation_state(); |
| 358 EXPECT_EQ(ActivationLevel::DRYRUN, state.activation_level); |
| 359 EXPECT_FALSE(state.filtering_disabled_for_document); |
| 360 EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| 361 } |
| 362 |
| 363 TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated) { |
| 364 NavigateAndCommitMainFrameWithPageActivationState( |
| 365 GURL("http://allow-child-to-be-whitelisted.com/"), |
| 366 ActivationState(ActivationLevel::ENABLED)); |
| 367 |
| 368 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com"), |
| 369 last_committed_frame_host(), |
| 370 last_activation_state()); |
| 371 SimulateStartAndExpectToProceed(); |
| 372 SimulateCommitAndExpectToProceed(); |
| 373 |
| 374 CreateSubframeAndInitTestNavigation(GURL("http://example.test/"), |
| 375 last_committed_frame_host(), |
| 376 last_activation_state()); |
| 377 SimulateStartAndExpectToProceed(); |
| 378 SimulateCommitAndExpectToProceed(); |
| 379 |
| 380 ActivationState state = last_activation_state(); |
| 381 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 382 EXPECT_TRUE(state.filtering_disabled_for_document); |
| 383 EXPECT_FALSE(state.generic_blocking_rules_disabled); |
| 384 } |
| 385 |
| 386 TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated2) { |
| 387 NavigateAndCommitMainFrameWithPageActivationState( |
| 388 GURL("http://allow-child-to-be-whitelisted.com/"), |
| 389 ActivationState(ActivationLevel::ENABLED)); |
| 390 |
| 391 CreateSubframeAndInitTestNavigation( |
| 392 GURL("http://whitelisted-generic-with-disabled-child.com/"), |
| 393 last_committed_frame_host(), last_activation_state()); |
| 394 SimulateStartAndExpectToProceed(); |
| 395 SimulateCommitAndExpectToProceed(); |
| 396 |
| 397 ActivationState state = last_activation_state(); |
| 398 EXPECT_FALSE(state.filtering_disabled_for_document); |
| 399 EXPECT_TRUE(state.generic_blocking_rules_disabled); |
| 400 |
| 401 CreateSubframeAndInitTestNavigation(GURL("http://whitelisted.com/"), |
| 402 last_committed_frame_host(), |
| 403 last_activation_state()); |
| 404 SimulateStartAndExpectToProceed(); |
| 405 SimulateCommitAndExpectToProceed(); |
| 406 |
| 407 state = last_activation_state(); |
| 408 EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); |
| 409 EXPECT_TRUE(state.filtering_disabled_for_document); |
| 410 EXPECT_TRUE(state.generic_blocking_rules_disabled); |
| 411 } |
| 412 |
| 413 } // namespace subresource_filter |
OLD | NEW |