blob: 8b9be279a21cfc7a55d68c60de1aed4966842ee5 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <optional>
#include <string>
#include "base/functional/callback.h"
#include "base/json/json_writer.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h"
#include "chrome/browser/extensions/api/browsing_data/browsing_data_api.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/profiles/profile.h"
#include "components/browsing_data/content/browsing_data_helper.h"
#include "components/browsing_data/core/browsing_data_utils.h"
#include "components/browsing_data/core/features.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/history/core/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/test/mock_browsing_data_remover_delegate.h"
#include "extensions/browser/api_test_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
using extensions::api_test_utils::RunFunctionAndReturnError;
using extensions::api_test_utils::RunFunctionAndReturnSingleResult;
namespace extensions {
namespace {
enum OriginTypeMask {
UNPROTECTED_WEB = content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
PROTECTED_WEB = content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
EXTENSION = chrome_browsing_data_remover::ORIGIN_TYPE_EXTENSION
};
// TODO(http://crbug.com/1266606): appcache is a noop and should be removed.
// TODO(http://crbug.com/420857719): webSQL is a noop and should be removed.
const char kRemoveEverythingArguments[] =
R"([{"since": 1000}, {
"appcache": true, "cache": true, "cookies": true, "downloads": true,
"fileSystems": true, "formData": true, "history": true, "indexedDB": true,
"localStorage": true, "serverBoundCertificates": true, "passwords": true,
"pluginData": true, "serviceWorkers": true, "cacheStorage": true, "webSQL":
true
}])";
class BrowsingDataApiTest : public ExtensionServiceTestBase {
protected:
void SetUp() override {
#if !BUILDFLAG(IS_ANDROID)
scoped_feature_list_.InitAndEnableFeature(
browsing_data::features::kDbdRevampDesktop);
#endif // !BUILDFLAG(IS_ANDROID)
ExtensionServiceTestBase::SetUp();
InitializeEmptyExtensionService();
remover_ = profile()->GetBrowsingDataRemover();
remover_->SetEmbedderDelegate(&delegate_);
}
const base::Time& GetBeginTime() {
return remover_->GetLastUsedBeginTimeForTesting();
}
uint64_t GetRemovalMask() {
return remover_->GetLastUsedRemovalMaskForTesting();
}
uint64_t GetOriginTypeMask() {
return remover_->GetLastUsedOriginTypeMaskForTesting();
}
uint64_t GetAsMask(const base::Value::Dict* dict,
std::string path,
uint64_t mask_value) {
std::optional<bool> value = dict->FindBool(path);
DCHECK(value.has_value());
return *value ? mask_value : 0;
}
void RunBrowsingDataRemoveFunctionAndCompareRemovalMask(
const std::string& data_types,
uint64_t expected_mask) {
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
SCOPED_TRACE(data_types);
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
function.get(), std::string("[{\"since\": 1},") + data_types + "]",
profile()));
EXPECT_EQ(expected_mask, GetRemovalMask());
EXPECT_EQ(UNPROTECTED_WEB, GetOriginTypeMask());
}
void RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
const std::string& key,
uint64_t expected_mask) {
RunBrowsingDataRemoveFunctionAndCompareRemovalMask(
std::string("{\"") + key + "\": true}", expected_mask);
}
void RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask(
const std::string& protectedStr,
uint64_t expected_mask) {
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
SCOPED_TRACE(protectedStr);
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
function.get(),
"[{\"originTypes\": " + protectedStr + "}, {\"cookies\": true}]",
profile()));
EXPECT_EQ(expected_mask, GetOriginTypeMask());
}
template <class ShortcutFunction>
void RunAndCompareRemovalMask(uint64_t expected_mask) {
scoped_refptr<ShortcutFunction> function = new ShortcutFunction();
SCOPED_TRACE(ShortcutFunction::static_function_name());
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
function.get(), std::string("[{\"since\": 1}]"), profile()));
EXPECT_EQ(expected_mask, GetRemovalMask());
EXPECT_EQ(UNPROTECTED_WEB, GetOriginTypeMask());
}
void SetSinceAndVerify(browsing_data::TimePeriod since_pref) {
PrefService* prefs = profile()->GetPrefs();
browsing_data::ClearBrowsingDataTab tab =
static_cast<browsing_data::ClearBrowsingDataTab>(
prefs->GetInteger(browsing_data::prefs::kLastClearBrowsingDataTab));
auto* time_period_pref = browsing_data::GetTimePeriodPreferenceName(tab);
prefs->SetInteger(time_period_pref, static_cast<int>(since_pref));
scoped_refptr<BrowsingDataSettingsFunction> function =
new BrowsingDataSettingsFunction();
SCOPED_TRACE("settings");
std::optional<base::Value> result = RunFunctionAndReturnSingleResult(
function.get(), std::string("[]"), profile());
EXPECT_TRUE(result->is_dict());
ASSERT_TRUE(result->GetDict().FindDoubleByDottedPath("options.since"));
double since = *result->GetDict().FindDoubleByDottedPath("options.since");
double expected_since = 0;
if (since_pref != browsing_data::TimePeriod::ALL_TIME) {
base::Time time = CalculateBeginDeleteTime(since_pref);
expected_since = time.InMillisecondsFSinceUnixEpoch();
}
// Even a synchronous function takes nonzero time, but the difference
// between when the function was called and now should be well under a
// second, so we'll make sure the requested start time is within 10 seconds.
// Since the smallest selectable period is an hour, that should be
// sufficient.
EXPECT_LE(expected_since, since + 10.0 * 1000.0);
}
void SetPrefsAndVerifySettings(uint64_t data_type_flags,
uint64_t expected_origin_type_mask,
uint64_t expected_removal_mask) {
PrefService* prefs = profile()->GetPrefs();
prefs->SetInteger(
browsing_data::prefs::kLastClearBrowsingDataTab,
static_cast<int>(browsing_data::ClearBrowsingDataTab::ADVANCED));
prefs->SetBoolean(
browsing_data::prefs::kDeleteCache,
!!(data_type_flags & content::BrowsingDataRemover::DATA_TYPE_CACHE));
prefs->SetBoolean(
browsing_data::prefs::kDeleteCookies,
!!(data_type_flags & content::BrowsingDataRemover::DATA_TYPE_COOKIES));
prefs->SetBoolean(
browsing_data::prefs::kDeleteBrowsingHistory,
!!(data_type_flags & chrome_browsing_data_remover::DATA_TYPE_HISTORY));
prefs->SetBoolean(browsing_data::prefs::kDeleteFormData,
!!(data_type_flags &
chrome_browsing_data_remover::DATA_TYPE_FORM_DATA));
prefs->SetBoolean(browsing_data::prefs::kDeleteDownloadHistory,
!!(data_type_flags &
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS));
prefs->SetBoolean(
browsing_data::prefs::kDeleteHostedAppsData,
!!(data_type_flags &
chrome_browsing_data_remover::DATA_TYPE_HOSTED_APP_DATA_TEST_ONLY));
prefs->SetBoolean(browsing_data::prefs::kDeletePasswords,
!!(data_type_flags &
chrome_browsing_data_remover::DATA_TYPE_PASSWORDS));
VerifyRemovalMask(expected_origin_type_mask, expected_removal_mask);
}
void SetBasicPrefsAndVerifySettings(uint64_t data_type_flags,
uint64_t expected_origin_type_mask,
uint64_t expected_removal_mask) {
PrefService* prefs = profile()->GetPrefs();
prefs->SetInteger(
browsing_data::prefs::kLastClearBrowsingDataTab,
static_cast<int>(browsing_data::ClearBrowsingDataTab::BASIC));
prefs->SetBoolean(
browsing_data::prefs::kDeleteCacheBasic,
!!(data_type_flags & content::BrowsingDataRemover::DATA_TYPE_CACHE));
prefs->SetBoolean(
browsing_data::prefs::kDeleteCookiesBasic,
!!(data_type_flags & content::BrowsingDataRemover::DATA_TYPE_COOKIES));
prefs->SetBoolean(
browsing_data::prefs::kDeleteBrowsingHistoryBasic,
!!(data_type_flags & chrome_browsing_data_remover::DATA_TYPE_HISTORY));
VerifyRemovalMask(expected_origin_type_mask, expected_removal_mask);
}
void VerifyRemovalMask(uint64_t expected_origin_type_mask,
uint64_t expected_removal_mask) {
scoped_refptr<BrowsingDataSettingsFunction> function =
new BrowsingDataSettingsFunction();
SCOPED_TRACE("settings");
std::optional<base::Value> result = RunFunctionAndReturnSingleResult(
function.get(), std::string("[]"), profile());
ASSERT_TRUE(result->is_dict());
const base::Value::Dict& result_dict = result->GetDict();
const base::Value::Dict* origin_types =
result_dict.FindDictByDottedPath("options.originTypes");
ASSERT_TRUE(origin_types);
uint64_t origin_type_mask =
GetAsMask(origin_types, "unprotectedWeb", UNPROTECTED_WEB) |
GetAsMask(origin_types, "protectedWeb", PROTECTED_WEB) |
GetAsMask(origin_types, "extension", EXTENSION);
EXPECT_EQ(expected_origin_type_mask, origin_type_mask);
const base::Value::Dict* data_to_remove =
result_dict.FindDict("dataToRemove");
ASSERT_TRUE(data_to_remove);
uint64_t removal_mask =
GetAsMask(data_to_remove, "cache",
content::BrowsingDataRemover::DATA_TYPE_CACHE) |
GetAsMask(data_to_remove, "cacheStorage",
content::BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE) |
GetAsMask(data_to_remove, "cookies",
content::BrowsingDataRemover::DATA_TYPE_COOKIES) |
GetAsMask(data_to_remove, "downloads",
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS) |
GetAsMask(data_to_remove, "fileSystems",
content::BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS) |
GetAsMask(data_to_remove, "formData",
chrome_browsing_data_remover::DATA_TYPE_FORM_DATA) |
GetAsMask(data_to_remove, "history",
chrome_browsing_data_remover::DATA_TYPE_HISTORY) |
GetAsMask(data_to_remove, "indexedDB",
content::BrowsingDataRemover::DATA_TYPE_INDEXED_DB) |
GetAsMask(data_to_remove, "localStorage",
content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE) |
// PluginData is not supported anymore.
GetAsMask(data_to_remove, "pluginData", 0) |
GetAsMask(data_to_remove, "passwords",
chrome_browsing_data_remover::DATA_TYPE_PASSWORDS) |
GetAsMask(data_to_remove, "serviceWorkers",
content::BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS);
EXPECT_EQ(expected_removal_mask, removal_mask);
}
// The kAllowDeletingBrowserHistory pref must be set to false before this
// is called.
void CheckRemovalPermitted(const std::string& data_types, bool permitted) {
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
std::string args = "[{\"since\": 1}," + data_types + "]";
if (permitted) {
EXPECT_FALSE(
RunFunctionAndReturnSingleResult(function.get(), args, profile()))
<< " for " << args;
} else {
EXPECT_EQ(RunFunctionAndReturnError(function.get(), args, profile()),
extension_browsing_data_api_constants::kDeleteProhibitedError)
<< " for " << args;
}
}
void CheckInvalidRemovalArgs(const std::string& args,
const std::string& expected_error) {
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_EQ(RunFunctionAndReturnError(function.get(), args, profile()),
expected_error)
<< " for " << args;
}
void VerifyFilterBuilder(const std::string& options,
content::BrowsingDataFilterBuilder* filter_builder) {
delegate()->ExpectCall(
base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, UNPROTECTED_WEB,
filter_builder);
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
function.get(), "[" + options + ", {\"localStorage\": true}]",
profile()))
<< options;
delegate()->VerifyAndClearExpectations();
}
content::MockBrowsingDataRemoverDelegate* delegate() { return &delegate_; }
private:
raw_ptr<content::BrowsingDataRemover> remover_;
content::MockBrowsingDataRemoverDelegate delegate_;
#if !BUILDFLAG(IS_ANDROID)
base::test::ScopedFeatureList scoped_feature_list_;
#endif // !BUILDFLAG(IS_ANDROID)
};
} // namespace
TEST_F(BrowsingDataApiTest, RemovalProhibited) {
PrefService* prefs = profile()->GetPrefs();
prefs->SetBoolean(prefs::kAllowDeletingBrowserHistory, false);
CheckRemovalPermitted("{\"cache\": true}", true);
CheckRemovalPermitted("{\"cacheStorage\": true}", true);
CheckRemovalPermitted("{\"cookies\": true}", true);
CheckRemovalPermitted("{\"downloads\": true}", false);
CheckRemovalPermitted("{\"fileSystems\": true}", true);
CheckRemovalPermitted("{\"formData\": true}", true);
CheckRemovalPermitted("{\"history\": true}", false);
CheckRemovalPermitted("{\"indexedDB\": true}", true);
CheckRemovalPermitted("{\"localStorage\": true}", true);
CheckRemovalPermitted("{\"serverBoundCertificates\": true}", true);
CheckRemovalPermitted("{\"passwords\": true}", true);
CheckRemovalPermitted("{\"serviceWorkers\": true}", true);
// The entire removal is prohibited if any part is.
CheckRemovalPermitted("{\"cache\": true, \"history\": true}", false);
CheckRemovalPermitted("{\"cookies\": true, \"downloads\": true}", false);
// If a prohibited type is not selected, the removal is OK.
CheckRemovalPermitted("{\"history\": false}", true);
CheckRemovalPermitted("{\"downloads\": false}", true);
CheckRemovalPermitted("{\"cache\": true, \"history\": false}", true);
CheckRemovalPermitted("{\"cookies\": true, \"downloads\": false}", true);
}
TEST_F(BrowsingDataApiTest, RemoveBrowsingDataAll) {
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
function.get(), kRemoveEverythingArguments, profile()));
EXPECT_EQ(base::Time::FromSecondsSinceUnixEpoch(1.0), GetBeginTime());
EXPECT_EQ(
// TODO(benwells): implement clearing of site usage data via the
// browsing data API. https://crbug.com/500801.
// TODO(dmurph): implement clearing of durable storage permission
// via the browsing data API. https://crbug.com/500801.
// TODO(ramyasharma): implement clearing of external protocol data
// via the browsing data API. https://crbug.com/692850.
content::BrowsingDataRemover::DATA_TYPE_COOKIES |
(content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE &
~content::BrowsingDataRemover::DATA_TYPE_BACKGROUND_FETCH &
~content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE) |
content::BrowsingDataRemover::DATA_TYPE_CACHE |
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS |
chrome_browsing_data_remover::DATA_TYPE_FORM_DATA |
chrome_browsing_data_remover::DATA_TYPE_HISTORY |
chrome_browsing_data_remover::DATA_TYPE_PASSWORDS,
GetRemovalMask());
}
TEST_F(BrowsingDataApiTest, BrowsingDataOriginTypeMask) {
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask("{}", 0);
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask(
"{\"unprotectedWeb\": true}", UNPROTECTED_WEB);
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask(
"{\"protectedWeb\": true}", PROTECTED_WEB);
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask("{\"extension\": true}",
EXTENSION);
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask(
"{\"unprotectedWeb\": true, \"protectedWeb\": true}",
UNPROTECTED_WEB | PROTECTED_WEB);
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask(
"{\"unprotectedWeb\": true, \"extension\": true}",
UNPROTECTED_WEB | EXTENSION);
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask(
"{\"protectedWeb\": true, \"extension\": true}",
PROTECTED_WEB | EXTENSION);
RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask(
("{\"unprotectedWeb\": true, \"protectedWeb\": true, "
"\"extension\": true}"),
UNPROTECTED_WEB | PROTECTED_WEB | EXTENSION);
}
TEST_F(BrowsingDataApiTest, BrowsingDataRemovalMask) {
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"cache", content::BrowsingDataRemover::DATA_TYPE_CACHE);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"cacheStorage", content::BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"cookies", content::BrowsingDataRemover::DATA_TYPE_COOKIES);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"downloads", content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"fileSystems", content::BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"formData", chrome_browsing_data_remover::DATA_TYPE_FORM_DATA);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"history", chrome_browsing_data_remover::DATA_TYPE_HISTORY);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"indexedDB", content::BrowsingDataRemover::DATA_TYPE_INDEXED_DB);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"localStorage", content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"passwords", chrome_browsing_data_remover::DATA_TYPE_PASSWORDS);
RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(
"serviceWorkers",
content::BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS);
}
// Test an arbitrary combination of data types.
TEST_F(BrowsingDataApiTest, BrowsingDataRemovalMaskCombination) {
RunBrowsingDataRemoveFunctionAndCompareRemovalMask(
"{\"cookies\": true, \"history\": true}",
content::BrowsingDataRemover::DATA_TYPE_COOKIES |
chrome_browsing_data_remover::DATA_TYPE_HISTORY);
}
// Make sure the remove() function accepts the format produced by settings().
TEST_F(BrowsingDataApiTest, BrowsingDataRemovalInputFromSettings) {
PrefService* prefs = profile()->GetPrefs();
prefs->SetInteger(
browsing_data::prefs::kLastClearBrowsingDataTab,
static_cast<int>(browsing_data::ClearBrowsingDataTab::ADVANCED));
prefs->SetBoolean(browsing_data::prefs::kDeleteCache, true);
prefs->SetBoolean(browsing_data::prefs::kDeleteBrowsingHistory, true);
prefs->SetBoolean(browsing_data::prefs::kDeleteDownloadHistory, true);
prefs->SetBoolean(browsing_data::prefs::kDeleteCookies, false);
prefs->SetBoolean(browsing_data::prefs::kDeleteFormData, false);
prefs->SetBoolean(browsing_data::prefs::kDeleteHostedAppsData, false);
prefs->SetBoolean(browsing_data::prefs::kDeletePasswords, true);
uint64_t expected_mask = content::BrowsingDataRemover::DATA_TYPE_CACHE |
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS |
chrome_browsing_data_remover::DATA_TYPE_HISTORY;
std::optional<std::string> json;
// Scoping for the traces.
{
scoped_refptr<BrowsingDataSettingsFunction> settings_function =
new BrowsingDataSettingsFunction();
SCOPED_TRACE("settings_json");
std::optional<base::Value> result = RunFunctionAndReturnSingleResult(
settings_function.get(), std::string("[]"), profile());
EXPECT_TRUE(result->is_dict());
base::Value::Dict* data_to_remove =
result->GetDict().FindDict("dataToRemove");
ASSERT_TRUE(data_to_remove);
json = base::WriteJson(*data_to_remove);
ASSERT_TRUE(json);
}
{
auto remove_function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
SCOPED_TRACE("remove_json");
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
remove_function.get(), std::string("[{\"since\": 1},") + *json + "]",
profile()));
EXPECT_EQ(expected_mask, GetRemovalMask());
EXPECT_EQ(UNPROTECTED_WEB, GetOriginTypeMask());
}
}
TEST_F(BrowsingDataApiTest, ShortcutFunctionRemovalMask) {
RunAndCompareRemovalMask<BrowsingDataRemoveCacheFunction>(
content::BrowsingDataRemover::DATA_TYPE_CACHE);
RunAndCompareRemovalMask<BrowsingDataRemoveCacheStorageFunction>(
content::BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE);
RunAndCompareRemovalMask<BrowsingDataRemoveCookiesFunction>(
content::BrowsingDataRemover::DATA_TYPE_COOKIES);
RunAndCompareRemovalMask<BrowsingDataRemoveDownloadsFunction>(
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS);
RunAndCompareRemovalMask<BrowsingDataRemoveFileSystemsFunction>(
content::BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS);
RunAndCompareRemovalMask<BrowsingDataRemoveFormDataFunction>(
chrome_browsing_data_remover::DATA_TYPE_FORM_DATA);
RunAndCompareRemovalMask<BrowsingDataRemoveHistoryFunction>(
chrome_browsing_data_remover::DATA_TYPE_HISTORY);
RunAndCompareRemovalMask<BrowsingDataRemoveIndexedDBFunction>(
content::BrowsingDataRemover::DATA_TYPE_INDEXED_DB);
RunAndCompareRemovalMask<BrowsingDataRemoveLocalStorageFunction>(
content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE);
RunAndCompareRemovalMask<BrowsingDataRemovePasswordsFunction>(
chrome_browsing_data_remover::DATA_TYPE_PASSWORDS);
RunAndCompareRemovalMask<BrowsingDataRemoveServiceWorkersFunction>(
content::BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS);
}
// Test the processing of the 'delete since' preference.
TEST_F(BrowsingDataApiTest, SettingsFunctionSince) {
SetSinceAndVerify(browsing_data::TimePeriod::ALL_TIME);
SetSinceAndVerify(browsing_data::TimePeriod::LAST_15_MINUTES);
SetSinceAndVerify(browsing_data::TimePeriod::LAST_HOUR);
SetSinceAndVerify(browsing_data::TimePeriod::LAST_DAY);
SetSinceAndVerify(browsing_data::TimePeriod::LAST_WEEK);
SetSinceAndVerify(browsing_data::TimePeriod::FOUR_WEEKS);
}
TEST_F(BrowsingDataApiTest, SettingsFunctionEmpty) {
SetPrefsAndVerifySettings(0, 0, 0);
}
// Test straightforward settings, mapped 1:1 to data types.
TEST_F(BrowsingDataApiTest, SettingsFunctionSimple) {
SetPrefsAndVerifySettings(content::BrowsingDataRemover::DATA_TYPE_CACHE, 0,
content::BrowsingDataRemover::DATA_TYPE_CACHE);
SetPrefsAndVerifySettings(chrome_browsing_data_remover::DATA_TYPE_HISTORY, 0,
chrome_browsing_data_remover::DATA_TYPE_HISTORY);
SetPrefsAndVerifySettings(chrome_browsing_data_remover::DATA_TYPE_FORM_DATA,
0,
chrome_browsing_data_remover::DATA_TYPE_FORM_DATA);
SetPrefsAndVerifySettings(content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
0,
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS);
SetPrefsAndVerifySettings(chrome_browsing_data_remover::DATA_TYPE_PASSWORDS,
0, 0);
SetBasicPrefsAndVerifySettings(content::BrowsingDataRemover::DATA_TYPE_CACHE,
0,
content::BrowsingDataRemover::DATA_TYPE_CACHE);
SetBasicPrefsAndVerifySettings(
chrome_browsing_data_remover::DATA_TYPE_HISTORY, 0,
chrome_browsing_data_remover::DATA_TYPE_HISTORY);
}
// Test cookie and app data settings.
TEST_F(BrowsingDataApiTest, SettingsFunctionSiteData) {
uint64_t supported_site_data =
(content::BrowsingDataRemover::DATA_TYPE_COOKIES |
content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE) &
~content::BrowsingDataRemover::DATA_TYPE_BACKGROUND_FETCH &
~content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE;
SetPrefsAndVerifySettings(content::BrowsingDataRemover::DATA_TYPE_COOKIES,
UNPROTECTED_WEB, supported_site_data);
SetPrefsAndVerifySettings(
chrome_browsing_data_remover::DATA_TYPE_HOSTED_APP_DATA_TEST_ONLY,
PROTECTED_WEB, supported_site_data);
SetPrefsAndVerifySettings(
content::BrowsingDataRemover::DATA_TYPE_COOKIES |
chrome_browsing_data_remover::DATA_TYPE_HOSTED_APP_DATA_TEST_ONLY,
PROTECTED_WEB | UNPROTECTED_WEB, supported_site_data);
SetBasicPrefsAndVerifySettings(
content::BrowsingDataRemover::DATA_TYPE_COOKIES, UNPROTECTED_WEB,
supported_site_data);
}
// Test an arbitrary assortment of settings.
TEST_F(BrowsingDataApiTest, SettingsFunctionAssorted) {
uint64_t supported_site_data =
(content::BrowsingDataRemover::DATA_TYPE_COOKIES |
content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE) &
~content::BrowsingDataRemover::DATA_TYPE_BACKGROUND_FETCH &
~content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE;
SetPrefsAndVerifySettings(
content::BrowsingDataRemover::DATA_TYPE_COOKIES |
chrome_browsing_data_remover::DATA_TYPE_HISTORY |
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS,
UNPROTECTED_WEB,
supported_site_data | chrome_browsing_data_remover::DATA_TYPE_HISTORY |
content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS);
}
TEST_F(BrowsingDataApiTest, RemoveWithoutFilter) {
auto filter_builder = content::BrowsingDataFilterBuilder::Create(
content::BrowsingDataFilterBuilder::Mode::kPreserve);
ASSERT_TRUE(filter_builder->MatchesAllOriginsAndDomains());
VerifyFilterBuilder("{}", filter_builder.get());
}
TEST_F(BrowsingDataApiTest, RemoveWithDeleteListFilter) {
auto filter_builder = content::BrowsingDataFilterBuilder::Create(
content::BrowsingDataFilterBuilder::Mode::kDelete);
filter_builder->AddOrigin(url::Origin::Create(GURL("http://example.com")));
VerifyFilterBuilder(R"({"origins": ["http://example.com"]})",
filter_builder.get());
}
TEST_F(BrowsingDataApiTest, RemoveWithPreserveListFilter) {
auto filter_builder = content::BrowsingDataFilterBuilder::Create(
content::BrowsingDataFilterBuilder::Mode::kPreserve);
filter_builder->AddOrigin(url::Origin::Create(GURL("http://example.com")));
VerifyFilterBuilder(R"({"excludeOrigins": ["http://example.com"]})",
filter_builder.get());
}
TEST_F(BrowsingDataApiTest, RemoveWithSpecialUrlFilter) {
auto filter_builder = content::BrowsingDataFilterBuilder::Create(
content::BrowsingDataFilterBuilder::Mode::kPreserve);
filter_builder->AddOrigin(url::Origin::Create(GURL("file:///")));
filter_builder->AddOrigin(url::Origin::Create(GURL("http://example.com")));
VerifyFilterBuilder(
R"({"excludeOrigins": ["file:///tmp/foo.html/",
"filesystem:http://example.com/foo.txt"]})",
filter_builder.get());
}
TEST_F(BrowsingDataApiTest, RemoveCookiesWithFilter) {
auto filter_builder = content::BrowsingDataFilterBuilder::Create(
content::BrowsingDataFilterBuilder::Mode::kPreserve);
filter_builder->AddRegisterableDomain("example.com");
delegate()->ExpectCall(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
UNPROTECTED_WEB, filter_builder.get());
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
function.get(),
R"([{"excludeOrigins": ["http://example.com"]},
{"cookies": true}])",
profile()));
delegate()->VerifyAndClearExpectations();
}
// Expect two separate BrowsingDataRemover calls if cookies and localstorage
// are passed with a filter.
TEST_F(BrowsingDataApiTest, RemoveCookiesAndStorageWithFilter) {
auto filter_builder1 = content::BrowsingDataFilterBuilder::Create(
content::BrowsingDataFilterBuilder::Mode::kDelete);
filter_builder1->AddRegisterableDomain("example.com");
delegate()->ExpectCall(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_COOKIES,
UNPROTECTED_WEB, filter_builder1.get());
auto filter_builder2 = content::BrowsingDataFilterBuilder::Create(
content::BrowsingDataFilterBuilder::Mode::kDelete);
filter_builder2->AddOrigin(
url::Origin::Create(GURL("http://www.example.com")));
delegate()->ExpectCall(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE,
UNPROTECTED_WEB, filter_builder2.get());
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_FALSE(RunFunctionAndReturnSingleResult(
function.get(),
R"([{"origins": ["http://www.example.com"]},
{"cookies": true, "localStorage": true}])",
profile()));
delegate()->VerifyAndClearExpectations();
}
TEST_F(BrowsingDataApiTest, RemoveWithFilterAndInvalidParameters) {
CheckInvalidRemovalArgs(
R"([{"origins": ["http://example.com"]}, {"passwords": true}])",
extension_browsing_data_api_constants::kNonFilterableError);
CheckInvalidRemovalArgs(
R"([{"origins": ["http://example.com"],
"excludeOrigins": ["https://example.com"]},
{"localStorage": true}])",
extension_browsing_data_api_constants::kIncompatibleFilterError);
CheckInvalidRemovalArgs(
R"([{"origins": ["foo"]}, {"localStorage": true}])",
base::StringPrintf(
extension_browsing_data_api_constants::kInvalidOriginError, "foo"));
CheckInvalidRemovalArgs(
R"([{"excludeOrigins": ["foo"]}, {"localStorage": true}])",
base::StringPrintf(
extension_browsing_data_api_constants::kInvalidOriginError, "foo"));
}
} // namespace extensions