- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / features / simple_feature_unittest.cc
1 // Copyright (c) 2012 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 "chrome/common/extensions/features/simple_feature.h"
6
7 #include "chrome/common/extensions/features/feature_channel.h"
8 #include "chrome/common/extensions/value_builder.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 using chrome::VersionInfo;
12 using extensions::DictionaryBuilder;
13 using extensions::Extension;
14 using extensions::Feature;
15 using extensions::ListBuilder;
16 using extensions::Manifest;
17 using extensions::ScopedCurrentChannel;
18 using extensions::SimpleFeature;
19
20 namespace {
21
22 struct IsAvailableTestData {
23   std::string extension_id;
24   Manifest::Type extension_type;
25   Feature::Location location;
26   Feature::Platform platform;
27   int manifest_version;
28   Feature::AvailabilityResult expected_result;
29 };
30
31 class ExtensionSimpleFeatureTest : public testing::Test {
32  protected:
33   ExtensionSimpleFeatureTest()
34       : current_channel_(VersionInfo::CHANNEL_UNKNOWN) {}
35   virtual ~ExtensionSimpleFeatureTest() {}
36
37  private:
38   ScopedCurrentChannel current_channel_;
39 };
40
41 TEST_F(ExtensionSimpleFeatureTest, IsAvailableNullCase) {
42   const IsAvailableTestData tests[] = {
43     { "", Manifest::TYPE_UNKNOWN,
44       Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1,
45       Feature::IS_AVAILABLE },
46     { "random-extension", Manifest::TYPE_UNKNOWN,
47       Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1,
48       Feature::IS_AVAILABLE },
49     { "", Manifest::TYPE_LEGACY_PACKAGED_APP,
50       Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1,
51       Feature::IS_AVAILABLE },
52     { "", Manifest::TYPE_UNKNOWN,
53       Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1,
54       Feature::IS_AVAILABLE },
55     { "", Manifest::TYPE_UNKNOWN,
56       Feature::COMPONENT_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1,
57       Feature::IS_AVAILABLE },
58     { "", Manifest::TYPE_UNKNOWN,
59       Feature::UNSPECIFIED_LOCATION, Feature::CHROMEOS_PLATFORM, -1,
60       Feature::IS_AVAILABLE },
61     { "", Manifest::TYPE_UNKNOWN,
62       Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, 25,
63       Feature::IS_AVAILABLE }
64   };
65
66   SimpleFeature feature;
67   for (size_t i = 0; i < arraysize(tests); ++i) {
68     const IsAvailableTestData& test = tests[i];
69     EXPECT_EQ(test.expected_result,
70               feature.IsAvailableToManifest(test.extension_id,
71                                             test.extension_type,
72                                             test.location,
73                                             test.manifest_version,
74                                             test.platform).result());
75   }
76 }
77
78 TEST_F(ExtensionSimpleFeatureTest, Whitelist) {
79   const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
80   const std::string kIdBar("barabbbbccccddddeeeeffffgggghhhh");
81   const std::string kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
82   SimpleFeature feature;
83   feature.whitelist()->insert(kIdFoo);
84   feature.whitelist()->insert(kIdBar);
85
86   EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest(
87       kIdFoo, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1,
88       Feature::UNSPECIFIED_PLATFORM).result());
89   EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest(
90       kIdBar, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1,
91       Feature::UNSPECIFIED_PLATFORM).result());
92
93   EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest(
94       kIdBaz, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1,
95       Feature::UNSPECIFIED_PLATFORM).result());
96   EXPECT_EQ(
97       Feature::NOT_FOUND_IN_WHITELIST,
98       feature.IsAvailableToManifest(std::string(),
99                                     Manifest::TYPE_UNKNOWN,
100                                     Feature::UNSPECIFIED_LOCATION,
101                                     -1,
102                                     Feature::UNSPECIFIED_PLATFORM).result());
103
104   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
105   EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest(
106       kIdBaz, Manifest::TYPE_LEGACY_PACKAGED_APP,
107       Feature::UNSPECIFIED_LOCATION, -1,
108       Feature::UNSPECIFIED_PLATFORM).result());
109 }
110
111 TEST_F(ExtensionSimpleFeatureTest, HashedIdWhitelist) {
112   // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
113   //   sha1sum | tr '[:lower:]' '[:upper:]'
114   const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
115   const std::string kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
116   SimpleFeature feature;
117
118   feature.whitelist()->insert(kIdFooHashed);
119
120   EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest(
121       kIdFoo, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1,
122       Feature::UNSPECIFIED_PLATFORM).result());
123   EXPECT_NE(Feature::IS_AVAILABLE, feature.IsAvailableToManifest(
124       kIdFooHashed, Manifest::TYPE_UNKNOWN,
125       Feature::UNSPECIFIED_LOCATION, -1,
126       Feature::UNSPECIFIED_PLATFORM).result());
127   EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest(
128       "slightlytoooolongforanextensionid", Manifest::TYPE_UNKNOWN,
129       Feature::UNSPECIFIED_LOCATION, -1,
130       Feature::UNSPECIFIED_PLATFORM).result());
131   EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest(
132       "tooshortforanextensionid", Manifest::TYPE_UNKNOWN,
133       Feature::UNSPECIFIED_LOCATION, -1,
134       Feature::UNSPECIFIED_PLATFORM).result());
135 }
136
137 TEST_F(ExtensionSimpleFeatureTest, PackageType) {
138   SimpleFeature feature;
139   feature.extension_types()->insert(Manifest::TYPE_EXTENSION);
140   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
141
142   EXPECT_EQ(
143       Feature::IS_AVAILABLE,
144       feature.IsAvailableToManifest(std::string(),
145                                     Manifest::TYPE_EXTENSION,
146                                     Feature::UNSPECIFIED_LOCATION,
147                                     -1,
148                                     Feature::UNSPECIFIED_PLATFORM).result());
149   EXPECT_EQ(
150       Feature::IS_AVAILABLE,
151       feature.IsAvailableToManifest(std::string(),
152                                     Manifest::TYPE_LEGACY_PACKAGED_APP,
153                                     Feature::UNSPECIFIED_LOCATION,
154                                     -1,
155                                     Feature::UNSPECIFIED_PLATFORM).result());
156
157   EXPECT_EQ(
158       Feature::INVALID_TYPE,
159       feature.IsAvailableToManifest(std::string(),
160                                     Manifest::TYPE_UNKNOWN,
161                                     Feature::UNSPECIFIED_LOCATION,
162                                     -1,
163                                     Feature::UNSPECIFIED_PLATFORM).result());
164   EXPECT_EQ(
165       Feature::INVALID_TYPE,
166       feature.IsAvailableToManifest(std::string(),
167                                     Manifest::TYPE_THEME,
168                                     Feature::UNSPECIFIED_LOCATION,
169                                     -1,
170                                     Feature::UNSPECIFIED_PLATFORM).result());
171 }
172
173 TEST_F(ExtensionSimpleFeatureTest, Context) {
174   SimpleFeature feature;
175   feature.set_name("somefeature");
176   feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
177   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
178   feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
179   feature.set_min_manifest_version(21);
180   feature.set_max_manifest_version(25);
181
182   base::DictionaryValue manifest;
183   manifest.SetString("name", "test");
184   manifest.SetString("version", "1");
185   manifest.SetInteger("manifest_version", 21);
186   manifest.SetString("app.launch.local_path", "foo.html");
187
188   std::string error;
189   scoped_refptr<const Extension> extension(Extension::Create(
190       base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS,
191       &error));
192   EXPECT_EQ("", error);
193   ASSERT_TRUE(extension.get());
194
195   feature.whitelist()->insert("monkey");
196   EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToContext(
197       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
198       Feature::CHROMEOS_PLATFORM).result());
199   feature.whitelist()->clear();
200
201   feature.extension_types()->clear();
202   feature.extension_types()->insert(Manifest::TYPE_THEME);
203   {
204     Feature::Availability availability = feature.IsAvailableToContext(
205         extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
206         Feature::CHROMEOS_PLATFORM);
207     EXPECT_EQ(Feature::INVALID_TYPE, availability.result());
208     EXPECT_EQ("'somefeature' is only allowed for themes, "
209               "but this is a legacy packaged app.",
210               availability.message());
211   }
212
213   feature.extension_types()->clear();
214   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
215   feature.GetContexts()->clear();
216   feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
217   feature.GetContexts()->insert(Feature::CONTENT_SCRIPT_CONTEXT);
218   {
219     Feature::Availability availability = feature.IsAvailableToContext(
220         extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
221         Feature::CHROMEOS_PLATFORM);
222     EXPECT_EQ(Feature::INVALID_CONTEXT, availability.result());
223     EXPECT_EQ("'somefeature' is only allowed to run in extension iframes and "
224               "content scripts, but this is a privileged page",
225               availability.message());
226   }
227
228   feature.GetContexts()->insert(Feature::WEB_PAGE_CONTEXT);
229   {
230     Feature::Availability availability = feature.IsAvailableToContext(
231         extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
232         Feature::CHROMEOS_PLATFORM);
233     EXPECT_EQ(Feature::INVALID_CONTEXT, availability.result());
234     EXPECT_EQ("'somefeature' is only allowed to run in extension iframes, "
235               "content scripts, and web pages, but this is a privileged page",
236               availability.message());
237   }
238
239   feature.GetContexts()->clear();
240   feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
241   feature.set_location(Feature::COMPONENT_LOCATION);
242   EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToContext(
243       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
244       Feature::CHROMEOS_PLATFORM).result());
245   feature.set_location(Feature::UNSPECIFIED_LOCATION);
246
247   EXPECT_EQ(Feature::INVALID_PLATFORM, feature.IsAvailableToContext(
248       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
249       Feature::UNSPECIFIED_PLATFORM).result());
250
251   feature.set_min_manifest_version(22);
252   EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION, feature.IsAvailableToContext(
253       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
254       Feature::CHROMEOS_PLATFORM).result());
255   feature.set_min_manifest_version(21);
256
257   feature.set_max_manifest_version(18);
258   EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION, feature.IsAvailableToContext(
259       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
260       Feature::CHROMEOS_PLATFORM).result());
261   feature.set_max_manifest_version(25);
262 }
263
264 TEST_F(ExtensionSimpleFeatureTest, Location) {
265   SimpleFeature feature;
266
267   // If the feature specifies "component" as its location, then only component
268   // extensions can access it.
269   feature.set_location(Feature::COMPONENT_LOCATION);
270   EXPECT_EQ(
271       Feature::IS_AVAILABLE,
272       feature.IsAvailableToManifest(std::string(),
273                                     Manifest::TYPE_UNKNOWN,
274                                     Feature::COMPONENT_LOCATION,
275                                     -1,
276                                     Feature::UNSPECIFIED_PLATFORM).result());
277   EXPECT_EQ(
278       Feature::INVALID_LOCATION,
279       feature.IsAvailableToManifest(std::string(),
280                                     Manifest::TYPE_UNKNOWN,
281                                     Feature::UNSPECIFIED_LOCATION,
282                                     -1,
283                                     Feature::UNSPECIFIED_PLATFORM).result());
284
285   // But component extensions can access anything else, whatever their location.
286   feature.set_location(Feature::UNSPECIFIED_LOCATION);
287   EXPECT_EQ(
288       Feature::IS_AVAILABLE,
289       feature.IsAvailableToManifest(std::string(),
290                                     Manifest::TYPE_UNKNOWN,
291                                     Feature::COMPONENT_LOCATION,
292                                     -1,
293                                     Feature::UNSPECIFIED_PLATFORM).result());
294 }
295
296 TEST_F(ExtensionSimpleFeatureTest, Platform) {
297   SimpleFeature feature;
298   feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
299   EXPECT_EQ(Feature::IS_AVAILABLE,
300             feature.IsAvailableToManifest(std::string(),
301                                           Manifest::TYPE_UNKNOWN,
302                                           Feature::UNSPECIFIED_LOCATION,
303                                           -1,
304                                           Feature::CHROMEOS_PLATFORM).result());
305   EXPECT_EQ(
306       Feature::INVALID_PLATFORM,
307       feature.IsAvailableToManifest(std::string(),
308                                     Manifest::TYPE_UNKNOWN,
309                                     Feature::UNSPECIFIED_LOCATION,
310                                     -1,
311                                     Feature::UNSPECIFIED_PLATFORM).result());
312 }
313
314 TEST_F(ExtensionSimpleFeatureTest, Version) {
315   SimpleFeature feature;
316   feature.set_min_manifest_version(5);
317
318   EXPECT_EQ(
319       Feature::INVALID_MIN_MANIFEST_VERSION,
320       feature.IsAvailableToManifest(std::string(),
321                                     Manifest::TYPE_UNKNOWN,
322                                     Feature::UNSPECIFIED_LOCATION,
323                                     0,
324                                     Feature::UNSPECIFIED_PLATFORM).result());
325   EXPECT_EQ(
326       Feature::INVALID_MIN_MANIFEST_VERSION,
327       feature.IsAvailableToManifest(std::string(),
328                                     Manifest::TYPE_UNKNOWN,
329                                     Feature::UNSPECIFIED_LOCATION,
330                                     4,
331                                     Feature::UNSPECIFIED_PLATFORM).result());
332
333   EXPECT_EQ(
334       Feature::IS_AVAILABLE,
335       feature.IsAvailableToManifest(std::string(),
336                                     Manifest::TYPE_UNKNOWN,
337                                     Feature::UNSPECIFIED_LOCATION,
338                                     5,
339                                     Feature::UNSPECIFIED_PLATFORM).result());
340   EXPECT_EQ(
341       Feature::IS_AVAILABLE,
342       feature.IsAvailableToManifest(std::string(),
343                                     Manifest::TYPE_UNKNOWN,
344                                     Feature::UNSPECIFIED_LOCATION,
345                                     10,
346                                     Feature::UNSPECIFIED_PLATFORM).result());
347
348   feature.set_max_manifest_version(8);
349
350   EXPECT_EQ(
351       Feature::INVALID_MAX_MANIFEST_VERSION,
352       feature.IsAvailableToManifest(std::string(),
353                                     Manifest::TYPE_UNKNOWN,
354                                     Feature::UNSPECIFIED_LOCATION,
355                                     10,
356                                     Feature::UNSPECIFIED_PLATFORM).result());
357   EXPECT_EQ(
358       Feature::IS_AVAILABLE,
359       feature.IsAvailableToManifest(std::string(),
360                                     Manifest::TYPE_UNKNOWN,
361                                     Feature::UNSPECIFIED_LOCATION,
362                                     8,
363                                     Feature::UNSPECIFIED_PLATFORM).result());
364   EXPECT_EQ(
365       Feature::IS_AVAILABLE,
366       feature.IsAvailableToManifest(std::string(),
367                                     Manifest::TYPE_UNKNOWN,
368                                     Feature::UNSPECIFIED_LOCATION,
369                                     7,
370                                     Feature::UNSPECIFIED_PLATFORM).result());
371 }
372
373 TEST_F(ExtensionSimpleFeatureTest, ParseNull) {
374   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
375   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
376   feature->Parse(value.get());
377   EXPECT_TRUE(feature->whitelist()->empty());
378   EXPECT_TRUE(feature->extension_types()->empty());
379   EXPECT_TRUE(feature->GetContexts()->empty());
380   EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location());
381   EXPECT_TRUE(feature->platforms()->empty());
382   EXPECT_EQ(0, feature->min_manifest_version());
383   EXPECT_EQ(0, feature->max_manifest_version());
384 }
385
386 TEST_F(ExtensionSimpleFeatureTest, ParseWhitelist) {
387   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
388   base::ListValue* whitelist = new base::ListValue();
389   whitelist->Append(new base::StringValue("foo"));
390   whitelist->Append(new base::StringValue("bar"));
391   value->Set("whitelist", whitelist);
392   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
393   feature->Parse(value.get());
394   EXPECT_EQ(2u, feature->whitelist()->size());
395   EXPECT_TRUE(feature->whitelist()->count("foo"));
396   EXPECT_TRUE(feature->whitelist()->count("bar"));
397 }
398
399 TEST_F(ExtensionSimpleFeatureTest, ParsePackageTypes) {
400   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
401   base::ListValue* extension_types = new base::ListValue();
402   extension_types->Append(new base::StringValue("extension"));
403   extension_types->Append(new base::StringValue("theme"));
404   extension_types->Append(new base::StringValue("legacy_packaged_app"));
405   extension_types->Append(new base::StringValue("hosted_app"));
406   extension_types->Append(new base::StringValue("platform_app"));
407   extension_types->Append(new base::StringValue("shared_module"));
408   value->Set("extension_types", extension_types);
409   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
410   feature->Parse(value.get());
411   EXPECT_EQ(6u, feature->extension_types()->size());
412   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_EXTENSION));
413   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_THEME));
414   EXPECT_TRUE(feature->extension_types()->count(
415       Manifest::TYPE_LEGACY_PACKAGED_APP));
416   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_HOSTED_APP));
417   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP));
418   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_SHARED_MODULE));
419
420   value->SetString("extension_types", "all");
421   scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
422   feature2->Parse(value.get());
423   EXPECT_EQ(*(feature->extension_types()), *(feature2->extension_types()));
424 }
425
426 TEST_F(ExtensionSimpleFeatureTest, ParseContexts) {
427   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
428   base::ListValue* contexts = new base::ListValue();
429   contexts->Append(new base::StringValue("blessed_extension"));
430   contexts->Append(new base::StringValue("unblessed_extension"));
431   contexts->Append(new base::StringValue("content_script"));
432   contexts->Append(new base::StringValue("web_page"));
433   value->Set("contexts", contexts);
434   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
435   feature->Parse(value.get());
436   EXPECT_EQ(4u, feature->GetContexts()->size());
437   EXPECT_TRUE(
438       feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT));
439   EXPECT_TRUE(
440       feature->GetContexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
441   EXPECT_TRUE(
442       feature->GetContexts()->count(Feature::CONTENT_SCRIPT_CONTEXT));
443   EXPECT_TRUE(
444       feature->GetContexts()->count(Feature::WEB_PAGE_CONTEXT));
445
446   value->SetString("contexts", "all");
447   scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
448   feature2->Parse(value.get());
449   EXPECT_EQ(*(feature->GetContexts()), *(feature2->GetContexts()));
450 }
451
452 TEST_F(ExtensionSimpleFeatureTest, ParseLocation) {
453   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
454   value->SetString("location", "component");
455   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
456   feature->Parse(value.get());
457   EXPECT_EQ(Feature::COMPONENT_LOCATION, feature->location());
458 }
459
460 TEST_F(ExtensionSimpleFeatureTest, ParsePlatforms) {
461   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
462   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
463   base::ListValue* platforms = new base::ListValue();
464   value->Set("platforms", platforms);
465   feature->Parse(value.get());
466   EXPECT_TRUE(feature->platforms()->empty());
467
468   platforms->AppendString("chromeos");
469   feature->Parse(value.get());
470   EXPECT_FALSE(feature->platforms()->empty());
471   EXPECT_EQ(Feature::CHROMEOS_PLATFORM, *feature->platforms()->begin());
472
473   platforms->Clear();
474   platforms->AppendString("windows");
475   feature->Parse(value.get());
476   EXPECT_FALSE(feature->platforms()->empty());
477   EXPECT_EQ(Feature::WIN_PLATFORM, *feature->platforms()->begin());
478
479   platforms->Clear();
480   platforms->AppendString("windows");
481   platforms->AppendString("chromeos");
482   feature->Parse(value.get());
483   std::set<Feature::Platform> expected_platforms;
484   expected_platforms.insert(Feature::CHROMEOS_PLATFORM);
485   expected_platforms.insert(Feature::WIN_PLATFORM);
486
487   EXPECT_FALSE(feature->platforms()->empty());
488   EXPECT_EQ(expected_platforms, *feature->platforms());
489 }
490
491 TEST_F(ExtensionSimpleFeatureTest, ManifestVersion) {
492   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
493   value->SetInteger("min_manifest_version", 1);
494   value->SetInteger("max_manifest_version", 5);
495   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
496   feature->Parse(value.get());
497   EXPECT_EQ(1, feature->min_manifest_version());
498   EXPECT_EQ(5, feature->max_manifest_version());
499 }
500
501 TEST_F(ExtensionSimpleFeatureTest, Inheritance) {
502   SimpleFeature feature;
503   feature.whitelist()->insert("foo");
504   feature.extension_types()->insert(Manifest::TYPE_THEME);
505   feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
506   feature.set_location(Feature::COMPONENT_LOCATION);
507   feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
508   feature.set_min_manifest_version(1);
509   feature.set_max_manifest_version(2);
510
511   SimpleFeature feature2 = feature;
512   EXPECT_TRUE(feature2.Equals(feature));
513
514   base::DictionaryValue definition;
515   feature2.Parse(&definition);
516   EXPECT_TRUE(feature2.Equals(feature));
517
518   base::ListValue* whitelist = new base::ListValue();
519   base::ListValue* extension_types = new base::ListValue();
520   base::ListValue* contexts = new base::ListValue();
521   whitelist->Append(new base::StringValue("bar"));
522   extension_types->Append(new base::StringValue("extension"));
523   contexts->Append(new base::StringValue("unblessed_extension"));
524   definition.Set("whitelist", whitelist);
525   definition.Set("extension_types", extension_types);
526   definition.Set("contexts", contexts);
527   // Can't test location or platform because we only have one value so far.
528   definition.Set("min_manifest_version", new base::FundamentalValue(2));
529   definition.Set("max_manifest_version", new base::FundamentalValue(3));
530
531   feature2.Parse(&definition);
532   EXPECT_FALSE(feature2.Equals(feature));
533   EXPECT_EQ(1u, feature2.whitelist()->size());
534   EXPECT_EQ(1u, feature2.extension_types()->size());
535   EXPECT_EQ(1u, feature2.GetContexts()->size());
536   EXPECT_EQ(1u, feature2.whitelist()->count("bar"));
537   EXPECT_EQ(1u, feature2.extension_types()->count(Manifest::TYPE_EXTENSION));
538   EXPECT_EQ(1u, feature2.GetContexts()->count(
539       Feature::UNBLESSED_EXTENSION_CONTEXT));
540   EXPECT_EQ(2, feature2.min_manifest_version());
541   EXPECT_EQ(3, feature2.max_manifest_version());
542 }
543
544 TEST_F(ExtensionSimpleFeatureTest, Equals) {
545   SimpleFeature feature;
546   feature.whitelist()->insert("foo");
547   feature.extension_types()->insert(Manifest::TYPE_THEME);
548   feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
549   feature.set_location(Feature::COMPONENT_LOCATION);
550   feature.platforms()->insert(Feature::CHROMEOS_PLATFORM);
551   feature.set_min_manifest_version(18);
552   feature.set_max_manifest_version(25);
553
554   SimpleFeature feature2(feature);
555   EXPECT_TRUE(feature2.Equals(feature));
556
557   feature2.whitelist()->clear();
558   EXPECT_FALSE(feature2.Equals(feature));
559
560   feature2 = feature;
561   feature2.extension_types()->clear();
562   EXPECT_FALSE(feature2.Equals(feature));
563
564   feature2 = feature;
565   feature2.GetContexts()->clear();
566   EXPECT_FALSE(feature2.Equals(feature));
567
568   feature2 = feature;
569   feature2.set_location(Feature::UNSPECIFIED_LOCATION);
570   EXPECT_FALSE(feature2.Equals(feature));
571
572   feature2 = feature;
573   feature.platforms()->insert(Feature::UNSPECIFIED_PLATFORM);
574   EXPECT_FALSE(feature2.Equals(feature));
575
576   feature2 = feature;
577   feature2.set_min_manifest_version(0);
578   EXPECT_FALSE(feature2.Equals(feature));
579
580   feature2 = feature;
581   feature2.set_max_manifest_version(0);
582   EXPECT_FALSE(feature2.Equals(feature));
583 }
584
585 Feature::AvailabilityResult IsAvailableInChannel(
586     const std::string& channel, VersionInfo::Channel channel_for_testing) {
587   ScopedCurrentChannel current_channel(channel_for_testing);
588
589   SimpleFeature feature;
590   if (!channel.empty()) {
591     base::DictionaryValue feature_value;
592     feature_value.SetString("channel", channel);
593     feature.Parse(&feature_value);
594   }
595
596   return feature.IsAvailableToManifest(
597       "random-extension",
598       Manifest::TYPE_UNKNOWN,
599       Feature::UNSPECIFIED_LOCATION,
600       -1,
601       Feature::GetCurrentPlatform()).result();
602 }
603
604 TEST_F(ExtensionSimpleFeatureTest, SupportedChannel) {
605   // stable supported.
606   EXPECT_EQ(Feature::IS_AVAILABLE,
607       IsAvailableInChannel("stable", VersionInfo::CHANNEL_UNKNOWN));
608   EXPECT_EQ(Feature::IS_AVAILABLE,
609       IsAvailableInChannel("stable", VersionInfo::CHANNEL_CANARY));
610   EXPECT_EQ(Feature::IS_AVAILABLE,
611       IsAvailableInChannel("stable", VersionInfo::CHANNEL_DEV));
612   EXPECT_EQ(Feature::IS_AVAILABLE,
613       IsAvailableInChannel("stable", VersionInfo::CHANNEL_BETA));
614   EXPECT_EQ(Feature::IS_AVAILABLE,
615       IsAvailableInChannel("stable", VersionInfo::CHANNEL_STABLE));
616
617   // beta supported.
618   EXPECT_EQ(Feature::IS_AVAILABLE,
619       IsAvailableInChannel("beta", VersionInfo::CHANNEL_UNKNOWN));
620   EXPECT_EQ(Feature::IS_AVAILABLE,
621       IsAvailableInChannel("beta", VersionInfo::CHANNEL_CANARY));
622   EXPECT_EQ(Feature::IS_AVAILABLE,
623       IsAvailableInChannel("beta", VersionInfo::CHANNEL_DEV));
624   EXPECT_EQ(Feature::IS_AVAILABLE,
625       IsAvailableInChannel("beta", VersionInfo::CHANNEL_BETA));
626   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
627       IsAvailableInChannel("beta", VersionInfo::CHANNEL_STABLE));
628
629   // dev supported.
630   EXPECT_EQ(Feature::IS_AVAILABLE,
631       IsAvailableInChannel("dev", VersionInfo::CHANNEL_UNKNOWN));
632   EXPECT_EQ(Feature::IS_AVAILABLE,
633       IsAvailableInChannel("dev", VersionInfo::CHANNEL_CANARY));
634   EXPECT_EQ(Feature::IS_AVAILABLE,
635       IsAvailableInChannel("dev", VersionInfo::CHANNEL_DEV));
636   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
637       IsAvailableInChannel("dev", VersionInfo::CHANNEL_BETA));
638   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
639       IsAvailableInChannel("dev", VersionInfo::CHANNEL_STABLE));
640
641   // canary supported.
642   EXPECT_EQ(Feature::IS_AVAILABLE,
643       IsAvailableInChannel("canary", VersionInfo::CHANNEL_UNKNOWN));
644   EXPECT_EQ(Feature::IS_AVAILABLE,
645       IsAvailableInChannel("canary", VersionInfo::CHANNEL_CANARY));
646   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
647       IsAvailableInChannel("canary", VersionInfo::CHANNEL_DEV));
648   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
649       IsAvailableInChannel("canary", VersionInfo::CHANNEL_BETA));
650   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
651       IsAvailableInChannel("canary", VersionInfo::CHANNEL_STABLE));
652
653   // trunk supported.
654   EXPECT_EQ(Feature::IS_AVAILABLE,
655       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_UNKNOWN));
656   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
657       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_CANARY));
658   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
659       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_DEV));
660   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
661       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_BETA));
662   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
663       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_STABLE));
664 }
665
666 }  // namespace