Index: extensions/common/features/base_feature_provider_unittest.cc |
diff --git a/extensions/common/features/base_feature_provider_unittest.cc b/extensions/common/features/base_feature_provider_unittest.cc |
index 28c8dedad51ae4436930e1482ffe9605e0c13ba2..974ee76f711952858b457450b104e9ef40150752 100644 |
--- a/extensions/common/features/base_feature_provider_unittest.cc |
+++ b/extensions/common/features/base_feature_provider_unittest.cc |
@@ -4,209 +4,135 @@ |
#include "extensions/common/features/base_feature_provider.h" |
-#include "chrome/common/extensions/features/chrome_channel_feature_filter.h" |
-#include "chrome/common/extensions/features/feature_channel.h" |
-#include "extensions/common/features/permission_feature.h" |
+#include <set> |
+#include <string> |
+ |
+#include "extensions/common/extension_builder.h" |
+#include "extensions/common/features/feature.h" |
+#include "extensions/common/features/simple_feature.h" |
+#include "extensions/common/manifest.h" |
#include "extensions/common/value_builder.h" |
#include "testing/gtest/include/gtest/gtest.h" |
-using chrome::VersionInfo; |
- |
namespace extensions { |
-namespace { |
- |
-template <class FeatureClass> |
-SimpleFeature* CreateFeature() { |
- SimpleFeature* feature = new FeatureClass(); |
- feature->AddFilter( |
- scoped_ptr<SimpleFeatureFilter>(new ChromeChannelFeatureFilter(feature))); |
- return feature; |
-} |
- |
-} // namespace |
- |
-TEST(BaseFeatureProviderTest, ManifestFeatures) { |
+// Tests that a real manifest feature is available for the correct types of |
+// extensions and apps. |
+TEST(BaseFeatureProviderTest, ManifestFeatureTypes) { |
const FeatureProvider* provider = BaseFeatureProvider::GetByName("manifest"); |
+ // NOTE: This feature cannot have multiple rules, otherwise it is not a |
+ // SimpleFeature. |
SimpleFeature* feature = |
static_cast<SimpleFeature*>(provider->GetFeature("description")); |
ASSERT_TRUE(feature); |
- EXPECT_EQ(6u, feature->extension_types()->size()); |
- EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_EXTENSION)); |
- EXPECT_EQ(1u, |
- feature->extension_types()->count(Manifest::TYPE_LEGACY_PACKAGED_APP)); |
- EXPECT_EQ(1u, |
- feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP)); |
- EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_HOSTED_APP)); |
- EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_THEME)); |
- EXPECT_EQ(1u, |
- feature->extension_types()->count(Manifest::TYPE_SHARED_MODULE)); |
- |
- base::DictionaryValue manifest; |
- manifest.SetString("name", "test extension"); |
- manifest.SetString("version", "1"); |
- manifest.SetString("description", "hello there"); |
- |
- std::string error; |
- scoped_refptr<const Extension> extension(Extension::Create( |
- base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS, |
- &error)); |
+ std::set<Manifest::Type>* extension_types = feature->extension_types(); |
+ EXPECT_EQ(6u, extension_types->size()); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_EXTENSION)); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_LEGACY_PACKAGED_APP)); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_PLATFORM_APP)); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_HOSTED_APP)); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_THEME)); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_SHARED_MODULE)); |
+} |
+ |
+// Tests that real manifest features have the correct availability for an |
+// extension. |
+TEST(BaseFeatureProviderTest, ManifestFeatureAvailability) { |
James Cook
2014/09/11 23:32:31
The important changes here are switching to descri
|
+ const FeatureProvider* provider = BaseFeatureProvider::GetByName("manifest"); |
+ scoped_refptr<const Extension> extension = |
+ ExtensionBuilder() |
+ .SetManifest(DictionaryBuilder() |
+ .Set("name", "test extension") |
+ .Set("version", "1") |
+ .Set("description", "hello there")) |
+ .Build(); |
ASSERT_TRUE(extension.get()); |
- EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToContext( |
- extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); |
- feature = |
- static_cast<SimpleFeature*>(provider->GetFeature("theme")); |
+ Feature* feature = provider->GetFeature("description"); |
+ EXPECT_EQ(Feature::IS_AVAILABLE, |
+ feature->IsAvailableToContext(extension.get(), |
+ Feature::UNSPECIFIED_CONTEXT, |
+ GURL()).result()); |
+ |
+ // This is a generic extension, so an app-only feature isn't allowed. |
+ feature = provider->GetFeature("app.background"); |
ASSERT_TRUE(feature); |
- EXPECT_EQ(Feature::INVALID_TYPE, feature->IsAvailableToContext( |
- extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); |
+ EXPECT_EQ(Feature::INVALID_TYPE, |
+ feature->IsAvailableToContext(extension.get(), |
+ Feature::UNSPECIFIED_CONTEXT, |
+ GURL()).result()); |
- feature = |
- static_cast<SimpleFeature*>(provider->GetFeature("devtools_page")); |
+ // A feature not listed in the manifest isn't allowed. |
+ feature = provider->GetFeature("background"); |
ASSERT_TRUE(feature); |
- EXPECT_EQ(Feature::NOT_PRESENT, feature->IsAvailableToContext( |
- extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); |
+ EXPECT_EQ(Feature::NOT_PRESENT, |
+ feature->IsAvailableToContext(extension.get(), |
+ Feature::UNSPECIFIED_CONTEXT, |
+ GURL()).result()); |
} |
-TEST(BaseFeatureProviderTest, PermissionFeatures) { |
+// Tests that a real permission feature is available for the correct types of |
+// extensions and apps. |
+TEST(BaseFeatureProviderTest, PermissionFeatureTypes) { |
const FeatureProvider* provider = |
BaseFeatureProvider::GetByName("permission"); |
+ // NOTE: This feature cannot have multiple rules, otherwise it is not a |
+ // SimpleFeature. |
SimpleFeature* feature = |
- static_cast<SimpleFeature*>(provider->GetFeature("contextMenus")); |
+ static_cast<SimpleFeature*>(provider->GetFeature("power")); |
ASSERT_TRUE(feature); |
- EXPECT_EQ(3u, feature->extension_types()->size()); |
- EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_EXTENSION)); |
- EXPECT_EQ(1u, |
- feature->extension_types()->count(Manifest::TYPE_LEGACY_PACKAGED_APP)); |
- EXPECT_EQ(1u, |
- feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP)); |
- |
- base::DictionaryValue manifest; |
- manifest.SetString("name", "test extension"); |
- manifest.SetString("version", "1"); |
- base::ListValue* permissions = new base::ListValue(); |
- manifest.Set("permissions", permissions); |
- permissions->Append(new base::StringValue("contextMenus")); |
- |
- std::string error; |
- scoped_refptr<const Extension> extension(Extension::Create( |
- base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS, |
- &error)); |
+ std::set<Manifest::Type>* extension_types = feature->extension_types(); |
+ EXPECT_EQ(3u, extension_types->size()); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_EXTENSION)); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_LEGACY_PACKAGED_APP)); |
+ EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_PLATFORM_APP)); |
+} |
- ASSERT_TRUE(extension.get()); |
- EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToContext( |
- extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); |
+// Tests that real permission features have the correct availability for an app. |
+TEST(BaseFeatureProviderTest, PermissionFeatureAvailability) { |
James Cook
2014/09/11 23:32:31
Same thing here:
* SimpleFeature -> Feature
* cont
|
+ const FeatureProvider* provider = |
+ BaseFeatureProvider::GetByName("permission"); |
- feature = |
- static_cast<SimpleFeature*>(provider->GetFeature("chromePrivate")); |
+ scoped_refptr<const Extension> app = |
+ ExtensionBuilder() |
+ .SetManifest(DictionaryBuilder() |
+ .Set("name", "test app") |
+ .Set("version", "1") |
+ .Set("app", |
+ DictionaryBuilder().Set( |
+ "background", |
+ DictionaryBuilder().Set( |
+ "scripts", |
+ ListBuilder().Append("background.js")))) |
+ .Set("permissions", ListBuilder().Append("power"))) |
+ .Build(); |
+ ASSERT_TRUE(app.get()); |
+ ASSERT_TRUE(app->is_platform_app()); |
+ |
+ // A permission requested in the manifest is available. |
+ Feature* feature = provider->GetFeature("power"); |
+ EXPECT_EQ( |
+ Feature::IS_AVAILABLE, |
+ feature->IsAvailableToContext( |
+ app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result()); |
+ |
+ // A permission only available to whitelisted extensions returns availability |
+ // NOT_FOUND_IN_WHITELIST. |
+ feature = provider->GetFeature("bluetoothPrivate"); |
ASSERT_TRUE(feature); |
- EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature->IsAvailableToContext( |
- extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); |
+ EXPECT_EQ( |
+ Feature::NOT_FOUND_IN_WHITELIST, |
+ feature->IsAvailableToContext( |
+ app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result()); |
- feature = |
- static_cast<SimpleFeature*>(provider->GetFeature("clipboardWrite")); |
+ // A permission that isn't part of the manifest returns NOT_PRESENT. |
+ feature = provider->GetFeature("serial"); |
ASSERT_TRUE(feature); |
- EXPECT_EQ(Feature::NOT_PRESENT, feature->IsAvailableToContext( |
- extension.get(), Feature::UNSPECIFIED_CONTEXT).result()); |
-} |
- |
-TEST(BaseFeatureProviderTest, Validation) { |
- scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); |
- |
- base::DictionaryValue* feature1 = new base::DictionaryValue(); |
- feature1->SetString("channel", "trunk"); |
- value->Set("feature1", feature1); |
- |
- base::DictionaryValue* feature2 = new base::DictionaryValue(); |
- feature2->SetString("channel", "trunk"); |
- base::ListValue* extension_types = new base::ListValue(); |
- extension_types->Append(new base::StringValue("extension")); |
- feature2->Set("extension_types", extension_types); |
- base::ListValue* contexts = new base::ListValue(); |
- contexts->Append(new base::StringValue("blessed_extension")); |
- feature2->Set("contexts", contexts); |
- value->Set("feature2", feature2); |
- |
- scoped_ptr<BaseFeatureProvider> provider( |
- new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>)); |
- |
- // feature1 won't validate because it lacks an extension type. |
- EXPECT_FALSE(provider->GetFeature("feature1")); |
- |
- // If we add one, it works. |
- feature1->Set("extension_types", extension_types->DeepCopy()); |
- provider.reset( |
- new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>)); |
- EXPECT_TRUE(provider->GetFeature("feature1")); |
- |
- // Remove the channel, and feature1 won't validate. |
- feature1->Remove("channel", NULL); |
- provider.reset( |
- new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>)); |
- EXPECT_FALSE(provider->GetFeature("feature1")); |
- |
- // feature2 won't validate because of the presence of "contexts". |
- EXPECT_FALSE(provider->GetFeature("feature2")); |
- |
- // If we remove it, it works. |
- feature2->Remove("contexts", NULL); |
- provider.reset( |
- new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>)); |
- EXPECT_TRUE(provider->GetFeature("feature2")); |
-} |
- |
-TEST(BaseFeatureProviderTest, ComplexFeatures) { |
- scoped_ptr<base::DictionaryValue> rule( |
- DictionaryBuilder() |
- .Set("feature1", ListBuilder() |
- .Append(DictionaryBuilder() |
- .Set("channel", "beta") |
- .Set("extension_types", ListBuilder() |
- .Append("extension"))) |
- .Append(DictionaryBuilder() |
- .Set("channel", "beta") |
- .Set("extension_types", ListBuilder() |
- .Append("legacy_packaged_app")))) |
- .Build()); |
- |
- scoped_ptr<BaseFeatureProvider> provider( |
- new BaseFeatureProvider(*rule, CreateFeature<SimpleFeature>)); |
- |
- Feature* feature = provider->GetFeature("feature1"); |
- EXPECT_TRUE(feature); |
- |
- // Make sure both rules are applied correctly. |
- { |
- ScopedCurrentChannel current_channel(VersionInfo::CHANNEL_BETA); |
- EXPECT_EQ( |
- Feature::IS_AVAILABLE, |
- feature->IsAvailableToManifest("1", |
- Manifest::TYPE_EXTENSION, |
- Manifest::INVALID_LOCATION, |
- Feature::UNSPECIFIED_PLATFORM).result()); |
- EXPECT_EQ( |
- Feature::IS_AVAILABLE, |
- feature->IsAvailableToManifest("2", |
- Manifest::TYPE_LEGACY_PACKAGED_APP, |
- Manifest::INVALID_LOCATION, |
- Feature::UNSPECIFIED_PLATFORM).result()); |
- } |
- { |
- ScopedCurrentChannel current_channel(VersionInfo::CHANNEL_STABLE); |
- EXPECT_NE( |
- Feature::IS_AVAILABLE, |
- feature->IsAvailableToManifest("1", |
- Manifest::TYPE_EXTENSION, |
- Manifest::INVALID_LOCATION, |
- Feature::UNSPECIFIED_PLATFORM).result()); |
- EXPECT_NE( |
- Feature::IS_AVAILABLE, |
- feature->IsAvailableToManifest("2", |
- Manifest::TYPE_LEGACY_PACKAGED_APP, |
- Manifest::INVALID_LOCATION, |
- Feature::UNSPECIFIED_PLATFORM).result()); |
- } |
+ EXPECT_EQ( |
+ Feature::NOT_PRESENT, |
+ feature->IsAvailableToContext( |
+ app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result()); |
} |
} // namespace extensions |