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/stl_util.h"
11 #include "base/values.h"
12 #include "extensions/common/manifest.h"
13 #include "extensions/common/value_builder.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace extensions
{
20 struct IsAvailableTestData
{
21 std::string extension_id
;
22 Manifest::Type extension_type
;
23 Manifest::Location location
;
24 Feature::Platform platform
;
26 Feature::AvailabilityResult expected_result
;
29 class ScopedCommandLineSwitch
{
31 explicit ScopedCommandLineSwitch(const std::string
& arg
)
32 : original_command_line_(*base::CommandLine::ForCurrentProcess()) {
33 base::CommandLine::ForCurrentProcess()->AppendSwitch(arg
);
36 ~ScopedCommandLineSwitch() {
37 *base::CommandLine::ForCurrentProcess() = original_command_line_
;
41 base::CommandLine original_command_line_
;
46 class SimpleFeatureTest
: public testing::Test
{
48 bool LocationIsAvailable(SimpleFeature::Location feature_location
,
49 Manifest::Location manifest_location
) {
50 SimpleFeature feature
;
51 feature
.set_location(feature_location
);
52 Feature::AvailabilityResult availability_result
=
53 feature
.IsAvailableToManifest(std::string(),
54 Manifest::TYPE_UNKNOWN
,
57 Feature::UNSPECIFIED_PLATFORM
).result();
58 return availability_result
== Feature::IS_AVAILABLE
;
62 TEST_F(SimpleFeatureTest
, IsAvailableNullCase
) {
63 const IsAvailableTestData tests
[] = {
64 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
65 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
66 {"random-extension", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
67 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
68 {"", Manifest::TYPE_LEGACY_PACKAGED_APP
, Manifest::INVALID_LOCATION
,
69 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
70 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
71 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
72 {"", Manifest::TYPE_UNKNOWN
, Manifest::COMPONENT
,
73 Feature::UNSPECIFIED_PLATFORM
, -1, Feature::IS_AVAILABLE
},
74 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
75 Feature::CHROMEOS_PLATFORM
, -1, Feature::IS_AVAILABLE
},
76 {"", Manifest::TYPE_UNKNOWN
, Manifest::INVALID_LOCATION
,
77 Feature::UNSPECIFIED_PLATFORM
, 25, Feature::IS_AVAILABLE
}};
79 SimpleFeature feature
;
80 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
81 const IsAvailableTestData
& test
= tests
[i
];
82 EXPECT_EQ(test
.expected_result
,
83 feature
.IsAvailableToManifest(test
.extension_id
,
86 test
.manifest_version
,
87 test
.platform
).result());
91 TEST_F(SimpleFeatureTest
, Whitelist
) {
92 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
93 const std::string
kIdBar("barabbbbccccddddeeeeffffgggghhhh");
94 const std::string
kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
95 SimpleFeature feature
;
96 feature
.whitelist()->push_back(kIdFoo
);
97 feature
.whitelist()->push_back(kIdBar
);
100 Feature::IS_AVAILABLE
,
101 feature
.IsAvailableToManifest(kIdFoo
,
102 Manifest::TYPE_UNKNOWN
,
103 Manifest::INVALID_LOCATION
,
105 Feature::UNSPECIFIED_PLATFORM
).result());
107 Feature::IS_AVAILABLE
,
108 feature
.IsAvailableToManifest(kIdBar
,
109 Manifest::TYPE_UNKNOWN
,
110 Manifest::INVALID_LOCATION
,
112 Feature::UNSPECIFIED_PLATFORM
).result());
115 Feature::NOT_FOUND_IN_WHITELIST
,
116 feature
.IsAvailableToManifest(kIdBaz
,
117 Manifest::TYPE_UNKNOWN
,
118 Manifest::INVALID_LOCATION
,
120 Feature::UNSPECIFIED_PLATFORM
).result());
122 Feature::NOT_FOUND_IN_WHITELIST
,
123 feature
.IsAvailableToManifest(std::string(),
124 Manifest::TYPE_UNKNOWN
,
125 Manifest::INVALID_LOCATION
,
127 Feature::UNSPECIFIED_PLATFORM
).result());
129 feature
.extension_types()->push_back(Manifest::TYPE_LEGACY_PACKAGED_APP
);
131 Feature::NOT_FOUND_IN_WHITELIST
,
132 feature
.IsAvailableToManifest(kIdBaz
,
133 Manifest::TYPE_LEGACY_PACKAGED_APP
,
134 Manifest::INVALID_LOCATION
,
136 Feature::UNSPECIFIED_PLATFORM
).result());
139 TEST_F(SimpleFeatureTest
, HashedIdWhitelist
) {
140 // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
141 // sha1sum | tr '[:lower:]' '[:upper:]'
142 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
143 const std::string
kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
144 SimpleFeature feature
;
146 feature
.whitelist()->push_back(kIdFooHashed
);
149 Feature::IS_AVAILABLE
,
150 feature
.IsAvailableToManifest(kIdFoo
,
151 Manifest::TYPE_UNKNOWN
,
152 Manifest::INVALID_LOCATION
,
154 Feature::UNSPECIFIED_PLATFORM
).result());
156 Feature::IS_AVAILABLE
,
157 feature
.IsAvailableToManifest(kIdFooHashed
,
158 Manifest::TYPE_UNKNOWN
,
159 Manifest::INVALID_LOCATION
,
161 Feature::UNSPECIFIED_PLATFORM
).result());
163 Feature::NOT_FOUND_IN_WHITELIST
,
164 feature
.IsAvailableToManifest("slightlytoooolongforanextensionid",
165 Manifest::TYPE_UNKNOWN
,
166 Manifest::INVALID_LOCATION
,
168 Feature::UNSPECIFIED_PLATFORM
).result());
170 Feature::NOT_FOUND_IN_WHITELIST
,
171 feature
.IsAvailableToManifest("tooshortforanextensionid",
172 Manifest::TYPE_UNKNOWN
,
173 Manifest::INVALID_LOCATION
,
175 Feature::UNSPECIFIED_PLATFORM
).result());
178 TEST_F(SimpleFeatureTest
, Blacklist
) {
179 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
180 const std::string
kIdBar("barabbbbccccddddeeeeffffgggghhhh");
181 const std::string
kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
182 SimpleFeature feature
;
183 feature
.blacklist()->push_back(kIdFoo
);
184 feature
.blacklist()->push_back(kIdBar
);
187 Feature::FOUND_IN_BLACKLIST
,
188 feature
.IsAvailableToManifest(kIdFoo
,
189 Manifest::TYPE_UNKNOWN
,
190 Manifest::INVALID_LOCATION
,
192 Feature::UNSPECIFIED_PLATFORM
).result());
194 Feature::FOUND_IN_BLACKLIST
,
195 feature
.IsAvailableToManifest(kIdBar
,
196 Manifest::TYPE_UNKNOWN
,
197 Manifest::INVALID_LOCATION
,
199 Feature::UNSPECIFIED_PLATFORM
).result());
202 Feature::IS_AVAILABLE
,
203 feature
.IsAvailableToManifest(kIdBaz
,
204 Manifest::TYPE_UNKNOWN
,
205 Manifest::INVALID_LOCATION
,
207 Feature::UNSPECIFIED_PLATFORM
).result());
209 Feature::IS_AVAILABLE
,
210 feature
.IsAvailableToManifest(std::string(),
211 Manifest::TYPE_UNKNOWN
,
212 Manifest::INVALID_LOCATION
,
214 Feature::UNSPECIFIED_PLATFORM
).result());
217 TEST_F(SimpleFeatureTest
, HashedIdBlacklist
) {
218 // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
219 // sha1sum | tr '[:lower:]' '[:upper:]'
220 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
221 const std::string
kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
222 SimpleFeature feature
;
224 feature
.blacklist()->push_back(kIdFooHashed
);
227 Feature::FOUND_IN_BLACKLIST
,
228 feature
.IsAvailableToManifest(kIdFoo
,
229 Manifest::TYPE_UNKNOWN
,
230 Manifest::INVALID_LOCATION
,
232 Feature::UNSPECIFIED_PLATFORM
).result());
234 Feature::FOUND_IN_BLACKLIST
,
235 feature
.IsAvailableToManifest(kIdFooHashed
,
236 Manifest::TYPE_UNKNOWN
,
237 Manifest::INVALID_LOCATION
,
239 Feature::UNSPECIFIED_PLATFORM
).result());
241 Feature::IS_AVAILABLE
,
242 feature
.IsAvailableToManifest("slightlytoooolongforanextensionid",
243 Manifest::TYPE_UNKNOWN
,
244 Manifest::INVALID_LOCATION
,
246 Feature::UNSPECIFIED_PLATFORM
).result());
248 Feature::IS_AVAILABLE
,
249 feature
.IsAvailableToManifest("tooshortforanextensionid",
250 Manifest::TYPE_UNKNOWN
,
251 Manifest::INVALID_LOCATION
,
253 Feature::UNSPECIFIED_PLATFORM
).result());
256 TEST_F(SimpleFeatureTest
, PackageType
) {
257 SimpleFeature feature
;
258 feature
.extension_types()->push_back(Manifest::TYPE_EXTENSION
);
259 feature
.extension_types()->push_back(Manifest::TYPE_LEGACY_PACKAGED_APP
);
262 Feature::IS_AVAILABLE
,
263 feature
.IsAvailableToManifest(std::string(),
264 Manifest::TYPE_EXTENSION
,
265 Manifest::INVALID_LOCATION
,
267 Feature::UNSPECIFIED_PLATFORM
).result());
269 Feature::IS_AVAILABLE
,
270 feature
.IsAvailableToManifest(std::string(),
271 Manifest::TYPE_LEGACY_PACKAGED_APP
,
272 Manifest::INVALID_LOCATION
,
274 Feature::UNSPECIFIED_PLATFORM
).result());
277 Feature::INVALID_TYPE
,
278 feature
.IsAvailableToManifest(std::string(),
279 Manifest::TYPE_UNKNOWN
,
280 Manifest::INVALID_LOCATION
,
282 Feature::UNSPECIFIED_PLATFORM
).result());
284 Feature::INVALID_TYPE
,
285 feature
.IsAvailableToManifest(std::string(),
286 Manifest::TYPE_THEME
,
287 Manifest::INVALID_LOCATION
,
289 Feature::UNSPECIFIED_PLATFORM
).result());
292 TEST_F(SimpleFeatureTest
, Context
) {
293 SimpleFeature feature
;
294 feature
.set_name("somefeature");
295 feature
.contexts()->push_back(Feature::BLESSED_EXTENSION_CONTEXT
);
296 feature
.extension_types()->push_back(Manifest::TYPE_LEGACY_PACKAGED_APP
);
297 feature
.platforms()->push_back(Feature::CHROMEOS_PLATFORM
);
298 feature
.set_min_manifest_version(21);
299 feature
.set_max_manifest_version(25);
301 base::DictionaryValue manifest
;
302 manifest
.SetString("name", "test");
303 manifest
.SetString("version", "1");
304 manifest
.SetInteger("manifest_version", 21);
305 manifest
.SetString("app.launch.local_path", "foo.html");
308 scoped_refptr
<const Extension
> extension(Extension::Create(
309 base::FilePath(), Manifest::INTERNAL
, manifest
, Extension::NO_FLAGS
,
311 EXPECT_EQ("", error
);
312 ASSERT_TRUE(extension
.get());
314 feature
.whitelist()->push_back("monkey");
315 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST
, feature
.IsAvailableToContext(
316 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
317 Feature::CHROMEOS_PLATFORM
).result());
318 feature
.whitelist()->clear();
320 feature
.extension_types()->clear();
321 feature
.extension_types()->push_back(Manifest::TYPE_THEME
);
323 Feature::Availability availability
= feature
.IsAvailableToContext(
324 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
325 Feature::CHROMEOS_PLATFORM
);
326 EXPECT_EQ(Feature::INVALID_TYPE
, availability
.result());
327 EXPECT_EQ("'somefeature' is only allowed for themes, "
328 "but this is a legacy packaged app.",
329 availability
.message());
332 feature
.extension_types()->clear();
333 feature
.extension_types()->push_back(Manifest::TYPE_LEGACY_PACKAGED_APP
);
334 feature
.contexts()->clear();
335 feature
.contexts()->push_back(Feature::UNBLESSED_EXTENSION_CONTEXT
);
336 feature
.contexts()->push_back(Feature::CONTENT_SCRIPT_CONTEXT
);
338 Feature::Availability availability
= feature
.IsAvailableToContext(
339 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
340 Feature::CHROMEOS_PLATFORM
);
341 EXPECT_EQ(Feature::INVALID_CONTEXT
, availability
.result());
342 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes and "
343 "content scripts, but this is a privileged page",
344 availability
.message());
347 feature
.contexts()->push_back(Feature::WEB_PAGE_CONTEXT
);
349 Feature::Availability availability
= feature
.IsAvailableToContext(
350 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
351 Feature::CHROMEOS_PLATFORM
);
352 EXPECT_EQ(Feature::INVALID_CONTEXT
, availability
.result());
353 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes, "
354 "content scripts, and web pages, but this is a privileged page",
355 availability
.message());
358 feature
.contexts()->clear();
359 feature
.contexts()->push_back(Feature::BLESSED_EXTENSION_CONTEXT
);
360 feature
.set_location(SimpleFeature::COMPONENT_LOCATION
);
361 EXPECT_EQ(Feature::INVALID_LOCATION
, feature
.IsAvailableToContext(
362 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
363 Feature::CHROMEOS_PLATFORM
).result());
364 feature
.set_location(SimpleFeature::UNSPECIFIED_LOCATION
);
366 EXPECT_EQ(Feature::INVALID_PLATFORM
, feature
.IsAvailableToContext(
367 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
368 Feature::UNSPECIFIED_PLATFORM
).result());
370 feature
.set_min_manifest_version(22);
371 EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION
, feature
.IsAvailableToContext(
372 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
373 Feature::CHROMEOS_PLATFORM
).result());
374 feature
.set_min_manifest_version(21);
376 feature
.set_max_manifest_version(18);
377 EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION
, feature
.IsAvailableToContext(
378 extension
.get(), Feature::BLESSED_EXTENSION_CONTEXT
,
379 Feature::CHROMEOS_PLATFORM
).result());
380 feature
.set_max_manifest_version(25);
383 TEST_F(SimpleFeatureTest
, Location
) {
384 // Component extensions can access any location.
385 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
386 Manifest::COMPONENT
));
387 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::EXTERNAL_COMPONENT_LOCATION
,
388 Manifest::COMPONENT
));
390 LocationIsAvailable(SimpleFeature::POLICY_LOCATION
, Manifest::COMPONENT
));
391 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::UNSPECIFIED_LOCATION
,
392 Manifest::COMPONENT
));
394 // Only component extensions can access the "component" location.
395 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
396 Manifest::INVALID_LOCATION
));
397 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
398 Manifest::UNPACKED
));
399 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
400 Manifest::EXTERNAL_COMPONENT
));
401 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
402 Manifest::EXTERNAL_PREF_DOWNLOAD
));
403 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
404 Manifest::EXTERNAL_POLICY
));
405 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION
,
406 Manifest::EXTERNAL_POLICY_DOWNLOAD
));
408 // Policy extensions can access the "policy" location.
409 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
410 Manifest::EXTERNAL_POLICY
));
411 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
412 Manifest::EXTERNAL_POLICY_DOWNLOAD
));
414 // Non-policy (except component) extensions cannot access policy.
415 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
416 Manifest::EXTERNAL_COMPONENT
));
417 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
418 Manifest::INVALID_LOCATION
));
420 LocationIsAvailable(SimpleFeature::POLICY_LOCATION
, Manifest::UNPACKED
));
421 EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION
,
422 Manifest::EXTERNAL_PREF_DOWNLOAD
));
424 // External component extensions can access the "external_component"
426 EXPECT_TRUE(LocationIsAvailable(SimpleFeature::EXTERNAL_COMPONENT_LOCATION
,
427 Manifest::EXTERNAL_COMPONENT
));
430 TEST_F(SimpleFeatureTest
, Platform
) {
431 SimpleFeature feature
;
432 feature
.platforms()->push_back(Feature::CHROMEOS_PLATFORM
);
433 EXPECT_EQ(Feature::IS_AVAILABLE
,
434 feature
.IsAvailableToManifest(std::string(),
435 Manifest::TYPE_UNKNOWN
,
436 Manifest::INVALID_LOCATION
,
438 Feature::CHROMEOS_PLATFORM
).result());
440 Feature::INVALID_PLATFORM
,
441 feature
.IsAvailableToManifest(std::string(),
442 Manifest::TYPE_UNKNOWN
,
443 Manifest::INVALID_LOCATION
,
445 Feature::UNSPECIFIED_PLATFORM
).result());
448 TEST_F(SimpleFeatureTest
, ManifestVersion
) {
449 SimpleFeature feature
;
450 feature
.set_min_manifest_version(5);
453 Feature::INVALID_MIN_MANIFEST_VERSION
,
454 feature
.IsAvailableToManifest(std::string(),
455 Manifest::TYPE_UNKNOWN
,
456 Manifest::INVALID_LOCATION
,
458 Feature::UNSPECIFIED_PLATFORM
).result());
460 Feature::INVALID_MIN_MANIFEST_VERSION
,
461 feature
.IsAvailableToManifest(std::string(),
462 Manifest::TYPE_UNKNOWN
,
463 Manifest::INVALID_LOCATION
,
465 Feature::UNSPECIFIED_PLATFORM
).result());
468 Feature::IS_AVAILABLE
,
469 feature
.IsAvailableToManifest(std::string(),
470 Manifest::TYPE_UNKNOWN
,
471 Manifest::INVALID_LOCATION
,
473 Feature::UNSPECIFIED_PLATFORM
).result());
475 Feature::IS_AVAILABLE
,
476 feature
.IsAvailableToManifest(std::string(),
477 Manifest::TYPE_UNKNOWN
,
478 Manifest::INVALID_LOCATION
,
480 Feature::UNSPECIFIED_PLATFORM
).result());
482 feature
.set_max_manifest_version(8);
485 Feature::INVALID_MAX_MANIFEST_VERSION
,
486 feature
.IsAvailableToManifest(std::string(),
487 Manifest::TYPE_UNKNOWN
,
488 Manifest::INVALID_LOCATION
,
490 Feature::UNSPECIFIED_PLATFORM
).result());
492 Feature::IS_AVAILABLE
,
493 feature
.IsAvailableToManifest(std::string(),
494 Manifest::TYPE_UNKNOWN
,
495 Manifest::INVALID_LOCATION
,
497 Feature::UNSPECIFIED_PLATFORM
).result());
499 Feature::IS_AVAILABLE
,
500 feature
.IsAvailableToManifest(std::string(),
501 Manifest::TYPE_UNKNOWN
,
502 Manifest::INVALID_LOCATION
,
504 Feature::UNSPECIFIED_PLATFORM
).result());
507 TEST_F(SimpleFeatureTest
, ParseNull
) {
508 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
509 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
510 feature
->Parse(value
.get());
511 EXPECT_TRUE(feature
->whitelist()->empty());
512 EXPECT_TRUE(feature
->extension_types()->empty());
513 EXPECT_TRUE(feature
->contexts()->empty());
514 EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION
, feature
->location());
515 EXPECT_TRUE(feature
->platforms()->empty());
516 EXPECT_EQ(0, feature
->min_manifest_version());
517 EXPECT_EQ(0, feature
->max_manifest_version());
520 TEST_F(SimpleFeatureTest
, ParseWhitelist
) {
521 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
522 base::ListValue
* whitelist
= new base::ListValue();
523 whitelist
->Append(new base::StringValue("foo"));
524 whitelist
->Append(new base::StringValue("bar"));
525 value
->Set("whitelist", whitelist
);
526 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
527 feature
->Parse(value
.get());
528 EXPECT_EQ(2u, feature
->whitelist()->size());
529 EXPECT_TRUE(STLCount(*(feature
->whitelist()), "foo"));
530 EXPECT_TRUE(STLCount(*(feature
->whitelist()), "bar"));
533 TEST_F(SimpleFeatureTest
, ParsePackageTypes
) {
534 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
535 base::ListValue
* extension_types
= new base::ListValue();
536 extension_types
->Append(new base::StringValue("extension"));
537 extension_types
->Append(new base::StringValue("theme"));
538 extension_types
->Append(new base::StringValue("legacy_packaged_app"));
539 extension_types
->Append(new base::StringValue("hosted_app"));
540 extension_types
->Append(new base::StringValue("platform_app"));
541 extension_types
->Append(new base::StringValue("shared_module"));
542 value
->Set("extension_types", extension_types
);
543 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
544 feature
->Parse(value
.get());
545 EXPECT_EQ(6u, feature
->extension_types()->size());
547 STLCount(*(feature
->extension_types()), Manifest::TYPE_EXTENSION
));
549 STLCount(*(feature
->extension_types()), Manifest::TYPE_THEME
));
552 *(feature
->extension_types()), Manifest::TYPE_LEGACY_PACKAGED_APP
));
554 STLCount(*(feature
->extension_types()), Manifest::TYPE_HOSTED_APP
));
556 STLCount(*(feature
->extension_types()), Manifest::TYPE_PLATFORM_APP
));
558 STLCount(*(feature
->extension_types()), Manifest::TYPE_SHARED_MODULE
));
560 value
->SetString("extension_types", "all");
561 scoped_ptr
<SimpleFeature
> feature2(new SimpleFeature());
562 feature2
->Parse(value
.get());
563 EXPECT_EQ(*(feature
->extension_types()), *(feature2
->extension_types()));
566 TEST_F(SimpleFeatureTest
, ParseContexts
) {
567 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
568 base::ListValue
* contexts
= new base::ListValue();
569 contexts
->Append(new base::StringValue("blessed_extension"));
570 contexts
->Append(new base::StringValue("unblessed_extension"));
571 contexts
->Append(new base::StringValue("content_script"));
572 contexts
->Append(new base::StringValue("web_page"));
573 contexts
->Append(new base::StringValue("blessed_web_page"));
574 contexts
->Append(new base::StringValue("webui"));
575 value
->Set("contexts", contexts
);
576 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
577 feature
->Parse(value
.get());
578 EXPECT_EQ(6u, feature
->contexts()->size());
580 STLCount(*(feature
->contexts()), Feature::BLESSED_EXTENSION_CONTEXT
));
582 STLCount(*(feature
->contexts()), Feature::UNBLESSED_EXTENSION_CONTEXT
));
584 STLCount(*(feature
->contexts()), Feature::CONTENT_SCRIPT_CONTEXT
));
586 STLCount(*(feature
->contexts()), Feature::WEB_PAGE_CONTEXT
));
588 STLCount(*(feature
->contexts()), Feature::BLESSED_WEB_PAGE_CONTEXT
));
590 value
->SetString("contexts", "all");
591 scoped_ptr
<SimpleFeature
> feature2(new SimpleFeature());
592 feature2
->Parse(value
.get());
593 EXPECT_EQ(*(feature
->contexts()), *(feature2
->contexts()));
596 TEST_F(SimpleFeatureTest
, ParseLocation
) {
597 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
598 value
->SetString("location", "component");
599 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
600 feature
->Parse(value
.get());
601 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION
, feature
->location());
604 TEST_F(SimpleFeatureTest
, ParsePlatforms
) {
605 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
606 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
607 base::ListValue
* platforms
= new base::ListValue();
608 value
->Set("platforms", platforms
);
609 feature
->Parse(value
.get());
610 EXPECT_TRUE(feature
->platforms()->empty());
612 platforms
->AppendString("chromeos");
613 feature
->Parse(value
.get());
614 EXPECT_FALSE(feature
->platforms()->empty());
615 EXPECT_EQ(Feature::CHROMEOS_PLATFORM
, *feature
->platforms()->begin());
618 platforms
->AppendString("win");
619 feature
->Parse(value
.get());
620 EXPECT_FALSE(feature
->platforms()->empty());
621 EXPECT_EQ(Feature::WIN_PLATFORM
, *feature
->platforms()->begin());
624 platforms
->AppendString("win");
625 platforms
->AppendString("chromeos");
626 feature
->Parse(value
.get());
627 std::vector
<Feature::Platform
> expected_platforms
;
628 expected_platforms
.push_back(Feature::CHROMEOS_PLATFORM
);
629 expected_platforms
.push_back(Feature::WIN_PLATFORM
);
631 EXPECT_FALSE(feature
->platforms()->empty());
632 EXPECT_EQ(expected_platforms
, *feature
->platforms());
635 TEST_F(SimpleFeatureTest
, ParseManifestVersion
) {
636 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue());
637 value
->SetInteger("min_manifest_version", 1);
638 value
->SetInteger("max_manifest_version", 5);
639 scoped_ptr
<SimpleFeature
> feature(new SimpleFeature());
640 feature
->Parse(value
.get());
641 EXPECT_EQ(1, feature
->min_manifest_version());
642 EXPECT_EQ(5, feature
->max_manifest_version());
645 TEST_F(SimpleFeatureTest
, Inheritance
) {
646 SimpleFeature feature
;
647 feature
.whitelist()->push_back("foo");
648 feature
.extension_types()->push_back(Manifest::TYPE_THEME
);
649 feature
.contexts()->push_back(Feature::BLESSED_EXTENSION_CONTEXT
);
650 feature
.set_location(SimpleFeature::COMPONENT_LOCATION
);
651 feature
.platforms()->push_back(Feature::CHROMEOS_PLATFORM
);
652 feature
.set_min_manifest_version(1);
653 feature
.set_max_manifest_version(2);
655 // Test additive parsing. Parsing an empty dictionary should result in no
656 // changes to a SimpleFeature.
657 base::DictionaryValue definition
;
658 feature
.Parse(&definition
);
659 EXPECT_EQ(1u, feature
.whitelist()->size());
660 EXPECT_EQ(1u, feature
.extension_types()->size());
661 EXPECT_EQ(1u, feature
.contexts()->size());
662 EXPECT_EQ(1, STLCount(*(feature
.whitelist()), "foo"));
663 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION
, feature
.location());
664 EXPECT_EQ(1u, feature
.platforms()->size());
665 EXPECT_EQ(1, STLCount(*(feature
.platforms()), Feature::CHROMEOS_PLATFORM
));
666 EXPECT_EQ(1, feature
.min_manifest_version());
667 EXPECT_EQ(2, feature
.max_manifest_version());
669 base::ListValue
* whitelist
= new base::ListValue();
670 base::ListValue
* extension_types
= new base::ListValue();
671 base::ListValue
* contexts
= new base::ListValue();
672 whitelist
->Append(new base::StringValue("bar"));
673 extension_types
->Append(new base::StringValue("extension"));
674 contexts
->Append(new base::StringValue("unblessed_extension"));
675 definition
.Set("whitelist", whitelist
);
676 definition
.Set("extension_types", extension_types
);
677 definition
.Set("contexts", contexts
);
678 // Can't test location or platform because we only have one value so far.
679 definition
.Set("min_manifest_version", new base::FundamentalValue(2));
680 definition
.Set("max_manifest_version", new base::FundamentalValue(3));
682 feature
.Parse(&definition
);
683 EXPECT_EQ(1u, feature
.whitelist()->size());
684 EXPECT_EQ(1u, feature
.extension_types()->size());
685 EXPECT_EQ(1u, feature
.contexts()->size());
686 EXPECT_EQ(1, STLCount(*(feature
.whitelist()), "bar"));
688 STLCount(*(feature
.extension_types()), Manifest::TYPE_EXTENSION
));
691 *(feature
.contexts()), Feature::UNBLESSED_EXTENSION_CONTEXT
));
692 EXPECT_EQ(2, feature
.min_manifest_version());
693 EXPECT_EQ(3, feature
.max_manifest_version());
696 TEST_F(SimpleFeatureTest
, CommandLineSwitch
) {
697 SimpleFeature feature
;
698 feature
.set_command_line_switch("laser-beams");
700 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
701 feature
.IsAvailableToEnvironment().result());
704 ScopedCommandLineSwitch
scoped_switch("laser-beams");
705 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
706 feature
.IsAvailableToEnvironment().result());
709 ScopedCommandLineSwitch
scoped_switch("enable-laser-beams");
710 EXPECT_EQ(Feature::IS_AVAILABLE
,
711 feature
.IsAvailableToEnvironment().result());
714 ScopedCommandLineSwitch
scoped_switch("disable-laser-beams");
715 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
716 feature
.IsAvailableToEnvironment().result());
719 ScopedCommandLineSwitch
scoped_switch("laser-beams=1");
720 EXPECT_EQ(Feature::IS_AVAILABLE
,
721 feature
.IsAvailableToEnvironment().result());
724 ScopedCommandLineSwitch
scoped_switch("laser-beams=0");
725 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH
,
726 feature
.IsAvailableToEnvironment().result());
730 TEST_F(SimpleFeatureTest
, IsIdInArray
) {
731 EXPECT_FALSE(SimpleFeature::IsIdInArray("", {}, 0));
732 EXPECT_FALSE(SimpleFeature::IsIdInArray(
733 "bbbbccccdddddddddeeeeeeffffgghhh", {}, 0));
735 const char* const kIdArray
[] = {
736 "bbbbccccdddddddddeeeeeeffffgghhh",
737 // aaaabbbbccccddddeeeeffffgggghhhh
738 "9A0417016F345C934A1A88F55CA17C05014EEEBA"
740 EXPECT_FALSE(SimpleFeature::IsIdInArray("", kIdArray
, arraysize(kIdArray
)));
741 EXPECT_FALSE(SimpleFeature::IsIdInArray(
742 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", kIdArray
, arraysize(kIdArray
)));
743 EXPECT_TRUE(SimpleFeature::IsIdInArray(
744 "bbbbccccdddddddddeeeeeeffffgghhh", kIdArray
, arraysize(kIdArray
)));
745 EXPECT_TRUE(SimpleFeature::IsIdInArray(
746 "aaaabbbbccccddddeeeeffffgggghhhh", kIdArray
, arraysize(kIdArray
)));
749 } // namespace extensions