blob: ea54c058195bf6d1f7c290f6382aaaecd17829c0 [file]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/subresource_filter/core/browser/async_document_subresource_filter.h"
#include <array>
#include <memory>
#include <vector>
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "components/subresource_filter/core/browser/async_document_subresource_filter_test_utils.h"
#include "components/subresource_filter/core/common/constants.h"
#include "components/subresource_filter/core/common/load_policy.h"
#include "components/subresource_filter/core/common/memory_mapped_ruleset.h"
#include "components/subresource_filter/core/common/test_ruleset_creator.h"
#include "components/subresource_filter/core/common/test_ruleset_utils.h"
#include "components/url_pattern_index/proto/rules.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace subresource_filter {
namespace proto = url_pattern_index::proto;
constexpr const char kSubresourceLoadEvaluationWallDurationHistogram[] =
"SubresourceFilter.SubresourceLoad.Evaluation.WallDuration";
constexpr const char kSubresourceLoadEvaluationCPUDurationHistogram[] =
"SubresourceFilter.SubresourceLoad.Evaluation.CPUDuration";
class AsyncDocumentSubresourceFilterTest : public ::testing::Test {
public:
AsyncDocumentSubresourceFilterTest() = default;
AsyncDocumentSubresourceFilterTest(
const AsyncDocumentSubresourceFilterTest&) = delete;
AsyncDocumentSubresourceFilterTest& operator=(
const AsyncDocumentSubresourceFilterTest&) = delete;
protected:
void SetUp() override {
std::vector<proto::UrlRule> rules;
rules.push_back(testing::CreateAllowlistRuleForDocument(
"allowlisted.subframe.com", proto::ACTIVATION_TYPE_GENERICBLOCK,
{"example.com"}));
rules.push_back(testing::CreateSuffixRule("disallowed.html"));
ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules(
rules, &test_ruleset_pair_));
dealer_handle_ = std::make_unique<VerifiedRulesetDealer::Handle>(
blocking_task_runner_, kSafeBrowsingRulesetConfig);
}
void TearDown() override {
dealer_handle_.reset(nullptr);
RunUntilIdle();
}
const testing::TestRuleset& ruleset() const {
return test_ruleset_pair_.indexed;
}
void RunUntilIdle() {
base::RunLoop().RunUntilIdle();
while (blocking_task_runner_->HasPendingTask()) {
blocking_task_runner_->RunUntilIdle();
base::RunLoop().RunUntilIdle();
}
}
void RunBlockingTasks() {
if (blocking_task_runner_->HasPendingTask()) {
blocking_task_runner_->RunPendingTasks();
}
}
VerifiedRulesetDealer::Handle* dealer_handle() {
return dealer_handle_.get();
}
std::unique_ptr<VerifiedRuleset::Handle> CreateRulesetHandle() {
return std::make_unique<VerifiedRuleset::Handle>(dealer_handle());
}
private:
testing::TestRulesetCreator test_ruleset_creator_;
testing::TestRulesetPair test_ruleset_pair_;
// Note: ADSF assumes a task runner is associated with the current thread.
// Instantiate a MessageLoop on the current thread and use base::RunLoop to
// handle the replies ADSF tasks generate.
base::test::SingleThreadTaskEnvironment task_environment_;
scoped_refptr<base::TestSimpleTaskRunner> blocking_task_runner_ =
new base::TestSimpleTaskRunner;
std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_;
};
namespace {
// TODO(csharrison): If more consumers need to test these callbacks at this
// granularity, consider moving these classes into
// async_document_subresource_filter_test_utils.
class TestCallbackReceiver {
public:
TestCallbackReceiver() = default;
TestCallbackReceiver(const TestCallbackReceiver&) = delete;
TestCallbackReceiver& operator=(const TestCallbackReceiver&) = delete;
base::OnceClosure GetClosure() {
return base::BindOnce(&TestCallbackReceiver::Callback,
base::Unretained(this));
}
int callback_count() const { return callback_count_; }
private:
void Callback() { ++callback_count_; }
int callback_count_ = 0;
};
class LoadPolicyCallbackReceiver {
public:
LoadPolicyCallbackReceiver() = default;
LoadPolicyCallbackReceiver(const LoadPolicyCallbackReceiver&) = delete;
LoadPolicyCallbackReceiver& operator=(const LoadPolicyCallbackReceiver&) =
delete;
AsyncDocumentSubresourceFilter::LoadPolicyCallback GetCallback() {
return base::BindOnce(&LoadPolicyCallbackReceiver::Callback,
base::Unretained(this));
}
void ExpectReceivedOnce(LoadPolicy load_policy) const {
ASSERT_EQ(1, callback_count_);
EXPECT_EQ(load_policy, last_load_policy_);
}
private:
void Callback(LoadPolicy load_policy) {
++callback_count_;
last_load_policy_ = load_policy;
}
int callback_count_ = 0;
LoadPolicy last_load_policy_;
};
class MultiLoadPolicyCallbackReceiver {
public:
MultiLoadPolicyCallbackReceiver() = default;
MultiLoadPolicyCallbackReceiver(
const MultiLoadPolicyCallbackReceiver& other) = delete;
MultiLoadPolicyCallbackReceiver& operator=(
const MultiLoadPolicyCallbackReceiver& other) = delete;
~MultiLoadPolicyCallbackReceiver() = default;
AsyncDocumentSubresourceFilter::MultiLoadPolicyCallback GetCallback() {
return base::BindOnce(&MultiLoadPolicyCallbackReceiver::Callback,
base::Unretained(this));
}
int explicitly_allow_count() const { return explicitly_allow_count_; }
int allow_count() const { return allow_count_; }
int would_disallow_count() const { return would_disallow_count_; }
int disallow_count() const { return disallow_count_; }
void SetQuitClosure(base::OnceClosure quit_closure) {
CHECK(quit_closure);
quit_closure_ = std::move(quit_closure);
}
private:
void Callback(std::vector<LoadPolicy> policies) {
for (const auto& load_policy : policies) {
switch (load_policy) {
case LoadPolicy::EXPLICITLY_ALLOW:
explicitly_allow_count_++;
break;
case LoadPolicy::ALLOW:
allow_count_++;
break;
case LoadPolicy::WOULD_DISALLOW:
would_disallow_count_++;
break;
case LoadPolicy::DISALLOW:
disallow_count_++;
}
}
Quit();
}
void Quit() {
CHECK(!quit_closure_.is_null());
std::move(quit_closure_).Run();
}
base::OnceClosure quit_closure_;
int explicitly_allow_count_ = 0;
int allow_count_ = 0;
int would_disallow_count_ = 0;
int disallow_count_ = 0;
};
} // namespace
TEST_F(AsyncDocumentSubresourceFilterTest, ActivationStateIsReported) {
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://example.com"), mojom::ActivationLevel::kEnabled, false);
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
RunUntilIdle();
mojom::ActivationState expected_state;
expected_state.activation_level = mojom::ActivationLevel::kEnabled;
activation_state.ExpectReceivedOnce(expected_state);
}
TEST_F(AsyncDocumentSubresourceFilterTest, DeleteFilter_NoActivationCallback) {
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://example.com"), mojom::ActivationLevel::kEnabled, false);
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
EXPECT_FALSE(filter->has_activation_state());
filter.reset();
RunUntilIdle();
EXPECT_EQ(0, activation_state.callback_count());
}
TEST_F(AsyncDocumentSubresourceFilterTest, ActivationStateIsComputedCorrectly) {
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://allowlisted.subframe.com"), mojom::ActivationLevel::kEnabled,
false);
params.parent_document_origin =
url::Origin::Create(GURL("http://example.com"));
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
RunUntilIdle();
mojom::ActivationState expected_activation_state;
expected_activation_state.activation_level = mojom::ActivationLevel::kEnabled;
expected_activation_state.generic_blocking_rules_disabled = true;
activation_state.ExpectReceivedOnce(expected_activation_state);
}
TEST_F(AsyncDocumentSubresourceFilterTest, DisabledForCorruptRuleset) {
testing::TestRuleset::CorruptByFilling(ruleset(), 0, 100, 0xFF);
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://example.com"), mojom::ActivationLevel::kEnabled, false);
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
RunUntilIdle();
activation_state.ExpectReceivedOnce(mojom::ActivationState());
}
TEST_F(AsyncDocumentSubresourceFilterTest, GetLoadPolicyForSubdocument) {
base::HistogramTester histogram_tester;
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://example.com"), mojom::ActivationLevel::kEnabled, true);
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
LoadPolicyCallbackReceiver load_policy_1;
LoadPolicyCallbackReceiver load_policy_2;
filter->GetLoadPolicyForSubdocument(GURL("http://example.com/allowed.html"),
load_policy_1.GetCallback());
filter->GetLoadPolicyForSubdocument(
GURL("http://example.com/disallowed.html"), load_policy_2.GetCallback());
RunUntilIdle();
load_policy_1.ExpectReceivedOnce(LoadPolicy::ALLOW);
load_policy_2.ExpectReceivedOnce(LoadPolicy::DISALLOW);
// Check that the UMA tag is propagated for performance measurement metrics.
histogram_tester.ExpectTotalCount(
kSubresourceLoadEvaluationWallDurationHistogram, 2);
histogram_tester.ExpectTotalCount(
kSubresourceLoadEvaluationCPUDurationHistogram, 2);
}
TEST_F(AsyncDocumentSubresourceFilterTest, GetLoadPolicyForSubdocumentURLs) {
const struct {
mojom::ActivationLevel activation_level;
std::vector<GURL> urls;
int explicitly_allow_count;
int allow_count;
int would_disallow_count;
int disallow_count;
} kTestCases[] = {{mojom::ActivationLevel::kEnabled,
{},
0 /* explicitly_allow_count */,
0 /* allow_count */,
0 /* would_disallow_count */,
0 /* disallow_count */},
{mojom::ActivationLevel::kDryRun,
{},
0 /* explicitly_allow_count */,
0 /* allow_count */,
0 /* would_disallow_count */,
0 /* disallow_count */},
{mojom::ActivationLevel::kEnabled,
{GURL("http://alias1.com/allowed.html"),
GURL("http://alias2.com/disallowed.html")},
0 /* explicitly_allow_count */,
1 /* allow_count */,
0 /* would_disallow_count */,
1 /* disallow_count */},
{mojom::ActivationLevel::kDryRun,
{GURL("http://alias1.com/allowed.html"),
GURL("http://alias2.com/disallowed.html")},
0 /* explicitly_allow_count */,
1 /* allow_count */,
1 /* would_disallow_count */,
0 /* disallow_count */},
{mojom::ActivationLevel::kEnabled,
{GURL("http://example.alias1.com/allowed.html"),
GURL("http://example.alias2.com/allowed.html")},
0 /* explicitly_allow_count */,
2 /* allow_count */,
0 /* would_disallow_count */,
0 /* disallow_count */},
{mojom::ActivationLevel::kDryRun,
{GURL("http://example.alias1.com/allowed.html"),
GURL("http://example.alias2.com/allowed.html")},
0 /* explicitly_allow_count */,
2 /* allow_count */,
0 /* would_disallow_count */,
0 /* disallow_count */},
{mojom::ActivationLevel::kEnabled,
{GURL("http://example.alias1.com/disallowed.html"),
GURL("http://example.alias2.com/disallowed.html")},
0 /* explicitly_allow_count */,
0 /* allow_count */,
0 /* would_disallow_count */,
2 /* disallow_count */},
{mojom::ActivationLevel::kDryRun,
{GURL("http://example.alias1.com/disallowed.html"),
GURL("http://example.alias2.com/disallowed.html")},
0 /* explicitly_allow_count */,
0 /* allow_count */,
2 /* would_disallow_count */,
0 /* disallow_count */},
{mojom::ActivationLevel::kEnabled,
{GURL("http://test.alias1.com/disallowed.html"),
GURL("http://test.alias2.com/allowed.html"),
GURL("http://test.alias3.com/disallowed.html"),
GURL("http://test.alias4.com/disallowed.html")},
0 /* explicitly_allow_count */,
1 /* allow_count */,
0 /* would_disallow_count */,
3 /* disallow_count */},
{mojom::ActivationLevel::kDryRun,
{GURL("http://test.alias1.com/disallowed.html"),
GURL("http://test.alias2.com/allowed.html"),
GURL("http://test.alias3.com/disallowed.html"),
GURL("http://test.alias4.com/disallowed.html")},
0 /* explicitly_allow_count */,
1 /* allow_count */,
3 /* would_disallow_count */,
0 /* disallow_count */}};
for (const auto& test : kTestCases) {
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://example.com"), test.activation_level,
false /* measure_performance */);
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
base::RunLoop run_loop;
MultiLoadPolicyCallbackReceiver load_policy;
load_policy.SetQuitClosure(run_loop.QuitClosure());
filter->GetLoadPolicyForSubdocumentURLs(test.urls,
load_policy.GetCallback());
RunBlockingTasks();
run_loop.Run();
EXPECT_EQ(test.explicitly_allow_count,
load_policy.explicitly_allow_count());
EXPECT_EQ(test.allow_count, load_policy.allow_count());
EXPECT_EQ(test.would_disallow_count, load_policy.would_disallow_count());
EXPECT_EQ(test.disallow_count, load_policy.disallow_count());
}
}
TEST_F(AsyncDocumentSubresourceFilterTest, FirstDisallowedLoadIsReported) {
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
TestCallbackReceiver first_disallowed_load_receiver;
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://example.com"), mojom::ActivationLevel::kEnabled, false);
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
filter->set_first_disallowed_load_callback(
first_disallowed_load_receiver.GetClosure());
LoadPolicyCallbackReceiver load_policy_1;
filter->GetLoadPolicyForSubdocument(GURL("http://example.com/allowed.html"),
load_policy_1.GetCallback());
RunUntilIdle();
load_policy_1.ExpectReceivedOnce(LoadPolicy::ALLOW);
EXPECT_EQ(0, first_disallowed_load_receiver.callback_count());
LoadPolicyCallbackReceiver load_policy_2;
filter->GetLoadPolicyForSubdocument(
GURL("http://example.com/disallowed.html"), load_policy_2.GetCallback());
RunUntilIdle();
load_policy_2.ExpectReceivedOnce(LoadPolicy::DISALLOW);
EXPECT_EQ(0, first_disallowed_load_receiver.callback_count());
filter->ReportDisallowedLoad();
EXPECT_EQ(1, first_disallowed_load_receiver.callback_count());
RunUntilIdle();
}
TEST_F(AsyncDocumentSubresourceFilterTest, UpdateActivationState) {
// Properly initilize the ruleset and handle to use for computations.
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
// Initialize |filter| with a starting mojom::ActivationLevel of DRYRUN. This
// value will be updated later on.
AsyncDocumentSubresourceFilter::InitializationParams params(
GURL("http://example.com"), mojom::ActivationLevel::kDryRun, false);
testing::TestActivationStateCallbackReceiver activation_state;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), std::move(params), activation_state.GetCallback(),
kSafeBrowsingRulesetConfig.uma_tag);
// Make sure the ADSF computes its initial activation before updating it.
RunUntilIdle();
mojom::ActivationState dry_run_state;
dry_run_state.activation_level = mojom::ActivationLevel::kDryRun;
activation_state.ExpectReceivedOnce(dry_run_state);
// Update the mojom::ActivationState before calling
// GetLoadPolicyForSubdocument.
mojom::ActivationState enabled_state;
enabled_state.activation_level = mojom::ActivationLevel::kEnabled;
filter->UpdateWithMoreAccurateState(enabled_state);
LoadPolicyCallbackReceiver load_policy_1;
filter->GetLoadPolicyForSubdocument(GURL("http://example.com/allowed.html"),
load_policy_1.GetCallback());
RunUntilIdle();
load_policy_1.ExpectReceivedOnce(LoadPolicy::ALLOW);
LoadPolicyCallbackReceiver load_policy_2;
filter->GetLoadPolicyForSubdocument(
GURL("http://example.com/disallowed.html"), load_policy_2.GetCallback());
RunUntilIdle();
load_policy_2.ExpectReceivedOnce(LoadPolicy::DISALLOW);
}
// Tests the second constructor.
TEST_F(AsyncDocumentSubresourceFilterTest,
ActivationStateProvided_ActivationStateImmediatelyAvailable) {
dealer_handle()->TryOpenAndSetRulesetFile(
ruleset().path, /*expected_checksum=*/0, base::DoNothing());
auto ruleset_handle = CreateRulesetHandle();
mojom::ActivationState provided_state;
provided_state.activation_level = mojom::ActivationLevel::kEnabled;
auto filter = std::make_unique<AsyncDocumentSubresourceFilter>(
ruleset_handle.get(), url::Origin::Create(GURL("http://example.com")),
provided_state, kSafeBrowsingRulesetConfig.uma_tag);
EXPECT_TRUE(filter->has_activation_state());
EXPECT_EQ(provided_state.activation_level,
filter->activation_state().activation_level);
// Ensure the activation is not overwritten.
RunUntilIdle();
EXPECT_TRUE(filter->has_activation_state());
EXPECT_EQ(provided_state.activation_level,
filter->activation_state().activation_level);
}
// Tests for ComputeActivationState:
class SubresourceFilterComputeActivationStateTest : public ::testing::Test {
public:
SubresourceFilterComputeActivationStateTest() = default;
SubresourceFilterComputeActivationStateTest(
const SubresourceFilterComputeActivationStateTest&) = delete;
SubresourceFilterComputeActivationStateTest& operator=(
const SubresourceFilterComputeActivationStateTest&) = delete;
protected:
void SetUp() override {
constexpr int32_t kDocument = proto::ACTIVATION_TYPE_DOCUMENT;
constexpr int32_t kGenericBlock = proto::ACTIVATION_TYPE_GENERICBLOCK;
std::vector<proto::UrlRule> rules;
rules.push_back(testing::CreateAllowlistRuleForDocument(
"child1.com", kDocument, {"parent1.com", "parent2.com"}));
rules.push_back(testing::CreateAllowlistRuleForDocument(
"child2.com", kGenericBlock, {"parent1.com", "parent2.com"}));
rules.push_back(testing::CreateAllowlistRuleForDocument(
"child3.com", kDocument | kGenericBlock,
{"parent1.com", "parent2.com"}));
testing::TestRulesetPair test_ruleset_pair;
ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules(
rules, &test_ruleset_pair));
ruleset_ = MemoryMappedRuleset::CreateAndInitialize(
testing::TestRuleset::Open(test_ruleset_pair.indexed));
}
static mojom::ActivationState MakeState(
bool filtering_disabled_for_document,
bool generic_blocking_rules_disabled = false,
mojom::ActivationLevel activation_level =
mojom::ActivationLevel::kEnabled) {
mojom::ActivationState activation_state;
activation_state.activation_level = activation_level;
activation_state.filtering_disabled_for_document =
filtering_disabled_for_document;
activation_state.generic_blocking_rules_disabled =
generic_blocking_rules_disabled;
return activation_state;
}
const MemoryMappedRuleset* ruleset() { return ruleset_.get(); }
private:
testing::TestRulesetCreator test_ruleset_creator_;
scoped_refptr<const MemoryMappedRuleset> ruleset_;
};
TEST_F(SubresourceFilterComputeActivationStateTest,
ActivationBitsCorrectlyPropagateToChildDocument) {
// TODO(pkalinnikov): Find a short way to express all these tests.
struct TestCases {
const char* document_url;
const char* parent_document_origin;
mojom::ActivationState parent_activation;
mojom::ActivationState expected_activation_state;
};
const auto kTestCases = std::to_array<TestCases>({
{"http://example.com", "http://example.com", MakeState(false, false),
MakeState(false, false)},
{"http://example.com", "http://example.com", MakeState(false, true),
MakeState(false, true)},
{"http://example.com", "http://example.com", MakeState(true, false),
MakeState(true)},
{"http://example.com", "http://example.com", MakeState(true, true),
MakeState(true, true)},
{"http://child1.com", "http://parrrrent1.com", MakeState(false, false),
MakeState(false, false)},
{"http://child1.com", "http://parent1.com", MakeState(false, false),
MakeState(true, false)},
{"http://child1.com", "http://parent2.com", MakeState(false, false),
MakeState(true, false)},
{"http://child1.com", "http://parent2.com", MakeState(true, false),
MakeState(true)},
{"http://child1.com", "http://parent2.com", MakeState(false, true),
MakeState(true, true)},
{"http://child2.com", "http://parent1.com", MakeState(false, false),
MakeState(false, true)},
{"http://child2.com", "http://parent1.com", MakeState(false, true),
MakeState(false, true)},
{"http://child2.com", "http://parent1.com", MakeState(true, false),
MakeState(true)},
{"http://child2.com", "http://parent1.com", MakeState(true, true),
MakeState(true, true)},
{"http://child3.com", "http://parent1.com", MakeState(false, false),
MakeState(true)},
{"http://child3.com", "http://parent1.com", MakeState(false, true),
MakeState(true, true)},
{"http://child3.com", "http://parent1.com", MakeState(true, false),
MakeState(true)},
{"http://child3.com", "http://parent1.com", MakeState(true, true),
MakeState(true, true)},
});
for (size_t i = 0, size = std::size(kTestCases); i != size; ++i) {
SCOPED_TRACE(::testing::Message() << "Test number: " << i);
const auto& test_case = kTestCases[i];
GURL document_url(test_case.document_url);
url::Origin parent_document_origin =
url::Origin::Create(GURL(test_case.parent_document_origin));
mojom::ActivationState activation_state =
ComputeActivationState(document_url, parent_document_origin,
test_case.parent_activation, ruleset());
EXPECT_TRUE(test_case.expected_activation_state.Equals(activation_state))
<< activation_state.filtering_disabled_for_document << " "
<< activation_state.generic_blocking_rules_disabled;
}
}
} // namespace subresource_filter