| OLD | NEW |
| (Empty) |
| 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/complex_feature.h" | |
| 6 | |
| 7 #include "chrome/common/extensions/features/api_feature.h" | |
| 8 #include "chrome/common/extensions/features/chrome_channel_feature_filter.h" | |
| 9 #include "chrome/common/extensions/features/feature_channel.h" | |
| 10 #include "chrome/common/extensions/features/simple_feature.h" | |
| 11 #include "extensions/common/test_util.h" | |
| 12 #include "extensions/common/value_builder.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 using chrome::VersionInfo; | |
| 16 using extensions::APIFeature; | |
| 17 using extensions::ComplexFeature; | |
| 18 using extensions::DictionaryBuilder; | |
| 19 using extensions::Feature; | |
| 20 using extensions::ListBuilder; | |
| 21 using extensions::Manifest; | |
| 22 using extensions::ScopedCurrentChannel; | |
| 23 using extensions::SimpleFeature; | |
| 24 using extensions::test_util::ParseJsonDictionaryWithSingleQuotes; | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 class ExtensionComplexFeatureTest : public testing::Test { | |
| 29 protected: | |
| 30 ExtensionComplexFeatureTest() | |
| 31 : current_channel_(VersionInfo::CHANNEL_UNKNOWN) {} | |
| 32 virtual ~ExtensionComplexFeatureTest() {} | |
| 33 | |
| 34 SimpleFeature* CreateFeature() { | |
| 35 SimpleFeature* feature = new SimpleFeature(); | |
| 36 feature->AddFilter(scoped_ptr<extensions::SimpleFeatureFilter>( | |
| 37 new extensions::ChromeChannelFeatureFilter(feature))); | |
| 38 return feature; | |
| 39 } | |
| 40 | |
| 41 private: | |
| 42 ScopedCurrentChannel current_channel_; | |
| 43 }; | |
| 44 | |
| 45 TEST_F(ExtensionComplexFeatureTest, MultipleRulesWhitelist) { | |
| 46 const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh"); | |
| 47 const std::string kIdBar("barabbbbccccddddeeeeffffgggghhhh"); | |
| 48 scoped_ptr<ComplexFeature::FeatureList> features( | |
| 49 new ComplexFeature::FeatureList()); | |
| 50 | |
| 51 // Rule: "extension", whitelist "foo". | |
| 52 scoped_ptr<SimpleFeature> simple_feature(CreateFeature()); | |
| 53 scoped_ptr<base::DictionaryValue> rule( | |
| 54 DictionaryBuilder() | |
| 55 .Set("whitelist", ListBuilder().Append(kIdFoo)) | |
| 56 .Set("extension_types", ListBuilder() | |
| 57 .Append("extension")).Build()); | |
| 58 simple_feature->Parse(rule.get()); | |
| 59 features->push_back(simple_feature.release()); | |
| 60 | |
| 61 // Rule: "legacy_packaged_app", whitelist "bar". | |
| 62 simple_feature.reset(CreateFeature()); | |
| 63 rule = DictionaryBuilder() | |
| 64 .Set("whitelist", ListBuilder().Append(kIdBar)) | |
| 65 .Set("extension_types", ListBuilder() | |
| 66 .Append("legacy_packaged_app")).Build(); | |
| 67 simple_feature->Parse(rule.get()); | |
| 68 features->push_back(simple_feature.release()); | |
| 69 | |
| 70 scoped_ptr<ComplexFeature> feature(new ComplexFeature(features.Pass())); | |
| 71 | |
| 72 // Test match 1st rule. | |
| 73 EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToManifest( | |
| 74 kIdFoo, | |
| 75 Manifest::TYPE_EXTENSION, | |
| 76 Feature::UNSPECIFIED_LOCATION, | |
| 77 Feature::UNSPECIFIED_PLATFORM, | |
| 78 Feature::GetCurrentPlatform()).result()); | |
| 79 | |
| 80 // Test match 2nd rule. | |
| 81 EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToManifest( | |
| 82 kIdBar, | |
| 83 Manifest::TYPE_LEGACY_PACKAGED_APP, | |
| 84 Feature::UNSPECIFIED_LOCATION, | |
| 85 Feature::UNSPECIFIED_PLATFORM, | |
| 86 Feature::GetCurrentPlatform()).result()); | |
| 87 | |
| 88 // Test whitelist with wrong extension type. | |
| 89 EXPECT_NE(Feature::IS_AVAILABLE, feature->IsAvailableToManifest( | |
| 90 kIdBar, | |
| 91 Manifest::TYPE_EXTENSION, | |
| 92 Feature::UNSPECIFIED_LOCATION, | |
| 93 Feature::UNSPECIFIED_PLATFORM, | |
| 94 Feature::GetCurrentPlatform()).result()); | |
| 95 EXPECT_NE(Feature::IS_AVAILABLE, feature->IsAvailableToManifest(kIdFoo, | |
| 96 Manifest::TYPE_LEGACY_PACKAGED_APP, | |
| 97 Feature::UNSPECIFIED_LOCATION, | |
| 98 Feature::UNSPECIFIED_PLATFORM, | |
| 99 Feature::GetCurrentPlatform()).result()); | |
| 100 } | |
| 101 | |
| 102 TEST_F(ExtensionComplexFeatureTest, MultipleRulesChannels) { | |
| 103 scoped_ptr<ComplexFeature::FeatureList> features( | |
| 104 new ComplexFeature::FeatureList()); | |
| 105 | |
| 106 // Rule: "extension", channel trunk. | |
| 107 scoped_ptr<SimpleFeature> simple_feature(CreateFeature()); | |
| 108 scoped_ptr<base::DictionaryValue> rule( | |
| 109 DictionaryBuilder() | |
| 110 .Set("channel", "trunk") | |
| 111 .Set("extension_types", ListBuilder().Append("extension")).Build()); | |
| 112 simple_feature->Parse(rule.get()); | |
| 113 features->push_back(simple_feature.release()); | |
| 114 | |
| 115 // Rule: "legacy_packaged_app", channel stable. | |
| 116 simple_feature.reset(CreateFeature()); | |
| 117 rule = DictionaryBuilder() | |
| 118 .Set("channel", "stable") | |
| 119 .Set("extension_types", ListBuilder() | |
| 120 .Append("legacy_packaged_app")).Build(); | |
| 121 simple_feature->Parse(rule.get()); | |
| 122 features->push_back(simple_feature.release()); | |
| 123 | |
| 124 scoped_ptr<ComplexFeature> feature(new ComplexFeature(features.Pass())); | |
| 125 | |
| 126 // Test match 1st rule. | |
| 127 { | |
| 128 ScopedCurrentChannel current_channel(VersionInfo::CHANNEL_UNKNOWN); | |
| 129 EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToManifest( | |
| 130 "1", | |
| 131 Manifest::TYPE_EXTENSION, | |
| 132 Feature::UNSPECIFIED_LOCATION, | |
| 133 Feature::UNSPECIFIED_PLATFORM, | |
| 134 Feature::GetCurrentPlatform()).result()); | |
| 135 } | |
| 136 | |
| 137 // Test match 2nd rule. | |
| 138 { | |
| 139 ScopedCurrentChannel current_channel(VersionInfo::CHANNEL_BETA); | |
| 140 EXPECT_EQ(Feature::IS_AVAILABLE, feature->IsAvailableToManifest( | |
| 141 "2", | |
| 142 Manifest::TYPE_LEGACY_PACKAGED_APP, | |
| 143 Feature::UNSPECIFIED_LOCATION, | |
| 144 Feature::UNSPECIFIED_PLATFORM, | |
| 145 Feature::GetCurrentPlatform()).result()); | |
| 146 } | |
| 147 | |
| 148 // Test feature not available to extensions above channel unknown. | |
| 149 { | |
| 150 ScopedCurrentChannel current_channel(VersionInfo::CHANNEL_BETA); | |
| 151 EXPECT_NE(Feature::IS_AVAILABLE, feature->IsAvailableToManifest( | |
| 152 "1", | |
| 153 Manifest::TYPE_EXTENSION, | |
| 154 Feature::UNSPECIFIED_LOCATION, | |
| 155 Feature::UNSPECIFIED_PLATFORM, | |
| 156 Feature::GetCurrentPlatform()).result()); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 // Tests a complex feature with blocked_in_service_worker returns true for | |
| 161 // IsBlockedInServiceWorker(). | |
| 162 TEST_F(ExtensionComplexFeatureTest, BlockedInServiceWorker) { | |
| 163 scoped_ptr<ComplexFeature::FeatureList> features( | |
| 164 new ComplexFeature::FeatureList()); | |
| 165 | |
| 166 // Two feature rules, both with blocked_in_service_worker: true. | |
| 167 scoped_ptr<SimpleFeature> api_feature(new APIFeature()); | |
| 168 api_feature->Parse(ParseJsonDictionaryWithSingleQuotes( | |
| 169 "{" | |
| 170 " 'channel': 'trunk'," | |
| 171 " 'blocked_in_service_worker': true" | |
| 172 "}").get()); | |
| 173 features->push_back(api_feature.release()); | |
| 174 | |
| 175 api_feature.reset(new APIFeature()); | |
| 176 api_feature->Parse(ParseJsonDictionaryWithSingleQuotes( | |
| 177 "{" | |
| 178 " 'channel': 'stable'," | |
| 179 " 'blocked_in_service_worker': true" | |
| 180 "}").get()); | |
| 181 features->push_back(api_feature.release()); | |
| 182 | |
| 183 EXPECT_TRUE(ComplexFeature(features.Pass()).IsBlockedInServiceWorker()); | |
| 184 } | |
| 185 | |
| 186 // Tests a complex feature without blocked_in_service_worker returns false for | |
| 187 // IsBlockedInServiceWorker(). | |
| 188 TEST_F(ExtensionComplexFeatureTest, NotBlockedInServiceWorker) { | |
| 189 scoped_ptr<ComplexFeature::FeatureList> features( | |
| 190 new ComplexFeature::FeatureList()); | |
| 191 | |
| 192 // Two feature rules without blocked_in_service_worker. | |
| 193 scoped_ptr<SimpleFeature> api_feature(new APIFeature()); | |
| 194 api_feature->Parse(ParseJsonDictionaryWithSingleQuotes( | |
| 195 "{" | |
| 196 " 'channel': 'trunk'" | |
| 197 "}").get()); | |
| 198 features->push_back(api_feature.release()); | |
| 199 | |
| 200 api_feature.reset(new APIFeature()); | |
| 201 api_feature->Parse(ParseJsonDictionaryWithSingleQuotes( | |
| 202 "{" | |
| 203 " 'channel': 'stable'" | |
| 204 "}").get()); | |
| 205 features->push_back(api_feature.release()); | |
| 206 | |
| 207 EXPECT_FALSE(ComplexFeature(features.Pass()).IsBlockedInServiceWorker()); | |
| 208 } | |
| 209 | |
| 210 } // namespace | |
| OLD | NEW |