Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1068)

Unified Diff: chrome/browser/browsing_data/browsing_data_remover_unittest.cc

Issue 2648223003: Revert of Split BrowsingDataRemoverTest into two tests for Impl and Delegate. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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/"));
+}

Powered by Google App Engine
This is Rietveld 408576698