Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / extensions / common / features / simple_feature_unittest.cc
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.
4
5 #include "extensions/common/features/simple_feature.h"
6
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"
11
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;
20
21 namespace extensions {
22
23 namespace {
24
25 struct IsAvailableTestData {
26   std::string extension_id;
27   Manifest::Type extension_type;
28   Manifest::Location location;
29   Feature::Platform platform;
30   int manifest_version;
31   Feature::AvailabilityResult expected_result;
32 };
33
34 }  // namespace
35
36 class ExtensionSimpleFeatureTest : public testing::Test {
37  protected:
38   ExtensionSimpleFeatureTest()
39       : current_channel_(VersionInfo::CHANNEL_UNKNOWN) {}
40   virtual ~ExtensionSimpleFeatureTest() {}
41
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,
49                                       manifest_location,
50                                       -1,
51                                       Feature::UNSPECIFIED_PLATFORM).result();
52     return availability_result == Feature::IS_AVAILABLE;
53   }
54
55  private:
56   ScopedCurrentChannel current_channel_;
57 };
58
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}};
75
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,
81                                             test.extension_type,
82                                             test.location,
83                                             test.manifest_version,
84                                             test.platform).result());
85   }
86 }
87
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);
95
96   EXPECT_EQ(
97       Feature::IS_AVAILABLE,
98       feature.IsAvailableToManifest(kIdFoo,
99                                     Manifest::TYPE_UNKNOWN,
100                                     Manifest::INVALID_LOCATION,
101                                     -1,
102                                     Feature::UNSPECIFIED_PLATFORM).result());
103   EXPECT_EQ(
104       Feature::IS_AVAILABLE,
105       feature.IsAvailableToManifest(kIdBar,
106                                     Manifest::TYPE_UNKNOWN,
107                                     Manifest::INVALID_LOCATION,
108                                     -1,
109                                     Feature::UNSPECIFIED_PLATFORM).result());
110
111   EXPECT_EQ(
112       Feature::NOT_FOUND_IN_WHITELIST,
113       feature.IsAvailableToManifest(kIdBaz,
114                                     Manifest::TYPE_UNKNOWN,
115                                     Manifest::INVALID_LOCATION,
116                                     -1,
117                                     Feature::UNSPECIFIED_PLATFORM).result());
118   EXPECT_EQ(
119       Feature::NOT_FOUND_IN_WHITELIST,
120       feature.IsAvailableToManifest(std::string(),
121                                     Manifest::TYPE_UNKNOWN,
122                                     Manifest::INVALID_LOCATION,
123                                     -1,
124                                     Feature::UNSPECIFIED_PLATFORM).result());
125
126   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
127   EXPECT_EQ(
128       Feature::NOT_FOUND_IN_WHITELIST,
129       feature.IsAvailableToManifest(kIdBaz,
130                                     Manifest::TYPE_LEGACY_PACKAGED_APP,
131                                     Manifest::INVALID_LOCATION,
132                                     -1,
133                                     Feature::UNSPECIFIED_PLATFORM).result());
134 }
135
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;
142
143   feature.whitelist()->insert(kIdFooHashed);
144
145   EXPECT_EQ(
146       Feature::IS_AVAILABLE,
147       feature.IsAvailableToManifest(kIdFoo,
148                                     Manifest::TYPE_UNKNOWN,
149                                     Manifest::INVALID_LOCATION,
150                                     -1,
151                                     Feature::UNSPECIFIED_PLATFORM).result());
152   EXPECT_NE(
153       Feature::IS_AVAILABLE,
154       feature.IsAvailableToManifest(kIdFooHashed,
155                                     Manifest::TYPE_UNKNOWN,
156                                     Manifest::INVALID_LOCATION,
157                                     -1,
158                                     Feature::UNSPECIFIED_PLATFORM).result());
159   EXPECT_EQ(
160       Feature::NOT_FOUND_IN_WHITELIST,
161       feature.IsAvailableToManifest("slightlytoooolongforanextensionid",
162                                     Manifest::TYPE_UNKNOWN,
163                                     Manifest::INVALID_LOCATION,
164                                     -1,
165                                     Feature::UNSPECIFIED_PLATFORM).result());
166   EXPECT_EQ(
167       Feature::NOT_FOUND_IN_WHITELIST,
168       feature.IsAvailableToManifest("tooshortforanextensionid",
169                                     Manifest::TYPE_UNKNOWN,
170                                     Manifest::INVALID_LOCATION,
171                                     -1,
172                                     Feature::UNSPECIFIED_PLATFORM).result());
173 }
174
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);
182
183   EXPECT_EQ(
184       Feature::FOUND_IN_BLACKLIST,
185       feature.IsAvailableToManifest(kIdFoo,
186                                     Manifest::TYPE_UNKNOWN,
187                                     Manifest::INVALID_LOCATION,
188                                     -1,
189                                     Feature::UNSPECIFIED_PLATFORM).result());
190   EXPECT_EQ(
191       Feature::FOUND_IN_BLACKLIST,
192       feature.IsAvailableToManifest(kIdBar,
193                                     Manifest::TYPE_UNKNOWN,
194                                     Manifest::INVALID_LOCATION,
195                                     -1,
196                                     Feature::UNSPECIFIED_PLATFORM).result());
197
198   EXPECT_EQ(
199       Feature::IS_AVAILABLE,
200       feature.IsAvailableToManifest(kIdBaz,
201                                     Manifest::TYPE_UNKNOWN,
202                                     Manifest::INVALID_LOCATION,
203                                     -1,
204                                     Feature::UNSPECIFIED_PLATFORM).result());
205   EXPECT_EQ(
206       Feature::IS_AVAILABLE,
207       feature.IsAvailableToManifest(std::string(),
208                                     Manifest::TYPE_UNKNOWN,
209                                     Manifest::INVALID_LOCATION,
210                                     -1,
211                                     Feature::UNSPECIFIED_PLATFORM).result());
212 }
213
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;
220
221   feature.blacklist()->insert(kIdFooHashed);
222
223   EXPECT_EQ(
224       Feature::FOUND_IN_BLACKLIST,
225       feature.IsAvailableToManifest(kIdFoo,
226                                     Manifest::TYPE_UNKNOWN,
227                                     Manifest::INVALID_LOCATION,
228                                     -1,
229                                     Feature::UNSPECIFIED_PLATFORM).result());
230   EXPECT_NE(
231       Feature::FOUND_IN_BLACKLIST,
232       feature.IsAvailableToManifest(kIdFooHashed,
233                                     Manifest::TYPE_UNKNOWN,
234                                     Manifest::INVALID_LOCATION,
235                                     -1,
236                                     Feature::UNSPECIFIED_PLATFORM).result());
237   EXPECT_EQ(
238       Feature::IS_AVAILABLE,
239       feature.IsAvailableToManifest("slightlytoooolongforanextensionid",
240                                     Manifest::TYPE_UNKNOWN,
241                                     Manifest::INVALID_LOCATION,
242                                     -1,
243                                     Feature::UNSPECIFIED_PLATFORM).result());
244   EXPECT_EQ(
245       Feature::IS_AVAILABLE,
246       feature.IsAvailableToManifest("tooshortforanextensionid",
247                                     Manifest::TYPE_UNKNOWN,
248                                     Manifest::INVALID_LOCATION,
249                                     -1,
250                                     Feature::UNSPECIFIED_PLATFORM).result());
251 }
252
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);
257
258   EXPECT_EQ(
259       Feature::IS_AVAILABLE,
260       feature.IsAvailableToManifest(std::string(),
261                                     Manifest::TYPE_EXTENSION,
262                                     Manifest::INVALID_LOCATION,
263                                     -1,
264                                     Feature::UNSPECIFIED_PLATFORM).result());
265   EXPECT_EQ(
266       Feature::IS_AVAILABLE,
267       feature.IsAvailableToManifest(std::string(),
268                                     Manifest::TYPE_LEGACY_PACKAGED_APP,
269                                     Manifest::INVALID_LOCATION,
270                                     -1,
271                                     Feature::UNSPECIFIED_PLATFORM).result());
272
273   EXPECT_EQ(
274       Feature::INVALID_TYPE,
275       feature.IsAvailableToManifest(std::string(),
276                                     Manifest::TYPE_UNKNOWN,
277                                     Manifest::INVALID_LOCATION,
278                                     -1,
279                                     Feature::UNSPECIFIED_PLATFORM).result());
280   EXPECT_EQ(
281       Feature::INVALID_TYPE,
282       feature.IsAvailableToManifest(std::string(),
283                                     Manifest::TYPE_THEME,
284                                     Manifest::INVALID_LOCATION,
285                                     -1,
286                                     Feature::UNSPECIFIED_PLATFORM).result());
287 }
288
289 TEST_F(ExtensionSimpleFeatureTest, Context) {
290   SimpleFeature feature;
291   feature.set_name("somefeature");
292   feature.GetContexts()->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);
297
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");
303
304   std::string error;
305   scoped_refptr<const Extension> extension(Extension::Create(
306       base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS,
307       &error));
308   EXPECT_EQ("", error);
309   ASSERT_TRUE(extension.get());
310
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();
316
317   feature.extension_types()->clear();
318   feature.extension_types()->insert(Manifest::TYPE_THEME);
319   {
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());
327   }
328
329   feature.extension_types()->clear();
330   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
331   feature.GetContexts()->clear();
332   feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
333   feature.GetContexts()->insert(Feature::CONTENT_SCRIPT_CONTEXT);
334   {
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());
342   }
343
344   feature.GetContexts()->insert(Feature::WEB_PAGE_CONTEXT);
345   {
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());
353   }
354
355   feature.GetContexts()->clear();
356   feature.GetContexts()->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);
362
363   EXPECT_EQ(Feature::INVALID_PLATFORM, feature.IsAvailableToContext(
364       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
365       Feature::UNSPECIFIED_PLATFORM).result());
366
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);
372
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);
378 }
379
380 TEST_F(ExtensionSimpleFeatureTest, Location) {
381   // Component extensions can access any location.
382   EXPECT_TRUE(LocationIsAvailable(SimpleFeature::COMPONENT_LOCATION,
383                                   Manifest::COMPONENT));
384   EXPECT_TRUE(
385       LocationIsAvailable(SimpleFeature::POLICY_LOCATION, Manifest::COMPONENT));
386   EXPECT_TRUE(LocationIsAvailable(SimpleFeature::UNSPECIFIED_LOCATION,
387                                   Manifest::COMPONENT));
388
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));
400
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));
406
407   // Non-policy (except component) extensions cannot access policy.
408   EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION,
409                                    Manifest::INVALID_LOCATION));
410   EXPECT_FALSE(
411       LocationIsAvailable(SimpleFeature::POLICY_LOCATION, Manifest::UNPACKED));
412   EXPECT_FALSE(LocationIsAvailable(SimpleFeature::POLICY_LOCATION,
413                                    Manifest::EXTERNAL_PREF_DOWNLOAD));
414 }
415
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,
423                                           -1,
424                                           Feature::CHROMEOS_PLATFORM).result());
425   EXPECT_EQ(
426       Feature::INVALID_PLATFORM,
427       feature.IsAvailableToManifest(std::string(),
428                                     Manifest::TYPE_UNKNOWN,
429                                     Manifest::INVALID_LOCATION,
430                                     -1,
431                                     Feature::UNSPECIFIED_PLATFORM).result());
432 }
433
434 TEST_F(ExtensionSimpleFeatureTest, Version) {
435   SimpleFeature feature;
436   feature.set_min_manifest_version(5);
437
438   EXPECT_EQ(
439       Feature::INVALID_MIN_MANIFEST_VERSION,
440       feature.IsAvailableToManifest(std::string(),
441                                     Manifest::TYPE_UNKNOWN,
442                                     Manifest::INVALID_LOCATION,
443                                     0,
444                                     Feature::UNSPECIFIED_PLATFORM).result());
445   EXPECT_EQ(
446       Feature::INVALID_MIN_MANIFEST_VERSION,
447       feature.IsAvailableToManifest(std::string(),
448                                     Manifest::TYPE_UNKNOWN,
449                                     Manifest::INVALID_LOCATION,
450                                     4,
451                                     Feature::UNSPECIFIED_PLATFORM).result());
452
453   EXPECT_EQ(
454       Feature::IS_AVAILABLE,
455       feature.IsAvailableToManifest(std::string(),
456                                     Manifest::TYPE_UNKNOWN,
457                                     Manifest::INVALID_LOCATION,
458                                     5,
459                                     Feature::UNSPECIFIED_PLATFORM).result());
460   EXPECT_EQ(
461       Feature::IS_AVAILABLE,
462       feature.IsAvailableToManifest(std::string(),
463                                     Manifest::TYPE_UNKNOWN,
464                                     Manifest::INVALID_LOCATION,
465                                     10,
466                                     Feature::UNSPECIFIED_PLATFORM).result());
467
468   feature.set_max_manifest_version(8);
469
470   EXPECT_EQ(
471       Feature::INVALID_MAX_MANIFEST_VERSION,
472       feature.IsAvailableToManifest(std::string(),
473                                     Manifest::TYPE_UNKNOWN,
474                                     Manifest::INVALID_LOCATION,
475                                     10,
476                                     Feature::UNSPECIFIED_PLATFORM).result());
477   EXPECT_EQ(
478       Feature::IS_AVAILABLE,
479       feature.IsAvailableToManifest(std::string(),
480                                     Manifest::TYPE_UNKNOWN,
481                                     Manifest::INVALID_LOCATION,
482                                     8,
483                                     Feature::UNSPECIFIED_PLATFORM).result());
484   EXPECT_EQ(
485       Feature::IS_AVAILABLE,
486       feature.IsAvailableToManifest(std::string(),
487                                     Manifest::TYPE_UNKNOWN,
488                                     Manifest::INVALID_LOCATION,
489                                     7,
490                                     Feature::UNSPECIFIED_PLATFORM).result());
491 }
492
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->GetContexts()->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());
504 }
505
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"));
517 }
518
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));
539
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()));
544 }
545
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   value->Set("contexts", contexts);
555   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
556   feature->Parse(value.get());
557   EXPECT_EQ(5u, feature->GetContexts()->size());
558   EXPECT_TRUE(
559       feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT));
560   EXPECT_TRUE(
561       feature->GetContexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
562   EXPECT_TRUE(
563       feature->GetContexts()->count(Feature::CONTENT_SCRIPT_CONTEXT));
564   EXPECT_TRUE(
565       feature->GetContexts()->count(Feature::WEB_PAGE_CONTEXT));
566   EXPECT_TRUE(
567       feature->GetContexts()->count(Feature::BLESSED_WEB_PAGE_CONTEXT));
568
569   value->SetString("contexts", "all");
570   scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
571   feature2->Parse(value.get());
572   EXPECT_EQ(*(feature->GetContexts()), *(feature2->GetContexts()));
573 }
574
575 TEST_F(ExtensionSimpleFeatureTest, ParseLocation) {
576   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
577   value->SetString("location", "component");
578   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
579   feature->Parse(value.get());
580   EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature->location());
581 }
582
583 TEST_F(ExtensionSimpleFeatureTest, ParsePlatforms) {
584   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
585   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
586   base::ListValue* platforms = new base::ListValue();
587   value->Set("platforms", platforms);
588   feature->Parse(value.get());
589   EXPECT_TRUE(feature->platforms()->empty());
590
591   platforms->AppendString("chromeos");
592   feature->Parse(value.get());
593   EXPECT_FALSE(feature->platforms()->empty());
594   EXPECT_EQ(Feature::CHROMEOS_PLATFORM, *feature->platforms()->begin());
595
596   platforms->Clear();
597   platforms->AppendString("win");
598   feature->Parse(value.get());
599   EXPECT_FALSE(feature->platforms()->empty());
600   EXPECT_EQ(Feature::WIN_PLATFORM, *feature->platforms()->begin());
601
602   platforms->Clear();
603   platforms->AppendString("win");
604   platforms->AppendString("chromeos");
605   feature->Parse(value.get());
606   std::set<Feature::Platform> expected_platforms;
607   expected_platforms.insert(Feature::CHROMEOS_PLATFORM);
608   expected_platforms.insert(Feature::WIN_PLATFORM);
609
610   EXPECT_FALSE(feature->platforms()->empty());
611   EXPECT_EQ(expected_platforms, *feature->platforms());
612 }
613
614 TEST_F(ExtensionSimpleFeatureTest, ManifestVersion) {
615   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
616   value->SetInteger("min_manifest_version", 1);
617   value->SetInteger("max_manifest_version", 5);
618   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
619   feature->Parse(value.get());
620   EXPECT_EQ(1, feature->min_manifest_version());
621   EXPECT_EQ(5, feature->max_manifest_version());
622 }
623
624 TEST_F(ExtensionSimpleFeatureTest, Inheritance) {
625   SimpleFeature feature;
626   feature.whitelist()->insert("foo");
627   feature.extension_types()->insert(Manifest::TYPE_THEME);
628   feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
629   feature.set_location(SimpleFeature::COMPONENT_LOCATION);
630   feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
631   feature.set_min_manifest_version(1);
632   feature.set_max_manifest_version(2);
633
634   // Test additive parsing. Parsing an empty dictionary should result in no
635   // changes to a SimpleFeature.
636   base::DictionaryValue definition;
637   feature.Parse(&definition);
638   EXPECT_EQ(1u, feature.whitelist()->size());
639   EXPECT_EQ(1u, feature.extension_types()->size());
640   EXPECT_EQ(1u, feature.GetContexts()->size());
641   EXPECT_EQ(1u, feature.whitelist()->count("foo"));
642   EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature.location());
643   EXPECT_EQ(1u, feature.platforms()->size());
644   EXPECT_EQ(1u, feature.platforms()->count(Feature::CHROMEOS_PLATFORM));
645   EXPECT_EQ(1, feature.min_manifest_version());
646   EXPECT_EQ(2, feature.max_manifest_version());
647
648   base::ListValue* whitelist = new base::ListValue();
649   base::ListValue* extension_types = new base::ListValue();
650   base::ListValue* contexts = new base::ListValue();
651   whitelist->Append(new base::StringValue("bar"));
652   extension_types->Append(new base::StringValue("extension"));
653   contexts->Append(new base::StringValue("unblessed_extension"));
654   definition.Set("whitelist", whitelist);
655   definition.Set("extension_types", extension_types);
656   definition.Set("contexts", contexts);
657   // Can't test location or platform because we only have one value so far.
658   definition.Set("min_manifest_version", new base::FundamentalValue(2));
659   definition.Set("max_manifest_version", new base::FundamentalValue(3));
660
661   feature.Parse(&definition);
662   EXPECT_EQ(1u, feature.whitelist()->size());
663   EXPECT_EQ(1u, feature.extension_types()->size());
664   EXPECT_EQ(1u, feature.GetContexts()->size());
665   EXPECT_EQ(1u, feature.whitelist()->count("bar"));
666   EXPECT_EQ(1u, feature.extension_types()->count(Manifest::TYPE_EXTENSION));
667   EXPECT_EQ(1u,
668             feature.GetContexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
669   EXPECT_EQ(2, feature.min_manifest_version());
670   EXPECT_EQ(3, feature.max_manifest_version());
671 }
672
673 Feature::AvailabilityResult IsAvailableInChannel(
674     const std::string& channel, VersionInfo::Channel channel_for_testing) {
675   ScopedCurrentChannel current_channel(channel_for_testing);
676
677   SimpleFeature feature;
678   feature.AddFilter(scoped_ptr<extensions::SimpleFeatureFilter>(
679       new extensions::ChromeChannelFeatureFilter(&feature)));
680   if (!channel.empty()) {
681     base::DictionaryValue feature_value;
682     feature_value.SetString("channel", channel);
683     feature.Parse(&feature_value);
684   }
685
686   return feature.IsAvailableToManifest("random-extension",
687                                        Manifest::TYPE_UNKNOWN,
688                                        Manifest::INVALID_LOCATION,
689                                        -1,
690                                        Feature::GetCurrentPlatform()).result();
691 }
692
693 TEST_F(ExtensionSimpleFeatureTest, SupportedChannel) {
694   // stable supported.
695   EXPECT_EQ(Feature::IS_AVAILABLE,
696       IsAvailableInChannel("stable", VersionInfo::CHANNEL_UNKNOWN));
697   EXPECT_EQ(Feature::IS_AVAILABLE,
698       IsAvailableInChannel("stable", VersionInfo::CHANNEL_CANARY));
699   EXPECT_EQ(Feature::IS_AVAILABLE,
700       IsAvailableInChannel("stable", VersionInfo::CHANNEL_DEV));
701   EXPECT_EQ(Feature::IS_AVAILABLE,
702       IsAvailableInChannel("stable", VersionInfo::CHANNEL_BETA));
703   EXPECT_EQ(Feature::IS_AVAILABLE,
704       IsAvailableInChannel("stable", VersionInfo::CHANNEL_STABLE));
705
706   // beta supported.
707   EXPECT_EQ(Feature::IS_AVAILABLE,
708       IsAvailableInChannel("beta", VersionInfo::CHANNEL_UNKNOWN));
709   EXPECT_EQ(Feature::IS_AVAILABLE,
710       IsAvailableInChannel("beta", VersionInfo::CHANNEL_CANARY));
711   EXPECT_EQ(Feature::IS_AVAILABLE,
712       IsAvailableInChannel("beta", VersionInfo::CHANNEL_DEV));
713   EXPECT_EQ(Feature::IS_AVAILABLE,
714       IsAvailableInChannel("beta", VersionInfo::CHANNEL_BETA));
715   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
716       IsAvailableInChannel("beta", VersionInfo::CHANNEL_STABLE));
717
718   // dev supported.
719   EXPECT_EQ(Feature::IS_AVAILABLE,
720       IsAvailableInChannel("dev", VersionInfo::CHANNEL_UNKNOWN));
721   EXPECT_EQ(Feature::IS_AVAILABLE,
722       IsAvailableInChannel("dev", VersionInfo::CHANNEL_CANARY));
723   EXPECT_EQ(Feature::IS_AVAILABLE,
724       IsAvailableInChannel("dev", VersionInfo::CHANNEL_DEV));
725   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
726       IsAvailableInChannel("dev", VersionInfo::CHANNEL_BETA));
727   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
728       IsAvailableInChannel("dev", VersionInfo::CHANNEL_STABLE));
729
730   // canary supported.
731   EXPECT_EQ(Feature::IS_AVAILABLE,
732       IsAvailableInChannel("canary", VersionInfo::CHANNEL_UNKNOWN));
733   EXPECT_EQ(Feature::IS_AVAILABLE,
734       IsAvailableInChannel("canary", VersionInfo::CHANNEL_CANARY));
735   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
736       IsAvailableInChannel("canary", VersionInfo::CHANNEL_DEV));
737   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
738       IsAvailableInChannel("canary", VersionInfo::CHANNEL_BETA));
739   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
740       IsAvailableInChannel("canary", VersionInfo::CHANNEL_STABLE));
741
742   // trunk supported.
743   EXPECT_EQ(Feature::IS_AVAILABLE,
744       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_UNKNOWN));
745   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
746       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_CANARY));
747   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
748       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_DEV));
749   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
750       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_BETA));
751   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
752       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_STABLE));
753 }
754
755 }  // namespace extensions