blob: ec327a42179c3ec3459cc17885a16500ee8df805 [file] [log] [blame]
// Copyright (c) 2012 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 "extensions/browser/api/declarative/rules_registry_service.h"
#include <stddef.h>
#include <utility>
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
#include "chrome/test/base/testing_profile.h"
#include "components/version_info/channel.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/api/declarative/test_rules_registry.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
#include "extensions/common/api/declarative/declarative_constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_channel.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/value_builder.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kExtensionId[] = "foo";
void InsertRule(scoped_refptr<extensions::RulesRegistry> registry,
const std::string& id) {
std::vector<extensions::api::events::Rule> add_rules;
add_rules.emplace_back();
add_rules[0].id.reset(new std::string(id));
std::string error = registry->AddRules(kExtensionId, std::move(add_rules));
EXPECT_TRUE(error.empty());
}
void VerifyNumberOfRules(scoped_refptr<extensions::RulesRegistry> registry,
size_t expected_number_of_rules) {
std::vector<const extensions::api::events::Rule*> get_rules;
registry->GetAllRules(kExtensionId, &get_rules);
EXPECT_EQ(expected_number_of_rules, get_rules.size());
}
} // namespace
namespace extensions {
class RulesRegistryServiceTest : public testing::Test {
public:
RulesRegistryServiceTest() = default;
~RulesRegistryServiceTest() override {}
void TearDown() override {
// Make sure that deletion traits of all registries are executed.
base::RunLoop().RunUntilIdle();
}
protected:
content::TestBrowserThreadBundle test_browser_thread_bundle_;
};
TEST_F(RulesRegistryServiceTest, TestConstructionAndMultiThreading) {
RulesRegistryService registry_service(NULL);
int key = RulesRegistryService::kDefaultRulesRegistryID;
TestRulesRegistry* ui_registry =
new TestRulesRegistry(content::BrowserThread::UI, "ui", key);
TestRulesRegistry* io_registry =
new TestRulesRegistry(content::BrowserThread::IO, "io", key);
// Test registration.
registry_service.RegisterRulesRegistry(base::WrapRefCounted(ui_registry));
registry_service.RegisterRulesRegistry(base::WrapRefCounted(io_registry));
EXPECT_TRUE(registry_service.GetRulesRegistry(key, "ui").get());
EXPECT_TRUE(registry_service.GetRulesRegistry(key, "io").get());
EXPECT_FALSE(registry_service.GetRulesRegistry(key, "foo").get());
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&InsertRule, registry_service.GetRulesRegistry(key, "ui"),
"ui_task"));
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&InsertRule, registry_service.GetRulesRegistry(key, "io"),
"io_task"));
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&VerifyNumberOfRules,
registry_service.GetRulesRegistry(key, "ui"), 1));
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&VerifyNumberOfRules,
registry_service.GetRulesRegistry(key, "io"), 1));
base::RunLoop().RunUntilIdle();
// Test extension uninstalling.
std::unique_ptr<base::DictionaryValue> manifest =
DictionaryBuilder()
.Set("name", "Extension")
.Set("version", "1.0")
.Set("manifest_version", 2)
.Build();
scoped_refptr<const Extension> extension =
ExtensionBuilder()
.SetManifest(std::move(manifest))
.SetID(kExtensionId)
.Build();
registry_service.SimulateExtensionUninstalled(extension.get());
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&VerifyNumberOfRules,
registry_service.GetRulesRegistry(key, "ui"), 0));
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&VerifyNumberOfRules,
registry_service.GetRulesRegistry(key, "io"), 0));
base::RunLoop().RunUntilIdle();
}
TEST_F(RulesRegistryServiceTest, DefaultRulesRegistryRegistered) {
struct {
version_info::Channel channel;
bool expect_api_enabled;
} test_cases[] = {
{version_info::Channel::UNKNOWN, true},
{version_info::Channel::STABLE, false},
};
for (const auto& test_case : test_cases) {
SCOPED_TRACE(base::StringPrintf(
"Testing Channel %s",
version_info::GetChannelString(test_case.channel).c_str()));
ScopedCurrentChannel scoped_channel(test_case.channel);
ASSERT_EQ(test_case.expect_api_enabled,
FeatureProvider::GetAPIFeature("declarativeWebRequest")
->IsAvailableToEnvironment()
.is_available());
TestingProfile profile;
RulesRegistryService registry_service(&profile);
// The default web request rules registry should only be created if the API
// is enabled.
EXPECT_EQ(
test_case.expect_api_enabled,
registry_service
.GetRulesRegistry(RulesRegistryService::kDefaultRulesRegistryID,
declarative_webrequest_constants::kOnRequest)
.get() != nullptr);
// Content rules registry should always be created.
EXPECT_TRUE(registry_service.GetRulesRegistry(
RulesRegistryService::kDefaultRulesRegistryID,
declarative_content_constants::kOnPageChanged));
EXPECT_TRUE(registry_service.content_rules_registry());
// Rules registries for web views should always be created.
const int kWebViewRulesRegistryID = 1;
EXPECT_TRUE(registry_service.GetRulesRegistry(
kWebViewRulesRegistryID, declarative_webrequest_constants::kOnRequest));
}
}
} // namespace extensions