Chromium Code Reviews| Index: chrome/browser/chrome_content_browser_client_unittest.cc |
| diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc |
| index 88a062064fe2be72b758d2c6a23358533310d39c..85331d0e8a9a03810a10d19bbc00bab4b5c620aa 100644 |
| --- a/chrome/browser/chrome_content_browser_client_unittest.cc |
| +++ b/chrome/browser/chrome_content_browser_client_unittest.cc |
| @@ -8,10 +8,19 @@ |
| #include "base/command_line.h" |
| #include "base/macros.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/message_loop/message_loop.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| +#include "chrome/browser/browsing_data/browsing_data_filter_builder.h" |
| +#include "chrome/browser/browsing_data/browsing_data_helper.h" |
| +#include "chrome/browser/browsing_data/browsing_data_remover.h" |
| +#include "chrome/browser/browsing_data/browsing_data_remover_factory.h" |
| +#include "chrome/browser/browsing_data/origin_filter_builder.h" |
| +#include "chrome/browser/browsing_data/registrable_domain_filter_builder.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| +#include "chrome/test/base/testing_profile.h" |
| #include "components/content_settings/core/browser/host_content_settings_map.h" |
| #include "components/search_engines/template_url_service.h" |
| #include "components/variations/entropy_provider.h" |
| @@ -22,6 +31,7 @@ |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| @@ -33,6 +43,7 @@ |
| #include "chrome/test/base/search_test_utils.h" |
| #endif |
| +using testing::_; |
| using ChromeContentBrowserClientTest = testing::Test; |
| TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) { |
| @@ -328,3 +339,254 @@ TEST_F(InstantNTPURLRewriteTest, UberURLHandler_InstantExtendedNewTabPage) { |
| } // namespace content |
| #endif // !defined(OS_ANDROID) |
| + |
| +namespace { |
| + |
| +// Tests for ChromeContentBrowserClient::ClearSiteData(). |
| +class ChromeContentBrowserClientClearSiteDataTest : public testing::Test { |
| + public: |
| + class MockBrowsingDataRemover : public BrowsingDataRemover { |
| + public: |
| + explicit MockBrowsingDataRemover(content::BrowserContext* context) |
| + : BrowsingDataRemover(context) {} |
| + ~MockBrowsingDataRemover() {} |
| + |
| + MOCK_METHOD4(RemoveWithFilter, void( |
| + const TimeRange& time_range, int remove_mask, int origin_type_mask, |
| + const BrowsingDataFilterBuilder& filter_builder)); |
| + }; |
| + |
| + void SetUp() override { |
| + BrowsingDataRemoverFactory::GetInstance()->SetTestingFactoryAndUse( |
| + &profile_, &ChromeContentBrowserClientClearSiteDataTest::GetRemover); |
| + } |
| + |
| + content::BrowserContext* profile() { |
| + return &profile_; |
| + } |
| + |
| + MockBrowsingDataRemover* remover() { |
| + return static_cast<MockBrowsingDataRemover*>( |
| + BrowsingDataRemoverFactory::GetForBrowserContext(&profile_)); |
| + } |
| + |
| + private: |
| + static std::unique_ptr<KeyedService> GetRemover( |
| + content::BrowserContext* context) { |
| + return base::WrapUnique(new MockBrowsingDataRemover(context)); |
| + } |
| + |
| + base::MessageLoop loop_; |
| + TestingProfile profile_; |
| +}; |
| + |
| +// Matcher for BrowsingDataFilterBuilder. As it is not possible to compare |
| +// two BrowsingDataFilterBuilder-s of different kinds, it can only be used |
| +// when we know which subclass of BrowsingDataFilterBuilder we expect: |
| +// OriginFilterBuilder or RegistrableDomainFilterBuilder. |
| +class SameBuilderMatcher : |
| + public testing::MatcherInterface<const BrowsingDataFilterBuilder&> { |
| + public: |
| + explicit SameBuilderMatcher(const OriginFilterBuilder& builder) |
| + : origin_filter_builder_(&builder), domain_filter_builder_(nullptr) { |
| + } |
| + |
| + explicit SameBuilderMatcher(const RegistrableDomainFilterBuilder& builder) |
| + : origin_filter_builder_(nullptr), domain_filter_builder_(&builder) { |
| + } |
| + |
| + virtual bool MatchAndExplain(const BrowsingDataFilterBuilder& builder, |
| + testing::MatchResultListener* listener) const { |
| + DCHECK(origin_filter_builder_ || domain_filter_builder_); |
| + DCHECK(!origin_filter_builder_ || !domain_filter_builder_); |
|
Mike West
2016/07/18 13:35:48
Hrm. It's not clear to me that this is better than
msramek
2016/07/18 17:03:20
Well, there is no DCHECK_FALSE macro :) And I don'
|
| + |
| + if (origin_filter_builder_) { |
| + return *origin_filter_builder_ == |
| + static_cast<const OriginFilterBuilder&>(builder); |
| + } |
| + |
| + if (domain_filter_builder_) { |
| + return *domain_filter_builder_ == |
| + static_cast<const RegistrableDomainFilterBuilder&>(builder); |
| + } |
| + |
| + NOTREACHED(); |
| + return false; |
| + } |
| + |
| + void DescribeTo(std::ostream* os) const override { |
| + *os << "has the same scope, mode, and added entries as the expected " |
| + << "filter builder."; |
| + } |
| + |
| + void DescribeNegationTo(std::ostream* os) const override { |
| + *os << "differs from the expected filter builder in scope, mode, " |
| + << "or added entries."; |
| + } |
| + |
| + private: |
| + const OriginFilterBuilder* origin_filter_builder_; |
| + const RegistrableDomainFilterBuilder* domain_filter_builder_; |
| +}; |
| + |
| +// Tests that the parameters to ClearBrowsingData() are translated to |
| +// the correct BrowsingDataRemover::RemoveWithFilter() operation. The fourth |
| +// parameter, |filter_builder|, is tested in detail in the RegistrableDomains |
| +// test below. |
| +TEST_F(ChromeContentBrowserClientClearSiteDataTest, Parameters) { |
| + ChromeContentBrowserClient client; |
| + |
| + struct TestCase { |
| + bool cookies; |
| + bool storage; |
| + bool cache; |
| + int mask; |
| + } test_cases[] = { |
| + { false, false, false, 0 }, |
| + { true, false, false, |
| + BrowsingDataRemover::REMOVE_COOKIES | |
| + BrowsingDataRemover::REMOVE_CHANNEL_IDS }, |
| + { false, true, false, |
| + BrowsingDataRemover::REMOVE_SITE_DATA & |
| + ~BrowsingDataRemover::REMOVE_COOKIES & |
| + ~BrowsingDataRemover::REMOVE_CHANNEL_IDS }, |
| + { false, false, true, BrowsingDataRemover::REMOVE_CACHE }, |
| + { true, true, false, BrowsingDataRemover::REMOVE_SITE_DATA }, |
| + { true, false, true, |
| + BrowsingDataRemover::REMOVE_COOKIES | |
| + BrowsingDataRemover::REMOVE_CHANNEL_IDS | |
| + BrowsingDataRemover::REMOVE_CACHE }, |
| + { false, true, true, |
| + BrowsingDataRemover::REMOVE_CACHE | |
| + (BrowsingDataRemover::REMOVE_SITE_DATA & |
| + ~BrowsingDataRemover::REMOVE_COOKIES & |
| + ~BrowsingDataRemover::REMOVE_CHANNEL_IDS) }, |
| + { true, true, true, |
| + BrowsingDataRemover::REMOVE_SITE_DATA | |
| + BrowsingDataRemover::REMOVE_CACHE }, |
| + }; |
| + |
| + for (const TestCase& test_case : test_cases) { |
| + SCOPED_TRACE(test_case.mask); |
| + |
| + // We always delete data for all time and all origin types. |
| + BrowsingDataRemover::TimeRange all_time(base::Time(), base::Time::Max()); |
| + BrowsingDataHelper::OriginTypeMask all_origin_types = |
| + BrowsingDataHelper::ALL; |
| + |
| + // Some data are deleted for the origin and some for the registrable domain. |
| + // Depending on the chosen datatypes, this might result into one or two |
| + // calls. In the latter case, the removal mask will be split into two |
| + // parts - one for the origin deletion and one for the registrable domain. |
| + const int domain_scoped_types = |
| + BrowsingDataRemover::REMOVE_COOKIES | |
| + BrowsingDataRemover::REMOVE_CHANNEL_IDS; |
| + int origin_deletion_mask = |
| + test_case.mask & ~domain_scoped_types; |
| + int registrable_domain_deletion_mask = |
| + test_case.mask & domain_scoped_types; |
| + |
| + EXPECT_CALL( |
| + *remover(), |
| + RemoveWithFilter( |
| + all_time, |
| + origin_deletion_mask, |
| + all_origin_types, |
| + _)).Times(origin_deletion_mask != 0); |
| + |
| + EXPECT_CALL( |
| + *remover(), |
| + RemoveWithFilter( |
| + all_time, |
| + registrable_domain_deletion_mask, |
| + all_origin_types, |
| + _)).Times(registrable_domain_deletion_mask != 0); |
| + |
| + client.ClearSiteData( |
| + profile(), url::Origin(GURL("https://www.example.com")), |
| + test_case.cookies, test_case.storage, test_case.cache); |
| + |
| + testing::Mock::VerifyAndClearExpectations(remover()); |
| + } |
| +} |
| + |
| +// Tests that ClearBrowsingData() called for an origin deletes cookies in the |
| +// scope of the registrable domain corresponding to that origin, while cache |
| +// is deleted for that exact origin. |
| +TEST_F(ChromeContentBrowserClientClearSiteDataTest, RegistrableDomains) { |
| + ChromeContentBrowserClient client; |
| + |
| + struct TestCase { |
| + const char* origin; // origin on which ClearSiteData() is called. |
| + const char* domain; // domain on which cookies will be deleted. |
| + } test_cases[] = { |
| + // TLD has no embedded dot. |
| + { "https://example.com", "example.com" }, |
| + { "https://www.example.com", "example.com" }, |
| + { "https://www.fourth.third.second.com", "second.com" }, |
| + |
| + // TLD has one embedded dot. |
| + { "https://www.example.co.uk", "example.co.uk" }, |
| + { "https://example.co.uk", "example.co.uk" }, |
| + |
| + // TLD has more embedded dots. |
| + { "https://www.website.sp.nom.br", "website.sp.nom.br" }, |
| + |
| + // IP addresses. |
| + { "http://127.0.0.1", "127.0.0.1" }, |
| + { "http://192.168.0.1", "192.168.0.1" }, |
| + { "http://192.168.0.1", "192.168.0.1" }, |
| + |
| + // Internal hostnames. |
| + { "http://localhost", "localhost" }, |
| + { "http://fileserver", "fileserver" }, |
| + |
| + // These are not subdomains of internal hostnames, but subdomain of |
| + // unknown TLDs. |
| + { "http://subdomain.localhost", "subdomain.localhost" }, |
| + { "http://www.subdomain.localhost", "subdomain.localhost" }, |
| + { "http://documents.fileserver", "documents.fileserver" }, |
| + |
| + // Scheme and port don't matter. |
| + { "http://example.com", "example.com" }, |
| + { "http://example.com:8080", "example.com" }, |
| + { "https://example.com:4433", "example.com" }, |
| + }; |
| + |
| + for (const TestCase& test_case : test_cases) { |
| + SCOPED_TRACE(test_case.origin); |
| + |
| + OriginFilterBuilder origin_filter_builder( |
| + BrowsingDataFilterBuilder::WHITELIST); |
| + origin_filter_builder.AddOrigin(url::Origin(GURL(test_case.origin))); |
| + |
| + EXPECT_CALL( |
| + *remover(), |
| + RemoveWithFilter( |
| + _, |
| + BrowsingDataRemover::REMOVE_CACHE, |
| + _, |
| + MakeMatcher(new SameBuilderMatcher(origin_filter_builder)))); |
| + |
| + RegistrableDomainFilterBuilder registrable_domain_filter_builder( |
| + BrowsingDataFilterBuilder::WHITELIST); |
| + registrable_domain_filter_builder.AddRegisterableDomain(test_case.domain); |
| + |
| + EXPECT_CALL(*remover(), |
| + RemoveWithFilter( |
| + _, |
| + BrowsingDataRemover::REMOVE_COOKIES | |
| + BrowsingDataRemover::REMOVE_CHANNEL_IDS, |
| + _, |
| + MakeMatcher(new SameBuilderMatcher( |
| + registrable_domain_filter_builder)))); |
| + |
| + client.ClearSiteData( |
| + profile(), url::Origin(GURL(test_case.origin)), |
| + true /* cookies */, false /* storage */, true /* cache */); |
| + |
| + testing::Mock::VerifyAndClearExpectations(remover()); |
| + } |
| +} |
| + |
| +} // namespace |