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.
5 #include "extensions/common/features/complex_feature.h"
7 #include "chrome/common/extensions/features/chrome_channel_feature_filter.h"
8 #include "chrome/common/extensions/features/feature_channel.h"
9 #include "extensions/common/features/simple_feature.h"
10 #include "extensions/common/value_builder.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 using chrome::VersionInfo
;
14 using extensions::ComplexFeature
;
15 using extensions::DictionaryBuilder
;
16 using extensions::Feature
;
17 using extensions::ListBuilder
;
18 using extensions::Manifest
;
19 using extensions::ScopedCurrentChannel
;
20 using extensions::SimpleFeature
;
24 class ExtensionComplexFeatureTest
: public testing::Test
{
26 ExtensionComplexFeatureTest()
27 : current_channel_(VersionInfo::CHANNEL_UNKNOWN
) {}
28 virtual ~ExtensionComplexFeatureTest() {}
30 SimpleFeature
* CreateFeature() {
31 SimpleFeature
* feature
= new SimpleFeature();
32 feature
->AddFilter(scoped_ptr
<extensions::SimpleFeatureFilter
>(
33 new extensions::ChromeChannelFeatureFilter(feature
)));
38 ScopedCurrentChannel current_channel_
;
41 TEST_F(ExtensionComplexFeatureTest
, MultipleRulesWhitelist
) {
42 const std::string
kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
43 const std::string
kIdBar("barabbbbccccddddeeeeffffgggghhhh");
44 scoped_ptr
<ComplexFeature::FeatureList
> features(
45 new ComplexFeature::FeatureList());
47 // Rule: "extension", whitelist "foo".
48 scoped_ptr
<SimpleFeature
> simple_feature(CreateFeature());
49 scoped_ptr
<base::DictionaryValue
> rule(
51 .Set("whitelist", ListBuilder().Append(kIdFoo
))
52 .Set("extension_types", ListBuilder()
53 .Append("extension")).Build());
54 simple_feature
->Parse(rule
.get());
55 features
->push_back(simple_feature
.release());
57 // Rule: "legacy_packaged_app", whitelist "bar".
58 simple_feature
.reset(CreateFeature());
59 rule
= DictionaryBuilder()
60 .Set("whitelist", ListBuilder().Append(kIdBar
))
61 .Set("extension_types", ListBuilder()
62 .Append("legacy_packaged_app")).Build();
63 simple_feature
->Parse(rule
.get());
64 features
->push_back(simple_feature
.release());
66 scoped_ptr
<ComplexFeature
> feature(new ComplexFeature(features
.Pass()));
68 // Test match 1st rule.
70 Feature::IS_AVAILABLE
,
71 feature
->IsAvailableToManifest(kIdFoo
,
72 Manifest::TYPE_EXTENSION
,
73 Manifest::INVALID_LOCATION
,
74 Feature::UNSPECIFIED_PLATFORM
,
75 Feature::GetCurrentPlatform()).result());
77 // Test match 2nd rule.
79 Feature::IS_AVAILABLE
,
80 feature
->IsAvailableToManifest(kIdBar
,
81 Manifest::TYPE_LEGACY_PACKAGED_APP
,
82 Manifest::INVALID_LOCATION
,
83 Feature::UNSPECIFIED_PLATFORM
,
84 Feature::GetCurrentPlatform()).result());
86 // Test whitelist with wrong extension type.
88 Feature::IS_AVAILABLE
,
89 feature
->IsAvailableToManifest(kIdBar
,
90 Manifest::TYPE_EXTENSION
,
91 Manifest::INVALID_LOCATION
,
92 Feature::UNSPECIFIED_PLATFORM
,
93 Feature::GetCurrentPlatform()).result());
95 Feature::IS_AVAILABLE
,
96 feature
->IsAvailableToManifest(kIdFoo
,
97 Manifest::TYPE_LEGACY_PACKAGED_APP
,
98 Manifest::INVALID_LOCATION
,
99 Feature::UNSPECIFIED_PLATFORM
,
100 Feature::GetCurrentPlatform()).result());
103 TEST_F(ExtensionComplexFeatureTest
, MultipleRulesChannels
) {
104 scoped_ptr
<ComplexFeature::FeatureList
> features(
105 new ComplexFeature::FeatureList());
107 // Rule: "extension", channel trunk.
108 scoped_ptr
<SimpleFeature
> simple_feature(CreateFeature());
109 scoped_ptr
<base::DictionaryValue
> rule(
111 .Set("channel", "trunk")
112 .Set("extension_types", ListBuilder().Append("extension")).Build());
113 simple_feature
->Parse(rule
.get());
114 features
->push_back(simple_feature
.release());
116 // Rule: "legacy_packaged_app", channel stable.
117 simple_feature
.reset(CreateFeature());
118 rule
= DictionaryBuilder()
119 .Set("channel", "stable")
120 .Set("extension_types", ListBuilder()
121 .Append("legacy_packaged_app")).Build();
122 simple_feature
->Parse(rule
.get());
123 features
->push_back(simple_feature
.release());
125 scoped_ptr
<ComplexFeature
> feature(new ComplexFeature(features
.Pass()));
127 // Test match 1st rule.
129 ScopedCurrentChannel
current_channel(VersionInfo::CHANNEL_UNKNOWN
);
131 Feature::IS_AVAILABLE
,
132 feature
->IsAvailableToManifest("1",
133 Manifest::TYPE_EXTENSION
,
134 Manifest::INVALID_LOCATION
,
135 Feature::UNSPECIFIED_PLATFORM
,
136 Feature::GetCurrentPlatform()).result());
139 // Test match 2nd rule.
141 ScopedCurrentChannel
current_channel(VersionInfo::CHANNEL_BETA
);
143 Feature::IS_AVAILABLE
,
144 feature
->IsAvailableToManifest("2",
145 Manifest::TYPE_LEGACY_PACKAGED_APP
,
146 Manifest::INVALID_LOCATION
,
147 Feature::UNSPECIFIED_PLATFORM
,
148 Feature::GetCurrentPlatform()).result());
151 // Test feature not available to extensions above channel unknown.
153 ScopedCurrentChannel
current_channel(VersionInfo::CHANNEL_BETA
);
155 Feature::IS_AVAILABLE
,
156 feature
->IsAvailableToManifest("1",
157 Manifest::TYPE_EXTENSION
,
158 Manifest::INVALID_LOCATION
,
159 Feature::UNSPECIFIED_PLATFORM
,
160 Feature::GetCurrentPlatform()).result());
164 // Tests that dependencies are correctly checked.
165 TEST_F(ExtensionComplexFeatureTest
, Dependencies
) {
166 scoped_ptr
<ComplexFeature::FeatureList
> features(
167 new ComplexFeature::FeatureList());
169 // Rule which depends on an extension-only feature (omnibox).
170 scoped_ptr
<SimpleFeature
> simple_feature(CreateFeature());
171 scoped_ptr
<base::DictionaryValue
> rule
=
173 .Set("dependencies", ListBuilder().Append("manifest:omnibox"))
175 simple_feature
->Parse(rule
.get());
176 features
->push_back(simple_feature
.release());
178 // Rule which depends on an platform-app-only feature (serial).
179 simple_feature
.reset(CreateFeature());
180 rule
= DictionaryBuilder()
181 .Set("dependencies", ListBuilder().Append("permission:serial"))
183 simple_feature
->Parse(rule
.get());
184 features
->push_back(simple_feature
.release());
186 scoped_ptr
<ComplexFeature
> feature(new ComplexFeature(features
.Pass()));
188 // Available to extensions because of the omnibox rule.
190 Feature::IS_AVAILABLE
,
191 feature
->IsAvailableToManifest("extensionid",
192 Manifest::TYPE_EXTENSION
,
193 Manifest::INVALID_LOCATION
,
194 Feature::UNSPECIFIED_PLATFORM
,
195 Feature::GetCurrentPlatform()).result());
197 // Available to platofrm apps because of the serial rule.
199 Feature::IS_AVAILABLE
,
200 feature
->IsAvailableToManifest("platformappid",
201 Manifest::TYPE_PLATFORM_APP
,
202 Manifest::INVALID_LOCATION
,
203 Feature::UNSPECIFIED_PLATFORM
,
204 Feature::GetCurrentPlatform()).result());
206 // Not available to hosted apps.
208 Feature::INVALID_TYPE
,
209 feature
->IsAvailableToManifest("hostedappid",
210 Manifest::TYPE_HOSTED_APP
,
211 Manifest::INVALID_LOCATION
,
212 Feature::UNSPECIFIED_PLATFORM
,
213 Feature::GetCurrentPlatform()).result());