blob: 8feb129428b221831cb414f78d06a8f39273cb4c [file] [log] [blame]
// Copyright 2017 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 "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
#include <stdint.h>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/files/file_util.h"
#include "base/guid.h"
#include "base/memory/ptr_util.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/post_task.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "base/util/values/values_util.h"
#include "build/build_config.h"
#include "chrome/browser/autofill/personal_data_manager_factory.h"
#include "chrome/browser/autofill/strike_database_factory.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/domain_reliability/service_factory.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_core_service_impl.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/language/url_language_histogram_factory.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/permissions/adaptive_notification_permission_ui_selector.h"
#include "chrome/browser/permissions/permission_decision_auto_blocker.h"
#include "chrome/browser/permissions/permission_util.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
#include "chrome/browser/ssl/chrome_ssl_host_state_delegate_factory.h"
#include "chrome/browser/storage/durable_storage_permission_context.h"
#include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/common/chrome_features.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_test_utils.h"
#include "components/autofill/core/browser/data_model/autofill_profile.h"
#include "components/autofill/core/browser/data_model/credit_card.h"
#include "components/autofill/core/browser/payments/strike_database.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "components/autofill/core/browser/test_autofill_clock.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/content_settings_info.h"
#include "components/content_settings/core/browser/content_settings_registry.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/browser/website_settings_info.h"
#include "components/content_settings/core/browser/website_settings_registry.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/favicon/core/favicon_service.h"
#include "components/history/core/browser/history_service.h"
#include "components/language/core/browser/url_language_histogram.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 "components/safe_browsing/verdict_cache_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browsing_data_filter_builder.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/browsing_data_remover_test_util.h"
#include "content/public/test/mock_download_manager.h"
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/network_isolation_key.h"
#include "net/cookies/canonical_cookie.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_cache.h"
#include "net/http/http_transaction_factory.h"
#include "net/net_buildflags.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/network_context.h"
#include "services/network/network_service.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/favicon_size.h"
#if defined(OS_ANDROID)
#include "chrome/browser/android/customtabs/origin_verifier.h"
#include "chrome/browser/android/search_permissions/search_permissions_service.h"
#include "chrome/browser/android/webapps/webapp_registry.h"
#include "components/feed/buildflags.h"
#else // !defined(OS_ANDROID)
#include "content/public/browser/host_zoom_map.h"
#endif // !defined(OS_ANDROID)
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/users/mock_user_manager.h"
#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/scoped_user_manager.h"
#endif // defined(OS_CHROMEOS)
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
#include "chrome/common/chrome_paths.h"
#include "components/upload_list/crash_upload_list.h"
#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/mock_extension_special_storage_policy.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_PLUGINS)
#include "chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/plugins/plugin_utils.h"
#endif // BUILDFLAG(ENABLE_PLUGINS)
#if BUILDFLAG(ENABLE_REPORTING)
#include "net/network_error_logging/network_error_logging_service.h"
#include "net/reporting/reporting_browsing_data_remover.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_service.h"
#endif // BUILDFLAG(ENABLE_REPORTING)
using content::BrowsingDataFilterBuilder;
using domain_reliability::DomainReliabilityClearMode;
using domain_reliability::DomainReliabilityMonitor;
using testing::_;
using testing::ByRef;
using testing::Eq;
using testing::FloatEq;
using testing::Invoke;
using testing::Matcher;
using testing::MakeMatcher;
using testing::MatcherInterface;
using testing::MatchResultListener;
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[] = "devtools://abcdefghijklmnopqrstuvw/";
// For HTTP auth.
const char kTestRealm[] = "TestRealm";
// For Autofill.
const char kWebOrigin[] = "https://www.example.com/";
// Default search engine URL.
const char kDSETestUrl[] = "https://search.com";
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 GURL kDSEOrigin(kDSETestUrl);
// Shorthands for origin types.
#if BUILDFLAG(ENABLE_EXTENSIONS)
const int kExtension = ChromeBrowsingDataRemoverDelegate::ORIGIN_TYPE_EXTENSION;
#endif
const int kProtected = content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB;
const int kUnprotected =
content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB;
// Testers --------------------------------------------------------------------
#if defined(OS_ANDROID)
class TestWebappRegistry : public WebappRegistry {
public:
TestWebappRegistry() : WebappRegistry() { }
void UnregisterWebappsForUrls(
const base::RepeatingCallback<bool(const GURL&)>& url_filter) override {
// Mocks out a JNI call.
}
void ClearWebappHistoryForUrls(
const base::RepeatingCallback<bool(const GURL&)>& url_filter) override {
// Mocks out a JNI call.
}
};
// TestSearchEngineDelegate
class TestSearchEngineDelegate
: public SearchPermissionsService::SearchEngineDelegate {
public:
base::string16 GetDSEName() override { return base::string16(); }
url::Origin GetDSEOrigin() override {
return url::Origin::Create(kDSEOrigin);
}
void SetDSEChangedCallback(const base::Closure& callback) override {
dse_changed_callback_ = callback;
}
void UpdateDSEOrigin() { dse_changed_callback_.Run(); }
private:
base::Closure dse_changed_callback_;
};
#endif
#if defined(OS_CHROMEOS)
// Customized fake class to count TpmAttestationDeleteKeys call.
class FakeCryptohomeClient : public chromeos::FakeCryptohomeClient {
public:
void TpmAttestationDeleteKeys(
chromeos::attestation::AttestationKeyType key_type,
const cryptohome::AccountIdentifier& cryptohome_id,
const std::string& key_prefix,
chromeos::DBusMethodCallback<bool> callback) override {
++delete_keys_call_count_;
chromeos::FakeCryptohomeClient::TpmAttestationDeleteKeys(
key_type, cryptohome_id, key_prefix, std::move(callback));
}
int delete_keys_call_count() const { return delete_keys_call_count_; }
private:
int delete_keys_call_count_ = 0;
};
#endif
class RemoveCookieTester {
public:
RemoveCookieTester() {}
// Returns true, if the given cookie exists in the cookie store.
bool ContainsCookie() {
bool result = false;
base::RunLoop run_loop;
cookie_manager_->GetCookieList(
kOrigin1, net::CookieOptions(),
base::BindLambdaForTesting(
[&](const net::CookieStatusList& cookie_list,
const net::CookieStatusList& excluded_cookies) {
std::string cookie_line =
net::CanonicalCookie::BuildCookieLine(cookie_list);
if (cookie_line == "A=1") {
result = true;
} else {
EXPECT_EQ("", cookie_line);
result = false;
}
run_loop.Quit();
}));
run_loop.Run();
return result;
}
void AddCookie() {
base::RunLoop run_loop;
auto cookie = net::CanonicalCookie::Create(
kOrigin1, "A=1", base::Time::Now(), base::nullopt /* server_time */);
cookie_manager_->SetCanonicalCookie(
*cookie, "http", net::CookieOptions(),
base::BindLambdaForTesting(
[&](net::CanonicalCookie::CookieInclusionStatus result) {
EXPECT_TRUE(result.IsInclude());
run_loop.Quit();
}));
run_loop.Run();
}
protected:
void SetCookieManager(
mojo::Remote<network::mojom::CookieManager> cookie_manager) {
cookie_manager_ = std::move(cookie_manager);
}
private:
mojo::Remote<network::mojom::CookieManager> cookie_manager_;
DISALLOW_COPY_AND_ASSIGN(RemoveCookieTester);
};
class RemoveSafeBrowsingCookieTester : public RemoveCookieTester {
public:
RemoveSafeBrowsingCookieTester()
: browser_process_(TestingBrowserProcess::GetGlobal()) {
// TODO(crbug/925153): Port consumers of the |sb_service| to use the
// interface in components/safe_browsing, and remove this cast.
scoped_refptr<safe_browsing::SafeBrowsingService> sb_service =
static_cast<safe_browsing::SafeBrowsingService*>(
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;
mojo::Remote<network::mojom::CookieManager> cookie_manager;
sb_service->GetNetworkContext()->GetCookieManager(
cookie_manager.BindNewPipeAndPassReceiver());
cookie_manager->DeleteCookies(
network::mojom::CookieDeletionFilter::New(),
base::BindLambdaForTesting(
[&](uint32_t num_deleted) { run_loop.Quit(); }));
run_loop.Run();
SetCookieManager(std::move(cookie_manager));
}
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 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) {
bool contains_url = false;
base::RunLoop run_loop;
base::CancelableTaskTracker tracker;
history_service_->QueryURL(
url, true,
base::BindLambdaForTesting([&](history::QueryURLResult result) {
contains_url = result.success;
run_loop.Quit();
}),
&tracker);
run_loop.Run();
return contains_url;
}
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:
// 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::IconType::kFavicon,
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::IconType::kFavicon}, gfx::kFaviconSize,
/*fallback_to_host=*/false,
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);
};
// Custom ProtocolHandlerRegistry delegate that doesn't change any OS settings.
class FakeProtocolHandlerRegistryDelegate
: public ProtocolHandlerRegistry::Delegate {
public:
~FakeProtocolHandlerRegistryDelegate() override = default;
void RegisterExternalHandler(const std::string& protocol) override {
registered_protocols_.insert(protocol);
}
void DeregisterExternalHandler(const std::string& protocol) override {
registered_protocols_.erase(protocol);
}
bool IsExternalHandlerRegistered(const std::string& protocol) override {
return registered_protocols_.count(protocol);
}
void RegisterWithOSAsDefaultClient(
const std::string& protocol,
shell_integration::DefaultWebClientWorkerCallback callback) override {}
void CheckDefaultClientWithOS(
const std::string& protocol,
shell_integration::DefaultWebClientWorkerCallback callback) override {}
private:
std::set<std::string> registered_protocols_;
};
std::unique_ptr<KeyedService> BuildProtocolHandlerRegistry(
content::BrowserContext* context) {
Profile* profile = Profile::FromBrowserContext(context);
return std::make_unique<ProtocolHandlerRegistry>(
profile, std::make_unique<FakeProtocolHandlerRegistryDelegate>());
}
class ClearDomainReliabilityTester {
public:
explicit ClearDomainReliabilityTester(TestingProfile* profile) {
static_cast<ChromeBrowsingDataRemoverDelegate*>(
profile->GetBrowsingDataRemoverDelegate())
->OverrideDomainReliabilityClearerForTesting(base::BindRepeating(
&ClearDomainReliabilityTester::Clear, base::Unretained(this)));
}
unsigned clear_count() const { return clear_count_; }
network::mojom::NetworkContext::DomainReliabilityClearMode last_clear_mode()
const {
return last_clear_mode_;
}
const base::RepeatingCallback<bool(const GURL&)>& last_filter() const {
return last_filter_;
}
private:
void Clear(
content::BrowsingDataFilterBuilder* filter_builder,
network::mojom::NetworkContext_DomainReliabilityClearMode mode,
network::mojom::NetworkContext::ClearDomainReliabilityCallback callback) {
++clear_count_;
last_clear_mode_ = mode;
std::move(callback).Run();
last_filter_ = filter_builder->IsEmptyBlacklist()
? base::RepeatingCallback<bool(const GURL&)>()
: filter_builder->BuildGeneralFilter();
}
unsigned clear_count_ = 0;
network::mojom::NetworkContext::DomainReliabilityClearMode last_clear_mode_;
base::RepeatingCallback<bool(const GURL&)> last_filter_;
};
class RemovePasswordsTester {
public:
explicit RemovePasswordsTester(TestingProfile* testing_profile) {
PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
testing_profile,
base::BindRepeating(
&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::SetUp();
}
~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)
: autoblocker_(PermissionDecisionAutoBlocker::GetForProfile(profile)) {}
int GetDismissCount(const GURL& url, ContentSettingsType permission) {
return autoblocker_->GetDismissCount(url, permission);
}
int GetIgnoreCount(const GURL& url, ContentSettingsType permission) {
return autoblocker_->GetIgnoreCount(url, permission);
}
bool RecordIgnoreAndEmbargo(const GURL& url, ContentSettingsType permission) {
return autoblocker_->RecordIgnoreAndEmbargo(url, permission);
}
bool RecordDismissAndEmbargo(const GURL& url,
ContentSettingsType permission) {
return autoblocker_->RecordDismissAndEmbargo(url, permission);
}
void CheckEmbargo(const GURL& url,
ContentSettingsType permission,
ContentSetting expected_setting) {
EXPECT_EQ(expected_setting,
autoblocker_->GetEmbargoResult(url, permission).content_setting);
}
private:
PermissionDecisionAutoBlocker* autoblocker_;
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(GetSitesWithFlashDataCallback callback) override {
MockBrowsingDataFlashLSOHelper::StartFetching(std::move(callback));
Notify();
}
private:
~TestBrowsingDataFlashLSOHelper() override {}
DISALLOW_COPY_AND_ASSIGN(TestBrowsingDataFlashLSOHelper);
};
class RemovePluginDataTester {
public:
explicit RemovePluginDataTester(TestingProfile* profile)
: helper_(new TestBrowsingDataFlashLSOHelper(profile)) {
static_cast<ChromeBrowsingDataRemoverDelegate*>(
profile->GetBrowsingDataRemoverDelegate())
->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);
};
// Waits until a change is observed in content settings.
class FlashContentSettingsChangeWaiter : public content_settings::Observer {
public:
explicit FlashContentSettingsChangeWaiter(Profile* profile)
: profile_(profile) {
HostContentSettingsMapFactory::GetForProfile(profile)->AddObserver(this);
}
~FlashContentSettingsChangeWaiter() override {
HostContentSettingsMapFactory::GetForProfile(profile_)->RemoveObserver(
this);
}
// content_settings::Observer:
void OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
const std::string& resource_identifier) override {
if (content_type == ContentSettingsType::PLUGINS)
run_loop_.Quit();
}
void Wait() { run_loop_.Run(); }
private:
Profile* profile_;
base::RunLoop run_loop_;
DISALLOW_COPY_AND_ASSIGN(FlashContentSettingsChangeWaiter);
};
#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::RepeatingCallback::Equals() in this matcher.
class ProbablySameFilterMatcher
: public MatcherInterface<
const base::RepeatingCallback<bool(const GURL&)>&> {
public:
explicit ProbablySameFilterMatcher(
const base::RepeatingCallback<bool(const GURL&)>& filter)
: to_match_(filter) {}
virtual bool MatchAndExplain(
const base::RepeatingCallback<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::RepeatingCallback<bool(const GURL&)>& to_match_;
};
inline Matcher<const base::RepeatingCallback<bool(const GURL&)>&>
ProbablySameFilter(const base::RepeatingCallback<bool(const GURL&)>& filter) {
return MakeMatcher(new ProbablySameFilterMatcher(filter));
}
bool ProbablySameFilters(
const base::RepeatingCallback<bool(const GURL&)>& filter1,
const base::RepeatingCallback<bool(const GURL&)>& filter2) {
return ProbablySameFilter(filter1).MatchAndExplain(filter2, nullptr);
}
base::Time AnHourAgo() {
return base::Time::Now() - base::TimeDelta::FromHours(1);
}
class RemoveDownloadsTester {
public:
explicit RemoveDownloadsTester(TestingProfile* testing_profile)
: download_manager_(new content::MockDownloadManager()) {
content::BrowserContext::SetDownloadManagerForTesting(
testing_profile, base::WrapUnique(download_manager_));
std::unique_ptr<ChromeDownloadManagerDelegate> delegate =
std::make_unique<ChromeDownloadManagerDelegate>(testing_profile);
chrome_download_manager_delegate_ = delegate.get();
service_ =
DownloadCoreServiceFactory::GetForBrowserContext(testing_profile);
service_->SetDownloadManagerDelegateForTesting(std::move(delegate));
EXPECT_CALL(*download_manager_, GetBrowserContext())
.WillRepeatedly(Return(testing_profile));
EXPECT_CALL(*download_manager_, Shutdown());
}
~RemoveDownloadsTester() {
service_->SetDownloadManagerDelegateForTesting(nullptr);
}
content::MockDownloadManager* download_manager() { return download_manager_; }
private:
DownloadCoreService* service_;
content::MockDownloadManager* download_manager_; // Owned by testing profile.
ChromeDownloadManagerDelegate* chrome_download_manager_delegate_;
DISALLOW_COPY_AND_ASSIGN(RemoveDownloadsTester);
};
} // namespace
ACTION(QuitMainMessageLoop) {
base::RunLoop::QuitCurrentWhenIdleDeprecated();
}
class PersonalDataLoadedObserverMock
: public autofill::PersonalDataManagerObserver {
public:
PersonalDataLoadedObserverMock() {}
~PersonalDataLoadedObserverMock() override {}
MOCK_METHOD0(OnPersonalDataChanged, void());
MOCK_METHOD0(OnPersonalDataFinishedProfileTasks, void());
};
// RemoveAutofillTester is not a part of the anonymous namespace above, as
// PersonalDataManager declares it a friend in an empty namespace.
class RemoveAutofillTester {
public:
explicit RemoveAutofillTester(TestingProfile* profile)
: personal_data_manager_(
autofill::PersonalDataManagerFactory::GetForProfile(profile)) {
autofill::test::DisableSystemServices(profile->GetPrefs());
personal_data_manager_->AddObserver(&personal_data_observer_);
}
~RemoveAutofillTester() {
personal_data_manager_->RemoveObserver(&personal_data_observer_);
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);
WaitForOnPersonalDataFinishedProfileTasks();
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);
WaitForOnPersonalDataChanged();
}
private:
void WaitForOnPersonalDataChanged() {
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.WillRepeatedly(QuitMainMessageLoop());
base::RunLoop().Run();
}
void WaitForOnPersonalDataFinishedProfileTasks() {
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillRepeatedly(QuitMainMessageLoop());
base::RunLoop().Run();
}
autofill::PersonalDataManager* personal_data_manager_;
PersonalDataLoadedObserverMock personal_data_observer_;
DISALLOW_COPY_AND_ASSIGN(RemoveAutofillTester);
};
#if BUILDFLAG(ENABLE_REPORTING)
class MockReportingService : public net::ReportingService {
public:
MockReportingService() = default;
// net::ReportingService implementation:
~MockReportingService() override = default;
void QueueReport(const GURL& url,
const std::string& user_agent,
const std::string& group,
const std::string& type,
std::unique_ptr<const base::Value> body,
int depth) override {
NOTREACHED();
}
void ProcessHeader(const GURL& url,
const std::string& header_value) override {
NOTREACHED();
}
void RemoveBrowsingData(int data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>&
origin_filter) override {
++remove_calls_;
last_data_type_mask_ = data_type_mask;
last_origin_filter_ = origin_filter;
}
void RemoveAllBrowsingData(int data_type_mask) override {
++remove_all_calls_;
last_data_type_mask_ = data_type_mask;
last_origin_filter_ = base::RepeatingCallback<bool(const GURL&)>();
}
void OnShutdown() override {}
const net::ReportingPolicy& GetPolicy() const override {
static net::ReportingPolicy dummy_policy_;
NOTREACHED();
return dummy_policy_;
}
net::ReportingContext* GetContextForTesting() const override {
NOTREACHED();
return nullptr;
}
int remove_calls() const { return remove_calls_; }
int remove_all_calls() const { return remove_all_calls_; }
int last_data_type_mask() const { return last_data_type_mask_; }
const base::RepeatingCallback<bool(const GURL&)>& last_origin_filter() const {
return last_origin_filter_;
}
private:
int remove_calls_ = 0;
int remove_all_calls_ = 0;
int last_data_type_mask_ = 0;
base::RepeatingCallback<bool(const GURL&)> last_origin_filter_;
DISALLOW_COPY_AND_ASSIGN(MockReportingService);
};
namespace autofill {
// StrikeDatabaseTester is in the autofill namespace since
// StrikeDatabase declares it as a friend in the autofill namespace.
class StrikeDatabaseTester {
public:
explicit StrikeDatabaseTester(Profile* profile)
: strike_database_(
autofill::StrikeDatabaseFactory::GetForProfile(profile)) {}
bool IsEmpty() {
int num_keys;
base::RunLoop run_loop;
strike_database_->LoadKeys(base::BindLambdaForTesting(
[&](bool success, std::unique_ptr<std::vector<std::string>> keys) {
num_keys = keys.get()->size();
run_loop.Quit();
}));
run_loop.Run();
return (num_keys == 0);
}
private:
autofill::StrikeDatabase* strike_database_;
};
} // namespace autofill
class ClearReportingCacheTester {
public:
ClearReportingCacheTester(network::NetworkContext* network_context,
bool create_service)
: url_request_context_(network_context->url_request_context()) {
if (create_service)
service_ = std::make_unique<MockReportingService>();
old_service_ = url_request_context_->reporting_service();
url_request_context_->set_reporting_service(service_.get());
}
~ClearReportingCacheTester() {
DCHECK_EQ(service_.get(), url_request_context_->reporting_service());
url_request_context_->set_reporting_service(old_service_);
}
const MockReportingService& mock() { return *service_; }
private:
net::URLRequestContext* url_request_context_;
std::unique_ptr<MockReportingService> service_;
net::ReportingService* old_service_;
};
class MockNetworkErrorLoggingService : public net::NetworkErrorLoggingService {
public:
MockNetworkErrorLoggingService() = default;
// net::NetworkErrorLoggingService implementation:
~MockNetworkErrorLoggingService() override = default;
void OnHeader(const url::Origin& origin,
const net::IPAddress& received_ip_address,
const std::string& value) override {
NOTREACHED();
}
void OnRequest(RequestDetails details) override { NOTREACHED(); }
void QueueSignedExchangeReport(SignedExchangeReportDetails details) override {
NOTREACHED();
}
void RemoveBrowsingData(const base::RepeatingCallback<bool(const GURL&)>&
origin_filter) override {
++remove_calls_;
last_origin_filter_ = origin_filter;
}
void RemoveAllBrowsingData() override {
++remove_all_calls_;
last_origin_filter_ = base::RepeatingCallback<bool(const GURL&)>();
}
int remove_calls() const { return remove_calls_; }
int remove_all_calls() const { return remove_all_calls_; }
const base::RepeatingCallback<bool(const GURL&)>& last_origin_filter() const {
return last_origin_filter_;
}
private:
int remove_calls_ = 0;
int remove_all_calls_ = 0;
base::RepeatingCallback<bool(const GURL&)> last_origin_filter_;
DISALLOW_COPY_AND_ASSIGN(MockNetworkErrorLoggingService);
};
class ClearNetworkErrorLoggingTester {
public:
ClearNetworkErrorLoggingTester(network::NetworkContext* network_context,
bool create_service)
: url_request_context_(network_context->url_request_context()) {
if (create_service)
service_ = std::make_unique<MockNetworkErrorLoggingService>();
url_request_context_->set_network_error_logging_service(service_.get());
}
~ClearNetworkErrorLoggingTester() {
DCHECK_EQ(service_.get(),
url_request_context_->network_error_logging_service());
url_request_context_->set_network_error_logging_service(nullptr);
}
const MockNetworkErrorLoggingService& mock() { return *service_; }
private:
net::URLRequestContext* url_request_context_;
std::unique_ptr<MockNetworkErrorLoggingService> service_;
DISALLOW_COPY_AND_ASSIGN(ClearNetworkErrorLoggingTester);
};
#endif // BUILDFLAG(ENABLE_REPORTING)
// Implementation of the TestingProfile that provides an SSLHostStateDelegate
// which is required for the tests.
class BrowsingDataRemoverTestingProfile : public TestingProfile {
public:
BrowsingDataRemoverTestingProfile() {}
~BrowsingDataRemoverTestingProfile() override {}
content::SSLHostStateDelegate* GetSSLHostStateDelegate() override {
return ChromeSSLHostStateDelegateFactory::GetForProfile(this);
}
private:
DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemoverTestingProfile);
};
// Test Class -----------------------------------------------------------------
class ChromeBrowsingDataRemoverDelegateTest : public testing::Test {
public:
ChromeBrowsingDataRemoverDelegateTest()
: profile_(new BrowsingDataRemoverTestingProfile()) {
remover_ = content::BrowserContext::GetBrowsingDataRemover(profile_.get());
// Make sure the Network Service is started before making a NetworkContext.
content::GetNetworkService();
task_environment_.RunUntilIdle();
auto network_context = std::make_unique<network::NetworkContext>(
network::NetworkService::GetNetworkServiceForTesting(),
network_context_remote_.BindNewPipeAndPassReceiver(),
network::mojom::NetworkContextParams::New());
network_context_ = network_context.get();
profile_->SetNetworkContext(std::move(network_context));
ProtocolHandlerRegistryFactory::GetInstance()->SetTestingFactory(
profile_.get(), base::BindRepeating(&BuildProtocolHandlerRegistry));
#if defined(OS_ANDROID)
static_cast<ChromeBrowsingDataRemoverDelegate*>(
profile_->GetBrowsingDataRemoverDelegate())
->OverrideWebappRegistryForTesting(
base::WrapUnique<WebappRegistry>(new TestWebappRegistry()));
SearchPermissionsService* service =
SearchPermissionsService::Factory::GetForBrowserContext(profile_.get());
std::unique_ptr<TestSearchEngineDelegate> delegate =
std::make_unique<TestSearchEngineDelegate>();
TestSearchEngineDelegate* delegate_ptr = delegate.get();
service->SetSearchEngineDelegateForTest(std::move(delegate));
delegate_ptr->UpdateDSEOrigin();
#endif
}
void TearDown() override {
// 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);
}
~ChromeBrowsingDataRemoverDelegateTest() override {}
void BlockUntilBrowsingDataRemoved(const base::Time& delete_begin,
const base::Time& delete_end,
int remove_mask,
bool include_protected_origins) {
int origin_type_mask =
content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB;
if (include_protected_origins) {
origin_type_mask |=
content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB;
}
content::BrowsingDataRemoverCompletionObserver completion_observer(
remover_);
remover_->RemoveAndReply(
delete_begin, delete_end, remove_mask, origin_type_mask,
&completion_observer);
base::ThreadPoolInstance::Get()->FlushForTesting();
completion_observer.BlockUntilCompletion();
}
void BlockUntilOriginDataRemoved(
const base::Time& delete_begin,
const base::Time& delete_end,
int remove_mask,
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
content::BrowsingDataRemoverCompletionObserver completion_observer(
remover_);
remover_->RemoveWithFilterAndReply(
delete_begin, delete_end, remove_mask,
content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
std::move(filter_builder), &completion_observer);
base::ThreadPoolInstance::Get()->FlushForTesting();
completion_observer.BlockUntilCompletion();
}
const base::Time& GetBeginTime() {
return remover_->GetLastUsedBeginTime();
}
int GetRemovalMask() {
return remover_->GetLastUsedRemovalMask();
}
int GetOriginTypeMask() {
return remover_->GetLastUsedOriginTypeMask();
}
network::NetworkContext* network_context() { return network_context_; }
TestingProfile* GetProfile() {
return profile_.get();
}
bool Match(const GURL& origin,
int mask,
storage::SpecialStoragePolicy* policy) {
return remover_->DoesOriginMatchMask(mask, url::Origin::Create(origin),
policy);
}
private:
// Cached pointer to BrowsingDataRemover for access to testing methods.
content::BrowsingDataRemover* remover_;
content::BrowserTaskEnvironment task_environment_;
mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
network::NetworkContext* network_context_;
std::unique_ptr<TestingProfile> profile_;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowsingDataRemoverDelegateTest);
};
// TODO(crbug.com/812589): Disabled due to flakiness in cookie store
// initialization.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_RemoveSafeBrowsingCookieForever) {
RemoveSafeBrowsingCookieTester tester;
tester.AddCookie();
ASSERT_TRUE(tester.ContainsCookie());
BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
EXPECT_EQ(content::BrowsingDataRemover::DATA_TYPE_COOKIES, GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
EXPECT_FALSE(tester.ContainsCookie());
}
// TODO(crbug.com/812589): Disabled due to flakiness in cookie store
// initialization.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_RemoveSafeBrowsingCookieLastHour) {
RemoveSafeBrowsingCookieTester tester;
tester.AddCookie();
ASSERT_TRUE(tester.ContainsCookie());
BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
EXPECT_EQ(content::BrowsingDataRemover::DATA_TYPE_COOKIES, GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
// Removing with time period other than all time should not clear safe
// browsing cookies.
EXPECT_TRUE(tester.ContainsCookie());
}
// TODO(crbug.com/812589): Disabled due to flakiness in cookie store
// initialization.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_RemoveSafeBrowsingCookieForeverWithPredicate) {
RemoveSafeBrowsingCookieTester tester;
tester.AddCookie();
ASSERT_TRUE(tester.ContainsCookie());
std::unique_ptr<BrowsingDataFilterBuilder> filter(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
filter->AddRegisterableDomain(kTestRegisterableDomain1);
BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
std::move(filter));
EXPECT_EQ(content::BrowsingDataRemover::DATA_TYPE_COOKIES, GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
EXPECT_TRUE(tester.ContainsCookie());
std::unique_ptr<BrowsingDataFilterBuilder> filter2(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
filter2->AddRegisterableDomain(kTestRegisterableDomain1);
BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
std::move(filter2));
EXPECT_FALSE(tester.ContainsCookie());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, 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(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
EXPECT_FALSE(tester.HistoryContainsURL(kOrigin1));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, 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(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
EXPECT_FALSE(tester.HistoryContainsURL(kOrigin1));
EXPECT_TRUE(tester.HistoryContainsURL(kOrigin2));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveHistoryForOlderThan30Days) {
RemoveHistoryTester tester;
ASSERT_TRUE(tester.Init(GetProfile()));
base::Time older_than_29days =
base::Time::Now() - base::TimeDelta::FromDays(29);
base::Time older_than_30days =
base::Time::Now() - base::TimeDelta::FromDays(30);
base::Time older_than_31days =
base::Time::Now() - base::TimeDelta::FromDays(31);
tester.AddHistory(kOrigin1, base::Time::Now());
tester.AddHistory(kOrigin2, older_than_29days);
tester.AddHistory(kOrigin3, older_than_31days);
ASSERT_TRUE(tester.HistoryContainsURL(kOrigin1));
ASSERT_TRUE(tester.HistoryContainsURL(kOrigin2));
ASSERT_TRUE(tester.HistoryContainsURL(kOrigin3));
BlockUntilBrowsingDataRemoved(
base::Time(), older_than_30days,
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
EXPECT_TRUE(tester.HistoryContainsURL(kOrigin1));
EXPECT_TRUE(tester.HistoryContainsURL(kOrigin2));
EXPECT_FALSE(tester.HistoryContainsURL(kOrigin3));
}
// This should crash (DCHECK) in Debug, but death tests don't work properly
// here.
// TODO(msramek): To make this testable, the refusal to delete history should
// be made a part of interface (e.g. a success value) as opposed to a DCHECK.
#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
TEST_F(ChromeBrowsingDataRemoverDelegateTest, 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(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
// Nothing should have been deleted.
EXPECT_TRUE(tester.HistoryContainsURL(kOrigin1));
EXPECT_TRUE(tester.HistoryContainsURL(kOrigin2));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
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));
// Expect that passwords will be deleted, as they do not depend
// on |prefs::kAllowDeletingBrowserHistory|.
RemovePasswordsTester tester(GetProfile());
EXPECT_CALL(*tester.store(), RemoveLoginsByURLAndTimeImpl(_, _, _));
int removal_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY |
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS;
BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(),
removal_mask, false);
EXPECT_EQ(removal_mask, GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
// Verify that history was not deleted.
EXPECT_TRUE(history_tester.HistoryContainsURL(kOrigin1));
}
#endif
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveExternalProtocolData) {
TestingProfile* profile = GetProfile();
// Add external protocol data on profile.
base::DictionaryValue prefs;
prefs.SetBoolean("tel", true);
profile->GetPrefs()->Set(prefs::kExcludedSchemes, prefs);
EXPECT_FALSE(
profile->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty());
BlockUntilBrowsingDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_EXTERNAL_PROTOCOL_DATA,
false);
EXPECT_TRUE(
profile->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty());
}
// Check that clearing browsing data (either history or cookies with other site
// data) clears any saved isolated origins.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemovePersistentIsolatedOrigins) {
PrefService* prefs = GetProfile()->GetPrefs();
// Add foo.com to the list of stored isolated origins.
base::ListValue list;
list.AppendString("http://foo.com");
prefs->Set(prefs::kUserTriggeredIsolatedOrigins, list);
EXPECT_FALSE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
// Clear history and ensure the stored isolated origins are cleared.
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_TRUE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
// Re-add foo.com to stored isolated origins.
prefs->Set(prefs::kUserTriggeredIsolatedOrigins, list);
EXPECT_FALSE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
// Now clear cookies and other site data, and ensure foo.com is cleared.
// Note that this uses a short time period to document that time ranges are
// currently ignored by stored isolated origins.
BlockUntilBrowsingDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA, false);
EXPECT_TRUE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
// Re-add foo.com.
prefs->Set(prefs::kUserTriggeredIsolatedOrigins, list);
EXPECT_FALSE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
// Clear the isolated origins data type.
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_ISOLATED_ORIGINS, false);
EXPECT_TRUE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
// Re-add foo.com.
prefs->Set(prefs::kUserTriggeredIsolatedOrigins, list);
EXPECT_FALSE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
// Clear both history and site data, and ensure the stored isolated origins
// are cleared.
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY |
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA,
false);
EXPECT_TRUE(prefs->GetList(prefs::kUserTriggeredIsolatedOrigins)->empty());
}
// Test that clearing history deletes favicons not associated with bookmarks.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, 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(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_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(ChromeBrowsingDataRemoverDelegateTest, 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(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY,
GetRemovalMask());
EXPECT_TRUE(favicon_tester.HasExpiredFaviconForPageURL(bookmarked_page));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, DeleteBookmarks) {
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);
EXPECT_EQ(1u, bookmark_model->bookmark_bar_node()->children().size());
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_BOOKMARKS, false);
EXPECT_EQ(0u, bookmark_model->bookmark_bar_node()->children().size());
}
// TODO(crbug.com/589586): Disabled, since history is not yet marked as
// a filterable datatype.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_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));
std::unique_ptr<BrowsingDataFilterBuilder> builder(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
BlockUntilOriginDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, std::move(builder));
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
EXPECT_FALSE(tester.HistoryContainsURL(kOrigin1));
EXPECT_TRUE(tester.HistoryContainsURL(kOrigin2));
}
// Verify that clearing autofill form data works.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, AutofillRemovalLastHour) {
GetProfile()->CreateWebDataService();
RemoveAutofillTester tester(GetProfile());
ASSERT_FALSE(tester.HasProfile());
tester.AddProfilesAndCards();
ASSERT_TRUE(tester.HasProfile());
BlockUntilBrowsingDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
ASSERT_FALSE(tester.HasProfile());
}
// Verify the clearing of autofill profiles added / modified more than 30 days
// ago.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, AutofillRemovalOlderThan30Days) {
GetProfile()->CreateWebDataService();
RemoveAutofillTester tester(GetProfile());
const base::Time kNow = base::Time::Now();
const base::Time k30DaysOld = kNow - base::TimeDelta::FromDays(30);
const base::Time k31DaysOld = kNow - base::TimeDelta::FromDays(31);
const base::Time k32DaysOld = kNow - base::TimeDelta::FromDays(32);
// Add profiles and cards with modification date as 31 days old from now.
autofill::TestAutofillClock test_clock;
test_clock.SetNow(k31DaysOld);
ASSERT_FALSE(tester.HasProfile());
tester.AddProfilesAndCards();
ASSERT_TRUE(tester.HasProfile());
BlockUntilBrowsingDataRemoved(
base::Time(), k32DaysOld,
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA, false);
ASSERT_TRUE(tester.HasProfile());
BlockUntilBrowsingDataRemoved(
k30DaysOld, base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA, false);
ASSERT_TRUE(tester.HasProfile());
BlockUntilBrowsingDataRemoved(
base::Time(), k30DaysOld,
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
ASSERT_FALSE(tester.HasProfile());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, AutofillRemovalEverything) {
GetProfile()->CreateWebDataService();
RemoveAutofillTester tester(GetProfile());
ASSERT_FALSE(tester.HasProfile());
tester.AddProfilesAndCards();
ASSERT_TRUE(tester.HasProfile());
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
ASSERT_FALSE(tester.HasProfile());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
StrikeDatabaseEmptyOnAutofillRemoveEverything) {
GetProfile()->CreateWebDataService();
RemoveAutofillTester tester(GetProfile());
ASSERT_FALSE(tester.HasProfile());
tester.AddProfilesAndCards();
ASSERT_TRUE(tester.HasProfile());
autofill::StrikeDatabaseTester strike_database_tester(GetProfile());
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA, false);
// StrikeDatabase should be empty when DATA_TYPE_FORM_DATA browsing data
// gets deleted.
ASSERT_TRUE(strike_database_tester.IsEmpty());
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
ASSERT_FALSE(tester.HasProfile());
}
// Verify that clearing autofill form data works.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
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(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
EXPECT_TRUE(tester.HasOrigin(std::string()));
EXPECT_FALSE(tester.HasOrigin(kWebOrigin));
EXPECT_TRUE(tester.HasOrigin(autofill::kSettingsOrigin));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, ZeroSuggestCacheClear) {
PrefService* prefs = GetProfile()->GetPrefs();
prefs->SetString(omnibox::kZeroSuggestCachedResults,
"[\"\", [\"foo\", \"bar\"]]");
BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
// Expect the prefs to be cleared when cookies are removed.
EXPECT_TRUE(prefs->GetString(omnibox::kZeroSuggestCachedResults).empty());
EXPECT_EQ(content::BrowsingDataRemover::DATA_TYPE_COOKIES, GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
}
#if defined(OS_CHROMEOS)
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
ContentProtectionPlatformKeysRemoval) {
chromeos::MockUserManager* mock_user_manager =
new testing::NiceMock<chromeos::MockUserManager>();
mock_user_manager->SetActiveUser(
AccountId::FromUserEmail("test@example.com"));
user_manager::ScopedUserManager user_manager_enabler(
base::WrapUnique(mock_user_manager));
// Creates a derived fake global instance destroyed in
// CryptohomeClient::Shutdown().
auto* cryptohome_client = new FakeCryptohomeClient();
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES, false);
// Expect exactly one call. No calls means no attempt to delete keys and more
// than one call means a significant performance problem.
EXPECT_EQ(1, cryptohome_client->delete_keys_call_count());
chromeos::CryptohomeClient::Shutdown();
}
#endif
TEST_F(ChromeBrowsingDataRemoverDelegateTest, DomainReliability_Null) {
ClearDomainReliabilityTester tester(GetProfile());
EXPECT_EQ(0u, tester.clear_count());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, DomainReliability_Beacons) {
ClearDomainReliabilityTester tester(GetProfile());
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(1u, tester.clear_count());
EXPECT_EQ(
network::mojom::NetworkContext::DomainReliabilityClearMode::CLEAR_BEACONS,
tester.last_clear_mode());
EXPECT_TRUE(tester.last_filter().is_null());
}
// TODO(crbug.com/589586): Disabled, since history is not yet marked as
// a filterable datatype.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_DomainReliability_Beacons_WithFilter) {
ClearDomainReliabilityTester tester(GetProfile());
std::unique_ptr<BrowsingDataFilterBuilder> builder(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
builder->AddRegisterableDomain(kTestRegisterableDomain1);
BlockUntilOriginDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, builder->Copy());
EXPECT_EQ(1u, tester.clear_count());
EXPECT_EQ(
network::mojom::NetworkContext::DomainReliabilityClearMode::CLEAR_BEACONS,
tester.last_clear_mode());
EXPECT_TRUE(ProbablySameFilters(
builder->BuildGeneralFilter(), tester.last_filter()));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, DomainReliability_Contexts) {
ClearDomainReliabilityTester tester(GetProfile());
BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
EXPECT_EQ(1u, tester.clear_count());
EXPECT_EQ(network::mojom::NetworkContext::DomainReliabilityClearMode::
CLEAR_CONTEXTS,
tester.last_clear_mode());
EXPECT_TRUE(tester.last_filter().is_null());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DomainReliability_Contexts_WithFilter) {
ClearDomainReliabilityTester tester(GetProfile());
std::unique_ptr<BrowsingDataFilterBuilder> builder(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
builder->AddRegisterableDomain(kTestRegisterableDomain1);
BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
builder->Copy());
EXPECT_EQ(1u, tester.clear_count());
EXPECT_EQ(network::mojom::NetworkContext::DomainReliabilityClearMode::
CLEAR_CONTEXTS,
tester.last_clear_mode());
EXPECT_TRUE(ProbablySameFilters(
builder->BuildGeneralFilter(), tester.last_filter()));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, DomainReliability_ContextsWin) {
ClearDomainReliabilityTester tester(GetProfile());
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY |
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
EXPECT_EQ(1u, tester.clear_count());
EXPECT_EQ(network::mojom::NetworkContext::DomainReliabilityClearMode::
CLEAR_CONTEXTS,
tester.last_clear_mode());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DomainReliability_ProtectedOrigins) {
ClearDomainReliabilityTester tester(GetProfile());
BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
true);
EXPECT_EQ(1u, tester.clear_count());
EXPECT_EQ(network::mojom::NetworkContext::DomainReliabilityClearMode::
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(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_DomainReliability_NoMonitor) {
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY |
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
}
// Tests that the deletion of downloads completes successfully and that
// ChromeDownloadManagerDelegate is correctly created and shut down.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveDownloads) {
RemoveDownloadsTester tester(GetProfile());
EXPECT_CALL(
*tester.download_manager(), RemoveDownloadsByURLAndTime(_, _, _));
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS, false);
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemovePasswordStatistics) {
RemovePasswordsTester tester(GetProfile());
base::RepeatingCallback<bool(const GURL&)> empty_filter;
EXPECT_CALL(*tester.store(), RemoveStatisticsByOriginAndTimeImpl(
ProbablySameFilter(empty_filter),
base::Time(), base::Time::Max()));
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
}
// TODO(crbug.com/589586): Disabled, since history is not yet marked as
// a filterable datatype.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_RemovePasswordStatisticsByOrigin) {
RemovePasswordsTester tester(GetProfile());
std::unique_ptr<BrowsingDataFilterBuilder> builder(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
builder->AddRegisterableDomain(kTestRegisterableDomain1);
base::RepeatingCallback<bool(const GURL&)> filter =
builder->BuildGeneralFilter();
EXPECT_CALL(*tester.store(),
RemoveStatisticsByOriginAndTimeImpl(
ProbablySameFilter(filter), base::Time(), base::Time::Max()));
BlockUntilOriginDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, std::move(builder));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemovePasswordsByTimeOnly) {
RemovePasswordsTester tester(GetProfile());
base::RepeatingCallback<bool(const GURL&)> filter =
BrowsingDataFilterBuilder::BuildNoopFilter();
EXPECT_CALL(*tester.store(),
RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _))
.WillOnce(Return(password_manager::PasswordStoreChangeList()));
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS, false);
}
// Disabled, since passwords are not yet marked as a filterable datatype.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_RemovePasswordsByOrigin) {
RemovePasswordsTester tester(GetProfile());
std::unique_ptr<BrowsingDataFilterBuilder> builder(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
builder->AddRegisterableDomain(kTestRegisterableDomain1);
base::RepeatingCallback<bool(const GURL&)> filter =
builder->BuildGeneralFilter();
EXPECT_CALL(*tester.store(),
RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _))
.WillOnce(Return(password_manager::PasswordStoreChangeList()));
BlockUntilOriginDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS,
std::move(builder));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, DisableAutoSignIn) {
RemovePasswordsTester tester(GetProfile());
base::RepeatingCallback<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(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DisableAutoSignInAfterRemovingPasswords) {
RemovePasswordsTester tester(GetProfile());
base::RepeatingCallback<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(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES |
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS,
false);
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
RemoveLeakedCredentialsByTimeOnly) {
RemovePasswordsTester tester(GetProfile());
base::Callback<bool(const GURL&)> empty_filter;
EXPECT_CALL(*tester.store(), RemoveLeakedCredentialsByUrlAndTimeImpl(
ProbablySameFilter(empty_filter),
base::Time(), base::Time::Max()));
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
}
// TODO(crbug.com/589586): Disabled, since history is not yet marked as
// a filterable datatype.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_RemoveLeakedCredentialsByUrlAndTime) {
RemovePasswordsTester tester(GetProfile());
auto builder =
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST);
builder->AddRegisterableDomain(kTestRegisterableDomain1);
base::RepeatingCallback<bool(const GURL&)> filter =
builder->BuildGeneralFilter();
EXPECT_CALL(*tester.store(),
RemoveLeakedCredentialsByUrlAndTimeImpl(
ProbablySameFilter(filter), base::Time(), base::Time::Max()));
BlockUntilOriginDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, std::move(builder));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
RemoveContentSettingsWithBlacklist) {
// Add our settings.
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(GetProfile());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin1, GURL(), ContentSettingsType::SITE_ENGAGEMENT, std::string(),
std::make_unique<base::DictionaryValue>());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin2, GURL(), ContentSettingsType::SITE_ENGAGEMENT, std::string(),
std::make_unique<base::DictionaryValue>());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin3, GURL(), ContentSettingsType::SITE_ENGAGEMENT, std::string(),
std::make_unique<base::DictionaryValue>());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin4, GURL(), ContentSettingsType::SITE_ENGAGEMENT, std::string(),
std::make_unique<base::DictionaryValue>());
// Clear all except for origin1 and origin3.
std::unique_ptr<BrowsingDataFilterBuilder> filter(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
filter->AddRegisterableDomain(kTestRegisterableDomain1);
filter->AddRegisterableDomain(kTestRegisterableDomain3);
BlockUntilOriginDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA,
std::move(filter));
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
// Verify we only have true, and they're origin1, origin3, and origin4.
ContentSettingsForOneType host_settings;
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::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(ChromeBrowsingDataRemoverDelegateTest, RemoveContentSettings) {
auto* map = HostContentSettingsMapFactory::GetForProfile(GetProfile());
map->SetContentSettingDefaultScope(kOrigin1, kOrigin1,
ContentSettingsType::GEOLOCATION,
std::string(), CONTENT_SETTING_ALLOW);
map->SetContentSettingDefaultScope(kDSEOrigin, kDSEOrigin,
ContentSettingsType::GEOLOCATION,
std::string(), CONTENT_SETTING_BLOCK);
map->SetContentSettingDefaultScope(kOrigin2, kOrigin2,
ContentSettingsType::NOTIFICATIONS,
std::string(), CONTENT_SETTING_ALLOW);
map->SetContentSettingDefaultScope(kOrigin3, GURL(),
ContentSettingsType::COOKIES,
std::string(), CONTENT_SETTING_BLOCK);
ContentSettingsPattern pattern =
ContentSettingsPattern::FromString("[*.]example.com");
map->SetContentSettingCustomScope(pattern, ContentSettingsPattern::Wildcard(),
ContentSettingsType::COOKIES, std::string(),
CONTENT_SETTING_BLOCK);
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
// Everything except the default settings should be deleted. On Android the
// default search engine setting should also not be deleted.
bool expect_geolocation_dse_origin = false;
bool expect_notifications_dse_origin = false;
#if defined(OS_ANDROID)
expect_geolocation_dse_origin = true;
expect_notifications_dse_origin = true;
#endif
ContentSettingsForOneType host_settings;
map->GetSettingsForOneType(ContentSettingsType::GEOLOCATION, std::string(),
&host_settings);
if (expect_geolocation_dse_origin) {
ASSERT_EQ(2u, host_settings.size());
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kDSEOrigin),
host_settings[0].primary_pattern)
<< host_settings[0].primary_pattern.ToString();
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kDSEOrigin),
host_settings[0].secondary_pattern)
<< host_settings[0].secondary_pattern.ToString();
EXPECT_EQ(CONTENT_SETTING_ALLOW, host_settings[0].GetContentSetting());
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
host_settings[1].primary_pattern)
<< host_settings[1].primary_pattern.ToString();
EXPECT_EQ(CONTENT_SETTING_ASK, host_settings[1].GetContentSetting());
} else {
ASSERT_EQ(1u, host_settings.size());
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
host_settings[0].primary_pattern)
<< host_settings[0].primary_pattern.ToString();
EXPECT_EQ(CONTENT_SETTING_ASK, host_settings[0].GetContentSetting());
}
map->GetSettingsForOneType(ContentSettingsType::NOTIFICATIONS, std::string(),
&host_settings);
if (expect_notifications_dse_origin) {
ASSERT_EQ(2u, host_settings.size());
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kDSEOrigin),
host_settings[0].primary_pattern)
<< host_settings[0].primary_pattern.ToString();
EXPECT_EQ(CONTENT_SETTING_ALLOW, host_settings[0].GetContentSetting());
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
host_settings[1].primary_pattern)
<< host_settings[1].primary_pattern.ToString();
EXPECT_EQ(CONTENT_SETTING_ASK, host_settings[1].GetContentSetting());
} else {
ASSERT_EQ(1u, host_settings.size());
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
host_settings[0].primary_pattern)
<< host_settings[0].primary_pattern.ToString();
EXPECT_EQ(CONTENT_SETTING_ASK, host_settings[0].GetContentSetting());
}
map->GetSettingsForOneType(ContentSettingsType::COOKIES, std::string(),
&host_settings);
ASSERT_EQ(1u, host_settings.size());
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
host_settings[0].primary_pattern)
<< host_settings[0].primary_pattern.ToString();
EXPECT_EQ(CONTENT_SETTING_ALLOW, host_settings[0].GetContentSetting());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveProtocolHandler) {
auto* registry =
ProtocolHandlerRegistryFactory::GetForBrowserContext(GetProfile());
base::Time one_hour_ago = base::Time::Now() - base::TimeDelta::FromHours(1);
base::Time yesterday = base::Time::Now() - base::TimeDelta::FromDays(1);
registry->OnAcceptRegisterProtocolHandler(
ProtocolHandler::CreateProtocolHandler("news", kOrigin1));
registry->OnAcceptRegisterProtocolHandler(
ProtocolHandler("mailto", kOrigin1, yesterday));
EXPECT_TRUE(registry->IsHandledProtocol("news"));
EXPECT_TRUE(registry->IsHandledProtocol("mailto"));
EXPECT_EQ(
2U,
registry->GetUserDefinedHandlers(base::Time(), base::Time::Max()).size());
// Delete last hour.
BlockUntilBrowsingDataRemoved(
one_hour_ago, base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
EXPECT_FALSE(registry->IsHandledProtocol("news"));
EXPECT_TRUE(registry->IsHandledProtocol("mailto"));
EXPECT_EQ(
1U,
registry->GetUserDefinedHandlers(base::Time(), base::Time::Max()).size());
// Delete everything.
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
EXPECT_FALSE(registry->IsHandledProtocol("news"));
EXPECT_FALSE(registry->IsHandledProtocol("mailto"));
EXPECT_EQ(
0U,
registry->GetUserDefinedHandlers(base::Time(), base::Time::Max()).size());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveSelectedClientHints) {
// Add our settings.
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(GetProfile());
std::unique_ptr<base::ListValue> expiration_times_list =
std::make_unique<base::ListValue>();
expiration_times_list->AppendInteger(0);
expiration_times_list->AppendInteger(2);
double expiration_time =
(base::Time::Now() + base::TimeDelta::FromHours(24)).ToDoubleT();
auto expiration_times_dictionary = std::make_unique<base::DictionaryValue>();
expiration_times_dictionary->SetList("client_hints",
std::move(expiration_times_list));
expiration_times_dictionary->SetDouble("expiration_time", expiration_time);
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin1, GURL(), ContentSettingsType::CLIENT_HINTS, std::string(),
expiration_times_dictionary->CreateDeepCopy());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin2, GURL(), ContentSettingsType::CLIENT_HINTS, std::string(),
expiration_times_dictionary->CreateDeepCopy());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin3, GURL(), ContentSettingsType::CLIENT_HINTS, std::string(),
expiration_times_dictionary->CreateDeepCopy());
// Clear all except for origin1 and origin3.
std::unique_ptr<BrowsingDataFilterBuilder> filter(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
filter->AddRegisterableDomain(kTestRegisterableDomain1);
filter->AddRegisterableDomain(kTestRegisterableDomain3);
BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
std::move(filter));
ContentSettingsForOneType host_settings;
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::CLIENT_HINTS, std::string(), &host_settings);
ASSERT_EQ(2u, host_settings.size());
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin1),
host_settings[0].primary_pattern)
<< host_settings[0].primary_pattern.ToString();
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(kOrigin3),
host_settings[1].primary_pattern)
<< host_settings[1].primary_pattern.ToString();
for (size_t i = 0; i < host_settings.size(); ++i) {
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
host_settings.at(i).secondary_pattern);
EXPECT_EQ(*expiration_times_dictionary, host_settings.at(i).setting_value);
}
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveAllClientHints) {
// Add our settings.
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(GetProfile());
std::unique_ptr<base::ListValue> expiration_times_list =
std::make_unique<base::ListValue>();
expiration_times_list->AppendInteger(0);
expiration_times_list->AppendInteger(2);
double expiration_time =
(base::Time::Now() + base::TimeDelta::FromHours(24)).ToDoubleT();
auto expiration_times_dictionary = std::make_unique<base::DictionaryValue>();
expiration_times_dictionary->SetList("client_hints",
std::move(expiration_times_list));
expiration_times_dictionary->SetDouble("expiration_time", expiration_time);
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin1, GURL(), ContentSettingsType::CLIENT_HINTS, std::string(),
expiration_times_dictionary->CreateDeepCopy());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin2, GURL(), ContentSettingsType::CLIENT_HINTS, std::string(),
expiration_times_dictionary->CreateDeepCopy());
host_content_settings_map->SetWebsiteSettingDefaultScope(
kOrigin3, GURL(), ContentSettingsType::CLIENT_HINTS, std::string(),
expiration_times_dictionary->CreateDeepCopy());
// Clear all.
BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
false);
ContentSettingsForOneType host_settings;
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::CLIENT_HINTS, std::string(), &host_settings);
ASSERT_EQ(0u, host_settings.size());
}
#if !defined(OS_ANDROID)
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveZoomLevel) {
content::HostZoomMap* zoom_map =
content::HostZoomMap::GetDefaultForBrowserContext(GetProfile());
EXPECT_EQ(0u, zoom_map->GetAllZoomLevels().size());
base::SimpleTestClock test_clock;
zoom_map->SetClockForTesting(&test_clock);
base::Time now = base::Time::Now();
zoom_map->InitializeZoomLevelForHost(kTestRegisterableDomain1, 1.5,
now - base::TimeDelta::FromHours(5));
test_clock.SetNow(now - base::TimeDelta::FromHours(2));
zoom_map->SetZoomLevelForHost(kTestRegisterableDomain3, 2.0);
EXPECT_EQ(2u, zoom_map->GetAllZoomLevels().size());
// Remove everything created during the last hour.
BlockUntilBrowsingDataRemoved(
now - base::TimeDelta::FromHours(1), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
// Nothing should be deleted as the zoomlevels were created earlier.
EXPECT_EQ(2u, zoom_map->GetAllZoomLevels().size());
test_clock.SetNow(now);
zoom_map->SetZoomLevelForHost(kTestRegisterableDomain3, 2.0);
// Remove everything changed during the last hour (domain3).
BlockUntilBrowsingDataRemoved(
now - base::TimeDelta::FromHours(1), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
// Verify we still have the zoom_level for domain1.
auto levels = zoom_map->GetAllZoomLevels();
EXPECT_EQ(1u, levels.size());
EXPECT_EQ(kTestRegisterableDomain1, levels[0].host);
zoom_map->SetZoomLevelForHostAndScheme("chrome", "print", 4.0);
// Remove everything.
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
// Host and scheme zoomlevels should not be affected.
levels = zoom_map->GetAllZoomLevels();
EXPECT_EQ(1u, levels.size());
EXPECT_EQ("chrome", levels[0].scheme);
EXPECT_EQ("print", levels[0].host);
}
#endif
TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveTranslateBlacklist) {
auto translate_prefs =
ChromeTranslateClient::CreateTranslatePrefs(GetProfile()->GetPrefs());
translate_prefs->BlacklistSite("google.com");
base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
base::Time t = base::Time::Now();
translate_prefs->BlacklistSite("maps.google.com");
EXPECT_TRUE(translate_prefs->IsSiteBlacklisted("google.com"));
EXPECT_TRUE(translate_prefs->IsSiteBlacklisted("maps.google.com"));
BlockUntilBrowsingDataRemoved(
t, base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
EXPECT_TRUE(translate_prefs->IsSiteBlacklisted("google.com"));
EXPECT_FALSE(translate_prefs->IsSiteBlacklisted("maps.google.com"));
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
EXPECT_FALSE(translate_prefs->IsSiteBlacklisted("google.com"));
EXPECT_FALSE(translate_prefs->IsSiteBlacklisted("maps.google.com"));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, 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.
std::unique_ptr<BrowsingDataFilterBuilder> filter(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
filter->AddRegisterableDomain(kTestRegisterableDomain1);
filter->AddRegisterableDomain(kTestRegisterableDomain3);
BlockUntilOriginDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_DURABLE_PERMISSION,
std::move(filter));
EXPECT_EQ(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_DURABLE_PERMISSION,
GetRemovalMask());
EXPECT_EQ(content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
GetOriginTypeMask());
// Verify we only have allow for the first origin.
ContentSettingsForOneType host_settings;
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::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].GetContentSetting());
// 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].GetContentSetting());
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DurablePermissionIsPartOfEmbedderDOMStorage) {
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(GetProfile());
DurableStoragePermissionContext durable_permission(GetProfile());
durable_permission.UpdateContentSetting(kOrigin1, GURL(),
CONTENT_SETTING_ALLOW);
ContentSettingsForOneType host_settings;
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::DURABLE_STORAGE, std::string(), &host_settings);
EXPECT_EQ(2u, host_settings.size());
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE, false);
// After the deletion, only the wildcard should remain.
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::DURABLE_STORAGE, std::string(), &host_settings);
EXPECT_EQ(1u, host_settings.size());
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
host_settings[0].primary_pattern)
<< host_settings[0].primary_pattern.ToString();
}
// Test that removing passwords clears HTTP auth data.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
ClearHttpAuthCache_RemovePasswords) {
net::HttpNetworkSession* http_session = network_context()
->url_request_context()
->http_transaction_factory()
->GetSession();
DCHECK(http_session);
net::HttpAuthCache* http_auth_cache = http_session->http_auth_cache();
http_auth_cache->Add(kOrigin1, net::HttpAuth::AUTH_SERVER, kTestRealm,
net::HttpAuth::AUTH_SCHEME_BASIC,
net::NetworkIsolationKey(), "test challenge",
net::AuthCredentials(base::ASCIIToUTF16("foo"),
base::ASCIIToUTF16("bar")),
"/");
CHECK(http_auth_cache->Lookup(kOrigin1, net::HttpAuth::AUTH_SERVER,
kTestRealm, net::HttpAuth::AUTH_SCHEME_BASIC,
net::NetworkIsolationKey()));
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS, false);
EXPECT_EQ(nullptr,
http_auth_cache->Lookup(
kOrigin1, net::HttpAuth::AUTH_SERVER, kTestRealm,
net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey()));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, ClearPermissionPromptCounts) {
RemovePermissionPromptCountsTest tester(GetProfile());
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_1(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
filter_builder_1->AddRegisterableDomain(kTestRegisterableDomain1);
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_2(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST));
filter_builder_2->AddRegisterableDomain(kTestRegisterableDomain1);
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({features::kBlockPromptsIfDismissedOften}, {});
{
// Test REMOVE_HISTORY.
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin1, ContentSettingsType::NOTIFICATIONS));
EXPECT_FALSE(tester.RecordDismissAndEmbargo(
kOrigin1, ContentSettingsType::MIDI_SYSEX));
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin2, ContentSettingsType::DURABLE_STORAGE));
tester.CheckEmbargo(kOrigin2, ContentSettingsType::NOTIFICATIONS,
CONTENT_SETTING_ASK);
EXPECT_FALSE(tester.RecordDismissAndEmbargo(
kOrigin2, ContentSettingsType::NOTIFICATIONS));
EXPECT_FALSE(tester.RecordDismissAndEmbargo(
kOrigin2, ContentSettingsType::NOTIFICATIONS));
EXPECT_TRUE(tester.RecordDismissAndEmbargo(
kOrigin2, ContentSettingsType::NOTIFICATIONS));
tester.CheckEmbargo(kOrigin2, ContentSettingsType::NOTIFICATIONS,
CONTENT_SETTING_BLOCK);
BlockUntilOriginDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA,
std::move(filter_builder_1));
// kOrigin1 should be gone, but kOrigin2 remains.
EXPECT_EQ(
0, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_EQ(
0, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::NOTIFICATIONS));
EXPECT_EQ(
0, tester.GetDismissCount(kOrigin1, ContentSettingsType::MIDI_SYSEX));
EXPECT_EQ(1, tester.GetIgnoreCount(kOrigin2,
ContentSettingsType::DURABLE_STORAGE));
EXPECT_EQ(3, tester.GetDismissCount(kOrigin2,
ContentSettingsType::NOTIFICATIONS));
tester.CheckEmbargo(kOrigin2, ContentSettingsType::NOTIFICATIONS,
CONTENT_SETTING_BLOCK);
BlockUntilBrowsingDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
// Everything should be gone.
EXPECT_EQ(
0, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_EQ(
0, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::NOTIFICATIONS));
EXPECT_EQ(
0, tester.GetDismissCount(kOrigin1, ContentSettingsType::MIDI_SYSEX));
EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin2,
ContentSettingsType::DURABLE_STORAGE));
EXPECT_EQ(0, tester.GetDismissCount(kOrigin2,
ContentSettingsType::NOTIFICATIONS));
tester.CheckEmbargo(kOrigin2, ContentSettingsType::NOTIFICATIONS,
CONTENT_SETTING_ASK);
}
{
// Test REMOVE_SITE_DATA.
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin1, ContentSettingsType::NOTIFICATIONS));
EXPECT_FALSE(tester.RecordDismissAndEmbargo(
kOrigin1, ContentSettingsType::MIDI_SYSEX));
tester.CheckEmbargo(kOrigin1, ContentSettingsType::MIDI_SYSEX,
CONTENT_SETTING_ASK);
EXPECT_FALSE(tester.RecordIgnoreAndEmbargo(
kOrigin2, ContentSettingsType::DURABLE_STORAGE));
EXPECT_FALSE(tester.RecordDismissAndEmbargo(
kOrigin2, ContentSettingsType::NOTIFICATIONS));
BlockUntilOriginDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA,
std::move(filter_builder_2));
// kOrigin2 should be gone, but kOrigin1 remains.
EXPECT_EQ(
2, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_EQ(
1, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::NOTIFICATIONS));
EXPECT_EQ(
1, tester.GetDismissCount(kOrigin1, ContentSettingsType::MIDI_SYSEX));
EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin2,
ContentSettingsType::DURABLE_STORAGE));
EXPECT_EQ(0, tester.GetDismissCount(kOrigin2,
ContentSettingsType::NOTIFICATIONS));
EXPECT_FALSE(tester.RecordDismissAndEmbargo(
kOrigin1, ContentSettingsType::MIDI_SYSEX));
EXPECT_TRUE(tester.RecordDismissAndEmbargo(
kOrigin1, ContentSettingsType::MIDI_SYSEX));
EXPECT_EQ(
3, tester.GetDismissCount(kOrigin1, ContentSettingsType::MIDI_SYSEX));
tester.CheckEmbargo(kOrigin1, ContentSettingsType::MIDI_SYSEX,
CONTENT_SETTING_BLOCK);
BlockUntilBrowsingDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA, false);
// Everything should be gone.
EXPECT_EQ(
0, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::GEOLOCATION));
EXPECT_EQ(
0, tester.GetIgnoreCount(kOrigin1, ContentSettingsType::NOTIFICATIONS));
EXPECT_EQ(
0, tester.GetDismissCount(kOrigin1, ContentSettingsType::MIDI_SYSEX));
EXPECT_EQ(0, tester.GetIgnoreCount(kOrigin2,
ContentSettingsType::DURABLE_STORAGE));
EXPECT_EQ(0, tester.GetDismissCount(kOrigin2,
ContentSettingsType::NOTIFICATIONS));
tester.CheckEmbargo(kOrigin1, ContentSettingsType::MIDI_SYSEX,
CONTENT_SETTING_ASK);
}
}
#if BUILDFLAG(ENABLE_PLUGINS)
// Check the |ContentSettingsType::PLUGINS_DATA| content setting is cleared
// with browsing data.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, ClearFlashPreviouslyChanged) {
ChromePluginServiceFilter::GetInstance()->RegisterProfile(GetProfile());
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(GetProfile());
// PLUGINS_DATA gets cleared with history OR site usage data.
for (ChromeBrowsingDataRemoverDelegate::DataType data_type :
{ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA,
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY}) {
FlashContentSettingsChangeWaiter waiter(GetProfile());
host_content_settings_map->SetContentSettingDefaultScope(
kOrigin1, kOrigin1, ContentSettingsType::PLUGINS, std::string(),
CONTENT_SETTING_ALLOW);
host_content_settings_map->SetContentSettingDefaultScope(
kOrigin2, kOrigin2, ContentSettingsType::PLUGINS, std::string(),
CONTENT_SETTING_BLOCK);
waiter.Wait();
// Check that as a result, the PLUGINS_DATA prefs were populated.
EXPECT_NE(nullptr,
host_content_settings_map->GetWebsiteSetting(
kOrigin1, kOrigin1, ContentSettingsType::PLUGINS_DATA,
std::string(), nullptr));
EXPECT_NE(nullptr,
host_content_settings_map->GetWebsiteSetting(
kOrigin2, kOrigin2, ContentSettingsType::PLUGINS_DATA,
std::string(), nullptr));
std::unique_ptr<BrowsingDataFilterBuilder> filter(
BrowsingDataFilterBuilder::Create(
BrowsingDataFilterBuilder::BLACKLIST));
BlockUntilOriginDataRemoved(AnHourAgo(), base::Time::Max(), data_type,
std::move(filter));
EXPECT_EQ(nullptr,
host_content_settings_map->GetWebsiteSetting(
kOrigin1, kOrigin1, ContentSettingsType::PLUGINS_DATA,
std::string(), nullptr));
EXPECT_EQ(nullptr,
host_content_settings_map->GetWebsiteSetting(
kOrigin2, kOrigin2, ContentSettingsType::PLUGINS_DATA,
std::string(), nullptr));
}
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, 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|.
std::unique_ptr<BrowsingDataFilterBuilder> filter_builder(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
filter_builder->AddRegisterableDomain(kTestRegisterableDomain3);
BlockUntilOriginDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PLUGIN_DATA,
std::move(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
// Test that the remover clears language model data (normally added by the
// LanguageDetectionDriver).
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
LanguageHistogramClearedOnClearingCompleteHistory) {
language::UrlLanguageHistogram* language_histogram =
UrlLanguageHistogramFactory::GetForBrowserContext(GetProfile());
// Simulate browsing.
for (int i = 0; i < 100; i++) {
language_histogram->OnPageVisited("en");
language_histogram->OnPageVisited("en");
language_histogram->OnPageVisited("en");
language_histogram->OnPageVisited("es");
}
// Clearing a part of the history has no effect.
BlockUntilBrowsingDataRemoved(
AnHourAgo(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_THAT(language_histogram->GetTopLanguages(), SizeIs(2));
EXPECT_THAT(language_histogram->GetLanguageFrequency("en"), FloatEq(0.75));
EXPECT_THAT(language_histogram->GetLanguageFrequency("es"), FloatEq(0.25));
// Clearing the full history does the trick.
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_THAT(language_histogram->GetTopLanguages(), SizeIs(0));
EXPECT_THAT(language_histogram->GetLanguageFrequency("en"), FloatEq(0.0));
EXPECT_THAT(language_histogram->GetLanguageFrequency("es"), FloatEq(0.0));
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
TEST_F(ChromeBrowsingDataRemoverDelegateTest, OriginTypeMasks) {
scoped_refptr<MockExtensionSpecialStoragePolicy> mock_policy =
new MockExtensionSpecialStoragePolicy;
// Protect kOrigin1.
mock_policy->AddProtected(kOrigin1.GetOrigin());
EXPECT_FALSE(Match(kOrigin1, kUnprotected, mock_policy.get()));
EXPECT_TRUE(Match(kOrigin2, kUnprotected, mock_policy.get()));
EXPECT_FALSE(Match(kOriginExt, kUnprotected, mock_policy.get()));
EXPECT_FALSE(Match(kOriginDevTools, kUnprotected, mock_policy.get()));
EXPECT_TRUE(Match(kOrigin1, kProtected, mock_policy.get()));
EXPECT_FALSE(Match(kOrigin2, kProtected, mock_policy.get()));
EXPECT_FALSE(Match(kOriginExt, kProtected, mock_policy.get()));
EXPECT_FALSE(Match(kOriginDevTools, kProtected, mock_policy.get()));
EXPECT_FALSE(Match(kOrigin1, kExtension, mock_policy.get()));
EXPECT_FALSE(Match(kOrigin2, kExtension, mock_policy.get()));
EXPECT_TRUE(Match(kOriginExt, kExtension, mock_policy.get()));
EXPECT_FALSE(Match(kOriginDevTools, kExtension, mock_policy.get()));
EXPECT_TRUE(Match(kOrigin1, kUnprotected | kProtected, mock_policy.get()));
EXPECT_TRUE(Match(kOrigin2, kUnprotected | kProtected, mock_policy.get()));
EXPECT_FALSE(Match(kOriginExt, kUnprotected | kProtected, mock_policy.get()));
EXPECT_FALSE(
Match(kOriginDevTools, kUnprotected | kProtected, mock_policy.get()));
EXPECT_FALSE(Match(kOrigin1, kUnprotected | kExtension, mock_policy.get()));
EXPECT_TRUE(Match(kOrigin2, kUnprotected | kExtension, mock_policy.get()));
EXPECT_TRUE(Match(kOriginExt, kUnprotected | kExtension, mock_policy.get()));
EXPECT_FALSE(
Match(kOriginDevTools, kUnprotected | kExtension, mock_policy.get()));
EXPECT_TRUE(Match(kOrigin1, kProtected | kExtension, mock_policy.get()));
EXPECT_FALSE(Match(kOrigin2, kProtected | kExtension, mock_policy.get()));
EXPECT_TRUE(Match(kOriginExt, kProtected | kExtension, mock_policy.get()));
EXPECT_FALSE(
Match(kOriginDevTools, kProtected | kExtension, mock_policy.get()));
EXPECT_TRUE(Match(kOrigin1, kUnprotected | kProtected | kExtension,
mock_policy.get()));
EXPECT_TRUE(Match(kOrigin2, kUnprotected | kProtected | kExtension,
mock_policy.get()));
EXPECT_TRUE(Match(kOriginExt, kUnprotected | kProtected | kExtension,
mock_policy.get()));
EXPECT_FALSE(Match(kOriginDevTools, kUnprotected | kProtected | kExtension,
mock_policy.get()));
}
#endif
// If extensions are disabled, there is no policy.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, OriginTypeMasksNoPolicy) {
EXPECT_TRUE(Match(kOrigin1, kUnprotected, nullptr));
EXPECT_FALSE(Match(kOriginExt, kUnprotected, nullptr));
EXPECT_FALSE(Match(kOriginDevTools, kUnprotected, nullptr));
EXPECT_FALSE(Match(kOrigin1, kProtected, nullptr));
EXPECT_FALSE(Match(kOriginExt, kProtected, nullptr));
EXPECT_FALSE(Match(kOriginDevTools, kProtected, nullptr));
#if BUILDFLAG(ENABLE_EXTENSIONS)
EXPECT_FALSE(Match(kOrigin1, kExtension, nullptr));
EXPECT_TRUE(Match(kOriginExt, kExtension, nullptr));
EXPECT_FALSE(Match(kOriginDevTools, kExtension, nullptr));
#endif
}
#if BUILDFLAG(ENABLE_REPORTING)
TEST_F(ChromeBrowsingDataRemoverDelegateTest, ReportingCache_NoService) {
ClearReportingCacheTester tester(network_context(), false);
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, true);
// Nothing to check, since there's no mock service; we're just making sure
// nothing crashes without a service.
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, ReportingCache) {
ClearReportingCacheTester tester(network_context(), true);
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, true);
EXPECT_EQ(0, tester.mock().remove_calls());
EXPECT_EQ(1, tester.mock().remove_all_calls());
EXPECT_EQ(net::ReportingBrowsingDataRemover::DATA_TYPE_REPORTS,
tester.mock().last_data_type_mask());
EXPECT_TRUE(ProbablySameFilters(base::RepeatingCallback<bool(const GURL&)>(),
tester.mock().last_origin_filter()));
}
// TODO(crbug.com/589586): Disabled, since history is not yet marked as
// a filterable datatype.
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
DISABLED_ReportingCache_WithFilter) {
ClearReportingCacheTester tester(network_context(), true);
std::unique_ptr<BrowsingDataFilterBuilder> builder(
BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST));
builder->AddRegisterableDomain(kTestRegisterableDomain1);
BlockUntilOriginDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, builder->Copy());
EXPECT_EQ(1, tester.mock().remove_calls());
EXPECT_EQ(0, tester.mock().remove_all_calls());
EXPECT_EQ(net::ReportingBrowsingDataRemover::DATA_TYPE_REPORTS,
tester.mock().last_data_type_mask());
EXPECT_TRUE(ProbablySameFilters(builder->BuildGeneralFilter(),
tester.mock().last_origin_filter()));
}
TEST_F(ChromeBrowsingDataRemoverDelegateTest, NetworkErrorLogging_NoDelegate) {
ClearNetworkErrorLoggingTester tester(network_context(), false);
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, true);
// Nothing to check, since there's no mock service; we're just making sure
// nothing crashes without a service.
}
// This would use an origin filter, but history isn't yet filterable.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, NetworkErrorLogging_History) {
ClearNetworkErrorLoggingTester tester(network_context(), true);
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, true);
EXPECT_EQ(0, tester.mock().remove_calls());
EXPECT_EQ(1, tester.mock().remove_all_calls());
EXPECT_TRUE(ProbablySameFilters(base::RepeatingCallback<bool(const GURL&)>(),
tester.mock().last_origin_filter()));
}
#endif // BUILDFLAG(ENABLE_REPORTING)
// Test that all WebsiteSettings are getting deleted by creating a
// value for each of them and removing data.
TEST_F(ChromeBrowsingDataRemoverDelegateTest, AllTypesAreGettingDeleted) {
TestingProfile* profile = GetProfile();
ASSERT_TRUE(profile->CreateHistoryService(true, false));
ASSERT_TRUE(SubresourceFilterProfileContextFactory::GetForProfile(profile));
auto* map = HostContentSettingsMapFactory::GetForProfile(profile);
auto* registry = content_settings::WebsiteSettingsRegistry::GetInstance();
auto* content_setting_registry =
content_settings::ContentSettingsRegistry::GetInstance();
auto* history_service =
HistoryServiceFactory::GetForProfileWithoutCreating(profile);
// Create a safe_browsing::VerdictCacheManager that will handle deletion of
// ContentSettingsType::PASSWORD_PROTECTION entries.
safe_browsing::VerdictCacheManager sb_cache_manager(history_service, map);
GURL url("https://example.com");
// Whitelist of types that don't have to be deletable.
static const ContentSettingsType whitelisted_types[] = {
// Doesn't allow any values.
ContentSettingsType::PROTOCOL_HANDLERS,
// Doesn't allow any values.
ContentSettingsType::MIXEDSCRIPT,
// Only policy provider sets exceptions for this type.
ContentSettingsType::AUTO_SELECT_CERTIFICATE,
// TODO(710873): Make sure that these get fixed:
// Not deleted but should be deleted with history?
ContentSettingsType::IMPORTANT_SITE_INFO,
};
// Set a value for every WebsiteSetting.
for (const content_settings::WebsiteSettingsInfo* info : *registry) {
if (base::Contains(whitelisted_types, info->type()))
continue;
base::Value some_value;
auto* content_setting = content_setting_registry->Get(info->type());
if (content_setting) {
// Content Settings only allow integers.
if (content_setting->IsSettingValid(CONTENT_SETTING_ALLOW)) {
some_value = base::Value(CONTENT_SETTING_ALLOW);
} else {
ASSERT_TRUE(content_setting->IsSettingValid(CONTENT_SETTING_ASK));
some_value = base::Value(CONTENT_SETTING_ASK);
}
ASSERT_TRUE(content_setting->IsDefaultSettingValid(CONTENT_SETTING_BLOCK))
<< info->name();
// Set default to BLOCK to be able to differentiate an exception from the
// default.
map->SetDefaultContentSetting(info->type(), CONTENT_SETTING_BLOCK);
} else {
// Other website settings only allow dictionaries.
base::DictionaryValue dict;
dict.SetKey("foo", base::Value(42));
some_value = std::move(dict);
}
// Create an exception.
map->SetWebsiteSettingDefaultScope(
url, url, info->type(), std::string(),
std::make_unique<base::Value>(some_value.Clone()));
// Check that the exception was created.
std::unique_ptr<base::Value> value =
map->GetWebsiteSetting(url, url, info->type(), std::string(), nullptr);
EXPECT_TRUE(value) << "Not created: " << info->name();
if (value)
EXPECT_EQ(some_value, *value) << "Not created: " << info->name();
}
// Delete all data types that trigger website setting deletions.
int mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY |
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA |
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS;
BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), mask, false);
// All settings should be deleted now.
for (const content_settings::WebsiteSettingsInfo* info : *registry) {
if (base::Contains(whitelisted_types, info->type()))
continue;
std::unique_ptr<base::Value> value =
map->GetWebsiteSetting(url, url, info->type(), std::string(), nullptr);
if (value && value->is_int()) {
EXPECT_EQ(CONTENT_SETTING_BLOCK, value->GetInt())
<< "Not deleted: " << info->name() << " value: " << *value;
} else {
EXPECT_FALSE(value) << "Not deleted: " << info->name()
<< " value: " << *value;
}
}
}
#if defined(OS_ANDROID)
TEST_F(ChromeBrowsingDataRemoverDelegateTest, WipeOriginVerifierData) {
int before =
customtabs::OriginVerifier::GetClearBrowsingDataCallCountForTesting();
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_EQ(before + 1,
customtabs::OriginVerifier::GetClearBrowsingDataCallCountForTesting());
}
#endif // defined(OS_ANDROID)
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
TEST_F(ChromeBrowsingDataRemoverDelegateTest, WipeCrashData) {
base::FilePath crash_dir_path;
base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path);
base::FilePath upload_log_path =
crash_dir_path.AppendASCII(CrashUploadList::kReporterLogFilename);
constexpr char kCrashEntry1[] = "12345,abc\n";
constexpr char kCrashEntry2[] = "67890,def\n";
std::string initial_contents = kCrashEntry1;
initial_contents.append(kCrashEntry2);
ASSERT_GT(base::WriteFile(upload_log_path, initial_contents.c_str(),
static_cast<int>(initial_contents.size())),
0);
BlockUntilBrowsingDataRemoved(
base::Time::FromTimeT(67890u), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
std::string contents;
base::ReadFileToString(upload_log_path, &contents);
EXPECT_EQ(kCrashEntry1, contents);
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
EXPECT_FALSE(base::PathExists(upload_log_path));
}
#endif
TEST_F(ChromeBrowsingDataRemoverDelegateTest,
WipeNotificationPermissionPromptOutcomesData) {
PrefService* prefs = GetProfile()->GetPrefs();
auto* permission_ui_selector =
AdaptiveNotificationPermissionUiSelector::GetForProfile(GetProfile());
base::SimpleTestClock clock_;
clock_.SetNow(base::Time::Now());
base::Time first_recorded_time = clock_.Now();
permission_ui_selector->set_clock_for_testing(&clock_);
permission_ui_selector->RecordPermissionPromptOutcome(
PermissionAction::DENIED);
clock_.Advance(base::TimeDelta::FromDays(1));
permission_ui_selector->set_clock_for_testing(&clock_);
permission_ui_selector->RecordPermissionPromptOutcome(
PermissionAction::DENIED);
clock_.Advance(base::TimeDelta::FromDays(1));
base::Time third_recorded_time = clock_.Now();
permission_ui_selector->set_clock_for_testing(&clock_);
permission_ui_selector->RecordPermissionPromptOutcome(
PermissionAction::DENIED);
constexpr char kNotificationPermissionActionsPrefPath[] =
"profile.content_settings.permission_actions.notifications";
EXPECT_EQ(3u,
prefs->GetList(kNotificationPermissionActionsPrefPath)->GetSize());
// Remove the first and the second element.
BlockUntilBrowsingDataRemoved(
first_recorded_time, third_recorded_time,
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA, false);
// There is only one element left.
EXPECT_EQ(1u,
prefs->GetList(kNotificationPermissionActionsPrefPath)->GetSize());
EXPECT_EQ(
(util::ValueToTime(prefs->GetList(kNotificationPermissionActionsPrefPath)
->begin()
->FindKey("time")))
.value_or(base::Time()),
third_recorded_time);
// Test we wiped all the elements left.
BlockUntilBrowsingDataRemoved(
base::Time(), base::Time::Max(),
ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_USAGE_DATA, false);
EXPECT_TRUE(prefs->GetList(kNotificationPermissionActionsPrefPath)->empty());
}