Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: extensions/common/features/base_feature_provider_unittest.cc

Issue 563923004: Move most extension feature unit tests to extensions_unittests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/common/features/base_feature_provider.h" 5 #include "extensions/common/features/base_feature_provider.h"
6 6
7 #include "chrome/common/extensions/features/chrome_channel_feature_filter.h" 7 #include <set>
8 #include "chrome/common/extensions/features/feature_channel.h" 8 #include <string>
9 #include "extensions/common/features/permission_feature.h" 9
10 #include "extensions/common/extension_builder.h"
11 #include "extensions/common/features/feature.h"
12 #include "extensions/common/features/simple_feature.h"
13 #include "extensions/common/manifest.h"
10 #include "extensions/common/value_builder.h" 14 #include "extensions/common/value_builder.h"
11 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
12 16
13 using chrome::VersionInfo;
14
15 namespace extensions { 17 namespace extensions {
16 18
17 namespace { 19 // Tests that a real manifest feature is available for the correct types of
18 20 // extensions and apps.
19 template <class FeatureClass> 21 TEST(BaseFeatureProviderTest, ManifestFeatureTypes) {
20 SimpleFeature* CreateFeature() {
21 SimpleFeature* feature = new FeatureClass();
22 feature->AddFilter(
23 scoped_ptr<SimpleFeatureFilter>(new ChromeChannelFeatureFilter(feature)));
24 return feature;
25 }
26
27 } // namespace
28
29 TEST(BaseFeatureProviderTest, ManifestFeatures) {
30 const FeatureProvider* provider = BaseFeatureProvider::GetByName("manifest"); 22 const FeatureProvider* provider = BaseFeatureProvider::GetByName("manifest");
23 // NOTE: This feature cannot have multiple rules, otherwise it is not a
24 // SimpleFeature.
31 SimpleFeature* feature = 25 SimpleFeature* feature =
32 static_cast<SimpleFeature*>(provider->GetFeature("description")); 26 static_cast<SimpleFeature*>(provider->GetFeature("description"));
33 ASSERT_TRUE(feature); 27 ASSERT_TRUE(feature);
34 EXPECT_EQ(6u, feature->extension_types()->size()); 28 std::set<Manifest::Type>* extension_types = feature->extension_types();
35 EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_EXTENSION)); 29 EXPECT_EQ(6u, extension_types->size());
36 EXPECT_EQ(1u, 30 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_EXTENSION));
37 feature->extension_types()->count(Manifest::TYPE_LEGACY_PACKAGED_APP)); 31 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_LEGACY_PACKAGED_APP));
38 EXPECT_EQ(1u, 32 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_PLATFORM_APP));
39 feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP)); 33 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_HOSTED_APP));
40 EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_HOSTED_APP)); 34 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_THEME));
41 EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_THEME)); 35 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_SHARED_MODULE));
42 EXPECT_EQ(1u,
43 feature->extension_types()->count(Manifest::TYPE_SHARED_MODULE));
44
45 base::DictionaryValue manifest;
46 manifest.SetString("name", "test extension");
47 manifest.SetString("version", "1");
48 manifest.SetString("description", "hello there");
49
50 std::string error;
51 scoped_refptr<const Extension> extension(Extension::Create(
52 base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS,
53 &error));
54
55 ASSERT_TRUE(extension.get());
56 EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToContext(
57 extension.get(), Feature::UNSPECIFIED_CONTEXT).result());
58
59 feature =
60 static_cast<SimpleFeature*>(provider->GetFeature("theme"));
61 ASSERT_TRUE(feature);
62 EXPECT_EQ(Feature::INVALID_TYPE, feature->IsAvailableToContext(
63 extension.get(), Feature::UNSPECIFIED_CONTEXT).result());
64
65 feature =
66 static_cast<SimpleFeature*>(provider->GetFeature("devtools_page"));
67 ASSERT_TRUE(feature);
68 EXPECT_EQ(Feature::NOT_PRESENT, feature->IsAvailableToContext(
69 extension.get(), Feature::UNSPECIFIED_CONTEXT).result());
70 } 36 }
71 37
72 TEST(BaseFeatureProviderTest, PermissionFeatures) { 38 // Tests that real manifest features have the correct availability for an
39 // extension.
40 TEST(BaseFeatureProviderTest, ManifestFeatureAvailability) {
James Cook 2014/09/11 23:32:31 The important changes here are switching to descri
41 const FeatureProvider* provider = BaseFeatureProvider::GetByName("manifest");
42
43 scoped_refptr<const Extension> extension =
44 ExtensionBuilder()
45 .SetManifest(DictionaryBuilder()
46 .Set("name", "test extension")
47 .Set("version", "1")
48 .Set("description", "hello there"))
49 .Build();
50 ASSERT_TRUE(extension.get());
51
52 Feature* feature = provider->GetFeature("description");
53 EXPECT_EQ(Feature::IS_AVAILABLE,
54 feature->IsAvailableToContext(extension.get(),
55 Feature::UNSPECIFIED_CONTEXT,
56 GURL()).result());
57
58 // This is a generic extension, so an app-only feature isn't allowed.
59 feature = provider->GetFeature("app.background");
60 ASSERT_TRUE(feature);
61 EXPECT_EQ(Feature::INVALID_TYPE,
62 feature->IsAvailableToContext(extension.get(),
63 Feature::UNSPECIFIED_CONTEXT,
64 GURL()).result());
65
66 // A feature not listed in the manifest isn't allowed.
67 feature = provider->GetFeature("background");
68 ASSERT_TRUE(feature);
69 EXPECT_EQ(Feature::NOT_PRESENT,
70 feature->IsAvailableToContext(extension.get(),
71 Feature::UNSPECIFIED_CONTEXT,
72 GURL()).result());
73 }
74
75 // Tests that a real permission feature is available for the correct types of
76 // extensions and apps.
77 TEST(BaseFeatureProviderTest, PermissionFeatureTypes) {
73 const FeatureProvider* provider = 78 const FeatureProvider* provider =
74 BaseFeatureProvider::GetByName("permission"); 79 BaseFeatureProvider::GetByName("permission");
80 // NOTE: This feature cannot have multiple rules, otherwise it is not a
81 // SimpleFeature.
75 SimpleFeature* feature = 82 SimpleFeature* feature =
76 static_cast<SimpleFeature*>(provider->GetFeature("contextMenus")); 83 static_cast<SimpleFeature*>(provider->GetFeature("power"));
77 ASSERT_TRUE(feature); 84 ASSERT_TRUE(feature);
78 EXPECT_EQ(3u, feature->extension_types()->size()); 85 std::set<Manifest::Type>* extension_types = feature->extension_types();
79 EXPECT_EQ(1u, feature->extension_types()->count(Manifest::TYPE_EXTENSION)); 86 EXPECT_EQ(3u, extension_types->size());
80 EXPECT_EQ(1u, 87 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_EXTENSION));
81 feature->extension_types()->count(Manifest::TYPE_LEGACY_PACKAGED_APP)); 88 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_LEGACY_PACKAGED_APP));
82 EXPECT_EQ(1u, 89 EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_PLATFORM_APP));
83 feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP));
84
85 base::DictionaryValue manifest;
86 manifest.SetString("name", "test extension");
87 manifest.SetString("version", "1");
88 base::ListValue* permissions = new base::ListValue();
89 manifest.Set("permissions", permissions);
90 permissions->Append(new base::StringValue("contextMenus"));
91
92 std::string error;
93 scoped_refptr<const Extension> extension(Extension::Create(
94 base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS,
95 &error));
96
97 ASSERT_TRUE(extension.get());
98 EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToContext(
99 extension.get(), Feature::UNSPECIFIED_CONTEXT).result());
100
101 feature =
102 static_cast<SimpleFeature*>(provider->GetFeature("chromePrivate"));
103 ASSERT_TRUE(feature);
104 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature->IsAvailableToContext(
105 extension.get(), Feature::UNSPECIFIED_CONTEXT).result());
106
107 feature =
108 static_cast<SimpleFeature*>(provider->GetFeature("clipboardWrite"));
109 ASSERT_TRUE(feature);
110 EXPECT_EQ(Feature::NOT_PRESENT, feature->IsAvailableToContext(
111 extension.get(), Feature::UNSPECIFIED_CONTEXT).result());
112 } 90 }
113 91
114 TEST(BaseFeatureProviderTest, Validation) { 92 // Tests that real permission features have the correct availability for an app.
115 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 93 TEST(BaseFeatureProviderTest, PermissionFeatureAvailability) {
James Cook 2014/09/11 23:32:31 Same thing here: * SimpleFeature -> Feature * cont
94 const FeatureProvider* provider =
95 BaseFeatureProvider::GetByName("permission");
116 96
117 base::DictionaryValue* feature1 = new base::DictionaryValue(); 97 scoped_refptr<const Extension> app =
118 feature1->SetString("channel", "trunk"); 98 ExtensionBuilder()
119 value->Set("feature1", feature1); 99 .SetManifest(DictionaryBuilder()
100 .Set("name", "test app")
101 .Set("version", "1")
102 .Set("app",
103 DictionaryBuilder().Set(
104 "background",
105 DictionaryBuilder().Set(
106 "scripts",
107 ListBuilder().Append("background.js"))))
108 .Set("permissions", ListBuilder().Append("power")))
109 .Build();
110 ASSERT_TRUE(app.get());
111 ASSERT_TRUE(app->is_platform_app());
120 112
121 base::DictionaryValue* feature2 = new base::DictionaryValue(); 113 // A permission requested in the manifest is available.
122 feature2->SetString("channel", "trunk"); 114 Feature* feature = provider->GetFeature("power");
123 base::ListValue* extension_types = new base::ListValue(); 115 EXPECT_EQ(
124 extension_types->Append(new base::StringValue("extension")); 116 Feature::IS_AVAILABLE,
125 feature2->Set("extension_types", extension_types); 117 feature->IsAvailableToContext(
126 base::ListValue* contexts = new base::ListValue(); 118 app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result());
127 contexts->Append(new base::StringValue("blessed_extension"));
128 feature2->Set("contexts", contexts);
129 value->Set("feature2", feature2);
130 119
131 scoped_ptr<BaseFeatureProvider> provider( 120 // A permission only available to whitelisted extensions returns availability
132 new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>)); 121 // NOT_FOUND_IN_WHITELIST.
122 feature = provider->GetFeature("bluetoothPrivate");
123 ASSERT_TRUE(feature);
124 EXPECT_EQ(
125 Feature::NOT_FOUND_IN_WHITELIST,
126 feature->IsAvailableToContext(
127 app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result());
133 128
134 // feature1 won't validate because it lacks an extension type. 129 // A permission that isn't part of the manifest returns NOT_PRESENT.
135 EXPECT_FALSE(provider->GetFeature("feature1")); 130 feature = provider->GetFeature("serial");
136 131 ASSERT_TRUE(feature);
137 // If we add one, it works. 132 EXPECT_EQ(
138 feature1->Set("extension_types", extension_types->DeepCopy()); 133 Feature::NOT_PRESENT,
139 provider.reset( 134 feature->IsAvailableToContext(
140 new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>)); 135 app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result());
141 EXPECT_TRUE(provider->GetFeature("feature1"));
142
143 // Remove the channel, and feature1 won't validate.
144 feature1->Remove("channel", NULL);
145 provider.reset(
146 new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>));
147 EXPECT_FALSE(provider->GetFeature("feature1"));
148
149 // feature2 won't validate because of the presence of "contexts".
150 EXPECT_FALSE(provider->GetFeature("feature2"));
151
152 // If we remove it, it works.
153 feature2->Remove("contexts", NULL);
154 provider.reset(
155 new BaseFeatureProvider(*value, CreateFeature<PermissionFeature>));
156 EXPECT_TRUE(provider->GetFeature("feature2"));
157 }
158
159 TEST(BaseFeatureProviderTest, ComplexFeatures) {
160 scoped_ptr<base::DictionaryValue> rule(
161 DictionaryBuilder()
162 .Set("feature1", ListBuilder()
163 .Append(DictionaryBuilder()
164 .Set("channel", "beta")
165 .Set("extension_types", ListBuilder()
166 .Append("extension")))
167 .Append(DictionaryBuilder()
168 .Set("channel", "beta")
169 .Set("extension_types", ListBuilder()
170 .Append("legacy_packaged_app"))))
171 .Build());
172
173 scoped_ptr<BaseFeatureProvider> provider(
174 new BaseFeatureProvider(*rule, CreateFeature<SimpleFeature>));
175
176 Feature* feature = provider->GetFeature("feature1");
177 EXPECT_TRUE(feature);
178
179 // Make sure both rules are applied correctly.
180 {
181 ScopedCurrentChannel current_channel(VersionInfo::CHANNEL_BETA);
182 EXPECT_EQ(
183 Feature::IS_AVAILABLE,
184 feature->IsAvailableToManifest("1",
185 Manifest::TYPE_EXTENSION,
186 Manifest::INVALID_LOCATION,
187 Feature::UNSPECIFIED_PLATFORM).result());
188 EXPECT_EQ(
189 Feature::IS_AVAILABLE,
190 feature->IsAvailableToManifest("2",
191 Manifest::TYPE_LEGACY_PACKAGED_APP,
192 Manifest::INVALID_LOCATION,
193 Feature::UNSPECIFIED_PLATFORM).result());
194 }
195 {
196 ScopedCurrentChannel current_channel(VersionInfo::CHANNEL_STABLE);
197 EXPECT_NE(
198 Feature::IS_AVAILABLE,
199 feature->IsAvailableToManifest("1",
200 Manifest::TYPE_EXTENSION,
201 Manifest::INVALID_LOCATION,
202 Feature::UNSPECIFIED_PLATFORM).result());
203 EXPECT_NE(
204 Feature::IS_AVAILABLE,
205 feature->IsAvailableToManifest("2",
206 Manifest::TYPE_LEGACY_PACKAGED_APP,
207 Manifest::INVALID_LOCATION,
208 Feature::UNSPECIFIED_PLATFORM).result());
209 }
210 } 136 }
211 137
212 } // namespace extensions 138 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698