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 |