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
3 // found in the LICENSE file.
5 #include "extensions/common/features/simple_feature.h"
7 #include "chrome/common/extensions/features/chrome_channel_feature_filter.h"
8 #include "chrome/common/extensions/features/feature_channel.h"
9 #include "extensions/common/value_builder.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using chrome::VersionInfo;
13 using extensions::DictionaryBuilder;
14 using extensions::Extension;
15 using extensions::Feature;
16 using extensions::ListBuilder;
17 using extensions::Manifest;
18 using extensions::ScopedCurrentChannel;
19 using extensions::SimpleFeature;
21 namespace extensions {
25 struct IsAvailableTestData {
26 std::string extension_id;
27 Manifest::Type extension_type;
28 Manifest::Location location;
29 Feature::Platform platform;
31 Feature::AvailabilityResult expected_result;
36 class ExtensionSimpleFeatureTest : public testing::Test {
38 ExtensionSimpleFeatureTest()
39 : current_channel_(VersionInfo::CHANNEL_UNKNOWN) {}
40 virtual ~ExtensionSimpleFeatureTest() {}
42 bool LocationIsAvailable(SimpleFeature::Location feature_location,
43 Manifest::Location manifest_location) {
44 SimpleFeature feature;
45 feature.set_location(feature_location);
46 Feature::AvailabilityResult availability_result =
47 feature.IsAvailableToManifest(std::string(),
48 Manifest::TYPE_UNKNOWN,
51 Feature::UNSPECIFIED_PLATFORM).result();
52 return availability_result == Feature::IS_AVAILABLE;
56 ScopedCurrentChannel current_channel_;
59 TEST_F(ExtensionSimpleFeatureTest, IsAvailableNullCase) {
60 const IsAvailableTestData tests[] = {
61 {"", Manifest::TYPE_UNKNOWN, Manifest::INVALID_LOCATION,
62 Feature::UNSPECIFIED_PLATFORM, -1, Feature::IS_AVAILABLE},
63 {"random-extension", Manifest::TYPE_UNKNOWN, Manifest::INVALID_LOCATION,
64 Feature::UNSPECIFIED_PLATFORM, -1, Feature::IS_AVAILABLE},
65 {"", Manifest::TYPE_LEGACY_PACKAGED_APP, Manifest::INVALID_LOCATION,
66 Feature::UNSPECIFIED_PLATFORM, -1, Feature::IS_AVAILABLE},
67 {"", Manifest::TYPE_UNKNOWN, Manifest::INVALID_LOCATION,
68 Feature::UNSPECIFIED_PLATFORM, -1, Feature::IS_AVAILABLE},
69 {"", Manifest::TYPE_UNKNOWN, Manifest::COMPONENT,
70 Feature::UNSPECIFIED_PLATFORM, -1, Feature::IS_AVAILABLE},
71 {"", Manifest::TYPE_UNKNOWN, Manifest::INVALID_LOCATION,
72 Feature::CHROMEOS_PLATFORM, -1, Feature::IS_AVAILABLE},
73 {"", Manifest::TYPE_UNKNOWN, Manifest::INVALID_LOCATION,
74 Feature::UNSPECIFIED_PLATFORM, 25, Feature::IS_AVAILABLE}};
76 SimpleFeature feature;
77 for (size_t i = 0; i < arraysize(tests); ++i) {
78 const IsAvailableTestData& test = tests[i];
79 EXPECT_EQ(test.expected_result,
80 feature.IsAvailableToManifest(test.extension_id,
83 test.manifest_version,
84 test.platform).result());
88 TEST_F(ExtensionSimpleFeatureTest, Whitelist) {
89 const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
90 const std::string kIdBar("barabbbbccccddddeeeeffffgggghhhh");
91 const std::string kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
92 SimpleFeature feature;
93 feature.whitelist()->insert(kIdFoo);
94 feature.whitelist()->insert(kIdBar);
97 Feature::IS_AVAILABLE,
98 feature.IsAvailableToManifest(kIdFoo,
99 Manifest::TYPE_UNKNOWN,
100 Manifest::INVALID_LOCATION,
102 Feature::UNSPECIFIED_PLATFORM).result());
104 Feature::IS_AVAILABLE,
105 feature.IsAvailableToManifest(kIdBar,
106 Manifest::TYPE_UNKNOWN,
107 Manifest::INVALID_LOCATION,
109 Feature::UNSPECIFIED_PLATFORM).result());
112 Feature::NOT_FOUND_IN_WHITELIST,
113 feature.IsAvailableToManifest(kIdBaz,
114 Manifest::TYPE_UNKNOWN,
115 Manifest::INVALID_LOCATION,
117 Feature::UNSPECIFIED_PLATFORM).result());
119 Feature::NOT_FOUND_IN_WHITELIST,
120 feature.IsAvailableToManifest(std::string(),
121 Manifest::TYPE_UNKNOWN,
122 Manifest::INVALID_LOCATION,
124 Feature::UNSPECIFIED_PLATFORM).result());
126 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
128 Feature::NOT_FOUND_IN_WHITELIST,
129 feature.IsAvailableToManifest(kIdBaz,
130 Manifest::TYPE_LEGACY_PACKAGED_APP,
131 Manifest::INVALID_LOCATION,
133 Feature::UNSPECIFIED_PLATFORM).result());
136 TEST_F(ExtensionSimpleFeatureTest, HashedIdWhitelist) {
137 // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
138 // sha1sum | tr '[:lower:]' '[:upper:]'
139 const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
140 const std::string kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
141 SimpleFeature feature;
143 feature.whitelist()->insert(kIdFooHashed);
146 Feature::IS_AVAILABLE,
147 feature.IsAvailableToManifest(kIdFoo,
148 Manifest::TYPE_UNKNOWN,
149 Manifest::INVALID_LOCATION,
151 Feature::UNSPECIFIED_PLATFORM).result());
153 Feature::IS_AVAILABLE,
154 feature.IsAvailableToManifest(kIdFooHashed,
155 Manifest::TYPE_UNKNOWN,
156 Manifest::INVALID_LOCATION,
158 Feature::UNSPECIFIED_PLATFORM).result());
160 Feature::NOT_FOUND_IN_WHITELIST,
161 feature.IsAvailableToManifest("slightlytoooolongforanextensionid",
162 Manifest::TYPE_UNKNOWN,
163 Manifest::INVALID_LOCATION,
165 Feature::UNSPECIFIED_PLATFORM).result());
167 Feature::NOT_FOUND_IN_WHITELIST,
168 feature.IsAvailableToManifest("tooshortforanextensionid",
169 Manifest::TYPE_UNKNOWN,
170 Manifest::INVALID_LOCATION,
172 Feature::UNSPECIFIED_PLATFORM).result());
175 TEST_F(ExtensionSimpleFeatureTest, Blacklist) {
176 const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
177 const std::string kIdBar("barabbbbccccddddeeeeffffgggghhhh");
178 const std::string kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
179 SimpleFeature feature;
180 feature.blacklist()->insert(kIdFoo);
181 feature.blacklist()->insert(kIdBar);
184 Feature::FOUND_IN_BLACKLIST,
185 feature.IsAvailableToManifest(kIdFoo,
186 Manifest::TYPE_UNKNOWN,
187 Manifest::INVALID_LOCATION,
189 Feature::UNSPECIFIED_PLATFORM).result());
191 Feature::FOUND_IN_BLACKLIST,
192 feature.IsAvailableToManifest(kIdBar,
193 Manifest::TYPE_UNKNOWN,
194 Manifest::INVALID_LOCATION,
196 Feature::UNSPECIFIED_PLATFORM).result());
199 Feature::IS_AVAILABLE,
200 feature.IsAvailableToManifest(kIdBaz,
201 Manifest::TYPE_UNKNOWN,
202 Manifest::INVALID_LOCATION,
204 Feature::UNSPECIFIED_PLATFORM).result());
206 Feature::IS_AVAILABLE,
207 feature.IsAvailableToManifest(std::string(),
208 Manifest::TYPE_UNKNOWN,
209 Manifest::INVALID_LOCATION,
211 Feature::UNSPECIFIED_PLATFORM).result());
214 TEST_F(ExtensionSimpleFeatureTest, HashedIdBlacklist) {
215 // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
216 // sha1sum | tr '[:lower:]' '[:upper:]'
217 const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
218 const std::string kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
219 SimpleFeature feature;
221 feature.blacklist()->insert(kIdFooHashed);
224 Feature::FOUND_IN_BLACKLIST,
225 feature.IsAvailableToManifest(kIdFoo,
226 Manifest::TYPE_UNKNOWN,
227 Manifest::INVALID_LOCATION,
229 Feature::UNSPECIFIED_PLATFORM).result());
231 Feature::FOUND_IN_BLACKLIST,
232 feature.IsAvailableToManifest(kIdFooHashed,
233 Manifest::TYPE_UNKNOWN,
234 Manifest::INVALID_LOCATION,
236 Feature::UNSPECIFIED_PLATFORM).result());
238 Feature::IS_AVAILABLE,
239 feature.IsAvailableToManifest("slightlytoooolongforanextensionid",
240 Manifest::TYPE_UNKNOWN,
241 Manifest::INVALID_LOCATION,
243 Feature::UNSPECIFIED_PLATFORM).result());
245 Feature::IS_AVAILABLE,
246 feature.IsAvailableToManifest("tooshortforanextensionid",
247 Manifest::TYPE_UNKNOWN,
248 Manifest::INVALID_LOCATION,
250 Feature::UNSPECIFIED_PLATFORM).result());
253 TEST_F(ExtensionSimpleFeatureTest, PackageType) {
254 SimpleFeature feature;
255 feature.extension_types()->insert(Manifest::TYPE_EXTENSION);
256 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
259 Feature::IS_AVAILABLE,
260 feature.IsAvailableToManifest(std::string(),
261 Manifest::TYPE_EXTENSION,
262 Manifest::INVALID_LOCATION,
264 Feature::UNSPECIFIED_PLATFORM).result());
266 Feature::IS_AVAILABLE,
267 feature.IsAvailableToManifest(std::string(),
268 Manifest::TYPE_LEGACY_PACKAGED_APP,
269 Manifest::INVALID_LOCATION,
271 Feature::UNSPECIFIED_PLATFORM).result());
274 Feature::INVALID_TYPE,
275 feature.IsAvailableToManifest(std::string(),
276 Manifest::TYPE_UNKNOWN,
277 Manifest::INVALID_LOCATION,
279 Feature::UNSPECIFIED_PLATFORM).result());
281 Feature::INVALID_TYPE,
282 feature.IsAvailableToManifest(std::string(),
283 Manifest::TYPE_THEME,
284 Manifest::INVALID_LOCATION,
286 Feature::UNSPECIFIED_PLATFORM).result());
289 TEST_F(ExtensionSimpleFeatureTest, Context) {
290 SimpleFeature feature;
291 feature.set_name("somefeature");
292 feature.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
293 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
294 feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
295 feature.set_min_manifest_version(21);
296 feature.set_max_manifest_version(25);
298 base::DictionaryValue manifest;
299 manifest.SetString("name", "test");
300 manifest.SetString("version", "1");
301 manifest.SetInteger("manifest_version", 21);
302 manifest.SetString("app.launch.local_path", "foo.html");
305 scoped_refptr<const Extension> extension(Extension::Create(
306 base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS,
308 EXPECT_EQ("", error);
309 ASSERT_TRUE(extension.get());
311 feature.whitelist()->insert("monkey");
312 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToContext(
313 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
314 Feature::CHROMEOS_PLATFORM).result());
315 feature.whitelist()->clear();
317 feature.extension_types()->clear();
318 feature.extension_types()->insert(Manifest::TYPE_THEME);
320 Feature::Availability availability = feature.IsAvailableToContext(
321 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
322 Feature::CHROMEOS_PLATFORM);
323 EXPECT_EQ(Feature::INVALID_TYPE, availability.result());
324 EXPECT_EQ("'somefeature' is only allowed for themes, "
325 "but this is a legacy packaged app.",
326 availability.message());
329 feature.extension_types()->clear();
330 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
331 feature.contexts()->clear();
332 feature.contexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
333 feature.contexts()->insert(Feature::CONTENT_SCRIPT_CONTEXT);
335 Feature::Availability availability = feature.IsAvailableToContext(
336 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
337 Feature::CHROMEOS_PLATFORM);
338 EXPECT_EQ(Feature::INVALID_CONTEXT, availability.result());
339 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes and "
340 "content scripts, but this is a privileged page",
341 availability.message());
344 feature.contexts()->insert(Feature::WEB_PAGE_CONTEXT);
346 Feature::Availability availability = feature.IsAvailableToContext(
347 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
348 Feature::CHROMEOS_PLATFORM);
349 EXPECT_EQ(Feature::INVALID_CONTEXT, availability.result());
350 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes, "
351 "content scripts, and web pages, but this is a privileged page",
352 availability.message());
355 feature.contexts()->clear();
356 feature.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
357 feature.set_location(SimpleFeature::COMPONENT_LOCATION);
358 EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToContext(
359 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
360 Feature::CHROMEOS_PLATFORM).result());
361 feature.set_location(SimpleFeature::UNSPECIFIED_LOCATION);
363 EXPECT_EQ(Feature::INVALID_PLATFORM, feature.IsAvailableToContext(
364 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
365 Feature::UNSPECIFIED_PLATFORM).result());
367 feature.set_min_manifest_version(22);
368 EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION, feature.IsAvailableToContext(
369 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
370 Feature::CHROMEOS_PLATFORM).result());
371 feature.set_min_manifest_version(21);
373 feature.set_max_manifest_version(18);
374 EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION, feature.IsAvailableToContext(
375 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
376 Feature::CHROMEOS_PLATFORM).result());
377 feature.set_max_manifest_version(25);
380 TEST_F(ExtensionSimpleFeatureTest, Location) {
381 // Component extensions can access any location.
382 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION,
383 Manifest::COMPONENT));
385 LocationIsAvailable(SimpleFeature::POLICY_LOCATION, Manifest::COMPONENT));
386 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::UNSPECIFIED_LOCATION,
387 Manifest::COMPONENT));
389 // Only component extensions can access the "component" location.
390 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION,
391 Manifest::INVALID_LOCATION));
392 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION,
393 Manifest::UNPACKED));
394 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION,
395 Manifest::EXTERNAL_PREF_DOWNLOAD));
396 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION,
397 Manifest::EXTERNAL_POLICY));
398 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION,
399 Manifest::EXTERNAL_POLICY_DOWNLOAD));
401 // Policy extensions can access the "policy" location.
402 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION,
403 Manifest::EXTERNAL_POLICY));
404 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION,
405 Manifest::EXTERNAL_POLICY_DOWNLOAD));
407 // Non-policy (except component) extensions cannot access policy.
408 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION,
409 Manifest::INVALID_LOCATION));
411 LocationIsAvailable(SimpleFeature::POLICY_LOCATION, Manifest::UNPACKED));
412 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION,
413 Manifest::EXTERNAL_PREF_DOWNLOAD));
416 TEST_F(ExtensionSimpleFeatureTest, Platform) {
417 SimpleFeature feature;
418 feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
419 EXPECT_EQ(Feature::IS_AVAILABLE,
420 feature.IsAvailableToManifest(std::string(),
421 Manifest::TYPE_UNKNOWN,
422 Manifest::INVALID_LOCATION,
424 Feature::CHROMEOS_PLATFORM).result());
426 Feature::INVALID_PLATFORM,
427 feature.IsAvailableToManifest(std::string(),
428 Manifest::TYPE_UNKNOWN,
429 Manifest::INVALID_LOCATION,
431 Feature::UNSPECIFIED_PLATFORM).result());
434 TEST_F(ExtensionSimpleFeatureTest, Version) {
435 SimpleFeature feature;
436 feature.set_min_manifest_version(5);
439 Feature::INVALID_MIN_MANIFEST_VERSION,
440 feature.IsAvailableToManifest(std::string(),
441 Manifest::TYPE_UNKNOWN,
442 Manifest::INVALID_LOCATION,
444 Feature::UNSPECIFIED_PLATFORM).result());
446 Feature::INVALID_MIN_MANIFEST_VERSION,
447 feature.IsAvailableToManifest(std::string(),
448 Manifest::TYPE_UNKNOWN,
449 Manifest::INVALID_LOCATION,
451 Feature::UNSPECIFIED_PLATFORM).result());
454 Feature::IS_AVAILABLE,
455 feature.IsAvailableToManifest(std::string(),
456 Manifest::TYPE_UNKNOWN,
457 Manifest::INVALID_LOCATION,
459 Feature::UNSPECIFIED_PLATFORM).result());
461 Feature::IS_AVAILABLE,
462 feature.IsAvailableToManifest(std::string(),
463 Manifest::TYPE_UNKNOWN,
464 Manifest::INVALID_LOCATION,
466 Feature::UNSPECIFIED_PLATFORM).result());
468 feature.set_max_manifest_version(8);
471 Feature::INVALID_MAX_MANIFEST_VERSION,
472 feature.IsAvailableToManifest(std::string(),
473 Manifest::TYPE_UNKNOWN,
474 Manifest::INVALID_LOCATION,
476 Feature::UNSPECIFIED_PLATFORM).result());
478 Feature::IS_AVAILABLE,
479 feature.IsAvailableToManifest(std::string(),
480 Manifest::TYPE_UNKNOWN,
481 Manifest::INVALID_LOCATION,
483 Feature::UNSPECIFIED_PLATFORM).result());
485 Feature::IS_AVAILABLE,
486 feature.IsAvailableToManifest(std::string(),
487 Manifest::TYPE_UNKNOWN,
488 Manifest::INVALID_LOCATION,
490 Feature::UNSPECIFIED_PLATFORM).result());
493 TEST_F(ExtensionSimpleFeatureTest, ParseNull) {
494 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
495 scoped_ptr<SimpleFeature> feature(new SimpleFeature());
496 feature->Parse(value.get());
497 EXPECT_TRUE(feature->whitelist()->empty());
498 EXPECT_TRUE(feature->extension_types()->empty());
499 EXPECT_TRUE(feature->contexts()->empty());
500 EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION, feature->location());
501 EXPECT_TRUE(feature->platforms()->empty());
502 EXPECT_EQ(0, feature->min_manifest_version());
503 EXPECT_EQ(0, feature->max_manifest_version());
506 TEST_F(ExtensionSimpleFeatureTest, ParseWhitelist) {
507 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
508 base::ListValue* whitelist = new base::ListValue();
509 whitelist->Append(new base::StringValue("foo"));
510 whitelist->Append(new base::StringValue("bar"));
511 value->Set("whitelist", whitelist);
512 scoped_ptr<SimpleFeature> feature(new SimpleFeature());
513 feature->Parse(value.get());
514 EXPECT_EQ(2u, feature->whitelist()->size());
515 EXPECT_TRUE(feature->whitelist()->count("foo"));
516 EXPECT_TRUE(feature->whitelist()->count("bar"));
519 TEST_F(ExtensionSimpleFeatureTest, ParsePackageTypes) {
520 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
521 base::ListValue* extension_types = new base::ListValue();
522 extension_types->Append(new base::StringValue("extension"));
523 extension_types->Append(new base::StringValue("theme"));
524 extension_types->Append(new base::StringValue("legacy_packaged_app"));
525 extension_types->Append(new base::StringValue("hosted_app"));
526 extension_types->Append(new base::StringValue("platform_app"));
527 extension_types->Append(new base::StringValue("shared_module"));
528 value->Set("extension_types", extension_types);
529 scoped_ptr<SimpleFeature> feature(new SimpleFeature());
530 feature->Parse(value.get());
531 EXPECT_EQ(6u, feature->extension_types()->size());
532 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_EXTENSION));
533 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_THEME));
534 EXPECT_TRUE(feature->extension_types()->count(
535 Manifest::TYPE_LEGACY_PACKAGED_APP));
536 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_HOSTED_APP));
537 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP));
538 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_SHARED_MODULE));
540 value->SetString("extension_types", "all");
541 scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
542 feature2->Parse(value.get());
543 EXPECT_EQ(*(feature->extension_types()), *(feature2->extension_types()));
546 TEST_F(ExtensionSimpleFeatureTest, ParseContexts) {
547 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
548 base::ListValue* contexts = new base::ListValue();
549 contexts->Append(new base::StringValue("blessed_extension"));
550 contexts->Append(new base::StringValue("unblessed_extension"));
551 contexts->Append(new base::StringValue("content_script"));
552 contexts->Append(new base::StringValue("web_page"));
553 contexts->Append(new base::StringValue("blessed_web_page"));
554 contexts->Append(new base::StringValue("webui"));
555 value->Set("contexts", contexts);
556 scoped_ptr<SimpleFeature> feature(new SimpleFeature());
557 feature->Parse(value.get());
558 EXPECT_EQ(6u, feature->contexts()->size());
559 EXPECT_TRUE(feature->contexts()->count(Feature::BLESSED_EXTENSION_CONTEXT));
560 EXPECT_TRUE(feature->contexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
561 EXPECT_TRUE(feature->contexts()->count(Feature::CONTENT_SCRIPT_CONTEXT));
562 EXPECT_TRUE(feature->contexts()->count(Feature::WEB_PAGE_CONTEXT));
563 EXPECT_TRUE(feature->contexts()->count(Feature::BLESSED_WEB_PAGE_CONTEXT));
565 value->SetString("contexts", "all");
566 scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
567 feature2->Parse(value.get());
568 EXPECT_EQ(*(feature->contexts()), *(feature2->contexts()));
571 TEST_F(ExtensionSimpleFeatureTest, ParseLocation) {
572 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
573 value->SetString("location", "component");
574 scoped_ptr<SimpleFeature> feature(new SimpleFeature());
575 feature->Parse(value.get());
576 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature->location());
579 TEST_F(ExtensionSimpleFeatureTest, ParsePlatforms) {
580 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
581 scoped_ptr<SimpleFeature> feature(new SimpleFeature());
582 base::ListValue* platforms = new base::ListValue();
583 value->Set("platforms", platforms);
584 feature->Parse(value.get());
585 EXPECT_TRUE(feature->platforms()->empty());
587 platforms->AppendString("chromeos");
588 feature->Parse(value.get());
589 EXPECT_FALSE(feature->platforms()->empty());
590 EXPECT_EQ(Feature::CHROMEOS_PLATFORM, *feature->platforms()->begin());
593 platforms->AppendString("win");
594 feature->Parse(value.get());
595 EXPECT_FALSE(feature->platforms()->empty());
596 EXPECT_EQ(Feature::WIN_PLATFORM, *feature->platforms()->begin());
599 platforms->AppendString("win");
600 platforms->AppendString("chromeos");
601 feature->Parse(value.get());
602 std::set<Feature::Platform> expected_platforms;
603 expected_platforms.insert(Feature::CHROMEOS_PLATFORM);
604 expected_platforms.insert(Feature::WIN_PLATFORM);
606 EXPECT_FALSE(feature->platforms()->empty());
607 EXPECT_EQ(expected_platforms, *feature->platforms());
610 TEST_F(ExtensionSimpleFeatureTest, ManifestVersion) {
611 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
612 value->SetInteger("min_manifest_version", 1);
613 value->SetInteger("max_manifest_version", 5);
614 scoped_ptr<SimpleFeature> feature(new SimpleFeature());
615 feature->Parse(value.get());
616 EXPECT_EQ(1, feature->min_manifest_version());
617 EXPECT_EQ(5, feature->max_manifest_version());
620 TEST_F(ExtensionSimpleFeatureTest, Inheritance) {
621 SimpleFeature feature;
622 feature.whitelist()->insert("foo");
623 feature.extension_types()->insert(Manifest::TYPE_THEME);
624 feature.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
625 feature.set_location(SimpleFeature::COMPONENT_LOCATION);
626 feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
627 feature.set_min_manifest_version(1);
628 feature.set_max_manifest_version(2);
630 // Test additive parsing. Parsing an empty dictionary should result in no
631 // changes to a SimpleFeature.
632 base::DictionaryValue definition;
633 feature.Parse(&definition);
634 EXPECT_EQ(1u, feature.whitelist()->size());
635 EXPECT_EQ(1u, feature.extension_types()->size());
636 EXPECT_EQ(1u, feature.contexts()->size());
637 EXPECT_EQ(1u, feature.whitelist()->count("foo"));
638 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature.location());
639 EXPECT_EQ(1u, feature.platforms()->size());
640 EXPECT_EQ(1u, feature.platforms()->count(Feature::CHROMEOS_PLATFORM));
641 EXPECT_EQ(1, feature.min_manifest_version());
642 EXPECT_EQ(2, feature.max_manifest_version());
644 base::ListValue* whitelist = new base::ListValue();
645 base::ListValue* extension_types = new base::ListValue();
646 base::ListValue* contexts = new base::ListValue();
647 whitelist->Append(new base::StringValue("bar"));
648 extension_types->Append(new base::StringValue("extension"));
649 contexts->Append(new base::StringValue("unblessed_extension"));
650 definition.Set("whitelist", whitelist);
651 definition.Set("extension_types", extension_types);
652 definition.Set("contexts", contexts);
653 // Can't test location or platform because we only have one value so far.
654 definition.Set("min_manifest_version", new base::FundamentalValue(2));
655 definition.Set("max_manifest_version", new base::FundamentalValue(3));
657 feature.Parse(&definition);
658 EXPECT_EQ(1u, feature.whitelist()->size());
659 EXPECT_EQ(1u, feature.extension_types()->size());
660 EXPECT_EQ(1u, feature.contexts()->size());
661 EXPECT_EQ(1u, feature.whitelist()->count("bar"));
662 EXPECT_EQ(1u, feature.extension_types()->count(Manifest::TYPE_EXTENSION));
664 feature.contexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
665 EXPECT_EQ(2, feature.min_manifest_version());
666 EXPECT_EQ(3, feature.max_manifest_version());
669 Feature::AvailabilityResult IsAvailableInChannel(
670 const std::string& channel, VersionInfo::Channel channel_for_testing) {
671 ScopedCurrentChannel current_channel(channel_for_testing);
673 SimpleFeature feature;
674 feature.AddFilter(scoped_ptr<extensions::SimpleFeatureFilter>(
675 new extensions::ChromeChannelFeatureFilter(&feature)));
676 if (!channel.empty()) {
677 base::DictionaryValue feature_value;
678 feature_value.SetString("channel", channel);
679 feature.Parse(&feature_value);
682 return feature.IsAvailableToManifest("random-extension",
683 Manifest::TYPE_UNKNOWN,
684 Manifest::INVALID_LOCATION,
686 Feature::GetCurrentPlatform()).result();
689 TEST_F(ExtensionSimpleFeatureTest, SupportedChannel) {
691 EXPECT_EQ(Feature::IS_AVAILABLE,
692 IsAvailableInChannel("stable", VersionInfo::CHANNEL_UNKNOWN));
693 EXPECT_EQ(Feature::IS_AVAILABLE,
694 IsAvailableInChannel("stable", VersionInfo::CHANNEL_CANARY));
695 EXPECT_EQ(Feature::IS_AVAILABLE,
696 IsAvailableInChannel("stable", VersionInfo::CHANNEL_DEV));
697 EXPECT_EQ(Feature::IS_AVAILABLE,
698 IsAvailableInChannel("stable", VersionInfo::CHANNEL_BETA));
699 EXPECT_EQ(Feature::IS_AVAILABLE,
700 IsAvailableInChannel("stable", VersionInfo::CHANNEL_STABLE));
703 EXPECT_EQ(Feature::IS_AVAILABLE,
704 IsAvailableInChannel("beta", VersionInfo::CHANNEL_UNKNOWN));
705 EXPECT_EQ(Feature::IS_AVAILABLE,
706 IsAvailableInChannel("beta", VersionInfo::CHANNEL_CANARY));
707 EXPECT_EQ(Feature::IS_AVAILABLE,
708 IsAvailableInChannel("beta", VersionInfo::CHANNEL_DEV));
709 EXPECT_EQ(Feature::IS_AVAILABLE,
710 IsAvailableInChannel("beta", VersionInfo::CHANNEL_BETA));
711 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
712 IsAvailableInChannel("beta", VersionInfo::CHANNEL_STABLE));
715 EXPECT_EQ(Feature::IS_AVAILABLE,
716 IsAvailableInChannel("dev", VersionInfo::CHANNEL_UNKNOWN));
717 EXPECT_EQ(Feature::IS_AVAILABLE,
718 IsAvailableInChannel("dev", VersionInfo::CHANNEL_CANARY));
719 EXPECT_EQ(Feature::IS_AVAILABLE,
720 IsAvailableInChannel("dev", VersionInfo::CHANNEL_DEV));
721 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
722 IsAvailableInChannel("dev", VersionInfo::CHANNEL_BETA));
723 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
724 IsAvailableInChannel("dev", VersionInfo::CHANNEL_STABLE));
727 EXPECT_EQ(Feature::IS_AVAILABLE,
728 IsAvailableInChannel("canary", VersionInfo::CHANNEL_UNKNOWN));
729 EXPECT_EQ(Feature::IS_AVAILABLE,
730 IsAvailableInChannel("canary", VersionInfo::CHANNEL_CANARY));
731 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
732 IsAvailableInChannel("canary", VersionInfo::CHANNEL_DEV));
733 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
734 IsAvailableInChannel("canary", VersionInfo::CHANNEL_BETA));
735 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
736 IsAvailableInChannel("canary", VersionInfo::CHANNEL_STABLE));
739 EXPECT_EQ(Feature::IS_AVAILABLE,
740 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_UNKNOWN));
741 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
742 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_CANARY));
743 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
744 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_DEV));
745 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
746 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_BETA));
747 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
748 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_STABLE));
751 } // namespace extensions