Home | History | Annotate | Download | only in features
      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.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
    176   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
    177   feature.set_platform(Feature::CHROMEOS_PLATFORM);
    178   feature.set_min_manifest_version(21);
    179   feature.set_max_manifest_version(25);
    180 
    181   base::DictionaryValue manifest;
    182   manifest.SetString("name", "test");
    183   manifest.SetString("version", "1");
    184   manifest.SetInteger("manifest_version", 21);
    185   manifest.SetString("app.launch.local_path", "foo.html");
    186 
    187   std::string error;
    188   scoped_refptr<const Extension> extension(Extension::Create(
    189       base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS,
    190       &error));
    191   EXPECT_EQ("", error);
    192   ASSERT_TRUE(extension.get());
    193 
    194   feature.whitelist()->insert("monkey");
    195   EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToContext(
    196       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
    197       Feature::CHROMEOS_PLATFORM).result());
    198   feature.whitelist()->clear();
    199 
    200   feature.extension_types()->clear();
    201   feature.extension_types()->insert(Manifest::TYPE_THEME);
    202   EXPECT_EQ(Feature::INVALID_TYPE, feature.IsAvailableToContext(
    203       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
    204       Feature::CHROMEOS_PLATFORM).result());
    205   feature.extension_types()->clear();
    206   feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP);
    207 
    208   feature.GetContexts()->clear();
    209   feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
    210   EXPECT_EQ(Feature::INVALID_CONTEXT, feature.IsAvailableToContext(
    211       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
    212       Feature::CHROMEOS_PLATFORM).result());
    213   feature.GetContexts()->clear();
    214   feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
    215 
    216   feature.set_location(Feature::COMPONENT_LOCATION);
    217   EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToContext(
    218       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
    219       Feature::CHROMEOS_PLATFORM).result());
    220   feature.set_location(Feature::UNSPECIFIED_LOCATION);
    221 
    222   EXPECT_EQ(Feature::INVALID_PLATFORM, feature.IsAvailableToContext(
    223       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
    224       Feature::UNSPECIFIED_PLATFORM).result());
    225 
    226   feature.set_min_manifest_version(22);
    227   EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION, feature.IsAvailableToContext(
    228       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
    229       Feature::CHROMEOS_PLATFORM).result());
    230   feature.set_min_manifest_version(21);
    231 
    232   feature.set_max_manifest_version(18);
    233   EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION, feature.IsAvailableToContext(
    234       extension.get(), Feature::BLESSED_EXTENSION_CONTEXT,
    235       Feature::CHROMEOS_PLATFORM).result());
    236   feature.set_max_manifest_version(25);
    237 }
    238 
    239 TEST_F(ExtensionSimpleFeatureTest, Location) {
    240   SimpleFeature feature;
    241 
    242   // If the feature specifies "component" as its location, then only component
    243   // extensions can access it.
    244   feature.set_location(Feature::COMPONENT_LOCATION);
    245   EXPECT_EQ(
    246       Feature::IS_AVAILABLE,
    247       feature.IsAvailableToManifest(std::string(),
    248                                     Manifest::TYPE_UNKNOWN,
    249                                     Feature::COMPONENT_LOCATION,
    250                                     -1,
    251                                     Feature::UNSPECIFIED_PLATFORM).result());
    252   EXPECT_EQ(
    253       Feature::INVALID_LOCATION,
    254       feature.IsAvailableToManifest(std::string(),
    255                                     Manifest::TYPE_UNKNOWN,
    256                                     Feature::UNSPECIFIED_LOCATION,
    257                                     -1,
    258                                     Feature::UNSPECIFIED_PLATFORM).result());
    259 
    260   // But component extensions can access anything else, whatever their location.
    261   feature.set_location(Feature::UNSPECIFIED_LOCATION);
    262   EXPECT_EQ(
    263       Feature::IS_AVAILABLE,
    264       feature.IsAvailableToManifest(std::string(),
    265                                     Manifest::TYPE_UNKNOWN,
    266                                     Feature::COMPONENT_LOCATION,
    267                                     -1,
    268                                     Feature::UNSPECIFIED_PLATFORM).result());
    269 }
    270 
    271 TEST_F(ExtensionSimpleFeatureTest, Platform) {
    272   SimpleFeature feature;
    273   feature.set_platform(Feature::CHROMEOS_PLATFORM);
    274   EXPECT_EQ(Feature::IS_AVAILABLE,
    275             feature.IsAvailableToManifest(std::string(),
    276                                           Manifest::TYPE_UNKNOWN,
    277                                           Feature::UNSPECIFIED_LOCATION,
    278                                           -1,
    279                                           Feature::CHROMEOS_PLATFORM).result());
    280   EXPECT_EQ(
    281       Feature::INVALID_PLATFORM,
    282       feature.IsAvailableToManifest(std::string(),
    283                                     Manifest::TYPE_UNKNOWN,
    284                                     Feature::UNSPECIFIED_LOCATION,
    285                                     -1,
    286                                     Feature::UNSPECIFIED_PLATFORM).result());
    287 }
    288 
    289 TEST_F(ExtensionSimpleFeatureTest, Version) {
    290   SimpleFeature feature;
    291   feature.set_min_manifest_version(5);
    292 
    293   EXPECT_EQ(
    294       Feature::INVALID_MIN_MANIFEST_VERSION,
    295       feature.IsAvailableToManifest(std::string(),
    296                                     Manifest::TYPE_UNKNOWN,
    297                                     Feature::UNSPECIFIED_LOCATION,
    298                                     0,
    299                                     Feature::UNSPECIFIED_PLATFORM).result());
    300   EXPECT_EQ(
    301       Feature::INVALID_MIN_MANIFEST_VERSION,
    302       feature.IsAvailableToManifest(std::string(),
    303                                     Manifest::TYPE_UNKNOWN,
    304                                     Feature::UNSPECIFIED_LOCATION,
    305                                     4,
    306                                     Feature::UNSPECIFIED_PLATFORM).result());
    307 
    308   EXPECT_EQ(
    309       Feature::IS_AVAILABLE,
    310       feature.IsAvailableToManifest(std::string(),
    311                                     Manifest::TYPE_UNKNOWN,
    312                                     Feature::UNSPECIFIED_LOCATION,
    313                                     5,
    314                                     Feature::UNSPECIFIED_PLATFORM).result());
    315   EXPECT_EQ(
    316       Feature::IS_AVAILABLE,
    317       feature.IsAvailableToManifest(std::string(),
    318                                     Manifest::TYPE_UNKNOWN,
    319                                     Feature::UNSPECIFIED_LOCATION,
    320                                     10,
    321                                     Feature::UNSPECIFIED_PLATFORM).result());
    322 
    323   feature.set_max_manifest_version(8);
    324 
    325   EXPECT_EQ(
    326       Feature::INVALID_MAX_MANIFEST_VERSION,
    327       feature.IsAvailableToManifest(std::string(),
    328                                     Manifest::TYPE_UNKNOWN,
    329                                     Feature::UNSPECIFIED_LOCATION,
    330                                     10,
    331                                     Feature::UNSPECIFIED_PLATFORM).result());
    332   EXPECT_EQ(
    333       Feature::IS_AVAILABLE,
    334       feature.IsAvailableToManifest(std::string(),
    335                                     Manifest::TYPE_UNKNOWN,
    336                                     Feature::UNSPECIFIED_LOCATION,
    337                                     8,
    338                                     Feature::UNSPECIFIED_PLATFORM).result());
    339   EXPECT_EQ(
    340       Feature::IS_AVAILABLE,
    341       feature.IsAvailableToManifest(std::string(),
    342                                     Manifest::TYPE_UNKNOWN,
    343                                     Feature::UNSPECIFIED_LOCATION,
    344                                     7,
    345                                     Feature::UNSPECIFIED_PLATFORM).result());
    346 }
    347 
    348 TEST_F(ExtensionSimpleFeatureTest, ParseNull) {
    349   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
    350   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
    351   feature->Parse(value.get());
    352   EXPECT_TRUE(feature->whitelist()->empty());
    353   EXPECT_TRUE(feature->extension_types()->empty());
    354   EXPECT_TRUE(feature->GetContexts()->empty());
    355   EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location());
    356   EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform());
    357   EXPECT_EQ(0, feature->min_manifest_version());
    358   EXPECT_EQ(0, feature->max_manifest_version());
    359 }
    360 
    361 TEST_F(ExtensionSimpleFeatureTest, ParseWhitelist) {
    362   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
    363   base::ListValue* whitelist = new base::ListValue();
    364   whitelist->Append(new base::StringValue("foo"));
    365   whitelist->Append(new base::StringValue("bar"));
    366   value->Set("whitelist", whitelist);
    367   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
    368   feature->Parse(value.get());
    369   EXPECT_EQ(2u, feature->whitelist()->size());
    370   EXPECT_TRUE(feature->whitelist()->count("foo"));
    371   EXPECT_TRUE(feature->whitelist()->count("bar"));
    372 }
    373 
    374 TEST_F(ExtensionSimpleFeatureTest, ParsePackageTypes) {
    375   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
    376   base::ListValue* extension_types = new base::ListValue();
    377   extension_types->Append(new base::StringValue("extension"));
    378   extension_types->Append(new base::StringValue("theme"));
    379   extension_types->Append(new base::StringValue("packaged_app"));
    380   extension_types->Append(new base::StringValue("hosted_app"));
    381   extension_types->Append(new base::StringValue("platform_app"));
    382   extension_types->Append(new base::StringValue("shared_module"));
    383   value->Set("extension_types", extension_types);
    384   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
    385   feature->Parse(value.get());
    386   EXPECT_EQ(6u, feature->extension_types()->size());
    387   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_EXTENSION));
    388   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_THEME));
    389   EXPECT_TRUE(feature->extension_types()->count(
    390       Manifest::TYPE_LEGACY_PACKAGED_APP));
    391   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_HOSTED_APP));
    392   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP));
    393   EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_SHARED_MODULE));
    394 
    395   value->SetString("extension_types", "all");
    396   scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
    397   feature2->Parse(value.get());
    398   EXPECT_EQ(*(feature->extension_types()), *(feature2->extension_types()));
    399 }
    400 
    401 TEST_F(ExtensionSimpleFeatureTest, ParseContexts) {
    402   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
    403   base::ListValue* contexts = new base::ListValue();
    404   contexts->Append(new base::StringValue("blessed_extension"));
    405   contexts->Append(new base::StringValue("unblessed_extension"));
    406   contexts->Append(new base::StringValue("content_script"));
    407   contexts->Append(new base::StringValue("web_page"));
    408   value->Set("contexts", contexts);
    409   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
    410   feature->Parse(value.get());
    411   EXPECT_EQ(4u, feature->GetContexts()->size());
    412   EXPECT_TRUE(
    413       feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT));
    414   EXPECT_TRUE(
    415       feature->GetContexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT));
    416   EXPECT_TRUE(
    417       feature->GetContexts()->count(Feature::CONTENT_SCRIPT_CONTEXT));
    418   EXPECT_TRUE(
    419       feature->GetContexts()->count(Feature::WEB_PAGE_CONTEXT));
    420 
    421   value->SetString("contexts", "all");
    422   scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
    423   feature2->Parse(value.get());
    424   EXPECT_EQ(*(feature->GetContexts()), *(feature2->GetContexts()));
    425 }
    426 
    427 TEST_F(ExtensionSimpleFeatureTest, ParseLocation) {
    428   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
    429   value->SetString("location", "component");
    430   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
    431   feature->Parse(value.get());
    432   EXPECT_EQ(Feature::COMPONENT_LOCATION, feature->location());
    433 }
    434 
    435 TEST_F(ExtensionSimpleFeatureTest, ParsePlatform) {
    436   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
    437   value->SetString("platform", "chromeos");
    438   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
    439   feature->Parse(value.get());
    440   EXPECT_EQ(Feature::CHROMEOS_PLATFORM, feature->platform());
    441 }
    442 
    443 TEST_F(ExtensionSimpleFeatureTest, ManifestVersion) {
    444   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
    445   value->SetInteger("min_manifest_version", 1);
    446   value->SetInteger("max_manifest_version", 5);
    447   scoped_ptr<SimpleFeature> feature(new SimpleFeature());
    448   feature->Parse(value.get());
    449   EXPECT_EQ(1, feature->min_manifest_version());
    450   EXPECT_EQ(5, feature->max_manifest_version());
    451 }
    452 
    453 TEST_F(ExtensionSimpleFeatureTest, Inheritance) {
    454   SimpleFeature feature;
    455   feature.whitelist()->insert("foo");
    456   feature.extension_types()->insert(Manifest::TYPE_THEME);
    457   feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT);
    458   feature.set_location(Feature::COMPONENT_LOCATION);
    459   feature.set_platform(Feature::CHROMEOS_PLATFORM);
    460   feature.set_min_manifest_version(1);
    461   feature.set_max_manifest_version(2);
    462 
    463   SimpleFeature feature2 = feature;
    464   EXPECT_TRUE(feature2.Equals(feature));
    465 
    466   base::DictionaryValue definition;
    467   feature2.Parse(&definition);
    468   EXPECT_TRUE(feature2.Equals(feature));
    469 
    470   base::ListValue* whitelist = new base::ListValue();
    471   base::ListValue* extension_types = new base::ListValue();
    472   base::ListValue* contexts = new base::ListValue();
    473   whitelist->Append(new base::StringValue("bar"));
    474   extension_types->Append(new base::StringValue("extension"));
    475   contexts->Append(new base::StringValue("unblessed_extension"));
    476   definition.Set("whitelist", whitelist);
    477   definition.Set("extension_types", extension_types);
    478   definition.Set("contexts", contexts);
    479   // Can't test location or platform because we only have one value so far.
    480   definition.Set("min_manifest_version", new base::FundamentalValue(2));
    481   definition.Set("max_manifest_version", new base::FundamentalValue(3));
    482 
    483   feature2.Parse(&definition);
    484   EXPECT_FALSE(feature2.Equals(feature));
    485   EXPECT_EQ(1u, feature2.whitelist()->size());
    486   EXPECT_EQ(1u, feature2.extension_types()->size());
    487   EXPECT_EQ(1u, feature2.GetContexts()->size());
    488   EXPECT_EQ(1u, feature2.whitelist()->count("bar"));
    489   EXPECT_EQ(1u, feature2.extension_types()->count(Manifest::TYPE_EXTENSION));
    490   EXPECT_EQ(1u, feature2.GetContexts()->count(
    491       Feature::UNBLESSED_EXTENSION_CONTEXT));
    492   EXPECT_EQ(2, feature2.min_manifest_version());
    493   EXPECT_EQ(3, feature2.max_manifest_version());
    494 }
    495 
    496 TEST_F(ExtensionSimpleFeatureTest, Equals) {
    497   SimpleFeature feature;
    498   feature.whitelist()->insert("foo");
    499   feature.extension_types()->insert(Manifest::TYPE_THEME);
    500   feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT);
    501   feature.set_location(Feature::COMPONENT_LOCATION);
    502   feature.set_platform(Feature::CHROMEOS_PLATFORM);
    503   feature.set_min_manifest_version(18);
    504   feature.set_max_manifest_version(25);
    505 
    506   SimpleFeature feature2(feature);
    507   EXPECT_TRUE(feature2.Equals(feature));
    508 
    509   feature2.whitelist()->clear();
    510   EXPECT_FALSE(feature2.Equals(feature));
    511 
    512   feature2 = feature;
    513   feature2.extension_types()->clear();
    514   EXPECT_FALSE(feature2.Equals(feature));
    515 
    516   feature2 = feature;
    517   feature2.GetContexts()->clear();
    518   EXPECT_FALSE(feature2.Equals(feature));
    519 
    520   feature2 = feature;
    521   feature2.set_location(Feature::UNSPECIFIED_LOCATION);
    522   EXPECT_FALSE(feature2.Equals(feature));
    523 
    524   feature2 = feature;
    525   feature2.set_platform(Feature::UNSPECIFIED_PLATFORM);
    526   EXPECT_FALSE(feature2.Equals(feature));
    527 
    528   feature2 = feature;
    529   feature2.set_min_manifest_version(0);
    530   EXPECT_FALSE(feature2.Equals(feature));
    531 
    532   feature2 = feature;
    533   feature2.set_max_manifest_version(0);
    534   EXPECT_FALSE(feature2.Equals(feature));
    535 }
    536 
    537 Feature::AvailabilityResult IsAvailableInChannel(
    538     const std::string& channel, VersionInfo::Channel channel_for_testing) {
    539   ScopedCurrentChannel current_channel(channel_for_testing);
    540 
    541   SimpleFeature feature;
    542   if (!channel.empty()) {
    543     base::DictionaryValue feature_value;
    544     feature_value.SetString("channel", channel);
    545     feature.Parse(&feature_value);
    546   }
    547 
    548   return feature.IsAvailableToManifest(
    549       "random-extension",
    550       Manifest::TYPE_UNKNOWN,
    551       Feature::UNSPECIFIED_LOCATION,
    552       -1,
    553       Feature::GetCurrentPlatform()).result();
    554 }
    555 
    556 TEST_F(ExtensionSimpleFeatureTest, SupportedChannel) {
    557   // stable supported.
    558   EXPECT_EQ(Feature::IS_AVAILABLE,
    559       IsAvailableInChannel("stable", VersionInfo::CHANNEL_UNKNOWN));
    560   EXPECT_EQ(Feature::IS_AVAILABLE,
    561       IsAvailableInChannel("stable", VersionInfo::CHANNEL_CANARY));
    562   EXPECT_EQ(Feature::IS_AVAILABLE,
    563       IsAvailableInChannel("stable", VersionInfo::CHANNEL_DEV));
    564   EXPECT_EQ(Feature::IS_AVAILABLE,
    565       IsAvailableInChannel("stable", VersionInfo::CHANNEL_BETA));
    566   EXPECT_EQ(Feature::IS_AVAILABLE,
    567       IsAvailableInChannel("stable", VersionInfo::CHANNEL_STABLE));
    568 
    569   // beta supported.
    570   EXPECT_EQ(Feature::IS_AVAILABLE,
    571       IsAvailableInChannel("beta", VersionInfo::CHANNEL_UNKNOWN));
    572   EXPECT_EQ(Feature::IS_AVAILABLE,
    573       IsAvailableInChannel("beta", VersionInfo::CHANNEL_CANARY));
    574   EXPECT_EQ(Feature::IS_AVAILABLE,
    575       IsAvailableInChannel("beta", VersionInfo::CHANNEL_DEV));
    576   EXPECT_EQ(Feature::IS_AVAILABLE,
    577       IsAvailableInChannel("beta", VersionInfo::CHANNEL_BETA));
    578   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    579       IsAvailableInChannel("beta", VersionInfo::CHANNEL_STABLE));
    580 
    581   // dev supported.
    582   EXPECT_EQ(Feature::IS_AVAILABLE,
    583       IsAvailableInChannel("dev", VersionInfo::CHANNEL_UNKNOWN));
    584   EXPECT_EQ(Feature::IS_AVAILABLE,
    585       IsAvailableInChannel("dev", VersionInfo::CHANNEL_CANARY));
    586   EXPECT_EQ(Feature::IS_AVAILABLE,
    587       IsAvailableInChannel("dev", VersionInfo::CHANNEL_DEV));
    588   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    589       IsAvailableInChannel("dev", VersionInfo::CHANNEL_BETA));
    590   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    591       IsAvailableInChannel("dev", VersionInfo::CHANNEL_STABLE));
    592 
    593   // canary supported.
    594   EXPECT_EQ(Feature::IS_AVAILABLE,
    595       IsAvailableInChannel("canary", VersionInfo::CHANNEL_UNKNOWN));
    596   EXPECT_EQ(Feature::IS_AVAILABLE,
    597       IsAvailableInChannel("canary", VersionInfo::CHANNEL_CANARY));
    598   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    599       IsAvailableInChannel("canary", VersionInfo::CHANNEL_DEV));
    600   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    601       IsAvailableInChannel("canary", VersionInfo::CHANNEL_BETA));
    602   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    603       IsAvailableInChannel("canary", VersionInfo::CHANNEL_STABLE));
    604 
    605   // trunk supported.
    606   EXPECT_EQ(Feature::IS_AVAILABLE,
    607       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_UNKNOWN));
    608   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    609       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_CANARY));
    610   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    611       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_DEV));
    612   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    613       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_BETA));
    614   EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL,
    615       IsAvailableInChannel("trunk", VersionInfo::CHANNEL_STABLE));
    616 }
    617 
    618 }  // namespace
    619