OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chrome_content_browser_client.h" | 5 #include "chrome/browser/chrome_content_browser_client.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/message_loop/message_loop.h" |
11 #include "base/metrics/field_trial.h" | 13 #include "base/metrics/field_trial.h" |
12 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
13 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 16 #include "chrome/browser/browsing_data/browsing_data_filter_builder.h" |
| 17 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
| 18 #include "chrome/browser/browsing_data/browsing_data_remover.h" |
| 19 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h" |
| 20 #include "chrome/browser/browsing_data/origin_filter_builder.h" |
| 21 #include "chrome/browser/browsing_data/registrable_domain_filter_builder.h" |
14 #include "chrome/browser/search_engines/template_url_service_factory.h" | 22 #include "chrome/browser/search_engines/template_url_service_factory.h" |
| 23 #include "chrome/test/base/testing_profile.h" |
15 #include "components/content_settings/core/browser/host_content_settings_map.h" | 24 #include "components/content_settings/core/browser/host_content_settings_map.h" |
16 #include "components/search_engines/template_url_service.h" | 25 #include "components/search_engines/template_url_service.h" |
17 #include "components/variations/entropy_provider.h" | 26 #include "components/variations/entropy_provider.h" |
18 #include "components/variations/variations_associated_data.h" | 27 #include "components/variations/variations_associated_data.h" |
19 #include "components/version_info/version_info.h" | 28 #include "components/version_info/version_info.h" |
20 #include "content/public/browser/navigation_controller.h" | 29 #include "content/public/browser/navigation_controller.h" |
21 #include "content/public/browser/navigation_entry.h" | 30 #include "content/public/browser/navigation_entry.h" |
22 #include "content/public/browser/web_contents.h" | 31 #include "content/public/browser/web_contents.h" |
23 #include "content/public/common/content_switches.h" | 32 #include "content/public/common/content_switches.h" |
24 #include "content/public/test/test_browser_thread_bundle.h" | 33 #include "content/public/test/test_browser_thread_bundle.h" |
| 34 #include "testing/gmock/include/gmock/gmock.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
26 #include "url/gurl.h" | 36 #include "url/gurl.h" |
27 | 37 |
28 #if !defined(OS_ANDROID) | 38 #if !defined(OS_ANDROID) |
29 #include "chrome/browser/ui/browser.h" | 39 #include "chrome/browser/ui/browser.h" |
30 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 40 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
31 #include "chrome/common/pref_names.h" | 41 #include "chrome/common/pref_names.h" |
32 #include "chrome/test/base/browser_with_test_window_test.h" | 42 #include "chrome/test/base/browser_with_test_window_test.h" |
33 #include "chrome/test/base/search_test_utils.h" | 43 #include "chrome/test/base/search_test_utils.h" |
34 #endif | 44 #endif |
35 | 45 |
| 46 using testing::_; |
36 using ChromeContentBrowserClientTest = testing::Test; | 47 using ChromeContentBrowserClientTest = testing::Test; |
37 | 48 |
38 TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) { | 49 TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) { |
39 ChromeContentBrowserClient client; | 50 ChromeContentBrowserClient client; |
40 EXPECT_FALSE(client.ShouldAssignSiteForURL(GURL("chrome-native://test"))); | 51 EXPECT_FALSE(client.ShouldAssignSiteForURL(GURL("chrome-native://test"))); |
41 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("http://www.google.com"))); | 52 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("http://www.google.com"))); |
42 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("https://www.google.com"))); | 53 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("https://www.google.com"))); |
43 } | 54 } |
44 | 55 |
45 // BrowserWithTestWindowTest doesn't work on Android. | 56 // BrowserWithTestWindowTest doesn't work on Android. |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 | 332 |
322 NavigationEntry* entry = browser()->tab_strip_model()-> | 333 NavigationEntry* entry = browser()->tab_strip_model()-> |
323 GetActiveWebContents()->GetController().GetLastCommittedEntry(); | 334 GetActiveWebContents()->GetController().GetLastCommittedEntry(); |
324 ASSERT_TRUE(entry != NULL); | 335 ASSERT_TRUE(entry != NULL); |
325 EXPECT_EQ(url_rewritten, entry->GetURL()); | 336 EXPECT_EQ(url_rewritten, entry->GetURL()); |
326 EXPECT_EQ(url_original, entry->GetVirtualURL()); | 337 EXPECT_EQ(url_original, entry->GetVirtualURL()); |
327 } | 338 } |
328 | 339 |
329 } // namespace content | 340 } // namespace content |
330 #endif // !defined(OS_ANDROID) | 341 #endif // !defined(OS_ANDROID) |
| 342 |
| 343 namespace { |
| 344 |
| 345 // Tests for ChromeContentBrowserClient::ClearSiteData(). |
| 346 class ChromeContentBrowserClientClearSiteDataTest : public testing::Test { |
| 347 public: |
| 348 class MockBrowsingDataRemover : public BrowsingDataRemover { |
| 349 public: |
| 350 explicit MockBrowsingDataRemover(content::BrowserContext* context) |
| 351 : BrowsingDataRemover(context) {} |
| 352 ~MockBrowsingDataRemover() {} |
| 353 |
| 354 MOCK_METHOD4(RemoveWithFilter, |
| 355 void(const TimeRange& time_range, |
| 356 int remove_mask, |
| 357 int origin_type_mask, |
| 358 const BrowsingDataFilterBuilder& filter_builder)); |
| 359 }; |
| 360 |
| 361 void SetUp() override { |
| 362 BrowsingDataRemoverFactory::GetInstance()->SetTestingFactoryAndUse( |
| 363 &profile_, &ChromeContentBrowserClientClearSiteDataTest::GetRemover); |
| 364 } |
| 365 |
| 366 content::BrowserContext* profile() { return &profile_; } |
| 367 |
| 368 MockBrowsingDataRemover* remover() { |
| 369 return static_cast<MockBrowsingDataRemover*>( |
| 370 BrowsingDataRemoverFactory::GetForBrowserContext(&profile_)); |
| 371 } |
| 372 |
| 373 private: |
| 374 static std::unique_ptr<KeyedService> GetRemover( |
| 375 content::BrowserContext* context) { |
| 376 return base::WrapUnique(new MockBrowsingDataRemover(context)); |
| 377 } |
| 378 |
| 379 base::MessageLoop loop_; |
| 380 TestingProfile profile_; |
| 381 }; |
| 382 |
| 383 // Matcher for BrowsingDataFilterBuilder. As it is not possible to compare |
| 384 // two BrowsingDataFilterBuilder-s of different kinds, it can only be used |
| 385 // when we know which subclass of BrowsingDataFilterBuilder we expect: |
| 386 // OriginFilterBuilder or RegistrableDomainFilterBuilder. |
| 387 class SameBuilderMatcher |
| 388 : public testing::MatcherInterface<const BrowsingDataFilterBuilder&> { |
| 389 public: |
| 390 explicit SameBuilderMatcher(const OriginFilterBuilder& builder) |
| 391 : origin_filter_builder_(&builder), domain_filter_builder_(nullptr) {} |
| 392 |
| 393 explicit SameBuilderMatcher(const RegistrableDomainFilterBuilder& builder) |
| 394 : origin_filter_builder_(nullptr), domain_filter_builder_(&builder) {} |
| 395 |
| 396 virtual bool MatchAndExplain(const BrowsingDataFilterBuilder& builder, |
| 397 testing::MatchResultListener* listener) const { |
| 398 DCHECK(origin_filter_builder_ || domain_filter_builder_); |
| 399 DCHECK(!origin_filter_builder_ || !domain_filter_builder_); |
| 400 |
| 401 if (origin_filter_builder_) { |
| 402 return *origin_filter_builder_ == |
| 403 static_cast<const OriginFilterBuilder&>(builder); |
| 404 } |
| 405 |
| 406 if (domain_filter_builder_) { |
| 407 return *domain_filter_builder_ == |
| 408 static_cast<const RegistrableDomainFilterBuilder&>(builder); |
| 409 } |
| 410 |
| 411 NOTREACHED(); |
| 412 return false; |
| 413 } |
| 414 |
| 415 void DescribeTo(std::ostream* os) const override { |
| 416 *os << "has the same scope, mode, and added entries as the expected " |
| 417 << "filter builder."; |
| 418 } |
| 419 |
| 420 void DescribeNegationTo(std::ostream* os) const override { |
| 421 *os << "differs from the expected filter builder in scope, mode, " |
| 422 << "or added entries."; |
| 423 } |
| 424 |
| 425 private: |
| 426 const OriginFilterBuilder* origin_filter_builder_; |
| 427 const RegistrableDomainFilterBuilder* domain_filter_builder_; |
| 428 }; |
| 429 |
| 430 // Tests that the parameters to ClearBrowsingData() are translated to |
| 431 // the correct BrowsingDataRemover::RemoveWithFilter() operation. The fourth |
| 432 // parameter, |filter_builder|, is tested in detail in the RegistrableDomains |
| 433 // test below. |
| 434 TEST_F(ChromeContentBrowserClientClearSiteDataTest, Parameters) { |
| 435 ChromeContentBrowserClient client; |
| 436 |
| 437 struct TestCase { |
| 438 bool cookies; |
| 439 bool storage; |
| 440 bool cache; |
| 441 int mask; |
| 442 } test_cases[] = { |
| 443 {false, false, false, 0}, |
| 444 {true, false, false, BrowsingDataRemover::REMOVE_COOKIES | |
| 445 BrowsingDataRemover::REMOVE_CHANNEL_IDS}, |
| 446 {false, true, false, BrowsingDataRemover::REMOVE_SITE_DATA & |
| 447 ~BrowsingDataRemover::REMOVE_COOKIES & |
| 448 ~BrowsingDataRemover::REMOVE_CHANNEL_IDS}, |
| 449 {false, false, true, BrowsingDataRemover::REMOVE_CACHE}, |
| 450 {true, true, false, BrowsingDataRemover::REMOVE_SITE_DATA}, |
| 451 {true, false, true, BrowsingDataRemover::REMOVE_COOKIES | |
| 452 BrowsingDataRemover::REMOVE_CHANNEL_IDS | |
| 453 BrowsingDataRemover::REMOVE_CACHE}, |
| 454 {false, true, true, BrowsingDataRemover::REMOVE_CACHE | |
| 455 (BrowsingDataRemover::REMOVE_SITE_DATA & |
| 456 ~BrowsingDataRemover::REMOVE_COOKIES & |
| 457 ~BrowsingDataRemover::REMOVE_CHANNEL_IDS)}, |
| 458 {true, true, true, BrowsingDataRemover::REMOVE_SITE_DATA | |
| 459 BrowsingDataRemover::REMOVE_CACHE}, |
| 460 }; |
| 461 |
| 462 for (const TestCase& test_case : test_cases) { |
| 463 SCOPED_TRACE(test_case.mask); |
| 464 |
| 465 // We always delete data for all time and all origin types. |
| 466 BrowsingDataRemover::TimeRange all_time(base::Time(), base::Time::Max()); |
| 467 BrowsingDataHelper::OriginTypeMask all_origin_types = |
| 468 BrowsingDataHelper::ALL; |
| 469 |
| 470 // Some data are deleted for the origin and some for the registrable domain. |
| 471 // Depending on the chosen datatypes, this might result into one or two |
| 472 // calls. In the latter case, the removal mask will be split into two |
| 473 // parts - one for the origin deletion and one for the registrable domain. |
| 474 const int domain_scoped_types = BrowsingDataRemover::REMOVE_COOKIES | |
| 475 BrowsingDataRemover::REMOVE_CHANNEL_IDS; |
| 476 int origin_deletion_mask = test_case.mask & ~domain_scoped_types; |
| 477 int registrable_domain_deletion_mask = test_case.mask & domain_scoped_types; |
| 478 |
| 479 EXPECT_CALL(*remover(), RemoveWithFilter(all_time, origin_deletion_mask, |
| 480 all_origin_types, _)) |
| 481 .Times(origin_deletion_mask != 0); |
| 482 |
| 483 EXPECT_CALL(*remover(), |
| 484 RemoveWithFilter(all_time, registrable_domain_deletion_mask, |
| 485 all_origin_types, _)) |
| 486 .Times(registrable_domain_deletion_mask != 0); |
| 487 |
| 488 client.ClearSiteData(profile(), |
| 489 url::Origin(GURL("https://www.example.com")), |
| 490 test_case.cookies, test_case.storage, test_case.cache); |
| 491 |
| 492 testing::Mock::VerifyAndClearExpectations(remover()); |
| 493 } |
| 494 } |
| 495 |
| 496 // Tests that ClearBrowsingData() called for an origin deletes cookies in the |
| 497 // scope of the registrable domain corresponding to that origin, while cache |
| 498 // is deleted for that exact origin. |
| 499 TEST_F(ChromeContentBrowserClientClearSiteDataTest, RegistrableDomains) { |
| 500 ChromeContentBrowserClient client; |
| 501 |
| 502 struct TestCase { |
| 503 const char* origin; // origin on which ClearSiteData() is called. |
| 504 const char* domain; // domain on which cookies will be deleted. |
| 505 } test_cases[] = { |
| 506 // TLD has no embedded dot. |
| 507 {"https://example.com", "example.com"}, |
| 508 {"https://www.example.com", "example.com"}, |
| 509 {"https://www.fourth.third.second.com", "second.com"}, |
| 510 |
| 511 // TLD has one embedded dot. |
| 512 {"https://www.example.co.uk", "example.co.uk"}, |
| 513 {"https://example.co.uk", "example.co.uk"}, |
| 514 |
| 515 // TLD has more embedded dots. |
| 516 {"https://www.website.sp.nom.br", "website.sp.nom.br"}, |
| 517 |
| 518 // IP addresses. |
| 519 {"http://127.0.0.1", "127.0.0.1"}, |
| 520 {"http://192.168.0.1", "192.168.0.1"}, |
| 521 {"http://192.168.0.1", "192.168.0.1"}, |
| 522 |
| 523 // Internal hostnames. |
| 524 {"http://localhost", "localhost"}, |
| 525 {"http://fileserver", "fileserver"}, |
| 526 |
| 527 // These are not subdomains of internal hostnames, but subdomain of |
| 528 // unknown TLDs. |
| 529 {"http://subdomain.localhost", "subdomain.localhost"}, |
| 530 {"http://www.subdomain.localhost", "subdomain.localhost"}, |
| 531 {"http://documents.fileserver", "documents.fileserver"}, |
| 532 |
| 533 // Scheme and port don't matter. |
| 534 {"http://example.com", "example.com"}, |
| 535 {"http://example.com:8080", "example.com"}, |
| 536 {"https://example.com:4433", "example.com"}, |
| 537 }; |
| 538 |
| 539 for (const TestCase& test_case : test_cases) { |
| 540 SCOPED_TRACE(test_case.origin); |
| 541 |
| 542 OriginFilterBuilder origin_filter_builder( |
| 543 BrowsingDataFilterBuilder::WHITELIST); |
| 544 origin_filter_builder.AddOrigin(url::Origin(GURL(test_case.origin))); |
| 545 |
| 546 EXPECT_CALL( |
| 547 *remover(), |
| 548 RemoveWithFilter( |
| 549 _, BrowsingDataRemover::REMOVE_CACHE, _, |
| 550 MakeMatcher(new SameBuilderMatcher(origin_filter_builder)))); |
| 551 |
| 552 RegistrableDomainFilterBuilder registrable_domain_filter_builder( |
| 553 BrowsingDataFilterBuilder::WHITELIST); |
| 554 registrable_domain_filter_builder.AddRegisterableDomain(test_case.domain); |
| 555 |
| 556 EXPECT_CALL(*remover(), |
| 557 RemoveWithFilter(_, BrowsingDataRemover::REMOVE_COOKIES | |
| 558 BrowsingDataRemover::REMOVE_CHANNEL_IDS, |
| 559 _, MakeMatcher(new SameBuilderMatcher( |
| 560 registrable_domain_filter_builder)))); |
| 561 |
| 562 client.ClearSiteData(profile(), url::Origin(GURL(test_case.origin)), |
| 563 true /* cookies */, false /* storage */, |
| 564 true /* cache */); |
| 565 |
| 566 testing::Mock::VerifyAndClearExpectations(remover()); |
| 567 } |
| 568 } |
| 569 |
| 570 } // namespace |
OLD | NEW |