1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/extensions/features/base_feature_provider.h"
7 #include "chrome/common/extensions/features/feature_channel.h"
8 #include "chrome/common/extensions/features/permission_feature.h"
9 #include "extensions/common/value_builder.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using chrome::VersionInfo
;
14 namespace extensions
{
16 TEST(BaseFeatureProviderTest
, ManifestFeatures
) {
17 FeatureProvider
* provider
= BaseFeatureProvider::GetByName("manifest");
18 SimpleFeature
* feature
=
19 static_cast<SimpleFeature
*>(provider
->GetFeature("description"));
21 EXPECT_EQ(6u, feature
->extension_types()->size());
22 EXPECT_EQ(1u, feature
->extension_types()->count(Manifest::TYPE_EXTENSION
));
24 feature
->extension_types()->count(Manifest::TYPE_LEGACY_PACKAGED_APP
));
26 feature
->extension_types()->count(Manifest::TYPE_PLATFORM_APP
));
27 EXPECT_EQ(1u, feature
->extension_types()->count(Manifest::TYPE_HOSTED_APP
));
28 EXPECT_EQ(1u, feature
->extension_types()->count(Manifest::TYPE_THEME
));
30 feature
->extension_types()->count(Manifest::TYPE_SHARED_MODULE
));
32 base::DictionaryValue manifest
;
33 manifest
.SetString("name", "test extension");
34 manifest
.SetString("version", "1");
35 manifest
.SetString("description", "hello there");
38 scoped_refptr
<const Extension
> extension(Extension::Create(
39 base::FilePath(), Manifest::INTERNAL
, manifest
, Extension::NO_FLAGS
,
42 ASSERT_TRUE(extension
.get());
43 EXPECT_EQ(Feature::IS_AVAILABLE
, feature
->IsAvailableToContext(
44 extension
.get(), Feature::UNSPECIFIED_CONTEXT
).result());
47 static_cast<SimpleFeature
*>(provider
->GetFeature("theme"));
49 EXPECT_EQ(Feature::INVALID_TYPE
, feature
->IsAvailableToContext(
50 extension
.get(), Feature::UNSPECIFIED_CONTEXT
).result());
53 static_cast<SimpleFeature
*>(provider
->GetFeature("devtools_page"));
55 EXPECT_EQ(Feature::NOT_PRESENT
, feature
->IsAvailableToContext(
56 extension
.get(), Feature::UNSPECIFIED_CONTEXT
).result());
59 TEST(BaseFeatureProviderTest
, PermissionFeatures
) {
60 FeatureProvider
* provider
= BaseFeatureProvider::GetByName("permission");
61 SimpleFeature
* feature
=
62 static_cast<SimpleFeature
*>(provider
->GetFeature("contextMenus"));
64 EXPECT_EQ(3u, feature
->extension_types()->size());
65 EXPECT_EQ(1u, feature
->extension_types()->count(Manifest::TYPE_EXTENSION
));
67 feature
->extension_types()->count(Manifest::TYPE_LEGACY_PACKAGED_APP
));
69 feature
->extension_types()->count(Manifest::TYPE_PLATFORM_APP
));
71 base::DictionaryValue manifest
;
72 manifest
.SetString("name", "test extension");
73 manifest
.SetString("version", "1");
74 base::ListValue
* permissions
= new base::ListValue();
75 manifest
.Set("permissions", permissions
);
76 permissions
->Append(new base::StringValue("contextMenus"));
79 scoped_refptr
<const Extension
> extension(Extension::Create(
80 base::FilePath(), Manifest::INTERNAL
, manifest
, Extension::NO_FLAGS
,
83 ASSERT_TRUE(extension
.get());
84 EXPECT_EQ(Feature::IS_AVAILABLE
, feature
->IsAvailableToContext(
85 extension
.get(), Feature::UNSPECIFIED_CONTEXT
).result());
88 static_cast<SimpleFeature
*>(provider
->GetFeature("chromePrivate"));
90 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST
, feature
->IsAvailableToContext(
91 extension
.get(), Feature::UNSPECIFIED_CONTEXT
).result());
94 static_cast<SimpleFeature
*>(provider
->GetFeature("clipboardWrite"));
96 EXPECT_EQ(Feature::NOT_PRESENT
, feature
->IsAvailableToContext(
97 extension
.get(), Feature::UNSPECIFIED_CONTEXT
).result());
100 SimpleFeature
* CreatePermissionFeature() {
101 return new PermissionFeature();
104 TEST(BaseFeatureProviderTest
, Validation
) {
105 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
107 base::DictionaryValue
* feature1
= new base::DictionaryValue();
108 feature1
->SetString("channel", "trunk");
109 value
->Set("feature1", feature1
);
111 base::DictionaryValue
* feature2
= new base::DictionaryValue();
112 feature2
->SetString("channel", "trunk");
113 base::ListValue
* extension_types
= new base::ListValue();
114 extension_types
->Append(new base::StringValue("extension"));
115 feature2
->Set("extension_types", extension_types
);
116 base::ListValue
* contexts
= new base::ListValue();
117 contexts
->Append(new base::StringValue("blessed_extension"));
118 feature2
->Set("contexts", contexts
);
119 value
->Set("feature2", feature2
);
121 scoped_ptr
<BaseFeatureProvider
> provider(
122 new BaseFeatureProvider(*value
, CreatePermissionFeature
));
124 // feature1 won't validate because it lacks an extension type.
125 EXPECT_FALSE(provider
->GetFeature("feature1"));
127 // If we add one, it works.
128 feature1
->Set("extension_types", extension_types
->DeepCopy());
129 provider
.reset(new BaseFeatureProvider(*value
, CreatePermissionFeature
));
130 EXPECT_TRUE(provider
->GetFeature("feature1"));
132 // Remove the channel, and feature1 won't validate.
133 feature1
->Remove("channel", NULL
);
134 provider
.reset(new BaseFeatureProvider(*value
, CreatePermissionFeature
));
135 EXPECT_FALSE(provider
->GetFeature("feature1"));
137 // feature2 won't validate because of the presence of "contexts".
138 EXPECT_FALSE(provider
->GetFeature("feature2"));
140 // If we remove it, it works.
141 feature2
->Remove("contexts", NULL
);
142 provider
.reset(new BaseFeatureProvider(*value
, CreatePermissionFeature
));
143 EXPECT_TRUE(provider
->GetFeature("feature2"));
146 TEST(BaseFeatureProviderTest
, ComplexFeatures
) {
147 scoped_ptr
<base::DictionaryValue
> rule(
149 .Set("feature1", ListBuilder()
150 .Append(DictionaryBuilder()
151 .Set("channel", "beta")
152 .Set("extension_types", ListBuilder()
153 .Append("extension")))
154 .Append(DictionaryBuilder()
155 .Set("channel", "beta")
156 .Set("extension_types", ListBuilder()
157 .Append("legacy_packaged_app"))))
160 scoped_ptr
<BaseFeatureProvider
> provider(
161 new BaseFeatureProvider(*rule
, NULL
));
163 Feature
* feature
= provider
->GetFeature("feature1");
164 EXPECT_TRUE(feature
);
166 // Make sure both rules are applied correctly.
168 ScopedCurrentChannel
current_channel(VersionInfo::CHANNEL_BETA
);
169 EXPECT_EQ(Feature::IS_AVAILABLE
, feature
->IsAvailableToManifest(
171 Manifest::TYPE_EXTENSION
,
172 Feature::UNSPECIFIED_LOCATION
,
173 Feature::UNSPECIFIED_PLATFORM
).result());
174 EXPECT_EQ(Feature::IS_AVAILABLE
, feature
->IsAvailableToManifest(
176 Manifest::TYPE_LEGACY_PACKAGED_APP
,
177 Feature::UNSPECIFIED_LOCATION
,
178 Feature::UNSPECIFIED_PLATFORM
).result());
181 ScopedCurrentChannel
current_channel(VersionInfo::CHANNEL_STABLE
);
182 EXPECT_NE(Feature::IS_AVAILABLE
, feature
->IsAvailableToManifest(
184 Manifest::TYPE_EXTENSION
,
185 Feature::UNSPECIFIED_LOCATION
,
186 Feature::UNSPECIFIED_PLATFORM
).result());
187 EXPECT_NE(Feature::IS_AVAILABLE
, feature
->IsAvailableToManifest(
189 Manifest::TYPE_LEGACY_PACKAGED_APP
,
190 Feature::UNSPECIFIED_LOCATION
,
191 Feature::UNSPECIFIED_PLATFORM
).result());
195 } // namespace extensions