ladybird/Tests/LibWeb/TestContentBlocker.cpp
Andreas Kling 46e1a08742 LibWeb: Rename ContentFilter to ContentBlocker
Rename the local content blocking implementation and its tests from
ContentFilter to ContentBlocker while keeping the existing substring
matcher backend and behavior.

Update the WebContent IPC method, WebView option names, debug toggle,
and default config file name to use content blocker terminology.
2026-05-21 21:16:56 +02:00

126 lines
3.4 KiB
C++

/*
* Copyright (c) 2025, Tim Ledbetter <tim.ledbetter@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibTest/TestCase.h>
#include <LibURL/Parser.h>
#include <LibURL/URL.h>
#include <LibWeb/Loader/ContentBlocker.h>
namespace Web {
static ContentBlocker& make_blocker(Vector<String> patterns)
{
auto& blocker = ContentBlocker::the();
MUST(blocker.set_patterns(patterns));
return blocker;
}
static URL::URL url(StringView string)
{
auto result = URL::Parser::basic_parse(string);
EXPECT(result.has_value());
return result.release_value();
}
TEST_CASE(empty_pattern_list)
{
auto& blocker = make_blocker({});
EXPECT(!blocker.is_filtered(url("https://anything.com"sv)));
EXPECT(!blocker.is_filtered(url("data:text/plain,hi"sv)));
}
TEST_CASE(basic_blocking)
{
Vector<String> patterns = {
"ads."_string,
"?banner"_string,
"tracker"_string
};
auto& blocker = make_blocker(move(patterns));
EXPECT(blocker.is_filtered(url("https://example.com/ads.js"sv)));
EXPECT(blocker.is_filtered(url("http://site.com/page.html?banner=true"sv)));
EXPECT(blocker.is_filtered(url("https://tracker.example.org/ping"sv)));
EXPECT(!blocker.is_filtered(url("https://ds.example.com/page.html"sv)));
}
TEST_CASE(data_urls_exempt)
{
Vector<String> patterns = {
{ "data:"_string },
{ "evil.com"_string }
};
auto& blocker = make_blocker(move(patterns));
EXPECT(!blocker.is_filtered(url("data:text/plain,hello"sv)));
EXPECT(!blocker.is_filtered(url("data:image/png;base64,abc123"sv)));
EXPECT(blocker.is_filtered(url("https://evil.com/script.js"sv)));
}
TEST_CASE(disable_filtering)
{
Vector<String> patterns = {
{ "example.com"_string }
};
auto& blocker = make_blocker(move(patterns));
blocker.set_filtering_enabled(false);
EXPECT(!blocker.is_filtered(url("https://example.com"sv)));
EXPECT(!blocker.is_filtered(url("http://example.com/ads"sv)));
blocker.set_filtering_enabled(true);
EXPECT(blocker.is_filtered(url("https://example.com"sv)));
}
TEST_CASE(substring_matches)
{
Vector<String> patterns = {
{ "ads"_string },
{ "ad/"_string }
};
auto& blocker = make_blocker(move(patterns));
EXPECT(blocker.is_filtered(url("https://site.com/ads/banner.jpg"sv)));
EXPECT(blocker.is_filtered(url("http://marketing.com/ad/page"sv)));
EXPECT(!blocker.is_filtered(url("https://site.com/content/article.html"sv)));
EXPECT(!blocker.is_filtered(url("http://advancedtech.com/home"sv)));
}
TEST_CASE(file_scheme_can_be_filtered)
{
Vector<String> patterns = {
{ "secret"_string },
{ ".txt"_string }
};
auto& blocker = make_blocker(move(patterns));
EXPECT(blocker.is_filtered(url("file:///home/user/secret.txt"sv)));
EXPECT(!blocker.is_filtered(url("file:///home/user/document.pdf"sv)));
}
TEST_CASE(query_parameters_and_fragments)
{
Vector<String> patterns = {
{ "#ad="_string },
{ "?ad="_string },
{ "#sponsored"_string }
};
auto& blocker = make_blocker(move(patterns));
EXPECT(blocker.is_filtered(url("https://site.com/page?ad=123"sv)));
EXPECT(blocker.is_filtered(url("https://site.com/page#ad=456"sv)));
EXPECT(blocker.is_filtered(url("https://site.com/page?ref=home&ad=1#sponsored"sv)));
EXPECT(!blocker.is_filtered(url("https://site.com/page?ref=home"sv)));
}
}