Upstream version 9.38.198.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.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);
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.contexts()->clear();
332   feature.contexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
333   feature.contexts()->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.contexts()->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.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);
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->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());
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   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));
564
565   value->SetString("contexts", "all");
566   scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
567   feature2->Parse(value.get());
568   EXPECT_EQ(*(feature->contexts()), *(feature2->contexts()));
569 }
570
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());
577 }
578
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());
586
587   platforms->AppendString("chromeos");
588   feature->Parse(value.get());
589   EXPECT_FALSE(feature->platforms()->empty());
590   EXPECT_EQ(Feature::CHROMEOS_PLATFORM, *feature->platforms()->begin());
591
592   platforms->Clear();
593   platforms->AppendString("win");
594   feature->Parse(value.get());
595   EXPECT_FALSE(feature->platforms()->empty());
596   EXPECT_EQ(Feature::WIN_PLATFORM, *feature->platforms()->begin());
597
598   platforms->Clear();
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);
605
606   EXPECT_FALSE(feature->platforms()->empty());
607   EXPECT_EQ(expected_platforms, *feature->platforms());
608 }
609
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());
618 }
619
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);
629
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());
643
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));
656
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));
663   EXPECT_EQ(1u,
664             feature.contexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
665   EXPECT_EQ(2, feature.min_manifest_version());
666   EXPECT_EQ(3, feature.max_manifest_version());
667 }
668
669 Feature::AvailabilityResult IsAvailableInChannel(
670     const std::string& channel, VersionInfo::Channel channel_for_testing) {
671   ScopedCurrentChannel current_channel(channel_for_testing);
672
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);
680   }
681
682   return feature.IsAvailableToManifest("random-extension",
683                                        Manifest::TYPE_UNKNOWN,
684                                        Manifest::INVALID_LOCATION,
685                                        -1,
686                                        Feature::GetCurrentPlatform()).result();
687 }
688
689 TEST_F(ExtensionSimpleFeatureTest, SupportedChannel) {
690   // stable supported.
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));
701
702   // beta supported.
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));
713
714   // dev supported.
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));
725
726   // canary supported.
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));
737
738   // trunk supported.
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));
749 }
750
751 }  // namespace extensions