| // 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 |