Index: chrome/browser/browsing_data/browsing_data_remover_unittest.cc |
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..446d9b8dcc46bc05fbc277f2cbc7bd73ec575377 |
--- /dev/null |
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc |
@@ -0,0 +1,3138 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <stddef.h> |
+#include <stdint.h> |
+ |
+#include <list> |
+#include <memory> |
+#include <set> |
+#include <string> |
+#include <utility> |
+#include <vector> |
+ |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/files/file_path.h" |
+#include "base/files/file_util.h" |
+#include "base/guid.h" |
+#include "base/location.h" |
+#include "base/logging.h" |
+#include "base/macros.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/message_loop/message_loop.h" |
+#include "base/run_loop.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "base/task/cancelable_task_tracker.h" |
+#include "base/threading/thread_task_runner_handle.h" |
+#include "build/build_config.h" |
+#include "chrome/browser/autofill/personal_data_manager_factory.h" |
+#include "chrome/browser/bookmarks/bookmark_model_factory.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/browsing_data_remover_impl.h" |
+#include "chrome/browser/browsing_data/browsing_data_remover_test_util.h" |
+#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" |
+#include "chrome/browser/browsing_data/registrable_domain_filter_builder.h" |
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
+#include "chrome/browser/domain_reliability/service_factory.h" |
+#include "chrome/browser/download/chrome_download_manager_delegate.h" |
+#include "chrome/browser/favicon/favicon_service_factory.h" |
+#include "chrome/browser/history/history_service_factory.h" |
+#include "chrome/browser/password_manager/password_store_factory.h" |
+#include "chrome/browser/permissions/permission_decision_auto_blocker.h" |
+#include "chrome/browser/safe_browsing/safe_browsing_service.h" |
+#include "chrome/browser/storage/durable_storage_permission_context.h" |
+#include "chrome/common/pref_names.h" |
+#include "chrome/test/base/testing_browser_process.h" |
+#include "chrome/test/base/testing_profile.h" |
+#include "components/autofill/core/browser/autofill_profile.h" |
+#include "components/autofill/core/browser/autofill_test_utils.h" |
+#include "components/autofill/core/browser/credit_card.h" |
+#include "components/autofill/core/browser/personal_data_manager.h" |
+#include "components/autofill/core/browser/personal_data_manager_observer.h" |
+#include "components/autofill/core/common/autofill_constants.h" |
+#include "components/bookmarks/browser/bookmark_model.h" |
+#include "components/bookmarks/test/bookmark_test_helpers.h" |
+#include "components/browsing_data/core/browsing_data_utils.h" |
+#include "components/content_settings/core/browser/host_content_settings_map.h" |
+#include "components/content_settings/core/common/content_settings.h" |
+#include "components/content_settings/core/common/content_settings_pattern.h" |
+#include "components/domain_reliability/clear_mode.h" |
+#include "components/domain_reliability/monitor.h" |
+#include "components/domain_reliability/service.h" |
+#include "components/favicon/core/favicon_service.h" |
+#include "components/history/core/browser/history_service.h" |
+#include "components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h" |
+#include "components/omnibox/browser/omnibox_pref_names.h" |
+#include "components/os_crypt/os_crypt_mocker.h" |
+#include "components/password_manager/core/browser/mock_password_store.h" |
+#include "components/password_manager/core/browser/password_manager_test_utils.h" |
+#include "components/password_manager/core/browser/password_store_consumer.h" |
+#include "components/prefs/testing_pref_service.h" |
+#include "content/public/browser/browser_context.h" |
+#include "content/public/browser/cookie_store_factory.h" |
+#include "content/public/browser/dom_storage_context.h" |
+#include "content/public/browser/local_storage_usage_info.h" |
+#include "content/public/browser/permission_type.h" |
+#include "content/public/browser/storage_partition.h" |
+#include "content/public/test/mock_download_manager.h" |
+#include "content/public/test/test_browser_thread.h" |
+#include "content/public/test/test_browser_thread_bundle.h" |
+#include "content/public/test/test_utils.h" |
+#include "extensions/features/features.h" |
+#include "net/cookies/cookie_store.h" |
+#include "net/http/http_network_session.h" |
+#include "net/http/http_transaction_factory.h" |
+#include "net/ssl/channel_id_service.h" |
+#include "net/ssl/channel_id_store.h" |
+#include "net/ssl/ssl_client_cert_type.h" |
+#include "net/url_request/url_request_context.h" |
+#include "net/url_request/url_request_context_getter.h" |
+#include "ppapi/features/features.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/skia/include/core/SkBitmap.h" |
+#include "ui/gfx/favicon_size.h" |
+#include "url/origin.h" |
+ |
+#if defined(OS_ANDROID) |
+#include "chrome/browser/android/webapps/webapp_registry.h" |
+#endif |
+ |
+#if defined(OS_CHROMEOS) |
+#include "chrome/browser/chromeos/login/users/mock_user_manager.h" |
+#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" |
+#include "chrome/browser/chromeos/settings/cros_settings.h" |
+#include "chrome/browser/chromeos/settings/device_settings_service.h" |
+#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "chromeos/dbus/mock_cryptohome_client.h" |
+#include "components/signin/core/account_id/account_id.h" |
+#endif |
+ |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+#include "chrome/browser/extensions/mock_extension_special_storage_policy.h" |
+#endif |
+ |
+#if BUILDFLAG(ENABLE_PLUGINS) |
+#include "chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h" |
+#endif |
+ |
+class MockExtensionSpecialStoragePolicy; |
+ |
+using content::BrowserThread; |
+using content::StoragePartition; |
+using domain_reliability::CLEAR_BEACONS; |
+using domain_reliability::CLEAR_CONTEXTS; |
+using domain_reliability::DomainReliabilityClearMode; |
+using domain_reliability::DomainReliabilityMonitor; |
+using domain_reliability::DomainReliabilityService; |
+using domain_reliability::DomainReliabilityServiceFactory; |
+using testing::_; |
+using testing::ByRef; |
+using testing::Eq; |
+using testing::Invoke; |
+using testing::IsEmpty; |
+using testing::Matcher; |
+using testing::MakeMatcher; |
+using testing::MatcherInterface; |
+using testing::MatchResultListener; |
+using testing::Not; |
+using testing::Return; |
+using testing::SizeIs; |
+using testing::WithArgs; |
+ |
+namespace { |
+ |
+const char kTestOrigin1[] = "http://host1.com:1/"; |
+const char kTestRegisterableDomain1[] = "host1.com"; |
+const char kTestOrigin2[] = "http://host2.com:1/"; |
+const char kTestOrigin3[] = "http://host3.com:1/"; |
+const char kTestRegisterableDomain3[] = "host3.com"; |
+const char kTestOrigin4[] = "https://host3.com:1/"; |
+const char kTestOriginExt[] = "chrome-extension://abcdefghijklmnopqrstuvwxyz/"; |
+const char kTestOriginDevTools[] = "chrome-devtools://abcdefghijklmnopqrstuvw/"; |
+ |
+// For Autofill. |
+const char kWebOrigin[] = "https://www.example.com/"; |
+ |
+// For HTTP auth. |
+const char kTestRealm[] = "TestRealm"; |
+ |
+const GURL kOrigin1(kTestOrigin1); |
+const GURL kOrigin2(kTestOrigin2); |
+const GURL kOrigin3(kTestOrigin3); |
+const GURL kOrigin4(kTestOrigin4); |
+const GURL kOriginExt(kTestOriginExt); |
+const GURL kOriginDevTools(kTestOriginDevTools); |
+ |
+const base::FilePath::CharType kDomStorageOrigin1[] = |
+ FILE_PATH_LITERAL("http_host1_1.localstorage"); |
+ |
+const base::FilePath::CharType kDomStorageOrigin2[] = |
+ FILE_PATH_LITERAL("http_host2_1.localstorage"); |
+ |
+const base::FilePath::CharType kDomStorageOrigin3[] = |
+ FILE_PATH_LITERAL("http_host3_1.localstorage"); |
+ |
+const base::FilePath::CharType kDomStorageExt[] = FILE_PATH_LITERAL( |
+ "chrome-extension_abcdefghijklmnopqrstuvwxyz_0.localstorage"); |
+ |
+#if defined(OS_CHROMEOS) |
+void FakeDBusCall(const chromeos::BoolDBusMethodCallback& callback) { |
+ base::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, chromeos::DBUS_METHOD_CALL_SUCCESS, true)); |
+} |
+#endif |
+ |
+struct StoragePartitionRemovalData { |
+ uint32_t remove_mask = 0; |
+ uint32_t quota_storage_remove_mask = 0; |
+ base::Time remove_begin; |
+ base::Time remove_end; |
+ StoragePartition::OriginMatcherFunction origin_matcher; |
+ StoragePartition::CookieMatcherFunction cookie_matcher; |
+ |
+ StoragePartitionRemovalData() {} |
+}; |
+ |
+net::CanonicalCookie CreateCookieWithHost(const GURL& source) { |
+ std::unique_ptr<net::CanonicalCookie> cookie(net::CanonicalCookie::Create( |
+ source, "A", "1", std::string(), "/", base::Time::Now(), |
+ base::Time::Now(), false, false, net::CookieSameSite::DEFAULT_MODE, false, |
+ net::COOKIE_PRIORITY_MEDIUM)); |
+ EXPECT_TRUE(cookie); |
+ return *cookie; |
+} |
+ |
+class TestStoragePartition : public StoragePartition { |
+ public: |
+ TestStoragePartition() {} |
+ ~TestStoragePartition() override {} |
+ |
+ // content::StoragePartition implementation. |
+ base::FilePath GetPath() override { return base::FilePath(); } |
+ net::URLRequestContextGetter* GetURLRequestContext() override { |
+ return nullptr; |
+ } |
+ net::URLRequestContextGetter* GetMediaURLRequestContext() override { |
+ return nullptr; |
+ } |
+ storage::QuotaManager* GetQuotaManager() override { return nullptr; } |
+ content::AppCacheService* GetAppCacheService() override { return nullptr; } |
+ storage::FileSystemContext* GetFileSystemContext() override { |
+ return nullptr; |
+ } |
+ storage::DatabaseTracker* GetDatabaseTracker() override { return nullptr; } |
+ content::DOMStorageContext* GetDOMStorageContext() override { |
+ return nullptr; |
+ } |
+ content::IndexedDBContext* GetIndexedDBContext() override { return nullptr; } |
+ content::ServiceWorkerContext* GetServiceWorkerContext() override { |
+ return nullptr; |
+ } |
+ content::CacheStorageContext* GetCacheStorageContext() override { |
+ return nullptr; |
+ } |
+ content::PlatformNotificationContext* GetPlatformNotificationContext() |
+ override { |
+ return nullptr; |
+ } |
+ content::HostZoomMap* GetHostZoomMap() override { return nullptr; } |
+ content::HostZoomLevelContext* GetHostZoomLevelContext() override { |
+ return nullptr; |
+ } |
+ content::ZoomLevelDelegate* GetZoomLevelDelegate() override { |
+ return nullptr; |
+ } |
+ |
+ void ClearDataForOrigin(uint32_t remove_mask, |
+ uint32_t quota_storage_remove_mask, |
+ const GURL& storage_origin, |
+ net::URLRequestContextGetter* rq_context, |
+ const base::Closure& callback) override { |
+ BrowserThread::PostTask(BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&TestStoragePartition::AsyncRunCallback, |
+ base::Unretained(this), |
+ callback)); |
+ } |
+ |
+ void ClearData(uint32_t remove_mask, |
+ uint32_t quota_storage_remove_mask, |
+ const GURL& storage_origin, |
+ const OriginMatcherFunction& origin_matcher, |
+ const base::Time begin, |
+ const base::Time end, |
+ const base::Closure& callback) override { |
+ // Store stuff to verify parameters' correctness later. |
+ storage_partition_removal_data_.remove_mask = remove_mask; |
+ storage_partition_removal_data_.quota_storage_remove_mask = |
+ quota_storage_remove_mask; |
+ storage_partition_removal_data_.remove_begin = begin; |
+ storage_partition_removal_data_.remove_end = end; |
+ storage_partition_removal_data_.origin_matcher = origin_matcher; |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&TestStoragePartition::AsyncRunCallback, |
+ base::Unretained(this), callback)); |
+ } |
+ |
+ void ClearData(uint32_t remove_mask, |
+ uint32_t quota_storage_remove_mask, |
+ const OriginMatcherFunction& origin_matcher, |
+ const CookieMatcherFunction& cookie_matcher, |
+ const base::Time begin, |
+ const base::Time end, |
+ const base::Closure& callback) override { |
+ // Store stuff to verify parameters' correctness later. |
+ storage_partition_removal_data_.remove_mask = remove_mask; |
+ storage_partition_removal_data_.quota_storage_remove_mask = |
+ quota_storage_remove_mask; |
+ storage_partition_removal_data_.remove_begin = begin; |
+ storage_partition_removal_data_.remove_end = end; |
+ storage_partition_removal_data_.origin_matcher = origin_matcher; |
+ storage_partition_removal_data_.cookie_matcher = cookie_matcher; |
+ |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ base::Bind(&TestStoragePartition::AsyncRunCallback, |
+ base::Unretained(this), callback)); |
+ } |
+ |
+ void Flush() override {} |
+ |
+ StoragePartitionRemovalData GetStoragePartitionRemovalData() { |
+ return storage_partition_removal_data_; |
+ } |
+ |
+ private: |
+ void AsyncRunCallback(const base::Closure& callback) { |
+ callback.Run(); |
+ } |
+ |
+ StoragePartitionRemovalData storage_partition_removal_data_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestStoragePartition); |
+}; |
+ |
+#if defined(OS_ANDROID) |
+class TestWebappRegistry : public WebappRegistry { |
+ public: |
+ TestWebappRegistry() : WebappRegistry() { } |
+ |
+ void UnregisterWebappsForUrls( |
+ const base::Callback<bool(const GURL&)>& url_filter) override { |
+ // Mocks out a JNI call. |
+ } |
+ |
+ void ClearWebappHistoryForUrls( |
+ const base::Callback<bool(const GURL&)>& url_filter) override { |
+ // Mocks out a JNI call. |
+ } |
+}; |
+#endif |
+ |
+// Custom matcher to test the equivalence of two URL filters. Since those are |
+// blackbox predicates, we can only approximate the equivalence by testing |
+// whether the filter give the same answer for several URLs. This is currently |
+// good enough for our testing purposes, to distinguish whitelists |
+// and blacklists, empty and non-empty filters and such. |
+// TODO(msramek): BrowsingDataRemover and some of its backends support URL |
+// filters, but its constructor currently only takes a single URL and constructs |
+// its own url filter. If an url filter was directly passed to |
+// BrowsingDataRemover (what should eventually be the case), we can use the same |
+// instance in the test as well, and thus simply test base::Callback::Equals() |
+// in this matcher. |
+class ProbablySameFilterMatcher |
+ : public MatcherInterface<const base::Callback<bool(const GURL&)>&> { |
+ public: |
+ explicit ProbablySameFilterMatcher( |
+ const base::Callback<bool(const GURL&)>& filter) |
+ : to_match_(filter) { |
+ } |
+ |
+ virtual bool MatchAndExplain(const base::Callback<bool(const GURL&)>& filter, |
+ MatchResultListener* listener) const { |
+ if (filter.is_null() && to_match_.is_null()) |
+ return true; |
+ if (filter.is_null() != to_match_.is_null()) |
+ return false; |
+ |
+ const GURL urls_to_test_[] = |
+ {kOrigin1, kOrigin2, kOrigin3, GURL("invalid spec")}; |
+ for (GURL url : urls_to_test_) { |
+ if (filter.Run(url) != to_match_.Run(url)) { |
+ if (listener) |
+ *listener << "The filters differ on the URL " << url; |
+ return false; |
+ } |
+ } |
+ return true; |
+ } |
+ |
+ virtual void DescribeTo(::std::ostream* os) const { |
+ *os << "is probably the same url filter as " << &to_match_; |
+ } |
+ |
+ virtual void DescribeNegationTo(::std::ostream* os) const { |
+ *os << "is definitely NOT the same url filter as " << &to_match_; |
+ } |
+ |
+ private: |
+ const base::Callback<bool(const GURL&)>& to_match_; |
+}; |
+ |
+inline Matcher<const base::Callback<bool(const GURL&)>&> ProbablySameFilter( |
+ const base::Callback<bool(const GURL&)>& filter) { |
+ return MakeMatcher(new ProbablySameFilterMatcher(filter)); |
+} |
+ |
+bool ProbablySameFilters( |
+ const base::Callback<bool(const GURL&)>& filter1, |
+ const base::Callback<bool(const GURL&)>& filter2) { |
+ return ProbablySameFilter(filter1).MatchAndExplain(filter2, nullptr); |
+} |
+ |
+base::Time AnHourAgo() { |
+ return base::Time::Now() - base::TimeDelta::FromHours(1); |
+} |
+ |
+} // namespace |
+ |
+// Testers ------------------------------------------------------------------- |
+ |
+class RemoveCookieTester { |
+ public: |
+ RemoveCookieTester() {} |
+ |
+ // Returns true, if the given cookie exists in the cookie store. |
+ bool ContainsCookie() { |
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner = |
+ new content::MessageLoopRunner; |
+ quit_closure_ = message_loop_runner->QuitClosure(); |
+ get_cookie_success_ = false; |
+ cookie_store_->GetCookiesWithOptionsAsync( |
+ kOrigin1, net::CookieOptions(), |
+ base::Bind(&RemoveCookieTester::GetCookieCallback, |
+ base::Unretained(this))); |
+ message_loop_runner->Run(); |
+ return get_cookie_success_; |
+ } |
+ |
+ void AddCookie() { |
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner = |
+ new content::MessageLoopRunner; |
+ quit_closure_ = message_loop_runner->QuitClosure(); |
+ cookie_store_->SetCookieWithOptionsAsync( |
+ kOrigin1, "A=1", net::CookieOptions(), |
+ base::Bind(&RemoveCookieTester::SetCookieCallback, |
+ base::Unretained(this))); |
+ message_loop_runner->Run(); |
+ } |
+ |
+ protected: |
+ void SetCookieStore(net::CookieStore* cookie_store) { |
+ cookie_store_ = cookie_store; |
+ } |
+ |
+ private: |
+ void GetCookieCallback(const std::string& cookies) { |
+ if (cookies == "A=1") { |
+ get_cookie_success_ = true; |
+ } else { |
+ EXPECT_EQ("", cookies); |
+ get_cookie_success_ = false; |
+ } |
+ quit_closure_.Run(); |
+ } |
+ |
+ void SetCookieCallback(bool result) { |
+ ASSERT_TRUE(result); |
+ quit_closure_.Run(); |
+ } |
+ |
+ bool get_cookie_success_ = false; |
+ base::Closure quit_closure_; |
+ |
+ // CookieStore must out live |this|. |
+ net::CookieStore* cookie_store_ = nullptr; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemoveCookieTester); |
+}; |
+ |
+void RunClosureAfterCookiesCleared(const base::Closure& task, |
+ int cookies_deleted) { |
+ task.Run(); |
+} |
+ |
+class RemoveSafeBrowsingCookieTester : public RemoveCookieTester { |
+ public: |
+ RemoveSafeBrowsingCookieTester() |
+ : browser_process_(TestingBrowserProcess::GetGlobal()) { |
+ scoped_refptr<safe_browsing::SafeBrowsingService> sb_service = |
+ safe_browsing::SafeBrowsingService::CreateSafeBrowsingService(); |
+ browser_process_->SetSafeBrowsingService(sb_service.get()); |
+ sb_service->Initialize(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Make sure the safe browsing cookie store has no cookies. |
+ // TODO(mmenke): Is this really needed? |
+ base::RunLoop run_loop; |
+ net::URLRequestContext* request_context = |
+ sb_service->url_request_context()->GetURLRequestContext(); |
+ request_context->cookie_store()->DeleteAllAsync( |
+ base::Bind(&RunClosureAfterCookiesCleared, run_loop.QuitClosure())); |
+ run_loop.Run(); |
+ |
+ SetCookieStore(request_context->cookie_store()); |
+ } |
+ |
+ virtual ~RemoveSafeBrowsingCookieTester() { |
+ browser_process_->safe_browsing_service()->ShutDown(); |
+ base::RunLoop().RunUntilIdle(); |
+ browser_process_->SetSafeBrowsingService(nullptr); |
+ } |
+ |
+ private: |
+ TestingBrowserProcess* browser_process_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemoveSafeBrowsingCookieTester); |
+}; |
+ |
+class RemoveChannelIDTester : public net::SSLConfigService::Observer { |
+ public: |
+ explicit RemoveChannelIDTester(TestingProfile* profile) { |
+ channel_id_service_ = profile->GetRequestContext()-> |
+ GetURLRequestContext()->channel_id_service(); |
+ ssl_config_service_ = profile->GetSSLConfigService(); |
+ ssl_config_service_->AddObserver(this); |
+ } |
+ |
+ ~RemoveChannelIDTester() override { |
+ ssl_config_service_->RemoveObserver(this); |
+ } |
+ |
+ int ChannelIDCount() { return channel_id_service_->channel_id_count(); } |
+ |
+ // Add a server bound cert for |server| with specific creation and expiry |
+ // times. The cert and key data will be filled with dummy values. |
+ void AddChannelIDWithTimes(const std::string& server_identifier, |
+ base::Time creation_time) { |
+ GetChannelIDStore()->SetChannelID( |
+ base::MakeUnique<net::ChannelIDStore::ChannelID>( |
+ server_identifier, creation_time, crypto::ECPrivateKey::Create())); |
+ } |
+ |
+ // Add a server bound cert for |server|, with the current time as the |
+ // creation time. The cert and key data will be filled with dummy values. |
+ void AddChannelID(const std::string& server_identifier) { |
+ base::Time now = base::Time::Now(); |
+ AddChannelIDWithTimes(server_identifier, now); |
+ } |
+ |
+ void GetChannelIDList(net::ChannelIDStore::ChannelIDList* channel_ids) { |
+ GetChannelIDStore()->GetAllChannelIDs( |
+ base::Bind(&RemoveChannelIDTester::GetAllChannelIDsCallback, |
+ channel_ids)); |
+ } |
+ |
+ net::ChannelIDStore* GetChannelIDStore() { |
+ return channel_id_service_->GetChannelIDStore(); |
+ } |
+ |
+ int ssl_config_changed_count() const { |
+ return ssl_config_changed_count_; |
+ } |
+ |
+ // net::SSLConfigService::Observer implementation: |
+ void OnSSLConfigChanged() override { ssl_config_changed_count_++; } |
+ |
+ private: |
+ static void GetAllChannelIDsCallback( |
+ net::ChannelIDStore::ChannelIDList* dest, |
+ const net::ChannelIDStore::ChannelIDList& result) { |
+ *dest = result; |
+ } |
+ |
+ net::ChannelIDService* channel_id_service_; |
+ scoped_refptr<net::SSLConfigService> ssl_config_service_; |
+ int ssl_config_changed_count_ = 0; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemoveChannelIDTester); |
+}; |
+ |
+class RemoveHistoryTester { |
+ public: |
+ RemoveHistoryTester() {} |
+ |
+ bool Init(TestingProfile* profile) WARN_UNUSED_RESULT { |
+ if (!profile->CreateHistoryService(true, false)) |
+ return false; |
+ history_service_ = HistoryServiceFactory::GetForProfile( |
+ profile, ServiceAccessType::EXPLICIT_ACCESS); |
+ return true; |
+ } |
+ |
+ // Returns true, if the given URL exists in the history service. |
+ bool HistoryContainsURL(const GURL& url) { |
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner = |
+ new content::MessageLoopRunner; |
+ quit_closure_ = message_loop_runner->QuitClosure(); |
+ history_service_->QueryURL( |
+ url, |
+ true, |
+ base::Bind(&RemoveHistoryTester::SaveResultAndQuit, |
+ base::Unretained(this)), |
+ &tracker_); |
+ message_loop_runner->Run(); |
+ return query_url_success_; |
+ } |
+ |
+ void AddHistory(const GURL& url, base::Time time) { |
+ history_service_->AddPage(url, time, nullptr, 0, GURL(), |
+ history::RedirectList(), ui::PAGE_TRANSITION_LINK, |
+ history::SOURCE_BROWSED, false); |
+ } |
+ |
+ private: |
+ // Callback for HistoryService::QueryURL. |
+ void SaveResultAndQuit(bool success, |
+ const history::URLRow&, |
+ const history::VisitVector&) { |
+ query_url_success_ = success; |
+ quit_closure_.Run(); |
+ } |
+ |
+ // For History requests. |
+ base::CancelableTaskTracker tracker_; |
+ bool query_url_success_ = false; |
+ base::Closure quit_closure_; |
+ |
+ // TestingProfile owns the history service; we shouldn't delete it. |
+ history::HistoryService* history_service_ = nullptr; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemoveHistoryTester); |
+}; |
+ |
+class RemoveFaviconTester { |
+ public: |
+ RemoveFaviconTester() {} |
+ |
+ bool Init(TestingProfile* profile) WARN_UNUSED_RESULT { |
+ // Create the history service if it has not been created yet. |
+ history_service_ = HistoryServiceFactory::GetForProfile( |
+ profile, ServiceAccessType::EXPLICIT_ACCESS); |
+ if (!history_service_) { |
+ if (!profile->CreateHistoryService(true, false)) |
+ return false; |
+ history_service_ = HistoryServiceFactory::GetForProfile( |
+ profile, ServiceAccessType::EXPLICIT_ACCESS); |
+ } |
+ |
+ profile->CreateFaviconService(); |
+ favicon_service_ = FaviconServiceFactory::GetForProfile( |
+ profile, ServiceAccessType::EXPLICIT_ACCESS); |
+ return true; |
+ } |
+ |
+ // Returns true if there is a favicon stored for |page_url| in the favicon |
+ // database. |
+ bool HasFaviconForPageURL(const GURL& page_url) { |
+ RequestFaviconSyncForPageURL(page_url); |
+ return got_favicon_; |
+ } |
+ |
+ // Returns true if: |
+ // - There is a favicon stored for |page_url| in the favicon database. |
+ // - The stored favicon is expired. |
+ bool HasExpiredFaviconForPageURL(const GURL& page_url) { |
+ RequestFaviconSyncForPageURL(page_url); |
+ return got_expired_favicon_; |
+ } |
+ |
+ // Adds a visit to history and stores an arbitrary favicon bitmap for |
+ // |page_url|. |
+ void VisitAndAddFavicon(const GURL& page_url) { |
+ history_service_->AddPage(page_url, base::Time::Now(), nullptr, 0, GURL(), |
+ history::RedirectList(), ui::PAGE_TRANSITION_LINK, |
+ history::SOURCE_BROWSED, false); |
+ |
+ SkBitmap bitmap; |
+ bitmap.allocN32Pixels(gfx::kFaviconSize, gfx::kFaviconSize); |
+ bitmap.eraseColor(SK_ColorBLUE); |
+ favicon_service_->SetFavicons(page_url, page_url, favicon_base::FAVICON, |
+ gfx::Image::CreateFrom1xBitmap(bitmap)); |
+ } |
+ |
+ private: |
+ // Synchronously requests the favicon for |page_url| from the favicon |
+ // database. |
+ void RequestFaviconSyncForPageURL(const GURL& page_url) { |
+ base::RunLoop run_loop; |
+ quit_closure_ = run_loop.QuitClosure(); |
+ favicon_service_->GetRawFaviconForPageURL( |
+ page_url, |
+ favicon_base::FAVICON, |
+ gfx::kFaviconSize, |
+ base::Bind(&RemoveFaviconTester::SaveResultAndQuit, |
+ base::Unretained(this)), |
+ &tracker_); |
+ run_loop.Run(); |
+ } |
+ |
+ // Callback for HistoryService::QueryURL. |
+ void SaveResultAndQuit(const favicon_base::FaviconRawBitmapResult& result) { |
+ got_favicon_ = result.is_valid(); |
+ got_expired_favicon_ = result.is_valid() && result.expired; |
+ quit_closure_.Run(); |
+ } |
+ |
+ // For favicon requests. |
+ base::CancelableTaskTracker tracker_; |
+ bool got_favicon_ = false; |
+ bool got_expired_favicon_ = false; |
+ base::Closure quit_closure_; |
+ |
+ // Owned by TestingProfile. |
+ history::HistoryService* history_service_ = nullptr; |
+ favicon::FaviconService* favicon_service_ = nullptr; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemoveFaviconTester); |
+}; |
+ |
+class RemoveAutofillTester : public autofill::PersonalDataManagerObserver { |
+ public: |
+ explicit RemoveAutofillTester(TestingProfile* profile) |
+ : personal_data_manager_( |
+ autofill::PersonalDataManagerFactory::GetForProfile(profile)) { |
+ autofill::test::DisableSystemServices(profile->GetPrefs()); |
+ personal_data_manager_->AddObserver(this); |
+ } |
+ |
+ ~RemoveAutofillTester() override { |
+ personal_data_manager_->RemoveObserver(this); |
+ autofill::test::ReenableSystemServices(); |
+ } |
+ |
+ // Returns true if there are autofill profiles. |
+ bool HasProfile() { |
+ return !personal_data_manager_->GetProfiles().empty() && |
+ !personal_data_manager_->GetCreditCards().empty(); |
+ } |
+ |
+ bool HasOrigin(const std::string& origin) { |
+ const std::vector<autofill::AutofillProfile*>& profiles = |
+ personal_data_manager_->GetProfiles(); |
+ for (const autofill::AutofillProfile* profile : profiles) { |
+ if (profile->origin() == origin) |
+ return true; |
+ } |
+ |
+ const std::vector<autofill::CreditCard*>& credit_cards = |
+ personal_data_manager_->GetCreditCards(); |
+ for (const autofill::CreditCard* credit_card : credit_cards) { |
+ if (credit_card->origin() == origin) |
+ return true; |
+ } |
+ |
+ return false; |
+ } |
+ |
+ // Add two profiles and two credit cards to the database. In each pair, one |
+ // entry has a web origin and the other has a Chrome origin. |
+ void AddProfilesAndCards() { |
+ std::vector<autofill::AutofillProfile> profiles; |
+ autofill::AutofillProfile profile; |
+ profile.set_guid(base::GenerateGUID()); |
+ profile.set_origin(kWebOrigin); |
+ profile.SetRawInfo(autofill::NAME_FIRST, base::ASCIIToUTF16("Bob")); |
+ profile.SetRawInfo(autofill::NAME_LAST, base::ASCIIToUTF16("Smith")); |
+ profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, base::ASCIIToUTF16("94043")); |
+ profile.SetRawInfo(autofill::EMAIL_ADDRESS, |
+ base::ASCIIToUTF16("sue@example.com")); |
+ profile.SetRawInfo(autofill::COMPANY_NAME, base::ASCIIToUTF16("Company X")); |
+ profiles.push_back(profile); |
+ |
+ profile.set_guid(base::GenerateGUID()); |
+ profile.set_origin(autofill::kSettingsOrigin); |
+ profiles.push_back(profile); |
+ |
+ personal_data_manager_->SetProfiles(&profiles); |
+ base::RunLoop().Run(); |
+ |
+ std::vector<autofill::CreditCard> cards; |
+ autofill::CreditCard card; |
+ card.set_guid(base::GenerateGUID()); |
+ card.set_origin(kWebOrigin); |
+ card.SetRawInfo(autofill::CREDIT_CARD_NUMBER, |
+ base::ASCIIToUTF16("1234-5678-9012-3456")); |
+ cards.push_back(card); |
+ |
+ card.set_guid(base::GenerateGUID()); |
+ card.set_origin(autofill::kSettingsOrigin); |
+ cards.push_back(card); |
+ |
+ personal_data_manager_->SetCreditCards(&cards); |
+ base::RunLoop().Run(); |
+ } |
+ |
+ private: |
+ void OnPersonalDataChanged() override { |
+ base::MessageLoop::current()->QuitWhenIdle(); |
+ } |
+ |
+ autofill::PersonalDataManager* personal_data_manager_; |
+ DISALLOW_COPY_AND_ASSIGN(RemoveAutofillTester); |
+}; |
+ |
+class RemoveLocalStorageTester { |
+ public: |
+ explicit RemoveLocalStorageTester(TestingProfile* profile) |
+ : profile_(profile) { |
+ dom_storage_context_ = |
+ content::BrowserContext::GetDefaultStoragePartition(profile)-> |
+ GetDOMStorageContext(); |
+ } |
+ |
+ // Returns true, if the given origin URL exists. |
+ bool DOMStorageExistsForOrigin(const GURL& origin) { |
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner = |
+ new content::MessageLoopRunner; |
+ quit_closure_ = message_loop_runner->QuitClosure(); |
+ GetLocalStorageUsage(); |
+ message_loop_runner->Run(); |
+ for (size_t i = 0; i < infos_.size(); ++i) { |
+ if (origin == infos_[i].origin) |
+ return true; |
+ } |
+ return false; |
+ } |
+ |
+ void AddDOMStorageTestData() { |
+ // Note: This test depends on details of how the dom_storage library |
+ // stores data in the host file system. |
+ base::FilePath storage_path = |
+ profile_->GetPath().AppendASCII("Local Storage"); |
+ base::CreateDirectory(storage_path); |
+ |
+ // Write some files. |
+ base::WriteFile(storage_path.Append(kDomStorageOrigin1), nullptr, 0); |
+ base::WriteFile(storage_path.Append(kDomStorageOrigin2), nullptr, 0); |
+ base::WriteFile(storage_path.Append(kDomStorageOrigin3), nullptr, 0); |
+ base::WriteFile(storage_path.Append(kDomStorageExt), nullptr, 0); |
+ |
+ // Tweak their dates. |
+ base::Time now = base::Time::Now(); |
+ base::TouchFile(storage_path.Append(kDomStorageOrigin1), now, now); |
+ |
+ base::Time one_day_ago = now - base::TimeDelta::FromDays(1); |
+ base::TouchFile(storage_path.Append(kDomStorageOrigin2), |
+ one_day_ago, one_day_ago); |
+ |
+ base::Time sixty_days_ago = now - base::TimeDelta::FromDays(60); |
+ base::TouchFile(storage_path.Append(kDomStorageOrigin3), |
+ sixty_days_ago, sixty_days_ago); |
+ |
+ base::TouchFile(storage_path.Append(kDomStorageExt), now, now); |
+ } |
+ |
+ private: |
+ void GetLocalStorageUsage() { |
+ dom_storage_context_->GetLocalStorageUsage( |
+ base::Bind(&RemoveLocalStorageTester::OnGotLocalStorageUsage, |
+ base::Unretained(this))); |
+ } |
+ void OnGotLocalStorageUsage( |
+ const std::vector<content::LocalStorageUsageInfo>& infos) { |
+ infos_ = infos; |
+ quit_closure_.Run(); |
+ } |
+ |
+ // We don't own these pointers. |
+ TestingProfile* profile_; |
+ content::DOMStorageContext* dom_storage_context_ = nullptr; |
+ |
+ std::vector<content::LocalStorageUsageInfo> infos_; |
+ base::Closure quit_closure_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemoveLocalStorageTester); |
+}; |
+ |
+class MockDomainReliabilityService : public DomainReliabilityService { |
+ public: |
+ MockDomainReliabilityService() {} |
+ |
+ ~MockDomainReliabilityService() override {} |
+ |
+ std::unique_ptr<DomainReliabilityMonitor> CreateMonitor( |
+ scoped_refptr<base::SingleThreadTaskRunner> network_task_runner) |
+ override { |
+ NOTREACHED(); |
+ return std::unique_ptr<DomainReliabilityMonitor>(); |
+ } |
+ |
+ void ClearBrowsingData( |
+ DomainReliabilityClearMode clear_mode, |
+ const base::Callback<bool(const GURL&)>& origin_filter, |
+ const base::Closure& callback) override { |
+ clear_count_++; |
+ last_clear_mode_ = clear_mode; |
+ last_filter_ = origin_filter; |
+ callback.Run(); |
+ } |
+ |
+ void GetWebUIData(const base::Callback<void(std::unique_ptr<base::Value>)>& |
+ callback) const override { |
+ NOTREACHED(); |
+ } |
+ |
+ void SetDiscardUploadsForTesting(bool discard_uploads) override { |
+ NOTREACHED(); |
+ } |
+ |
+ void AddContextForTesting( |
+ std::unique_ptr<const domain_reliability::DomainReliabilityConfig> config) |
+ override { |
+ NOTREACHED(); |
+ } |
+ |
+ void ForceUploadsForTesting() override { NOTREACHED(); } |
+ |
+ int clear_count() const { return clear_count_; } |
+ |
+ DomainReliabilityClearMode last_clear_mode() const { |
+ return last_clear_mode_; |
+ } |
+ |
+ const base::Callback<bool(const GURL&)>& last_filter() const { |
+ return last_filter_; |
+ } |
+ |
+ private: |
+ unsigned clear_count_ = 0; |
+ DomainReliabilityClearMode last_clear_mode_; |
+ base::Callback<bool(const GURL&)> last_filter_; |
+}; |
+ |
+struct TestingDomainReliabilityServiceFactoryUserData |
+ : public base::SupportsUserData::Data { |
+ TestingDomainReliabilityServiceFactoryUserData( |
+ content::BrowserContext* context, |
+ MockDomainReliabilityService* service) |
+ : context(context), |
+ service(service), |
+ attached(false) {} |
+ ~TestingDomainReliabilityServiceFactoryUserData() override {} |
+ |
+ content::BrowserContext* const context; |
+ MockDomainReliabilityService* const service; |
+ bool attached; |
+ |
+ static const void* kKey; |
+}; |
+ |
+// static |
+const void* TestingDomainReliabilityServiceFactoryUserData::kKey = |
+ &TestingDomainReliabilityServiceFactoryUserData::kKey; |
+ |
+std::unique_ptr<KeyedService> TestingDomainReliabilityServiceFactoryFunction( |
+ content::BrowserContext* context) { |
+ const void* kKey = TestingDomainReliabilityServiceFactoryUserData::kKey; |
+ |
+ TestingDomainReliabilityServiceFactoryUserData* data = |
+ static_cast<TestingDomainReliabilityServiceFactoryUserData*>( |
+ context->GetUserData(kKey)); |
+ EXPECT_TRUE(data); |
+ EXPECT_EQ(data->context, context); |
+ EXPECT_FALSE(data->attached); |
+ |
+ data->attached = true; |
+ return base::WrapUnique(data->service); |
+} |
+ |
+class ClearDomainReliabilityTester { |
+ public: |
+ explicit ClearDomainReliabilityTester(TestingProfile* profile) : |
+ profile_(profile), |
+ mock_service_(new MockDomainReliabilityService()) { |
+ AttachService(); |
+ } |
+ |
+ unsigned clear_count() const { return mock_service_->clear_count(); } |
+ |
+ DomainReliabilityClearMode last_clear_mode() const { |
+ return mock_service_->last_clear_mode(); |
+ } |
+ |
+ const base::Callback<bool(const GURL&)>& last_filter() const { |
+ return mock_service_->last_filter(); |
+ } |
+ |
+ private: |
+ void AttachService() { |
+ const void* kKey = TestingDomainReliabilityServiceFactoryUserData::kKey; |
+ |
+ // Attach kludgey UserData struct to profile. |
+ TestingDomainReliabilityServiceFactoryUserData* data = |
+ new TestingDomainReliabilityServiceFactoryUserData(profile_, |
+ mock_service_); |
+ EXPECT_FALSE(profile_->GetUserData(kKey)); |
+ profile_->SetUserData(kKey, data); |
+ |
+ // Set and use factory that will attach service stuffed in kludgey struct. |
+ DomainReliabilityServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
+ profile_, |
+ &TestingDomainReliabilityServiceFactoryFunction); |
+ |
+ // Verify and detach kludgey struct. |
+ EXPECT_EQ(data, profile_->GetUserData(kKey)); |
+ EXPECT_TRUE(data->attached); |
+ profile_->RemoveUserData(kKey); |
+ } |
+ |
+ TestingProfile* profile_; |
+ MockDomainReliabilityService* mock_service_; |
+}; |
+ |
+class RemoveDownloadsTester { |
+ public: |
+ explicit RemoveDownloadsTester(TestingProfile* testing_profile) |
+ : download_manager_(new content::MockDownloadManager()), |
+ chrome_download_manager_delegate_(testing_profile) { |
+ content::BrowserContext::SetDownloadManagerForTesting(testing_profile, |
+ download_manager_); |
+ EXPECT_EQ(download_manager_, |
+ content::BrowserContext::GetDownloadManager(testing_profile)); |
+ |
+ EXPECT_CALL(*download_manager_, GetDelegate()) |
+ .WillOnce(Return(&chrome_download_manager_delegate_)); |
+ EXPECT_CALL(*download_manager_, Shutdown()); |
+ } |
+ |
+ ~RemoveDownloadsTester() { chrome_download_manager_delegate_.Shutdown(); } |
+ |
+ content::MockDownloadManager* download_manager() { return download_manager_; } |
+ |
+ private: |
+ content::MockDownloadManager* download_manager_; |
+ ChromeDownloadManagerDelegate chrome_download_manager_delegate_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemoveDownloadsTester); |
+}; |
+ |
+class RemovePasswordsTester { |
+ public: |
+ explicit RemovePasswordsTester(TestingProfile* testing_profile) { |
+ PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( |
+ testing_profile, |
+ password_manager::BuildPasswordStore< |
+ content::BrowserContext, |
+ testing::NiceMock<password_manager::MockPasswordStore>>); |
+ |
+ store_ = static_cast<password_manager::MockPasswordStore*>( |
+ PasswordStoreFactory::GetInstance() |
+ ->GetForProfile(testing_profile, ServiceAccessType::EXPLICIT_ACCESS) |
+ .get()); |
+ |
+ OSCryptMocker::SetUpWithSingleton(); |
+ } |
+ |
+ ~RemovePasswordsTester() { OSCryptMocker::TearDown(); } |
+ |
+ password_manager::MockPasswordStore* store() { return store_; } |
+ |
+ private: |
+ password_manager::MockPasswordStore* store_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemovePasswordsTester); |
+}; |
+ |
+class RemovePermissionPromptCountsTest { |
+ public: |
+ explicit RemovePermissionPromptCountsTest(TestingProfile* profile) |
+ : profile_(profile) {} |
+ |
+ int GetDismissCount(const GURL& url, content::PermissionType permission) { |
+ return PermissionDecisionAutoBlocker::GetDismissCount( |
+ url, permission, profile_); |
+ } |
+ |
+ int GetIgnoreCount(const GURL& url, content::PermissionType permission) { |
+ return PermissionDecisionAutoBlocker::GetIgnoreCount( |
+ url, permission, profile_); |
+ } |
+ |
+ int RecordIgnore(const GURL& url, content::PermissionType permission) { |
+ return PermissionDecisionAutoBlocker::RecordIgnore(url, permission, |
+ profile_); |
+ } |
+ |
+ bool ShouldChangeDismissalToBlock(const GURL& url, |
+ content::PermissionType permission) { |
+ return PermissionDecisionAutoBlocker::ShouldChangeDismissalToBlock( |
+ url, permission, profile_); |
+ } |
+ |
+ private: |
+ TestingProfile* profile_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemovePermissionPromptCountsTest); |
+}; |
+ |
+#if BUILDFLAG(ENABLE_PLUGINS) |
+// A small modification to MockBrowsingDataFlashLSOHelper so that it responds |
+// immediately and does not wait for the Notify() call. Otherwise it would |
+// deadlock BrowsingDataRemoverImpl::RemoveImpl. |
+class TestBrowsingDataFlashLSOHelper : public MockBrowsingDataFlashLSOHelper { |
+ public: |
+ explicit TestBrowsingDataFlashLSOHelper(TestingProfile* profile) |
+ : MockBrowsingDataFlashLSOHelper(profile) {} |
+ |
+ void StartFetching(const GetSitesWithFlashDataCallback& callback) override { |
+ MockBrowsingDataFlashLSOHelper::StartFetching(callback); |
+ Notify(); |
+ } |
+ |
+ private: |
+ ~TestBrowsingDataFlashLSOHelper() override {} |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestBrowsingDataFlashLSOHelper); |
+}; |
+ |
+class RemovePluginDataTester { |
+ public: |
+ explicit RemovePluginDataTester(TestingProfile* profile) |
+ : helper_(new TestBrowsingDataFlashLSOHelper(profile)) { |
+ static_cast<ChromeBrowsingDataRemoverDelegate*>( |
+ BrowsingDataRemoverFactory::GetForBrowserContext(profile) |
+ ->GetEmbedderDelegate())->OverrideFlashLSOHelperForTesting(helper_); |
+ } |
+ |
+ void AddDomain(const std::string& domain) { |
+ helper_->AddFlashLSODomain(domain); |
+ } |
+ |
+ const std::vector<std::string>& GetDomains() { |
+ // TestBrowsingDataFlashLSOHelper is synchronous, so we can immediately |
+ // return the fetched domains. |
+ helper_->StartFetching( |
+ base::Bind(&RemovePluginDataTester::OnSitesWithFlashDataFetched, |
+ base::Unretained(this))); |
+ return domains_; |
+ } |
+ |
+ private: |
+ void OnSitesWithFlashDataFetched(const std::vector<std::string>& sites) { |
+ domains_ = sites; |
+ } |
+ |
+ std::vector<std::string> domains_; |
+ scoped_refptr<TestBrowsingDataFlashLSOHelper> helper_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RemovePluginDataTester); |
+}; |
+#endif |
+ |
+// Test Class ---------------------------------------------------------------- |
+ |
+class BrowsingDataRemoverTest : public testing::Test { |
+ public: |
+ BrowsingDataRemoverTest() |
+ : profile_(new TestingProfile()), |
+ clear_domain_reliability_tester_(GetProfile()) { |
+ remover_ = static_cast<BrowsingDataRemoverImpl*>( |
+ BrowsingDataRemoverFactory::GetForBrowserContext(profile_.get())); |
+ |
+#if defined(OS_ANDROID) |
+ static_cast<ChromeBrowsingDataRemoverDelegate*>( |
+ remover_->GetEmbedderDelegate())->OverrideWebappRegistryForTesting( |
+ base::WrapUnique<WebappRegistry>(new TestWebappRegistry())); |
+#endif |
+ } |
+ |
+ ~BrowsingDataRemoverTest() override {} |
+ |
+ void TearDown() override { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ mock_policy_ = nullptr; |
+#endif |
+ |
+ // TestingProfile contains a DOMStorageContext. BrowserContext's destructor |
+ // posts a message to the WEBKIT thread to delete some of its member |
+ // variables. We need to ensure that the profile is destroyed, and that |
+ // the message loop is cleared out, before destroying the threads and loop. |
+ // Otherwise we leak memory. |
+ profile_.reset(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); |
+ } |
+ |
+ void BlockUntilBrowsingDataRemoved(const base::Time& delete_begin, |
+ const base::Time& delete_end, |
+ int remove_mask, |
+ bool include_protected_origins) { |
+ TestStoragePartition storage_partition; |
+ remover_->OverrideStoragePartitionForTesting(&storage_partition); |
+ |
+ int origin_type_mask = BrowsingDataHelper::UNPROTECTED_WEB; |
+ if (include_protected_origins) |
+ origin_type_mask |= BrowsingDataHelper::PROTECTED_WEB; |
+ |
+ BrowsingDataRemoverCompletionObserver completion_observer(remover_); |
+ remover_->RemoveAndReply( |
+ delete_begin, delete_end, remove_mask, origin_type_mask, |
+ &completion_observer); |
+ completion_observer.BlockUntilCompletion(); |
+ |
+ // Save so we can verify later. |
+ storage_partition_removal_data_ = |
+ storage_partition.GetStoragePartitionRemovalData(); |
+ } |
+ |
+ void BlockUntilOriginDataRemoved( |
+ const base::Time& delete_begin, |
+ const base::Time& delete_end, |
+ int remove_mask, |
+ const BrowsingDataFilterBuilder& filter_builder) { |
+ TestStoragePartition storage_partition; |
+ remover_->OverrideStoragePartitionForTesting(&storage_partition); |
+ |
+ BrowsingDataRemoverCompletionInhibitor completion_inhibitor; |
+ remover_->RemoveImpl(delete_begin, delete_end, remove_mask, filter_builder, |
+ BrowsingDataHelper::UNPROTECTED_WEB); |
+ completion_inhibitor.BlockUntilNearCompletion(); |
+ completion_inhibitor.ContinueToCompletion(); |
+ |
+ // Save so we can verify later. |
+ storage_partition_removal_data_ = |
+ storage_partition.GetStoragePartitionRemovalData(); |
+ } |
+ |
+ TestingProfile* GetProfile() { |
+ return profile_.get(); |
+ } |
+ |
+ void DestroyProfile() { profile_.reset(); } |
+ |
+ const base::Time& GetBeginTime() { |
+ return remover_->GetLastUsedBeginTime(); |
+ } |
+ |
+ int GetRemovalMask() { |
+ return remover_->GetLastUsedRemovalMask(); |
+ } |
+ |
+ int GetOriginTypeMask() { |
+ return remover_->GetLastUsedOriginTypeMask(); |
+ } |
+ |
+ StoragePartitionRemovalData GetStoragePartitionRemovalData() { |
+ return storage_partition_removal_data_; |
+ } |
+ |
+ MockExtensionSpecialStoragePolicy* CreateMockPolicy() { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ mock_policy_ = new MockExtensionSpecialStoragePolicy; |
+ return mock_policy_.get(); |
+#else |
+ NOTREACHED(); |
+ return nullptr; |
+#endif |
+ } |
+ |
+ storage::SpecialStoragePolicy* mock_policy() { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ return mock_policy_.get(); |
+#else |
+ return nullptr; |
+#endif |
+ } |
+ |
+ // If |kOrigin1| is protected when extensions are enabled, the expected |
+ // result for tests where the OriginMatcherFunction result is variable. |
+ bool ShouldRemoveForProtectedOriginOne() const { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ return false; |
+#else |
+ return true; |
+#endif |
+ } |
+ |
+ const ClearDomainReliabilityTester& clear_domain_reliability_tester() { |
+ return clear_domain_reliability_tester_; |
+ } |
+ |
+ private: |
+ // Cached pointer to BrowsingDataRemoverImpl for access to testing methods. |
+ BrowsingDataRemoverImpl* remover_; |
+ |
+ content::TestBrowserThreadBundle thread_bundle_; |
+ std::unique_ptr<TestingProfile> profile_; |
+ |
+ StoragePartitionRemovalData storage_partition_removal_data_; |
+ |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ scoped_refptr<MockExtensionSpecialStoragePolicy> mock_policy_; |
+#endif |
+ |
+ // Needed to mock out DomainReliabilityService, even for unrelated tests. |
+ ClearDomainReliabilityTester clear_domain_reliability_tester_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemoverTest); |
+}; |
+ |
+// Tests --------------------------------------------------------------------- |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveCookieForever) { |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify that storage partition was instructed to remove the cookies. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_COOKIES); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveCookieLastHour) { |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify that storage partition was instructed to remove the cookies. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_COOKIES); |
+ // Removing with time period other than all time should not clear |
+ // persistent storage data. |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT); |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveCookiesDomainBlacklist) { |
+ RegistrableDomainFilterBuilder filter( |
+ RegistrableDomainFilterBuilder::BLACKLIST); |
+ filter.AddRegisterableDomain(kTestRegisterableDomain1); |
+ filter.AddRegisterableDomain(kTestRegisterableDomain3); |
+ BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, filter); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify that storage partition was instructed to remove the cookies. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_COOKIES); |
+ // Removing with time period other than all time should not clear |
+ // persistent storage data. |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT); |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+ // Even though it's a different origin, it's the same domain. |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin4, mock_policy())); |
+ |
+ EXPECT_FALSE(removal_data.cookie_matcher.Run(CreateCookieWithHost(kOrigin1))); |
+ EXPECT_TRUE(removal_data.cookie_matcher.Run(CreateCookieWithHost(kOrigin2))); |
+ EXPECT_FALSE(removal_data.cookie_matcher.Run(CreateCookieWithHost(kOrigin3))); |
+ // This is false, because this is the same domain as 3, just with a different |
+ // scheme. |
+ EXPECT_FALSE(removal_data.cookie_matcher.Run(CreateCookieWithHost(kOrigin4))); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveSafeBrowsingCookieForever) { |
+ RemoveSafeBrowsingCookieTester tester; |
+ |
+ tester.AddCookie(); |
+ ASSERT_TRUE(tester.ContainsCookie()); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_FALSE(tester.ContainsCookie()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveSafeBrowsingCookieLastHour) { |
+ RemoveSafeBrowsingCookieTester tester; |
+ |
+ tester.AddCookie(); |
+ ASSERT_TRUE(tester.ContainsCookie()); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ // Removing with time period other than all time should not clear safe |
+ // browsing cookies. |
+ EXPECT_TRUE(tester.ContainsCookie()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveSafeBrowsingCookieForeverWithPredicate) { |
+ RemoveSafeBrowsingCookieTester tester; |
+ |
+ tester.AddCookie(); |
+ ASSERT_TRUE(tester.ContainsCookie()); |
+ RegistrableDomainFilterBuilder filter( |
+ RegistrableDomainFilterBuilder::BLACKLIST); |
+ filter.AddRegisterableDomain(kTestRegisterableDomain1); |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, filter); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_TRUE(tester.ContainsCookie()); |
+ |
+ RegistrableDomainFilterBuilder filter2( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ filter2.AddRegisterableDomain(kTestRegisterableDomain1); |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, filter2); |
+ EXPECT_FALSE(tester.ContainsCookie()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveChannelIDForever) { |
+ RemoveChannelIDTester tester(GetProfile()); |
+ |
+ tester.AddChannelID(kTestOrigin1); |
+ EXPECT_EQ(0, tester.ssl_config_changed_count()); |
+ EXPECT_EQ(1, tester.ChannelIDCount()); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_CHANNEL_IDS, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_CHANNEL_IDS, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_EQ(1, tester.ssl_config_changed_count()); |
+ EXPECT_EQ(0, tester.ChannelIDCount()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveChannelIDLastHour) { |
+ RemoveChannelIDTester tester(GetProfile()); |
+ |
+ base::Time now = base::Time::Now(); |
+ tester.AddChannelID(kTestOrigin1); |
+ tester.AddChannelIDWithTimes(kTestOrigin2, |
+ now - base::TimeDelta::FromHours(2)); |
+ EXPECT_EQ(0, tester.ssl_config_changed_count()); |
+ EXPECT_EQ(2, tester.ChannelIDCount()); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_CHANNEL_IDS, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_CHANNEL_IDS, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_EQ(1, tester.ssl_config_changed_count()); |
+ ASSERT_EQ(1, tester.ChannelIDCount()); |
+ net::ChannelIDStore::ChannelIDList channel_ids; |
+ tester.GetChannelIDList(&channel_ids); |
+ ASSERT_EQ(1U, channel_ids.size()); |
+ EXPECT_EQ(kTestOrigin2, channel_ids.front().server_identifier()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveChannelIDsForServerIdentifiers) { |
+ RemoveChannelIDTester tester(GetProfile()); |
+ |
+ tester.AddChannelID(kTestRegisterableDomain1); |
+ tester.AddChannelID(kTestRegisterableDomain3); |
+ EXPECT_EQ(2, tester.ChannelIDCount()); |
+ |
+ RegistrableDomainFilterBuilder filter_builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ filter_builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_CHANNEL_IDS, |
+ filter_builder); |
+ |
+ EXPECT_EQ(1, tester.ChannelIDCount()); |
+ net::ChannelIDStore::ChannelIDList channel_ids; |
+ tester.GetChannelIDList(&channel_ids); |
+ EXPECT_EQ(kTestRegisterableDomain3, channel_ids.front().server_identifier()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveUnprotectedLocalStorageForever) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ MockExtensionSpecialStoragePolicy* policy = CreateMockPolicy(); |
+ // Protect kOrigin1. |
+ policy->AddProtected(kOrigin1.GetOrigin()); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_LOCAL_STORAGE, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_LOCAL_STORAGE, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify that storage partition was instructed to remove the data correctly. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+ |
+ // Check origin matcher. |
+ EXPECT_EQ(ShouldRemoveForProtectedOriginOne(), |
+ removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOriginExt, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveProtectedLocalStorageForever) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ // Protect kOrigin1. |
+ MockExtensionSpecialStoragePolicy* policy = CreateMockPolicy(); |
+ policy->AddProtected(kOrigin1.GetOrigin()); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_LOCAL_STORAGE, |
+ true); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_LOCAL_STORAGE, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB | |
+ BrowsingDataHelper::PROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify that storage partition was instructed to remove the data correctly. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+ |
+ // Check origin matcher all http origin will match since we specified |
+ // both protected and unprotected. |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOriginExt, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveLocalStorageForLastWeek) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ CreateMockPolicy(); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time::Now() - base::TimeDelta::FromDays(7), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_LOCAL_STORAGE, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_LOCAL_STORAGE, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify that storage partition was instructed to remove the data correctly. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE); |
+ // Persistent storage won't be deleted. |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT); |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+ |
+ // Check origin matcher. |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOriginExt, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveHistoryForever) { |
+ RemoveHistoryTester tester; |
+ ASSERT_TRUE(tester.Init(GetProfile())); |
+ |
+ tester.AddHistory(kOrigin1, base::Time::Now()); |
+ ASSERT_TRUE(tester.HistoryContainsURL(kOrigin1)); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_FALSE(tester.HistoryContainsURL(kOrigin1)); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveHistoryForLastHour) { |
+ RemoveHistoryTester tester; |
+ ASSERT_TRUE(tester.Init(GetProfile())); |
+ |
+ base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2); |
+ |
+ tester.AddHistory(kOrigin1, base::Time::Now()); |
+ tester.AddHistory(kOrigin2, two_hours_ago); |
+ ASSERT_TRUE(tester.HistoryContainsURL(kOrigin1)); |
+ ASSERT_TRUE(tester.HistoryContainsURL(kOrigin2)); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_FALSE(tester.HistoryContainsURL(kOrigin1)); |
+ EXPECT_TRUE(tester.HistoryContainsURL(kOrigin2)); |
+} |
+ |
+// This should crash (DCHECK) in Debug, but death tests don't work properly |
+// here. |
+#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) |
+TEST_F(BrowsingDataRemoverTest, RemoveHistoryProhibited) { |
+ RemoveHistoryTester tester; |
+ ASSERT_TRUE(tester.Init(GetProfile())); |
+ PrefService* prefs = GetProfile()->GetPrefs(); |
+ prefs->SetBoolean(prefs::kAllowDeletingBrowserHistory, false); |
+ |
+ base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2); |
+ |
+ tester.AddHistory(kOrigin1, base::Time::Now()); |
+ tester.AddHistory(kOrigin2, two_hours_ago); |
+ ASSERT_TRUE(tester.HistoryContainsURL(kOrigin1)); |
+ ASSERT_TRUE(tester.HistoryContainsURL(kOrigin2)); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Nothing should have been deleted. |
+ EXPECT_TRUE(tester.HistoryContainsURL(kOrigin1)); |
+ EXPECT_TRUE(tester.HistoryContainsURL(kOrigin2)); |
+} |
+#endif |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveMultipleTypes) { |
+ // Add some history. |
+ RemoveHistoryTester history_tester; |
+ ASSERT_TRUE(history_tester.Init(GetProfile())); |
+ history_tester.AddHistory(kOrigin1, base::Time::Now()); |
+ ASSERT_TRUE(history_tester.HistoryContainsURL(kOrigin1)); |
+ |
+ int removal_mask = BrowsingDataRemover::REMOVE_HISTORY | |
+ BrowsingDataRemover::REMOVE_COOKIES; |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ removal_mask, false); |
+ |
+ EXPECT_EQ(removal_mask, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_FALSE(history_tester.HistoryContainsURL(kOrigin1)); |
+ |
+ // The cookie would be deleted throught the StorageParition, check if the |
+ // partition was requested to remove cookie. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_COOKIES); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+} |
+ |
+// This should crash (DCHECK) in Debug, but death tests don't work properly |
+// here. |
+#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) |
+TEST_F(BrowsingDataRemoverTest, RemoveMultipleTypesHistoryProhibited) { |
+ PrefService* prefs = GetProfile()->GetPrefs(); |
+ prefs->SetBoolean(prefs::kAllowDeletingBrowserHistory, false); |
+ |
+ // Add some history. |
+ RemoveHistoryTester history_tester; |
+ ASSERT_TRUE(history_tester.Init(GetProfile())); |
+ history_tester.AddHistory(kOrigin1, base::Time::Now()); |
+ ASSERT_TRUE(history_tester.HistoryContainsURL(kOrigin1)); |
+ |
+ int removal_mask = BrowsingDataRemover::REMOVE_HISTORY | |
+ BrowsingDataRemover::REMOVE_COOKIES; |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ removal_mask, false); |
+ EXPECT_EQ(removal_mask, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // 1/2. History should remain. |
+ EXPECT_TRUE(history_tester.HistoryContainsURL(kOrigin1)); |
+ |
+ // 2/2. The cookie(s) would be deleted throught the StorageParition, check if |
+ // the partition was requested to remove cookie. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_COOKIES); |
+ // Persistent storage won't be deleted, since the time period is not all time. |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT); |
+} |
+#endif |
+ |
+// Test that clearing history deletes favicons not associated with bookmarks. |
+TEST_F(BrowsingDataRemoverTest, RemoveFaviconsForever) { |
+ GURL page_url("http://a"); |
+ |
+ RemoveFaviconTester favicon_tester; |
+ ASSERT_TRUE(favicon_tester.Init(GetProfile())); |
+ favicon_tester.VisitAndAddFavicon(page_url); |
+ ASSERT_TRUE(favicon_tester.HasFaviconForPageURL(page_url)); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY, GetRemovalMask()); |
+ EXPECT_FALSE(favicon_tester.HasFaviconForPageURL(page_url)); |
+} |
+ |
+// Test that a bookmark's favicon is expired and not deleted when clearing |
+// history. Expiring the favicon causes the bookmark's favicon to be updated |
+// when the user next visits the bookmarked page. Expiring the bookmark's |
+// favicon is useful when the bookmark's favicon becomes incorrect (See |
+// crbug.com/474421 for a sample bug which causes this). |
+TEST_F(BrowsingDataRemoverTest, ExpireBookmarkFavicons) { |
+ GURL bookmarked_page("http://a"); |
+ |
+ TestingProfile* profile = GetProfile(); |
+ profile->CreateBookmarkModel(true); |
+ bookmarks::BookmarkModel* bookmark_model = |
+ BookmarkModelFactory::GetForBrowserContext(profile); |
+ bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model); |
+ bookmark_model->AddURL(bookmark_model->bookmark_bar_node(), 0, |
+ base::ASCIIToUTF16("a"), bookmarked_page); |
+ |
+ RemoveFaviconTester favicon_tester; |
+ ASSERT_TRUE(favicon_tester.Init(GetProfile())); |
+ favicon_tester.VisitAndAddFavicon(bookmarked_page); |
+ ASSERT_TRUE(favicon_tester.HasFaviconForPageURL(bookmarked_page)); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY, GetRemovalMask()); |
+ EXPECT_TRUE(favicon_tester.HasExpiredFaviconForPageURL(bookmarked_page)); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverBoth) { |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverOnlyTemporary) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ CreateMockPolicy(); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ |
+ // Check that all related origin data would be removed, that is, origin |
+ // matcher would match these origin. |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverOnlyPersistent) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ CreateMockPolicy(); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ |
+ // Check that all related origin data would be removed, that is, origin |
+ // matcher would match these origin. |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverNeither) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ CreateMockPolicy(); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ |
+ // Check that all related origin data would be removed, that is, origin |
+ // matcher would match these origin. |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverSpecificOrigin) { |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ // Remove Origin 1. |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ builder); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin4, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForLastHour) { |
+ BlockUntilBrowsingDataRemoved( |
+ AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ |
+ // Persistent data would be left out since we are not removing from |
+ // beginning of time. |
+ uint32_t expected_quota_mask = |
+ ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT; |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, expected_quota_mask); |
+ // Check removal begin time. |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForLastWeek) { |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time::Now() - base::TimeDelta::FromDays(7), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ |
+ // Persistent data would be left out since we are not removing from |
+ // beginning of time. |
+ uint32_t expected_quota_mask = |
+ ~StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT; |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, expected_quota_mask); |
+ // Check removal begin time. |
+ EXPECT_EQ(removal_data.remove_begin, GetBeginTime()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedUnprotectedOrigins) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ MockExtensionSpecialStoragePolicy* policy = CreateMockPolicy(); |
+ // Protect kOrigin1. |
+ policy->AddProtected(kOrigin1.GetOrigin()); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_WEBSQL | |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ |
+ // Check OriginMatcherFunction. |
+ EXPECT_EQ(ShouldRemoveForProtectedOriginOne(), |
+ removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedProtectedSpecificOrigin) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ MockExtensionSpecialStoragePolicy* policy = CreateMockPolicy(); |
+ // Protect kOrigin1. |
+ policy->AddProtected(kOrigin1.GetOrigin()); |
+#endif |
+ |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ |
+ // Try to remove kOrigin1. Expect failure. |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ builder); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ |
+ // Check OriginMatcherFunction. |
+ EXPECT_EQ(ShouldRemoveForProtectedOriginOne(), |
+ removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ // Since we use the matcher function to validate origins now, this should |
+ // return false for the origins we're not trying to clear. |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedProtectedOrigins) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ MockExtensionSpecialStoragePolicy* policy = CreateMockPolicy(); |
+ // Protect kOrigin1. |
+ policy->AddProtected(kOrigin1.GetOrigin()); |
+#endif |
+ |
+ // Try to remove kOrigin1. Expect success. |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ true); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::PROTECTED_WEB | |
+ BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ |
+ // Check OriginMatcherFunction, |kOrigin1| would match mask since we |
+ // would have 'protected' specified in origin_type_mask. |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin1, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin2, mock_policy())); |
+ EXPECT_TRUE(removal_data.origin_matcher.Run(kOrigin3, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedIgnoreExtensionsAndDevTools) { |
+#if BUILDFLAG(ENABLE_EXTENSIONS) |
+ CreateMockPolicy(); |
+#endif |
+ |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_APPCACHE | |
+ BrowsingDataRemover::REMOVE_SERVICE_WORKERS | |
+ BrowsingDataRemover::REMOVE_CACHE_STORAGE | |
+ BrowsingDataRemover::REMOVE_FILE_SYSTEMS | |
+ BrowsingDataRemover::REMOVE_INDEXEDDB | |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify storage partition related stuffs. |
+ StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData(); |
+ |
+ EXPECT_EQ(removal_data.remove_mask, |
+ StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS | |
+ StoragePartition::REMOVE_DATA_MASK_WEBSQL | |
+ StoragePartition::REMOVE_DATA_MASK_APPCACHE | |
+ StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS | |
+ StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE | |
+ StoragePartition::REMOVE_DATA_MASK_INDEXEDDB); |
+ EXPECT_EQ(removal_data.quota_storage_remove_mask, |
+ StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL); |
+ |
+ // Check that extension and devtools data wouldn't be removed, that is, |
+ // origin matcher would not match these origin. |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOriginExt, mock_policy())); |
+ EXPECT_FALSE(removal_data.origin_matcher.Run(kOriginDevTools, mock_policy())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, TimeBasedHistoryRemoval) { |
+ RemoveHistoryTester tester; |
+ ASSERT_TRUE(tester.Init(GetProfile())); |
+ |
+ base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2); |
+ |
+ tester.AddHistory(kOrigin1, base::Time::Now()); |
+ tester.AddHistory(kOrigin2, two_hours_ago); |
+ ASSERT_TRUE(tester.HistoryContainsURL(kOrigin1)); |
+ ASSERT_TRUE(tester.HistoryContainsURL(kOrigin2)); |
+ |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::BLACKLIST); |
+ BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, builder); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_FALSE(tester.HistoryContainsURL(kOrigin1)); |
+ EXPECT_TRUE(tester.HistoryContainsURL(kOrigin2)); |
+} |
+ |
+// Verify that clearing autofill form data works. |
+TEST_F(BrowsingDataRemoverTest, AutofillRemovalLastHour) { |
+ GetProfile()->CreateWebDataService(); |
+ RemoveAutofillTester tester(GetProfile()); |
+ |
+ ASSERT_FALSE(tester.HasProfile()); |
+ tester.AddProfilesAndCards(); |
+ ASSERT_TRUE(tester.HasProfile()); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FORM_DATA, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FORM_DATA, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ ASSERT_FALSE(tester.HasProfile()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, AutofillRemovalEverything) { |
+ GetProfile()->CreateWebDataService(); |
+ RemoveAutofillTester tester(GetProfile()); |
+ |
+ ASSERT_FALSE(tester.HasProfile()); |
+ tester.AddProfilesAndCards(); |
+ ASSERT_TRUE(tester.HasProfile()); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_FORM_DATA, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_FORM_DATA, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ ASSERT_FALSE(tester.HasProfile()); |
+} |
+ |
+// Verify that clearing autofill form data works. |
+TEST_F(BrowsingDataRemoverTest, AutofillOriginsRemovedWithHistory) { |
+ GetProfile()->CreateWebDataService(); |
+ RemoveAutofillTester tester(GetProfile()); |
+ |
+ tester.AddProfilesAndCards(); |
+ EXPECT_FALSE(tester.HasOrigin(std::string())); |
+ EXPECT_TRUE(tester.HasOrigin(kWebOrigin)); |
+ EXPECT_TRUE(tester.HasOrigin(autofill::kSettingsOrigin)); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ EXPECT_TRUE(tester.HasOrigin(std::string())); |
+ EXPECT_FALSE(tester.HasOrigin(kWebOrigin)); |
+ EXPECT_TRUE(tester.HasOrigin(autofill::kSettingsOrigin)); |
+} |
+ |
+class InspectableCompletionObserver |
+ : public BrowsingDataRemoverCompletionObserver { |
+ public: |
+ explicit InspectableCompletionObserver(BrowsingDataRemover* remover) |
+ : BrowsingDataRemoverCompletionObserver(remover) {} |
+ ~InspectableCompletionObserver() override {} |
+ |
+ bool called() { return called_; } |
+ |
+ protected: |
+ void OnBrowsingDataRemoverDone() override { |
+ BrowsingDataRemoverCompletionObserver::OnBrowsingDataRemoverDone(); |
+ called_ = true; |
+ } |
+ |
+ private: |
+ bool called_ = false; |
+}; |
+ |
+TEST_F(BrowsingDataRemoverTest, CompletionInhibition) { |
+ // The |completion_inhibitor| on the stack should prevent removal sessions |
+ // from completing until after ContinueToCompletion() is called. |
+ BrowsingDataRemoverCompletionInhibitor completion_inhibitor; |
+ |
+ BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>( |
+ BrowsingDataRemoverFactory::GetForBrowserContext(GetProfile())); |
+ InspectableCompletionObserver completion_observer(remover); |
+ remover->RemoveAndReply(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataHelper::UNPROTECTED_WEB, |
+ &completion_observer); |
+ |
+ // Process messages until the inhibitor is notified, and then some, to make |
+ // sure we do not complete asynchronously before ContinueToCompletion() is |
+ // called. |
+ completion_inhibitor.BlockUntilNearCompletion(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Verify that the removal has not yet been completed and the observer has |
+ // not been called. |
+ EXPECT_TRUE(remover->is_removing()); |
+ EXPECT_FALSE(completion_observer.called()); |
+ |
+ // Now run the removal process until completion, and verify that observers are |
+ // now notified, and the notifications is sent out. |
+ completion_inhibitor.ContinueToCompletion(); |
+ completion_observer.BlockUntilCompletion(); |
+ |
+ EXPECT_FALSE(remover->is_removing()); |
+ EXPECT_TRUE(completion_observer.called()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, EarlyShutdown) { |
+ BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>( |
+ BrowsingDataRemoverFactory::GetForBrowserContext(GetProfile())); |
+ InspectableCompletionObserver completion_observer(remover); |
+ BrowsingDataRemoverCompletionInhibitor completion_inhibitor; |
+ remover->RemoveAndReply(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataHelper::UNPROTECTED_WEB, |
+ &completion_observer); |
+ |
+ completion_inhibitor.BlockUntilNearCompletion(); |
+ |
+ // Verify that the deletion has not yet been completed and the observer has |
+ // not been called. |
+ EXPECT_TRUE(remover->is_removing()); |
+ EXPECT_FALSE(completion_observer.called()); |
+ |
+ // Destroying the profile should trigger the notification. |
+ DestroyProfile(); |
+ |
+ EXPECT_TRUE(completion_observer.called()); |
+ |
+ // Finishing after shutdown shouldn't break anything. |
+ completion_inhibitor.ContinueToCompletion(); |
+ completion_observer.BlockUntilCompletion(); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, ZeroSuggestCacheClear) { |
+ PrefService* prefs = GetProfile()->GetPrefs(); |
+ prefs->SetString(omnibox::kZeroSuggestCachedResults, |
+ "[\"\", [\"foo\", \"bar\"]]"); |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+ |
+ // Expect the prefs to be cleared when cookies are removed. |
+ EXPECT_TRUE(prefs->GetString(omnibox::kZeroSuggestCachedResults).empty()); |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+} |
+ |
+#if defined(OS_CHROMEOS) |
+TEST_F(BrowsingDataRemoverTest, ContentProtectionPlatformKeysRemoval) { |
+ chromeos::ScopedTestDeviceSettingsService test_device_settings_service; |
+ chromeos::ScopedTestCrosSettings test_cros_settings; |
+ chromeos::MockUserManager* mock_user_manager = |
+ new testing::NiceMock<chromeos::MockUserManager>(); |
+ mock_user_manager->SetActiveUser( |
+ AccountId::FromUserEmail("test@example.com")); |
+ chromeos::ScopedUserManagerEnabler user_manager_enabler(mock_user_manager); |
+ |
+ std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = |
+ chromeos::DBusThreadManager::GetSetterForTesting(); |
+ chromeos::MockCryptohomeClient* cryptohome_client = |
+ new chromeos::MockCryptohomeClient; |
+ dbus_setter->SetCryptohomeClient( |
+ std::unique_ptr<chromeos::CryptohomeClient>(cryptohome_client)); |
+ |
+ // Expect exactly one call. No calls means no attempt to delete keys and more |
+ // than one call means a significant performance problem. |
+ EXPECT_CALL(*cryptohome_client, TpmAttestationDeleteKeys(_, _, _, _)) |
+ .WillOnce(WithArgs<3>(Invoke(FakeDBusCall))); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_MEDIA_LICENSES, |
+ false); |
+ |
+ chromeos::DBusThreadManager::Shutdown(); |
+} |
+#endif |
+ |
+TEST_F(BrowsingDataRemoverTest, DomainReliability_Null) { |
+ const ClearDomainReliabilityTester& tester = |
+ clear_domain_reliability_tester(); |
+ |
+ EXPECT_EQ(0u, tester.clear_count()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DomainReliability_Beacons) { |
+ const ClearDomainReliabilityTester& tester = |
+ clear_domain_reliability_tester(); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ EXPECT_EQ(1u, tester.clear_count()); |
+ EXPECT_EQ(CLEAR_BEACONS, tester.last_clear_mode()); |
+ EXPECT_TRUE(ProbablySameFilters( |
+ BrowsingDataFilterBuilder::BuildNoopFilter(), tester.last_filter())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DomainReliability_Beacons_WithFilter) { |
+ const ClearDomainReliabilityTester& tester = |
+ clear_domain_reliability_tester(); |
+ |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, builder); |
+ EXPECT_EQ(1u, tester.clear_count()); |
+ EXPECT_EQ(CLEAR_BEACONS, tester.last_clear_mode()); |
+ EXPECT_TRUE(ProbablySameFilters( |
+ builder.BuildGeneralFilter(), tester.last_filter())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DomainReliability_Contexts) { |
+ const ClearDomainReliabilityTester& tester = |
+ clear_domain_reliability_tester(); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+ EXPECT_EQ(1u, tester.clear_count()); |
+ EXPECT_EQ(CLEAR_CONTEXTS, tester.last_clear_mode()); |
+ EXPECT_TRUE(ProbablySameFilters( |
+ BrowsingDataFilterBuilder::BuildNoopFilter(), tester.last_filter())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DomainReliability_Contexts_WithFilter) { |
+ const ClearDomainReliabilityTester& tester = |
+ clear_domain_reliability_tester(); |
+ |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, builder); |
+ EXPECT_EQ(1u, tester.clear_count()); |
+ EXPECT_EQ(CLEAR_CONTEXTS, tester.last_clear_mode()); |
+ EXPECT_TRUE(ProbablySameFilters( |
+ builder.BuildGeneralFilter(), tester.last_filter())); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DomainReliability_ContextsWin) { |
+ const ClearDomainReliabilityTester& tester = |
+ clear_domain_reliability_tester(); |
+ |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY | BrowsingDataRemover::REMOVE_COOKIES, |
+ false); |
+ EXPECT_EQ(1u, tester.clear_count()); |
+ EXPECT_EQ(CLEAR_CONTEXTS, tester.last_clear_mode()); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DomainReliability_ProtectedOrigins) { |
+ const ClearDomainReliabilityTester& tester = |
+ clear_domain_reliability_tester(); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, true); |
+ EXPECT_EQ(1u, tester.clear_count()); |
+ EXPECT_EQ(CLEAR_CONTEXTS, tester.last_clear_mode()); |
+} |
+ |
+// TODO(juliatuttle): This isn't actually testing the no-monitor case, since |
+// BrowsingDataRemoverTest now creates one unconditionally, since it's needed |
+// for some unrelated test cases. This should be fixed so it tests the no- |
+// monitor case again. |
+TEST_F(BrowsingDataRemoverTest, DISABLED_DomainReliability_NoMonitor) { |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY | BrowsingDataRemover::REMOVE_COOKIES, |
+ false); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveDownloadsByTimeOnly) { |
+ RemoveDownloadsTester tester(GetProfile()); |
+ base::Callback<bool(const GURL&)> filter = |
+ BrowsingDataFilterBuilder::BuildNoopFilter(); |
+ |
+ EXPECT_CALL( |
+ *tester.download_manager(), |
+ RemoveDownloadsByURLAndTime(ProbablySameFilter(filter), _, _)); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_DOWNLOADS, false); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveDownloadsByOrigin) { |
+ RemoveDownloadsTester tester(GetProfile()); |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ base::Callback<bool(const GURL&)> filter = builder.BuildGeneralFilter(); |
+ |
+ EXPECT_CALL( |
+ *tester.download_manager(), |
+ RemoveDownloadsByURLAndTime(ProbablySameFilter(filter), _, _)); |
+ |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_DOWNLOADS, builder); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemovePasswordStatistics) { |
+ RemovePasswordsTester tester(GetProfile()); |
+ base::Callback<bool(const GURL&)> empty_filter; |
+ |
+ EXPECT_CALL(*tester.store(), RemoveStatisticsByOriginAndTimeImpl( |
+ ProbablySameFilter(empty_filter), |
+ base::Time(), base::Time::Max())); |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemovePasswordStatisticsByOrigin) { |
+ RemovePasswordsTester tester(GetProfile()); |
+ |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ base::Callback<bool(const GURL&)> filter = builder.BuildGeneralFilter(); |
+ |
+ EXPECT_CALL(*tester.store(), |
+ RemoveStatisticsByOriginAndTimeImpl( |
+ ProbablySameFilter(filter), base::Time(), base::Time::Max())); |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, builder); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemovePasswordsByTimeOnly) { |
+ RemovePasswordsTester tester(GetProfile()); |
+ base::Callback<bool(const GURL&)> filter = |
+ BrowsingDataFilterBuilder::BuildNoopFilter(); |
+ |
+ EXPECT_CALL(*tester.store(), |
+ RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _)) |
+ .WillOnce(Return(password_manager::PasswordStoreChangeList())); |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_PASSWORDS, false); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemovePasswordsByOrigin) { |
+ RemovePasswordsTester tester(GetProfile()); |
+ RegistrableDomainFilterBuilder builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ builder.AddRegisterableDomain(kTestRegisterableDomain1); |
+ base::Callback<bool(const GURL&)> filter = builder.BuildGeneralFilter(); |
+ |
+ EXPECT_CALL(*tester.store(), |
+ RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _)) |
+ .WillOnce(Return(password_manager::PasswordStoreChangeList())); |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_PASSWORDS, builder); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DisableAutoSignIn) { |
+ RemovePasswordsTester tester(GetProfile()); |
+ base::Callback<bool(const GURL&)> empty_filter = |
+ BrowsingDataFilterBuilder::BuildNoopFilter(); |
+ |
+ EXPECT_CALL( |
+ *tester.store(), |
+ DisableAutoSignInForOriginsImpl(ProbablySameFilter(empty_filter))) |
+ .WillOnce(Return(password_manager::PasswordStoreChangeList())); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, DisableAutoSignInAfterRemovingPasswords) { |
+ RemovePasswordsTester tester(GetProfile()); |
+ base::Callback<bool(const GURL&)> empty_filter = |
+ BrowsingDataFilterBuilder::BuildNoopFilter(); |
+ |
+ EXPECT_CALL(*tester.store(), RemoveLoginsByURLAndTimeImpl(_, _, _)) |
+ .WillOnce(Return(password_manager::PasswordStoreChangeList())); |
+ EXPECT_CALL( |
+ *tester.store(), |
+ DisableAutoSignInForOriginsImpl(ProbablySameFilter(empty_filter))) |
+ .WillOnce(Return(password_manager::PasswordStoreChangeList())); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES | |
+ BrowsingDataRemover::REMOVE_PASSWORDS, |
+ false); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveContentSettingsWithBlacklist) { |
+ // Add our settings. |
+ HostContentSettingsMap* host_content_settings_map = |
+ HostContentSettingsMapFactory::GetForProfile(GetProfile()); |
+ host_content_settings_map->SetWebsiteSettingDefaultScope( |
+ kOrigin1, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), |
+ base::MakeUnique<base::DictionaryValue>()); |
+ host_content_settings_map->SetWebsiteSettingDefaultScope( |
+ kOrigin2, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), |
+ base::MakeUnique<base::DictionaryValue>()); |
+ host_content_settings_map->SetWebsiteSettingDefaultScope( |
+ kOrigin3, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), |
+ base::MakeUnique<base::DictionaryValue>()); |
+ host_content_settings_map->SetWebsiteSettingDefaultScope( |
+ kOrigin4, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), |
+ base::MakeUnique<base::DictionaryValue>()); |
+ |
+ // Clear all except for origin1 and origin3. |
+ RegistrableDomainFilterBuilder filter( |
+ RegistrableDomainFilterBuilder::BLACKLIST); |
+ filter.AddRegisterableDomain(kTestRegisterableDomain1); |
+ filter.AddRegisterableDomain(kTestRegisterableDomain3); |
+ BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_SITE_USAGE_DATA, |
+ filter); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_SITE_USAGE_DATA, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify we only have true, and they're origin1, origin3, and origin4. |
+ ContentSettingsForOneType host_settings; |
+ host_content_settings_map->GetSettingsForOneType( |
+ CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), &host_settings); |
+ EXPECT_EQ(3u, host_settings.size()); |
+ EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin1), |
+ host_settings[0].primary_pattern) |
+ << host_settings[0].primary_pattern.ToString(); |
+ EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin4), |
+ host_settings[1].primary_pattern) |
+ << host_settings[1].primary_pattern.ToString(); |
+ EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin3), |
+ host_settings[2].primary_pattern) |
+ << host_settings[2].primary_pattern.ToString(); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, RemoveDurablePermission) { |
+ // Add our settings. |
+ HostContentSettingsMap* host_content_settings_map = |
+ HostContentSettingsMapFactory::GetForProfile(GetProfile()); |
+ |
+ DurableStoragePermissionContext durable_permission(GetProfile()); |
+ durable_permission.UpdateContentSetting(kOrigin1, GURL(), |
+ CONTENT_SETTING_ALLOW); |
+ durable_permission.UpdateContentSetting(kOrigin2, GURL(), |
+ CONTENT_SETTING_ALLOW); |
+ |
+ // Clear all except for origin1 and origin3. |
+ RegistrableDomainFilterBuilder filter( |
+ RegistrableDomainFilterBuilder::BLACKLIST); |
+ filter.AddRegisterableDomain(kTestRegisterableDomain1); |
+ filter.AddRegisterableDomain(kTestRegisterableDomain3); |
+ BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_DURABLE_PERMISSION, |
+ filter); |
+ |
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_DURABLE_PERMISSION, GetRemovalMask()); |
+ EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask()); |
+ |
+ // Verify we only have allow for the first origin. |
+ ContentSettingsForOneType host_settings; |
+ host_content_settings_map->GetSettingsForOneType( |
+ CONTENT_SETTINGS_TYPE_DURABLE_STORAGE, std::string(), &host_settings); |
+ |
+ ASSERT_EQ(2u, host_settings.size()); |
+ // Only the first should should have a setting. |
+ EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin1), |
+ host_settings[0].primary_pattern) |
+ << host_settings[0].primary_pattern.ToString(); |
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, host_settings[0].setting); |
+ |
+ // And our wildcard. |
+ EXPECT_EQ(ContentSettingsPattern::Wildcard(), |
+ host_settings[1].primary_pattern) |
+ << host_settings[1].primary_pattern.ToString(); |
+ EXPECT_EQ(CONTENT_SETTING_ASK, host_settings[1].setting); |
+} |
+ |
+// Test that removing cookies clears HTTP auth data. |
+TEST_F(BrowsingDataRemoverTest, ClearHttpAuthCache_RemoveCookies) { |
+ net::HttpNetworkSession* http_session = GetProfile() |
+ ->GetRequestContext() |
+ ->GetURLRequestContext() |
+ ->http_transaction_factory() |
+ ->GetSession(); |
+ DCHECK(http_session); |
+ |
+ net::HttpAuthCache* http_auth_cache = http_session->http_auth_cache(); |
+ http_auth_cache->Add(kOrigin1, kTestRealm, net::HttpAuth::AUTH_SCHEME_BASIC, |
+ "test challenge", |
+ net::AuthCredentials(base::ASCIIToUTF16("foo"), |
+ base::ASCIIToUTF16("bar")), |
+ "/"); |
+ CHECK(http_auth_cache->Lookup(kOrigin1, kTestRealm, |
+ net::HttpAuth::AUTH_SCHEME_BASIC)); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, false); |
+ |
+ EXPECT_EQ(nullptr, http_auth_cache->Lookup(kOrigin1, kTestRealm, |
+ net::HttpAuth::AUTH_SCHEME_BASIC)); |
+} |
+ |
+// Test that removing passwords clears HTTP auth data. |
+TEST_F(BrowsingDataRemoverTest, ClearHttpAuthCache_RemovePasswords) { |
+ net::HttpNetworkSession* http_session = GetProfile() |
+ ->GetRequestContext() |
+ ->GetURLRequestContext() |
+ ->http_transaction_factory() |
+ ->GetSession(); |
+ DCHECK(http_session); |
+ |
+ net::HttpAuthCache* http_auth_cache = http_session->http_auth_cache(); |
+ http_auth_cache->Add(kOrigin1, kTestRealm, net::HttpAuth::AUTH_SCHEME_BASIC, |
+ "test challenge", |
+ net::AuthCredentials(base::ASCIIToUTF16("foo"), |
+ base::ASCIIToUTF16("bar")), |
+ "/"); |
+ CHECK(http_auth_cache->Lookup(kOrigin1, kTestRealm, |
+ net::HttpAuth::AUTH_SCHEME_BASIC)); |
+ |
+ BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_PASSWORDS, false); |
+ |
+ EXPECT_EQ(nullptr, http_auth_cache->Lookup(kOrigin1, kTestRealm, |
+ net::HttpAuth::AUTH_SCHEME_BASIC)); |
+} |
+ |
+TEST_F(BrowsingDataRemoverTest, ClearPermissionPromptCounts) { |
+ RemovePermissionPromptCountsTest tester(GetProfile()); |
+ |
+ RegistrableDomainFilterBuilder filter_builder_1( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ filter_builder_1.AddRegisterableDomain(kTestRegisterableDomain1); |
+ |
+ RegistrableDomainFilterBuilder filter_builder_2( |
+ RegistrableDomainFilterBuilder::BLACKLIST); |
+ filter_builder_2.AddRegisterableDomain(kTestRegisterableDomain1); |
+ |
+ { |
+ // Test REMOVE_HISTORY. |
+ EXPECT_EQ(1, tester.RecordIgnore(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(2, tester.RecordIgnore(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(1, tester.RecordIgnore(kOrigin1, |
+ content::PermissionType::NOTIFICATIONS)); |
+ tester.ShouldChangeDismissalToBlock(kOrigin1, |
+ content::PermissionType::MIDI_SYSEX); |
+ EXPECT_EQ(1, tester.RecordIgnore(kOrigin2, |
+ content::PermissionType::DURABLE_STORAGE)); |
+ tester.ShouldChangeDismissalToBlock(kOrigin2, |
+ content::PermissionType::NOTIFICATIONS); |
+ |
+ BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_SITE_USAGE_DATA, |
+ filter_builder_1); |
+ |
+ // kOrigin1 should be gone, but kOrigin2 remains. |
+ EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::NOTIFICATIONS)); |
+ EXPECT_EQ(0, tester.GetDismissCount(kOrigin1, |
+ content::PermissionType::MIDI_SYSEX)); |
+ EXPECT_EQ(1, tester.GetIgnoreCount( |
+ kOrigin2, content::PermissionType::DURABLE_STORAGE)); |
+ EXPECT_EQ(1, tester.GetDismissCount( |
+ kOrigin2, content::PermissionType::NOTIFICATIONS)); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, false); |
+ |
+ // Everything should be gone. |
+ EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::NOTIFICATIONS)); |
+ EXPECT_EQ(0, tester.GetDismissCount(kOrigin1, |
+ content::PermissionType::MIDI_SYSEX)); |
+ EXPECT_EQ(0, tester.GetIgnoreCount( |
+ kOrigin2, content::PermissionType::DURABLE_STORAGE)); |
+ EXPECT_EQ(0, tester.GetDismissCount( |
+ kOrigin2, content::PermissionType::NOTIFICATIONS)); |
+ } |
+ { |
+ // Test REMOVE_SITE_DATA. |
+ EXPECT_EQ(1, tester.RecordIgnore(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(2, tester.RecordIgnore(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(1, tester.RecordIgnore(kOrigin1, |
+ content::PermissionType::NOTIFICATIONS)); |
+ tester.ShouldChangeDismissalToBlock(kOrigin1, |
+ content::PermissionType::MIDI_SYSEX); |
+ EXPECT_EQ(1, tester.RecordIgnore(kOrigin2, |
+ content::PermissionType::DURABLE_STORAGE)); |
+ tester.ShouldChangeDismissalToBlock(kOrigin2, |
+ content::PermissionType::NOTIFICATIONS); |
+ |
+ BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_SITE_USAGE_DATA, |
+ filter_builder_2); |
+ |
+ // kOrigin2 should be gone, but kOrigin1 remains. |
+ EXPECT_EQ(2, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(1, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::NOTIFICATIONS)); |
+ EXPECT_EQ(1, tester.GetDismissCount(kOrigin1, |
+ content::PermissionType::MIDI_SYSEX)); |
+ EXPECT_EQ(0, tester.GetIgnoreCount( |
+ kOrigin2, content::PermissionType::DURABLE_STORAGE)); |
+ EXPECT_EQ(0, tester.GetDismissCount( |
+ kOrigin2, content::PermissionType::NOTIFICATIONS)); |
+ |
+ BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_SITE_USAGE_DATA, |
+ false); |
+ |
+ // Everything should be gone. |
+ EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::GEOLOCATION)); |
+ EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin1, |
+ content::PermissionType::NOTIFICATIONS)); |
+ EXPECT_EQ(0, tester.GetDismissCount(kOrigin1, |
+ content::PermissionType::MIDI_SYSEX)); |
+ EXPECT_EQ(0, tester.GetIgnoreCount( |
+ kOrigin2, content::PermissionType::DURABLE_STORAGE)); |
+ EXPECT_EQ(0, tester.GetDismissCount( |
+ kOrigin2, content::PermissionType::NOTIFICATIONS)); |
+ } |
+} |
+ |
+#if BUILDFLAG(ENABLE_PLUGINS) |
+TEST_F(BrowsingDataRemoverTest, RemovePluginData) { |
+ RemovePluginDataTester tester(GetProfile()); |
+ |
+ tester.AddDomain(kOrigin1.host()); |
+ tester.AddDomain(kOrigin2.host()); |
+ tester.AddDomain(kOrigin3.host()); |
+ |
+ std::vector<std::string> expected = { |
+ kOrigin1.host(), kOrigin2.host(), kOrigin3.host() }; |
+ EXPECT_EQ(expected, tester.GetDomains()); |
+ |
+ // Delete data with a filter for the registrable domain of |kOrigin3|. |
+ RegistrableDomainFilterBuilder filter_builder( |
+ RegistrableDomainFilterBuilder::WHITELIST); |
+ filter_builder.AddRegisterableDomain(kTestRegisterableDomain3); |
+ BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_PLUGIN_DATA, |
+ filter_builder); |
+ |
+ // Plugin data for |kOrigin3.host()| should have been removed. |
+ expected.pop_back(); |
+ EXPECT_EQ(expected, tester.GetDomains()); |
+ |
+ // TODO(msramek): Mock PluginDataRemover and test the complete deletion |
+ // of plugin data as well. |
+} |
+#endif |
+ |
+class MultipleTasksObserver { |
+ public: |
+ // A simple implementation of BrowsingDataRemover::Observer. |
+ // MultipleTasksObserver will use several instances of Target to test |
+ // that completion callbacks are returned to the correct one. |
+ class Target : public BrowsingDataRemover::Observer { |
+ public: |
+ Target(MultipleTasksObserver* parent, BrowsingDataRemover* remover) |
+ : parent_(parent), |
+ observer_(this) { |
+ observer_.Add(remover); |
+ } |
+ ~Target() override {} |
+ |
+ void OnBrowsingDataRemoverDone() override { |
+ parent_->SetLastCalledTarget(this); |
+ } |
+ |
+ private: |
+ MultipleTasksObserver* parent_; |
+ ScopedObserver<BrowsingDataRemover, BrowsingDataRemover::Observer> |
+ observer_; |
+ }; |
+ |
+ explicit MultipleTasksObserver(BrowsingDataRemover* remover) |
+ : target_a_(this, remover), |
+ target_b_(this, remover), |
+ last_called_target_(nullptr) {} |
+ ~MultipleTasksObserver() {} |
+ |
+ void ClearLastCalledTarget() { |
+ last_called_target_ = nullptr; |
+ } |
+ |
+ Target* GetLastCalledTarget() { |
+ return last_called_target_; |
+ } |
+ |
+ Target* target_a() { return &target_a_; } |
+ Target* target_b() { return &target_b_; } |
+ |
+ private: |
+ void SetLastCalledTarget(Target* target) { |
+ DCHECK(!last_called_target_) |
+ << "Call ClearLastCalledTarget() before every removal task."; |
+ last_called_target_ = target; |
+ } |
+ |
+ Target target_a_; |
+ Target target_b_; |
+ Target* last_called_target_; |
+}; |
+ |
+TEST_F(BrowsingDataRemoverTest, MultipleTasks) { |
+ BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>( |
+ BrowsingDataRemoverFactory::GetForBrowserContext(GetProfile())); |
+ EXPECT_FALSE(remover->is_removing()); |
+ |
+ std::unique_ptr<RegistrableDomainFilterBuilder> filter_builder_1( |
+ new RegistrableDomainFilterBuilder( |
+ RegistrableDomainFilterBuilder::WHITELIST)); |
+ std::unique_ptr<RegistrableDomainFilterBuilder> filter_builder_2( |
+ new RegistrableDomainFilterBuilder( |
+ RegistrableDomainFilterBuilder::BLACKLIST)); |
+ filter_builder_2->AddRegisterableDomain("example.com"); |
+ |
+ MultipleTasksObserver observer(remover); |
+ BrowsingDataRemoverCompletionInhibitor completion_inhibitor; |
+ |
+ // Test several tasks with various configuration of masks, filters, and target |
+ // observers. |
+ std::list<BrowsingDataRemoverImpl::RemovalTask> tasks; |
+ tasks.emplace_back(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataHelper::UNPROTECTED_WEB, |
+ base::MakeUnique<RegistrableDomainFilterBuilder>( |
+ RegistrableDomainFilterBuilder::BLACKLIST), |
+ observer.target_a()); |
+ tasks.emplace_back(base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, |
+ BrowsingDataHelper::PROTECTED_WEB, |
+ base::MakeUnique<RegistrableDomainFilterBuilder>( |
+ RegistrableDomainFilterBuilder::BLACKLIST), |
+ nullptr); |
+ tasks.emplace_back( |
+ base::Time::Now(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_PASSWORDS, BrowsingDataHelper::ALL, |
+ base::MakeUnique<RegistrableDomainFilterBuilder>( |
+ RegistrableDomainFilterBuilder::BLACKLIST), |
+ observer.target_b()); |
+ tasks.emplace_back( |
+ base::Time(), base::Time::UnixEpoch(), |
+ BrowsingDataRemover::REMOVE_WEBSQL, |
+ BrowsingDataHelper::UNPROTECTED_WEB, |
+ std::move(filter_builder_1), |
+ observer.target_b()); |
+ tasks.emplace_back( |
+ base::Time::UnixEpoch(), base::Time::Now(), |
+ BrowsingDataRemover::REMOVE_CHANNEL_IDS, |
+ BrowsingDataHelper::ALL, |
+ std::move(filter_builder_2), |
+ nullptr); |
+ |
+ for (BrowsingDataRemoverImpl::RemovalTask& task : tasks) { |
+ // All tasks can be directly translated to a RemoveInternal() call. Since |
+ // that is a private method, we must call the four public versions of |
+ // Remove.* instead. This also serves as a test that those methods are all |
+ // correctly reduced to RemoveInternal(). |
+ if (!task.observer && task.filter_builder->IsEmptyBlacklist()) { |
+ remover->Remove(task.delete_begin, task.delete_end, |
+ task.remove_mask, task.origin_type_mask); |
+ } else if (task.filter_builder->IsEmptyBlacklist()) { |
+ remover->RemoveAndReply(task.delete_begin, task.delete_end, |
+ task.remove_mask, task.origin_type_mask, |
+ task.observer); |
+ } else if (!task.observer) { |
+ remover->RemoveWithFilter(task.delete_begin, task.delete_end, |
+ task.remove_mask, task.origin_type_mask, |
+ std::move(task.filter_builder)); |
+ } else { |
+ remover->RemoveWithFilterAndReply(task.delete_begin, task.delete_end, |
+ task.remove_mask, task.origin_type_mask, |
+ std::move(task.filter_builder), |
+ task.observer); |
+ } |
+ } |
+ |
+ // Use the inhibitor to stop after every task and check the results. |
+ for (BrowsingDataRemoverImpl::RemovalTask& task : tasks) { |
+ EXPECT_TRUE(remover->is_removing()); |
+ observer.ClearLastCalledTarget(); |
+ |
+ // Finish the task execution synchronously. |
+ completion_inhibitor.BlockUntilNearCompletion(); |
+ completion_inhibitor.ContinueToCompletion(); |
+ |
+ // Observers, if any, should have been called by now (since we call |
+ // observers on the same thread). |
+ EXPECT_EQ(task.observer, observer.GetLastCalledTarget()); |
+ |
+ // TODO(msramek): If BrowsingDataRemover took ownership of the last used |
+ // filter builder and exposed it, we could also test it here. Make it so. |
+ EXPECT_EQ(task.remove_mask, GetRemovalMask()); |
+ EXPECT_EQ(task.origin_type_mask, GetOriginTypeMask()); |
+ EXPECT_EQ(task.delete_begin, GetBeginTime()); |
+ } |
+ |
+ EXPECT_FALSE(remover->is_removing()); |
+} |
+ |
+// The previous test, BrowsingDataRemoverTest.MultipleTasks, tests that the |
+// tasks are not mixed up and they are executed in a correct order. However, |
+// the completion inhibitor kept synchronizing the execution in order to verify |
+// the parameters. This test demonstrates that even running the tasks without |
+// inhibition is executed correctly and doesn't crash. |
+TEST_F(BrowsingDataRemoverTest, MultipleTasksInQuickSuccession) { |
+ BrowsingDataRemoverImpl* remover = static_cast<BrowsingDataRemoverImpl*>( |
+ BrowsingDataRemoverFactory::GetForBrowserContext(GetProfile())); |
+ EXPECT_FALSE(remover->is_removing()); |
+ |
+ int test_removal_masks[] = { |
+ BrowsingDataRemover::REMOVE_COOKIES, |
+ BrowsingDataRemover::REMOVE_PASSWORDS, |
+ BrowsingDataRemover::REMOVE_COOKIES, |
+ BrowsingDataRemover::REMOVE_COOKIES, |
+ BrowsingDataRemover::REMOVE_COOKIES, |
+ BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataRemover::REMOVE_COOKIES | BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataRemover::REMOVE_COOKIES | BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataRemover::REMOVE_COOKIES | |
+ BrowsingDataRemover::REMOVE_HISTORY | |
+ BrowsingDataRemover::REMOVE_PASSWORDS, |
+ BrowsingDataRemover::REMOVE_PASSWORDS, |
+ BrowsingDataRemover::REMOVE_PASSWORDS, |
+ }; |
+ |
+ for (int removal_mask : test_removal_masks) { |
+ remover->Remove(base::Time(), base::Time::Max(), removal_mask, |
+ BrowsingDataHelper::UNPROTECTED_WEB); |
+ } |
+ |
+ EXPECT_TRUE(remover->is_removing()); |
+ |
+ // Add one more deletion and wait for it. |
+ BlockUntilBrowsingDataRemoved( |
+ base::Time(), base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_COOKIES, |
+ BrowsingDataHelper::UNPROTECTED_WEB); |
+ |
+ EXPECT_FALSE(remover->is_removing()); |
+} |
+ |
+// Test that the remover clears bookmark meta data (normally added in a tab |
+// helper). |
+TEST_F(BrowsingDataRemoverTest, BookmarkLastVisitDatesGetCleared) { |
+ TestingProfile profile; |
+ profile.CreateBookmarkModel(true); |
+ |
+ bookmarks::BookmarkModel* bookmark_model = |
+ BookmarkModelFactory::GetForBrowserContext(&profile); |
+ bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model); |
+ |
+ const base::Time delete_begin = |
+ base::Time::Now() - base::TimeDelta::FromDays(1); |
+ |
+ // Create a couple of bookmarks. |
+ bookmark_model->AddURL(bookmark_model->bookmark_bar_node(), 0, |
+ base::string16(), |
+ GURL("http://foo.org/desktop")); |
+ bookmark_model->AddURL(bookmark_model->mobile_node(), 0, |
+ base::string16(), |
+ GURL("http://foo.org/mobile")); |
+ |
+ // Simulate their visits (this is using Time::Now() as timestamps). |
+ ntp_snippets::UpdateBookmarkOnURLVisitedInMainFrame( |
+ bookmark_model, GURL("http://foo.org/desktop"), |
+ /*is_mobile_platform=*/false); |
+ ntp_snippets::UpdateBookmarkOnURLVisitedInMainFrame( |
+ bookmark_model, GURL("http://foo.org/mobile"), |
+ /*is_mobile_platform=*/true); |
+ |
+ // Add a bookmark with a visited timestamp before the deletion interval. |
+ bookmarks::BookmarkNode::MetaInfoMap meta_info = { |
+ {"last_visited", |
+ base::Int64ToString((delete_begin - base::TimeDelta::FromSeconds(1)) |
+ .ToInternalValue())}}; |
+ bookmark_model->AddURLWithCreationTimeAndMetaInfo( |
+ bookmark_model->mobile_node(), 0, base::ASCIIToUTF16("my title"), |
+ GURL("http://foo-2.org/"), delete_begin - base::TimeDelta::FromDays(1), |
+ &meta_info); |
+ |
+ // There should be some recently visited bookmarks. |
+ EXPECT_THAT(ntp_snippets::GetRecentlyVisitedBookmarks( |
+ bookmark_model, 2, base::Time::UnixEpoch(), |
+ /*consider_visits_from_desktop=*/false), |
+ Not(IsEmpty())); |
+ |
+ // Inject the bookmark model into the remover. |
+ BrowsingDataRemover* remover = |
+ BrowsingDataRemoverFactory::GetForBrowserContext(&profile); |
+ |
+ BrowsingDataRemoverCompletionObserver completion_observer(remover); |
+ remover->RemoveAndReply(delete_begin, base::Time::Max(), |
+ BrowsingDataRemover::REMOVE_HISTORY, |
+ BrowsingDataHelper::ALL, &completion_observer); |
+ completion_observer.BlockUntilCompletion(); |
+ |
+ // There should be only 1 recently visited bookmarks. |
+ std::vector<const bookmarks::BookmarkNode*> remaining_nodes = |
+ ntp_snippets::GetRecentlyVisitedBookmarks( |
+ bookmark_model, 3, base::Time::UnixEpoch(), |
+ /*consider_visits_from_desktop=*/true); |
+ EXPECT_THAT(remaining_nodes, SizeIs(1)); |
+ EXPECT_THAT(remaining_nodes[0]->url().spec(), Eq("http://foo-2.org/")); |
+} |