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"
9 #include "base/command_line.h"
10 #include "base/values.h"
11 #include "extensions/common/manifest.h"
12 #include "extensions/common/value_builder.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace extensions
{
19 struct IsAvailableTestData
{
20 std::string extension_id
;
21 Manifest::Type extension_type
;
22 Manifest::Location location
;
23 Feature::Platform platform
;
25 Feature::AvailabilityResult expected_result
;
28 bool LocationIsAvailable(SimpleFeature::Location feature_location
,
29 Manifest::Location manifest_location
) {
30 SimpleFeature feature
;
31 feature
.set_location(feature_location
);
32 Feature::AvailabilityResult availability_result
=
33 feature
.IsAvailableToManifest(std::string(),
34 Manifest::TYPE_UNKNOWN
,
37 Feature::UNSPECIFIED_PLATFORM
).result();
38 return availability_result
== Feature::IS_AVAILABLE
;
41 class ScopedCommandLineSwitch
{
43 explicit ScopedCommandLineSwitch(const std::string
& arg
)
44 : original_command_line_(*base::CommandLine::ForCurrentProcess()) {
45 base::CommandLine::ForCurrentProcess()->AppendSwitch(arg
);
48 ~ScopedCommandLineSwitch() {
49 *base::CommandLine::ForCurrentProcess() = original_command_line_
;
53 base::CommandLine original_command_line_
;
58 TEST(SimpleFeatureTest
, IsAvailableNullCase
) {
59 const IsAvailableTestData tests
[] = {
60 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
61 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
62 {"random-extension", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
63 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
64 {"", Manifest::TYPE_LEGACY_PACKAGED_APP
, Manifest::INVALID_LOCATION
,
65 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
66 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
67 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
68 {"", Manifest::TYPE_UNKNOWN
, Manifest::COMPONENT
,
69 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
70 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
71 Feature::CHROMEOS_PLATFORM
, -1, Feature::IS_AVAILABLE
},
72 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
73 Feature::UNSPECIFIED_PLATFORM
, 25, Feature::IS_AVAILABLE
}};
75 SimpleFeature feature
;
76 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
77 const IsAvailableTestData
& test
= tests
[i
];
78 EXPECT_EQ(test
.expected_result
,
79 feature
.IsAvailableToManifest(test
.extension_id
,
82 test
.manifest_version
,
83 test
.platform
).result());
87 TEST(SimpleFeatureTest
, Whitelist
) {
88 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
89 const std::string
kIdBar("barabbbbccccddddeeeeffffgggghhhh");
90 const std::string
kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
91 SimpleFeature feature
;
92 feature
.whitelist()->insert(kIdFoo
);
93 feature
.whitelist()->insert(kIdBar
);
96 Feature::IS_AVAILABLE
,
97 feature
.IsAvailableToManifest(kIdFoo
,
98 Manifest::TYPE_UNKNOWN
,
99 Manifest::INVALID_LOCATION
,
101 Feature::UNSPECIFIED_PLATFORM
).result());
103 Feature::IS_AVAILABLE
,
104 feature
.IsAvailableToManifest(kIdBar
,
105 Manifest::TYPE_UNKNOWN
,
106 Manifest::INVALID_LOCATION
,
108 Feature::UNSPECIFIED_PLATFORM
).result());
111 Feature::NOT_FOUND_IN_WHITELIST
,
112 feature
.IsAvailableToManifest(kIdBaz
,
113 Manifest::TYPE_UNKNOWN
,
114 Manifest::INVALID_LOCATION
,
116 Feature::UNSPECIFIED_PLATFORM
).result());
118 Feature::NOT_FOUND_IN_WHITELIST
,
119 feature
.IsAvailableToManifest(std::string(),
120 Manifest::TYPE_UNKNOWN
,
121 Manifest::INVALID_LOCATION
,
123 Feature::UNSPECIFIED_PLATFORM
).result());
125 feature
.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP
);
127 Feature::NOT_FOUND_IN_WHITELIST
,
128 feature
.IsAvailableToManifest(kIdBaz
,
129 Manifest::TYPE_LEGACY_PACKAGED_APP
,
130 Manifest::INVALID_LOCATION
,
132 Feature::UNSPECIFIED_PLATFORM
).result());
135 TEST(SimpleFeatureTest
, HashedIdWhitelist
) {
136 // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
137 // sha1sum | tr '[:lower:]' '[:upper:]'
138 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
139 const std::string
kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
140 SimpleFeature feature
;
142 feature
.whitelist()->insert(kIdFooHashed
);
145 Feature::IS_AVAILABLE
,
146 feature
.IsAvailableToManifest(kIdFoo
,
147 Manifest::TYPE_UNKNOWN
,
148 Manifest::INVALID_LOCATION
,
150 Feature::UNSPECIFIED_PLATFORM
).result());
152 Feature::IS_AVAILABLE
,
153 feature
.IsAvailableToManifest(kIdFooHashed
,
154 Manifest::TYPE_UNKNOWN
,
155 Manifest::INVALID_LOCATION
,
157 Feature::UNSPECIFIED_PLATFORM
).result());
159 Feature::NOT_FOUND_IN_WHITELIST
,
160 feature
.IsAvailableToManifest("slightlytoooolongforanextensionid",
161 Manifest::TYPE_UNKNOWN
,
162 Manifest::INVALID_LOCATION
,
164 Feature::UNSPECIFIED_PLATFORM
).result());
166 Feature::NOT_FOUND_IN_WHITELIST
,
167 feature
.IsAvailableToManifest("tooshortforanextensionid",
168 Manifest::TYPE_UNKNOWN
,
169 Manifest::INVALID_LOCATION
,
171 Feature::UNSPECIFIED_PLATFORM
).result());
174 TEST(SimpleFeatureTest
, Blacklist
) {
175 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
176 const std::string
kIdBar("barabbbbccccddddeeeeffffgggghhhh");
177 const std::string
kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
178 SimpleFeature feature
;
179 feature
.blacklist()->insert(kIdFoo
);
180 feature
.blacklist()->insert(kIdBar
);
183 Feature::FOUND_IN_BLACKLIST
,
184 feature
.IsAvailableToManifest(kIdFoo
,
185 Manifest::TYPE_UNKNOWN
,
186 Manifest::INVALID_LOCATION
,
188 Feature::UNSPECIFIED_PLATFORM
).result());
190 Feature::FOUND_IN_BLACKLIST
,
191 feature
.IsAvailableToManifest(kIdBar
,
192 Manifest::TYPE_UNKNOWN
,
193 Manifest::INVALID_LOCATION
,
195 Feature::UNSPECIFIED_PLATFORM
).result());
198 Feature::IS_AVAILABLE
,
199 feature
.IsAvailableToManifest(kIdBaz
,
200 Manifest::TYPE_UNKNOWN
,
201 Manifest::INVALID_LOCATION
,
203 Feature::UNSPECIFIED_PLATFORM
).result());
205 Feature::IS_AVAILABLE
,
206 feature
.IsAvailableToManifest(std::string(),
207 Manifest::TYPE_UNKNOWN
,
208 Manifest::INVALID_LOCATION
,
210 Feature::UNSPECIFIED_PLATFORM
).result());
213 TEST(SimpleFeatureTest
, HashedIdBlacklist
) {
214 // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
215 // sha1sum | tr '[:lower:]' '[:upper:]'
216 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
217 const std::string
kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
218 SimpleFeature feature
;
220 feature
.blacklist()->insert(kIdFooHashed
);
223 Feature::FOUND_IN_BLACKLIST
,
224 feature
.IsAvailableToManifest(kIdFoo
,
225 Manifest::TYPE_UNKNOWN
,
226 Manifest::INVALID_LOCATION
,
228 Feature::UNSPECIFIED_PLATFORM
).result());
230 Feature::FOUND_IN_BLACKLIST
,
231 feature
.IsAvailableToManifest(kIdFooHashed
,
232 Manifest::TYPE_UNKNOWN
,
233 Manifest::INVALID_LOCATION
,
235 Feature::UNSPECIFIED_PLATFORM
).result());
237 Feature::IS_AVAILABLE
,
238 feature
.IsAvailableToManifest("slightlytoooolongforanextensionid",
239 Manifest::TYPE_UNKNOWN
,
240 Manifest::INVALID_LOCATION
,
242 Feature::UNSPECIFIED_PLATFORM
).result());
244 Feature::IS_AVAILABLE
,
245 feature
.IsAvailableToManifest("tooshortforanextensionid",
246 Manifest::TYPE_UNKNOWN
,
247 Manifest::INVALID_LOCATION
,
249 Feature::UNSPECIFIED_PLATFORM
).result());
252 TEST(SimpleFeatureTest
, PackageType
) {
253 SimpleFeature feature
;
254 feature
.extension_types()->insert(Manifest::TYPE_EXTENSION
);
255 feature
.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP
);
258 Feature::IS_AVAILABLE
,
259 feature
.IsAvailableToManifest(std::string(),
260 Manifest::TYPE_EXTENSION
,
261 Manifest::INVALID_LOCATION
,
263 Feature::UNSPECIFIED_PLATFORM
).result());
265 Feature::IS_AVAILABLE
,
266 feature
.IsAvailableToManifest(std::string(),
267 Manifest::TYPE_LEGACY_PACKAGED_APP
,
268 Manifest::INVALID_LOCATION
,
270 Feature::UNSPECIFIED_PLATFORM
).result());
273 Feature::INVALID_TYPE
,
274 feature
.IsAvailableToManifest(std::string(),
275 Manifest::TYPE_UNKNOWN
,
276 Manifest::INVALID_LOCATION
,
278 Feature::UNSPECIFIED_PLATFORM
).result());
280 Feature::INVALID_TYPE
,
281 feature
.IsAvailableToManifest(std::string(),
282 Manifest::TYPE_THEME
,
283 Manifest::INVALID_LOCATION
,
285 Feature::UNSPECIFIED_PLATFORM
).result());
288 TEST(SimpleFeatureTest
, Context
) {
289 SimpleFeature feature
;
290 feature
.set_name("somefeature");
291 feature
.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT
);
292 feature
.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP
);
293 feature
.platforms()->insert(Feature::CHROMEOS_PLATFORM
);
294 feature
.set_min_manifest_version(21);
295 feature
.set_max_manifest_version(25);
297 base::DictionaryValue manifest
;
298 manifest
.SetString("name", "test");
299 manifest
.SetString("version", "1");
300 manifest
.SetInteger("manifest_version", 21);
301 manifest
.SetString("app.launch.local_path", "foo.html");
304 scoped_refptr
<const Extension
> extension(Extension::Create(
305 base::FilePath(), Manifest::INTERNAL
, manifest
, Extension::NO_FLAGS
,
307 EXPECT_EQ("", error
);
308 ASSERT_TRUE(extension
.get());
310 feature
.whitelist()->insert("monkey");
311 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST
, feature
.IsAvailableToContext(
312 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
313 Feature::CHROMEOS_PLATFORM
).result());
314 feature
.whitelist()->clear();
316 feature
.extension_types()->clear();
317 feature
.extension_types()->insert(Manifest::TYPE_THEME
);
319 Feature::Availability availability
= feature
.IsAvailableToContext(
320 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
321 Feature::CHROMEOS_PLATFORM
);
322 EXPECT_EQ(Feature::INVALID_TYPE
, availability
.result());
323 EXPECT_EQ("'somefeature' is only allowed for themes, "
324 "but this is a legacy packaged app.",
325 availability
.message());
328 feature
.extension_types()->clear();
329 feature
.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP
);
330 feature
.contexts()->clear();
331 feature
.contexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT
);
332 feature
.contexts()->insert(Feature::CONTENT_SCRIPT_CONTEXT
);
334 Feature::Availability availability
= feature
.IsAvailableToContext(
335 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
336 Feature::CHROMEOS_PLATFORM
);
337 EXPECT_EQ(Feature::INVALID_CONTEXT
, availability
.result());
338 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes and "
339 "content scripts, but this is a privileged page",
340 availability
.message());
343 feature
.contexts()->insert(Feature::WEB_PAGE_CONTEXT
);
345 Feature::Availability availability
= feature
.IsAvailableToContext(
346 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
347 Feature::CHROMEOS_PLATFORM
);
348 EXPECT_EQ(Feature::INVALID_CONTEXT
, availability
.result());
349 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes, "
350 "content scripts, and web pages, but this is a privileged page",
351 availability
.message());
354 feature
.contexts()->clear();
355 feature
.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT
);
356 feature
.set_location(SimpleFeature::COMPONENT_LOCATION
);
357 EXPECT_EQ(Feature::INVALID_LOCATION
, feature
.IsAvailableToContext(
358 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
359 Feature::CHROMEOS_PLATFORM
).result());
360 feature
.set_location(SimpleFeature::UNSPECIFIED_LOCATION
);
362 EXPECT_EQ(Feature::INVALID_PLATFORM
, feature
.IsAvailableToContext(
363 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
364 Feature::UNSPECIFIED_PLATFORM
).result());
366 feature
.set_min_manifest_version(22);
367 EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION
, feature
.IsAvailableToContext(
368 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
369 Feature::CHROMEOS_PLATFORM
).result());
370 feature
.set_min_manifest_version(21);
372 feature
.set_max_manifest_version(18);
373 EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION
, feature
.IsAvailableToContext(
374 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
375 Feature::CHROMEOS_PLATFORM
).result());
376 feature
.set_max_manifest_version(25);
379 TEST(SimpleFeatureTest
, Location
) {
380 // Component extensions can access any location.
381 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
382 Manifest::COMPONENT
));
383 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::EXTERNAL_COMPONENT_LOCATION
,
384 Manifest::COMPONENT
));
386 LocationIsAvailable(SimpleFeature::POLICY_LOCATION
, Manifest::COMPONENT
));
387 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::UNSPECIFIED_LOCATION
,
388 Manifest::COMPONENT
));
390 // Only component extensions can access the "component" location.
391 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
392 Manifest::INVALID_LOCATION
));
393 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
394 Manifest::UNPACKED
));
395 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
396 Manifest::EXTERNAL_COMPONENT
));
397 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
398 Manifest::EXTERNAL_PREF_DOWNLOAD
));
399 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
400 Manifest::EXTERNAL_POLICY
));
401 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
402 Manifest::EXTERNAL_POLICY_DOWNLOAD
));
404 // Policy extensions can access the "policy" location.
405 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
406 Manifest::EXTERNAL_POLICY
));
407 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
408 Manifest::EXTERNAL_POLICY_DOWNLOAD
));
410 // Non-policy (except component) extensions cannot access policy.
411 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
412 Manifest::EXTERNAL_COMPONENT
));
413 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
414 Manifest::INVALID_LOCATION
));
416 LocationIsAvailable(SimpleFeature::POLICY_LOCATION
, Manifest::UNPACKED
));
417 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
418 Manifest::EXTERNAL_PREF_DOWNLOAD
));
420 // External component extensions can access the "external_component"
422 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::EXTERNAL_COMPONENT_LOCATION
,
423 Manifest::EXTERNAL_COMPONENT
));
426 TEST(SimpleFeatureTest
, Platform
) {
427 SimpleFeature feature
;
428 feature
.platforms()->insert(Feature::CHROMEOS_PLATFORM
);
429 EXPECT_EQ(Feature::IS_AVAILABLE
,
430 feature
.IsAvailableToManifest(std::string(),
431 Manifest::TYPE_UNKNOWN
,
432 Manifest::INVALID_LOCATION
,
434 Feature::CHROMEOS_PLATFORM
).result());
436 Feature::INVALID_PLATFORM
,
437 feature
.IsAvailableToManifest(std::string(),
438 Manifest::TYPE_UNKNOWN
,
439 Manifest::INVALID_LOCATION
,
441 Feature::UNSPECIFIED_PLATFORM
).result());
444 TEST(SimpleFeatureTest
, ManifestVersion
) {
445 SimpleFeature feature
;
446 feature
.set_min_manifest_version(5);
449 Feature::INVALID_MIN_MANIFEST_VERSION
,
450 feature
.IsAvailableToManifest(std::string(),
451 Manifest::TYPE_UNKNOWN
,
452 Manifest::INVALID_LOCATION
,
454 Feature::UNSPECIFIED_PLATFORM
).result());
456 Feature::INVALID_MIN_MANIFEST_VERSION
,
457 feature
.IsAvailableToManifest(std::string(),
458 Manifest::TYPE_UNKNOWN
,
459 Manifest::INVALID_LOCATION
,
461 Feature::UNSPECIFIED_PLATFORM
).result());
464 Feature::IS_AVAILABLE
,
465 feature
.IsAvailableToManifest(std::string(),
466 Manifest::TYPE_UNKNOWN
,
467 Manifest::INVALID_LOCATION
,
469 Feature::UNSPECIFIED_PLATFORM
).result());
471 Feature::IS_AVAILABLE
,
472 feature
.IsAvailableToManifest(std::string(),
473 Manifest::TYPE_UNKNOWN
,
474 Manifest::INVALID_LOCATION
,
476 Feature::UNSPECIFIED_PLATFORM
).result());
478 feature
.set_max_manifest_version(8);
481 Feature::INVALID_MAX_MANIFEST_VERSION
,
482 feature
.IsAvailableToManifest(std::string(),
483 Manifest::TYPE_UNKNOWN
,
484 Manifest::INVALID_LOCATION
,
486 Feature::UNSPECIFIED_PLATFORM
).result());
488 Feature::IS_AVAILABLE
,
489 feature
.IsAvailableToManifest(std::string(),
490 Manifest::TYPE_UNKNOWN
,
491 Manifest::INVALID_LOCATION
,
493 Feature::UNSPECIFIED_PLATFORM
).result());
495 Feature::IS_AVAILABLE
,
496 feature
.IsAvailableToManifest(std::string(),
497 Manifest::TYPE_UNKNOWN
,
498 Manifest::INVALID_LOCATION
,
500 Feature::UNSPECIFIED_PLATFORM
).result());
503 TEST(SimpleFeatureTest
, ParseNull
) {
504 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
505 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
506 feature
->Parse(value
.get());
507 EXPECT_TRUE(feature
->whitelist()->empty());
508 EXPECT_TRUE(feature
->extension_types()->empty());
509 EXPECT_TRUE(feature
->contexts()->empty());
510 EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION
, feature
->location());
511 EXPECT_TRUE(feature
->platforms()->empty());
512 EXPECT_EQ(0, feature
->min_manifest_version());
513 EXPECT_EQ(0, feature
->max_manifest_version());
516 TEST(SimpleFeatureTest
, ParseWhitelist
) {
517 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
518 base::ListValue
* whitelist
= new base::ListValue();
519 whitelist
->Append(new base::StringValue("foo"));
520 whitelist
->Append(new base::StringValue("bar"));
521 value
->Set("whitelist", whitelist
);
522 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
523 feature
->Parse(value
.get());
524 EXPECT_EQ(2u, feature
->whitelist()->size());
525 EXPECT_TRUE(feature
->whitelist()->count("foo"));
526 EXPECT_TRUE(feature
->whitelist()->count("bar"));
529 TEST(SimpleFeatureTest
, ParsePackageTypes
) {
530 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
531 base::ListValue
* extension_types
= new base::ListValue();
532 extension_types
->Append(new base::StringValue("extension"));
533 extension_types
->Append(new base::StringValue("theme"));
534 extension_types
->Append(new base::StringValue("legacy_packaged_app"));
535 extension_types
->Append(new base::StringValue("hosted_app"));
536 extension_types
->Append(new base::StringValue("platform_app"));
537 extension_types
->Append(new base::StringValue("shared_module"));
538 value
->Set("extension_types", extension_types
);
539 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
540 feature
->Parse(value
.get());
541 EXPECT_EQ(6u, feature
->extension_types()->size());
542 EXPECT_TRUE(feature
->extension_types()->count(Manifest::TYPE_EXTENSION
));
543 EXPECT_TRUE(feature
->extension_types()->count(Manifest::TYPE_THEME
));
544 EXPECT_TRUE(feature
->extension_types()->count(
545 Manifest::TYPE_LEGACY_PACKAGED_APP
));
546 EXPECT_TRUE(feature
->extension_types()->count(Manifest::TYPE_HOSTED_APP
));
547 EXPECT_TRUE(feature
->extension_types()->count(Manifest::TYPE_PLATFORM_APP
));
548 EXPECT_TRUE(feature
->extension_types()->count(Manifest::TYPE_SHARED_MODULE
));
550 value
->SetString("extension_types", "all");
551 scoped_ptr
<SimpleFeature
> feature2(new SimpleFeature());
552 feature2
->Parse(value
.get());
553 EXPECT_EQ(*(feature
->extension_types()), *(feature2
->extension_types()));
556 TEST(SimpleFeatureTest
, ParseContexts
) {
557 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
558 base::ListValue
* contexts
= new base::ListValue();
559 contexts
->Append(new base::StringValue("blessed_extension"));
560 contexts
->Append(new base::StringValue("unblessed_extension"));
561 contexts
->Append(new base::StringValue("content_script"));
562 contexts
->Append(new base::StringValue("web_page"));
563 contexts
->Append(new base::StringValue("blessed_web_page"));
564 contexts
->Append(new base::StringValue("webui"));
565 value
->Set("contexts", contexts
);
566 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
567 feature
->Parse(value
.get());
568 EXPECT_EQ(6u, feature
->contexts()->size());
569 EXPECT_TRUE(feature
->contexts()->count(Feature::BLESSED_EXTENSION_CONTEXT
));
570 EXPECT_TRUE(feature
->contexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT
));
571 EXPECT_TRUE(feature
->contexts()->count(Feature::CONTENT_SCRIPT_CONTEXT
));
572 EXPECT_TRUE(feature
->contexts()->count(Feature::WEB_PAGE_CONTEXT
));
573 EXPECT_TRUE(feature
->contexts()->count(Feature::BLESSED_WEB_PAGE_CONTEXT
));
575 value
->SetString("contexts", "all");
576 scoped_ptr
<SimpleFeature
> feature2(new SimpleFeature());
577 feature2
->Parse(value
.get());
578 EXPECT_EQ(*(feature
->contexts()), *(feature2
->contexts()));
581 TEST(SimpleFeatureTest
, ParseLocation
) {
582 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
583 value
->SetString("location", "component");
584 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
585 feature
->Parse(value
.get());
586 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION
, feature
->location());
589 TEST(SimpleFeatureTest
, ParsePlatforms
) {
590 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
591 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
592 base::ListValue
* platforms
= new base::ListValue();
593 value
->Set("platforms", platforms
);
594 feature
->Parse(value
.get());
595 EXPECT_TRUE(feature
->platforms()->empty());
597 platforms
->AppendString("chromeos");
598 feature
->Parse(value
.get());
599 EXPECT_FALSE(feature
->platforms()->empty());
600 EXPECT_EQ(Feature::CHROMEOS_PLATFORM
, *feature
->platforms()->begin());
603 platforms
->AppendString("win");
604 feature
->Parse(value
.get());
605 EXPECT_FALSE(feature
->platforms()->empty());
606 EXPECT_EQ(Feature::WIN_PLATFORM
, *feature
->platforms()->begin());
609 platforms
->AppendString("win");
610 platforms
->AppendString("chromeos");
611 feature
->Parse(value
.get());
612 std::set
<Feature::Platform
> expected_platforms
;
613 expected_platforms
.insert(Feature::CHROMEOS_PLATFORM
);
614 expected_platforms
.insert(Feature::WIN_PLATFORM
);
616 EXPECT_FALSE(feature
->platforms()->empty());
617 EXPECT_EQ(expected_platforms
, *feature
->platforms());
620 TEST(SimpleFeatureTest
, ParseManifestVersion
) {
621 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
622 value
->SetInteger("min_manifest_version", 1);
623 value
->SetInteger("max_manifest_version", 5);
624 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
625 feature
->Parse(value
.get());
626 EXPECT_EQ(1, feature
->min_manifest_version());
627 EXPECT_EQ(5, feature
->max_manifest_version());
630 TEST(SimpleFeatureTest
, Inheritance
) {
631 SimpleFeature feature
;
632 feature
.whitelist()->insert("foo");
633 feature
.extension_types()->insert(Manifest::TYPE_THEME
);
634 feature
.contexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT
);
635 feature
.set_location(SimpleFeature::COMPONENT_LOCATION
);
636 feature
.platforms()->insert(Feature::CHROMEOS_PLATFORM
);
637 feature
.set_min_manifest_version(1);
638 feature
.set_max_manifest_version(2);
640 // Test additive parsing. Parsing an empty dictionary should result in no
641 // changes to a SimpleFeature.
642 base::DictionaryValue definition
;
643 feature
.Parse(&definition
);
644 EXPECT_EQ(1u, feature
.whitelist()->size());
645 EXPECT_EQ(1u, feature
.extension_types()->size());
646 EXPECT_EQ(1u, feature
.contexts()->size());
647 EXPECT_EQ(1u, feature
.whitelist()->count("foo"));
648 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION
, feature
.location());
649 EXPECT_EQ(1u, feature
.platforms()->size());
650 EXPECT_EQ(1u, feature
.platforms()->count(Feature::CHROMEOS_PLATFORM
));
651 EXPECT_EQ(1, feature
.min_manifest_version());
652 EXPECT_EQ(2, feature
.max_manifest_version());
654 base::ListValue
* whitelist
= new base::ListValue();
655 base::ListValue
* extension_types
= new base::ListValue();
656 base::ListValue
* contexts
= new base::ListValue();
657 whitelist
->Append(new base::StringValue("bar"));
658 extension_types
->Append(new base::StringValue("extension"));
659 contexts
->Append(new base::StringValue("unblessed_extension"));
660 definition
.Set("whitelist", whitelist
);
661 definition
.Set("extension_types", extension_types
);
662 definition
.Set("contexts", contexts
);
663 // Can't test location or platform because we only have one value so far.
664 definition
.Set("min_manifest_version", new base::FundamentalValue(2));
665 definition
.Set("max_manifest_version", new base::FundamentalValue(3));
667 feature
.Parse(&definition
);
668 EXPECT_EQ(1u, feature
.whitelist()->size());
669 EXPECT_EQ(1u, feature
.extension_types()->size());
670 EXPECT_EQ(1u, feature
.contexts()->size());
671 EXPECT_EQ(1u, feature
.whitelist()->count("bar"));
672 EXPECT_EQ(1u, feature
.extension_types()->count(Manifest::TYPE_EXTENSION
));
674 feature
.contexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT
));
675 EXPECT_EQ(2, feature
.min_manifest_version());
676 EXPECT_EQ(3, feature
.max_manifest_version());
679 TEST(SimpleFeatureTest
, CommandLineSwitch
) {
680 SimpleFeature feature
;
681 feature
.set_command_line_switch("laser-beams");
683 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
684 feature
.IsAvailableToEnvironment().result());
687 ScopedCommandLineSwitch
scoped_switch("laser-beams");
688 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
689 feature
.IsAvailableToEnvironment().result());
692 ScopedCommandLineSwitch
scoped_switch("enable-laser-beams");
693 EXPECT_EQ(Feature::IS_AVAILABLE
,
694 feature
.IsAvailableToEnvironment().result());
697 ScopedCommandLineSwitch
scoped_switch("disable-laser-beams");
698 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
699 feature
.IsAvailableToEnvironment().result());
702 ScopedCommandLineSwitch
scoped_switch("laser-beams=1");
703 EXPECT_EQ(Feature::IS_AVAILABLE
,
704 feature
.IsAvailableToEnvironment().result());
707 ScopedCommandLineSwitch
scoped_switch("laser-beams=0");
708 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
709 feature
.IsAvailableToEnvironment().result());
713 } // namespace extensions