blob: e598f8ab635d7b2f52bdebc1e878f3681113060b [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/declarative_content/content_condition.h"
#include <vector>
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "extensions/buildflags/buildflags.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
namespace extensions {
namespace {
class TestPredicate : public ContentPredicate {
public:
TestPredicate() = default;
TestPredicate(const TestPredicate&) = delete;
TestPredicate& operator=(const TestPredicate&) = delete;
ContentPredicateEvaluator* GetEvaluator() const override {
return nullptr;
}
};
class TestPredicateFactoryGeneratingError : public ContentPredicateFactory {
public:
explicit TestPredicateFactoryGeneratingError(const std::string& error)
: error_(error) {
}
TestPredicateFactoryGeneratingError(
const TestPredicateFactoryGeneratingError&) = delete;
TestPredicateFactoryGeneratingError& operator=(
const TestPredicateFactoryGeneratingError&) = delete;
std::unique_ptr<const ContentPredicate> CreatePredicate(
const Extension* extension,
const base::Value& value,
std::string* error) override {
*error = error_;
return nullptr;
}
private:
const std::string error_;
};
class TestPredicateFactoryGeneratingPredicate : public ContentPredicateFactory {
public:
TestPredicateFactoryGeneratingPredicate() = default;
TestPredicateFactoryGeneratingPredicate(
const TestPredicateFactoryGeneratingPredicate&) = delete;
TestPredicateFactoryGeneratingPredicate& operator=(
const TestPredicateFactoryGeneratingPredicate&) = delete;
std::unique_ptr<const ContentPredicate> CreatePredicate(
const Extension* extension,
const base::Value& value,
std::string* error) override {
std::unique_ptr<const ContentPredicate> predicate(new TestPredicate);
created_predicates_.push_back(predicate.get());
return predicate;
}
const std::vector<raw_ptr<const ContentPredicate, VectorExperimental>>&
created_predicates() const {
return created_predicates_;
}
private:
std::vector<raw_ptr<const ContentPredicate, VectorExperimental>>
created_predicates_;
};
} // namespace
using testing::HasSubstr;
using testing::UnorderedElementsAre;
TEST(DeclarativeContentConditionTest, UnknownPredicateName) {
std::string error;
std::unique_ptr<ContentCondition> condition = CreateContentCondition(
nullptr, std::map<std::string, ContentPredicateFactory*>(),
base::test::ParseJson(R"({
"invalid": "foobar",
"instanceType": "declarativeContent.PageStateMatcher",
})"),
&error);
EXPECT_THAT(error, HasSubstr("Unknown condition attribute"));
EXPECT_FALSE(condition);
}
TEST(DeclarativeContentConditionTest,
PredicateWithErrorProducesEmptyCondition) {
TestPredicateFactoryGeneratingError factory("error message");
std::map<std::string, ContentPredicateFactory*> predicate_factories;
predicate_factories["test_predicate"] = &factory;
std::string error;
std::unique_ptr<ContentCondition> condition = CreateContentCondition(
nullptr, predicate_factories, base::test::ParseJson(R"({
"test_predicate": "",
"instanceType": "declarativeContent.PageStateMatcher",
})"),
&error);
EXPECT_EQ("error message", error);
EXPECT_FALSE(condition);
}
TEST(DeclarativeContentConditionTest, AllSpecifiedPredicatesCreated) {
TestPredicateFactoryGeneratingPredicate factory1, factory2;
std::map<std::string, ContentPredicateFactory*> predicate_factories;
predicate_factories["test_predicate1"] = &factory1;
predicate_factories["test_predicate2"] = &factory2;
std::string error;
std::unique_ptr<ContentCondition> condition = CreateContentCondition(
nullptr, predicate_factories, base::test::ParseJson(R"({
"test_predicate1": {},
"test_predicate2": [],
"instanceType": "declarativeContent.PageStateMatcher",
})"),
&error);
ASSERT_TRUE(condition);
ASSERT_EQ(1u, factory1.created_predicates().size());
ASSERT_EQ(1u, factory2.created_predicates().size());
std::vector<const ContentPredicate*> predicates;
for (const auto& predicate : condition->predicates)
predicates.push_back(predicate.get());
EXPECT_THAT(predicates,
UnorderedElementsAre(factory1.created_predicates()[0],
factory2.created_predicates()[0]));
}
} // namespace extensions