Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: chrome/common/extensions/api/extension_api_unittest.cc

Issue 9950046: Implement FeatureProvider for ExtensionAPI. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/extensions/api/extension_api.h" 5 #include "chrome/common/extensions/api/extension_api.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/json/json_writer.h"
10 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "chrome/common/extensions/extension.h" 14 #include "chrome/common/extensions/extension.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 16
16 namespace extensions { 17 namespace extensions {
17 namespace { 18 namespace {
18 19
20 TEST(ExtensionAPI, Creation) {
21 ExtensionAPI* shared_instance = ExtensionAPI::GetSharedInstance();
22 EXPECT_EQ(shared_instance, ExtensionAPI::GetSharedInstance());
23
24 scoped_ptr<ExtensionAPI> new_instance(
25 ExtensionAPI::CreateWithDefaultConfiguration());
26 EXPECT_NE(new_instance.get(),
27 scoped_ptr<ExtensionAPI>(
28 ExtensionAPI::CreateWithDefaultConfiguration()).get());
29
30 ExtensionAPI empty_instance;
31
32 struct {
33 ExtensionAPI* api;
34 bool expect_populated;
35 } test_data[] = {
36 { shared_instance, true },
37 { new_instance.get(), true },
38 { &empty_instance, false }
39 };
40
41 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
42 EXPECT_EQ(test_data[i].expect_populated,
43 test_data[i].api->GetSchema("bookmarks.create") != NULL);
44 }
45 }
46
47 TEST(ExtensionAPI, SplitDependencyName) {
48 struct {
49 std::string input;
50 std::string expected_feature_type;
51 std::string expected_feature_name;
52 } test_data[] = {
53 { "", "api", "" }, // assumes "api" when no type is present
54 { "foo", "api", "foo" },
55 { "foo:", "foo", "" },
56 { ":foo", "", "foo" },
57 { "foo:bar", "foo", "bar" },
58 { "foo:bar.baz", "foo", "bar.baz" }
59 };
60
61 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
62 std::string feature_type;
63 std::string feature_name;
64 ExtensionAPI::SplitDependencyName(test_data[i].input, &feature_type,
65 &feature_name);
66 EXPECT_EQ(test_data[i].expected_feature_type, feature_type) << i;
67 EXPECT_EQ(test_data[i].expected_feature_name, feature_name) << i;
68 }
69 }
70
19 TEST(ExtensionAPI, IsPrivileged) { 71 TEST(ExtensionAPI, IsPrivileged) {
20 ExtensionAPI extension_api; 72 scoped_ptr<ExtensionAPI> extension_api(
73 ExtensionAPI::CreateWithDefaultConfiguration());
21 74
22 EXPECT_FALSE(extension_api.IsPrivileged("extension.connect")); 75 EXPECT_FALSE(extension_api->IsPrivileged("extension.connect"));
23 EXPECT_FALSE(extension_api.IsPrivileged("extension.onConnect")); 76 EXPECT_FALSE(extension_api->IsPrivileged("extension.onConnect"));
24 77
25 // Properties are not supported yet. 78 // Properties are not supported yet.
26 EXPECT_TRUE(extension_api.IsPrivileged("extension.lastError")); 79 EXPECT_TRUE(extension_api->IsPrivileged("extension.lastError"));
27 80
28 // Default unknown names to privileged for paranoia's sake. 81 // Default unknown names to privileged for paranoia's sake.
29 EXPECT_TRUE(extension_api.IsPrivileged("")); 82 EXPECT_TRUE(extension_api->IsPrivileged(""));
30 EXPECT_TRUE(extension_api.IsPrivileged("<unknown-namespace>")); 83 EXPECT_TRUE(extension_api->IsPrivileged("<unknown-namespace>"));
31 EXPECT_TRUE(extension_api.IsPrivileged("extension.<unknown-member>")); 84 EXPECT_TRUE(extension_api->IsPrivileged("extension.<unknown-member>"));
32 85
33 // Exists, but privileged. 86 // Exists, but privileged.
34 EXPECT_TRUE(extension_api.IsPrivileged("extension.getViews")); 87 EXPECT_TRUE(extension_api->IsPrivileged("extension.getViews"));
35 EXPECT_TRUE(extension_api.IsPrivileged("history.search")); 88 EXPECT_TRUE(extension_api->IsPrivileged("history.search"));
36 89
37 // Whole APIs that are unprivileged. 90 // Whole APIs that are unprivileged.
38 EXPECT_FALSE(extension_api.IsPrivileged("app.getDetails")); 91 EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails"));
39 EXPECT_FALSE(extension_api.IsPrivileged("app.isInstalled")); 92 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled"));
40 EXPECT_FALSE(extension_api.IsPrivileged("storage.local")); 93 EXPECT_FALSE(extension_api->IsPrivileged("storage.local"));
41 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.onChanged")); 94 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged"));
42 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.set")); 95 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set"));
43 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.MAX_ITEMS")); 96 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS"));
44 EXPECT_FALSE(extension_api.IsPrivileged("storage.set")); 97 EXPECT_FALSE(extension_api->IsPrivileged("storage.set"));
45 } 98 }
46 99
47 TEST(ExtensionAPI, LazyGetSchema) { 100 TEST(ExtensionAPI, LazyGetSchema) {
48 ExtensionAPI apis; 101 scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration());
49 102
50 EXPECT_EQ(NULL, apis.GetSchema("")); 103 EXPECT_EQ(NULL, apis->GetSchema(""));
51 EXPECT_EQ(NULL, apis.GetSchema("")); 104 EXPECT_EQ(NULL, apis->GetSchema(""));
52 EXPECT_EQ(NULL, apis.GetSchema("experimental")); 105 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
53 EXPECT_EQ(NULL, apis.GetSchema("experimental")); 106 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
54 EXPECT_EQ(NULL, apis.GetSchema("foo")); 107 EXPECT_EQ(NULL, apis->GetSchema("foo"));
55 EXPECT_EQ(NULL, apis.GetSchema("foo")); 108 EXPECT_EQ(NULL, apis->GetSchema("foo"));
56 109
57 EXPECT_TRUE(apis.GetSchema("experimental.dns")); 110 EXPECT_TRUE(apis->GetSchema("experimental.dns"));
58 EXPECT_TRUE(apis.GetSchema("experimental.dns")); 111 EXPECT_TRUE(apis->GetSchema("experimental.dns"));
59 EXPECT_TRUE(apis.GetSchema("experimental.infobars")); 112 EXPECT_TRUE(apis->GetSchema("experimental.infobars"));
60 EXPECT_TRUE(apis.GetSchema("experimental.infobars")); 113 EXPECT_TRUE(apis->GetSchema("experimental.infobars"));
61 EXPECT_TRUE(apis.GetSchema("extension")); 114 EXPECT_TRUE(apis->GetSchema("extension"));
62 EXPECT_TRUE(apis.GetSchema("extension")); 115 EXPECT_TRUE(apis->GetSchema("extension"));
63 EXPECT_TRUE(apis.GetSchema("omnibox")); 116 EXPECT_TRUE(apis->GetSchema("omnibox"));
64 EXPECT_TRUE(apis.GetSchema("omnibox")); 117 EXPECT_TRUE(apis->GetSchema("omnibox"));
65 EXPECT_TRUE(apis.GetSchema("storage")); 118 EXPECT_TRUE(apis->GetSchema("storage"));
66 EXPECT_TRUE(apis.GetSchema("storage")); 119 EXPECT_TRUE(apis->GetSchema("storage"));
67 } 120 }
68 121
69 scoped_refptr<Extension> CreateExtensionWithPermissions( 122 scoped_refptr<Extension> CreateExtensionWithPermissions(
70 const std::set<std::string>& permissions) { 123 const std::set<std::string>& permissions) {
71 DictionaryValue manifest; 124 DictionaryValue manifest;
72 manifest.SetString("name", "extension"); 125 manifest.SetString("name", "extension");
73 manifest.SetString("version", "1.0"); 126 manifest.SetString("version", "1.0");
74 manifest.SetInteger("manifest_version", 2); 127 manifest.SetInteger("manifest_version", 2);
75 { 128 {
76 scoped_ptr<ListValue> permissions_list(new ListValue()); 129 scoped_ptr<ListValue> permissions_list(new ListValue());
(...skipping 22 matching lines...) Expand all
99 152
100 TEST(ExtensionAPI, ExtensionWithUnprivilegedAPIs) { 153 TEST(ExtensionAPI, ExtensionWithUnprivilegedAPIs) {
101 scoped_refptr<Extension> extension; 154 scoped_refptr<Extension> extension;
102 { 155 {
103 std::set<std::string> permissions; 156 std::set<std::string> permissions;
104 permissions.insert("storage"); 157 permissions.insert("storage");
105 permissions.insert("history"); 158 permissions.insert("history");
106 extension = CreateExtensionWithPermissions(permissions); 159 extension = CreateExtensionWithPermissions(permissions);
107 } 160 }
108 161
109 ExtensionAPI extension_api; 162 scoped_ptr<ExtensionAPI> extension_api(
163 ExtensionAPI::CreateWithDefaultConfiguration());
110 164
111 scoped_ptr<std::set<std::string> > privileged_apis = 165 scoped_ptr<std::set<std::string> > privileged_apis =
112 extension_api.GetAPIsForContext( 166 extension_api->GetAPIsForContext(
113 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 167 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
114 168
115 scoped_ptr<std::set<std::string> > unprivileged_apis = 169 scoped_ptr<std::set<std::string> > unprivileged_apis =
116 extension_api.GetAPIsForContext( 170 extension_api->GetAPIsForContext(
117 Feature::UNBLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 171 Feature::UNBLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
118 172
119 scoped_ptr<std::set<std::string> > content_script_apis = 173 scoped_ptr<std::set<std::string> > content_script_apis =
120 extension_api.GetAPIsForContext( 174 extension_api->GetAPIsForContext(
121 Feature::CONTENT_SCRIPT_CONTEXT, extension.get(), GURL()); 175 Feature::CONTENT_SCRIPT_CONTEXT, extension.get(), GURL());
122 176
123 // "storage" is completely unprivileged. 177 // "storage" is completely unprivileged.
124 EXPECT_EQ(1u, privileged_apis->count("storage")); 178 EXPECT_EQ(1u, privileged_apis->count("storage"));
125 EXPECT_EQ(1u, unprivileged_apis->count("storage")); 179 EXPECT_EQ(1u, unprivileged_apis->count("storage"));
126 EXPECT_EQ(1u, content_script_apis->count("storage")); 180 EXPECT_EQ(1u, content_script_apis->count("storage"));
127 181
128 // "extension" is partially unprivileged. 182 // "extension" is partially unprivileged.
129 EXPECT_EQ(1u, privileged_apis->count("extension")); 183 EXPECT_EQ(1u, privileged_apis->count("extension"));
130 EXPECT_EQ(1u, unprivileged_apis->count("extension")); 184 EXPECT_EQ(1u, unprivileged_apis->count("extension"));
131 EXPECT_EQ(1u, content_script_apis->count("extension")); 185 EXPECT_EQ(1u, content_script_apis->count("extension"));
132 186
133 // "history" is entirely privileged. 187 // "history" is entirely privileged.
134 EXPECT_EQ(1u, privileged_apis->count("history")); 188 EXPECT_EQ(1u, privileged_apis->count("history"));
135 EXPECT_EQ(0u, unprivileged_apis->count("history")); 189 EXPECT_EQ(0u, unprivileged_apis->count("history"));
136 EXPECT_EQ(0u, content_script_apis->count("history")); 190 EXPECT_EQ(0u, content_script_apis->count("history"));
137 } 191 }
138 192
139 TEST(ExtensionAPI, ExtensionWithDependencies) { 193 TEST(ExtensionAPI, ExtensionWithDependencies) {
140 // Extension with the "ttsEngine" permission but not the "tts" permission; it 194 // Extension with the "ttsEngine" permission but not the "tts" permission; it
141 // must load TTS. 195 // must load TTS.
142 { 196 {
143 scoped_refptr<Extension> extension = 197 scoped_refptr<Extension> extension =
144 CreateExtensionWithPermission("ttsEngine"); 198 CreateExtensionWithPermission("ttsEngine");
145 scoped_ptr<std::set<std::string> > apis = 199 scoped_ptr<ExtensionAPI> api(
146 ExtensionAPI().GetAPIsForContext( 200 ExtensionAPI::CreateWithDefaultConfiguration());
147 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 201 scoped_ptr<std::set<std::string> > apis = api->GetAPIsForContext(
202 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
148 EXPECT_EQ(1u, apis->count("ttsEngine")); 203 EXPECT_EQ(1u, apis->count("ttsEngine"));
149 EXPECT_EQ(1u, apis->count("tts")); 204 EXPECT_EQ(1u, apis->count("tts"));
150 } 205 }
151 206
152 // Conversely, extension with the "tts" permission but not the "ttsEngine" 207 // Conversely, extension with the "tts" permission but not the "ttsEngine"
153 // permission shouldn't get the "ttsEngine" permission. 208 // permission shouldn't get the "ttsEngine" permission.
154 { 209 {
155 scoped_refptr<Extension> extension = 210 scoped_refptr<Extension> extension =
156 CreateExtensionWithPermission("tts"); 211 CreateExtensionWithPermission("tts");
157 scoped_ptr<std::set<std::string> > apis = 212 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration()) ;
158 ExtensionAPI().GetAPIsForContext( 213 scoped_ptr<std::set<std::string> > apis = api->GetAPIsForContext(
159 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 214 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
160 EXPECT_EQ(0u, apis->count("ttsEngine")); 215 EXPECT_EQ(0u, apis->count("ttsEngine"));
161 EXPECT_EQ(1u, apis->count("tts")); 216 EXPECT_EQ(1u, apis->count("tts"));
162 } 217 }
163 } 218 }
164 219
165 bool MatchesURL( 220 bool MatchesURL(
166 ExtensionAPI* api, const std::string& api_name, const std::string& url) { 221 ExtensionAPI* api, const std::string& api_name, const std::string& url) {
167 scoped_ptr<std::set<std::string> > apis = 222 scoped_ptr<std::set<std::string> > apis =
168 api->GetAPIsForContext(Feature::WEB_PAGE_CONTEXT, NULL, GURL(url)); 223 api->GetAPIsForContext(Feature::WEB_PAGE_CONTEXT, NULL, GURL(url));
169 return apis->count(api_name); 224 return apis->count(api_name);
170 } 225 }
171 226
172 TEST(ExtensionAPI, URLMatching) { 227 TEST(ExtensionAPI, URLMatching) {
173 ExtensionAPI api; 228 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
174 229
175 // "app" API is available to all URLs that content scripts can be injected. 230 // "app" API is available to all URLs that content scripts can be injected.
176 EXPECT_TRUE(MatchesURL(&api, "app", "http://example.com/example.html")); 231 EXPECT_TRUE(MatchesURL(api.get(), "app", "http://example.com/example.html"));
177 EXPECT_TRUE(MatchesURL(&api, "app", "https://blah.net")); 232 EXPECT_TRUE(MatchesURL(api.get(), "app", "https://blah.net"));
178 EXPECT_TRUE(MatchesURL(&api, "app", "file://somefile.html")); 233 EXPECT_TRUE(MatchesURL(api.get(), "app", "file://somefile.html"));
179 234
180 // But not internal URLs (for chrome-extension:// the app API is injected by 235 // But not internal URLs (for chrome-extension:// the app API is injected by
181 // GetSchemasForExtension). 236 // GetSchemasForExtension).
182 EXPECT_FALSE(MatchesURL(&api, "app", "about:flags")); 237 EXPECT_FALSE(MatchesURL(api.get(), "app", "about:flags"));
183 EXPECT_FALSE(MatchesURL(&api, "app", "chrome://flags")); 238 EXPECT_FALSE(MatchesURL(api.get(), "app", "chrome://flags"));
184 EXPECT_FALSE(MatchesURL(&api, "app", "chrome-extension://fakeextension")); 239 EXPECT_FALSE(MatchesURL(api.get(), "app",
240 "chrome-extension://fakeextension"));
185 241
186 // "storage" API (for example) isn't available to any URLs. 242 // "storage" API (for example) isn't available to any URLs.
187 EXPECT_FALSE(MatchesURL(&api, "storage", "http://example.com/example.html")); 243 EXPECT_FALSE(MatchesURL(api.get(), "storage",
188 EXPECT_FALSE(MatchesURL(&api, "storage", "https://blah.net")); 244 "http://example.com/example.html"));
189 EXPECT_FALSE(MatchesURL(&api, "storage", "file://somefile.html")); 245 EXPECT_FALSE(MatchesURL(api.get(), "storage", "https://blah.net"));
190 EXPECT_FALSE(MatchesURL(&api, "storage", "about:flags")); 246 EXPECT_FALSE(MatchesURL(api.get(), "storage", "file://somefile.html"));
191 EXPECT_FALSE(MatchesURL(&api, "storage", "chrome://flags")); 247 EXPECT_FALSE(MatchesURL(api.get(), "storage", "about:flags"));
192 EXPECT_FALSE(MatchesURL(&api, "storage", "chrome-extension://fakeextension")); 248 EXPECT_FALSE(MatchesURL(api.get(), "storage", "chrome://flags"));
249 EXPECT_FALSE(MatchesURL(api.get(), "storage",
250 "chrome-extension://fakeextension"));
251 }
252
253 TEST(ExtensionAPI, GetAPINameForFullName) {
254 struct {
255 std::string input;
256 std::string api_name;
257 std::string child_name;
258 } test_data[] = {
259 { "", "", "" },
260 { "unknown", "", "" },
261 { "bookmarks", "bookmarks", "" },
262 { "bookmarks.", "bookmarks", "" },
263 { ".bookmarks", "", "" },
264 { "bookmarks.create", "bookmarks", "create" },
265 { "bookmarks.create.", "bookmarks", "create." },
266 { "bookmarks.create.monkey", "bookmarks", "create.monkey" },
267 { "experimental.bookmarkManager", "experimental.bookmarkManager", "" },
268 { "experimental.bookmarkManager.copy", "experimental.bookmarkManager",
269 "copy" }
270 };
271
272 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
273 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
274 std::string child_name;
275 std::string api_name = api->GetAPINameForFullName(test_data[i].input,
276 &child_name);
277 EXPECT_EQ(test_data[i].api_name, api_name) << test_data[i].input;
278 EXPECT_EQ(test_data[i].child_name, child_name) << test_data[i].input;
279 }
280 }
281
282 TEST(ExtensionAPI, Features) {
koz (OOO until 15th September) 2012/04/02 06:39:48 Features -> TestFeatureProperties?
Aaron Boodman 2012/04/02 08:21:54 Done.
283 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
284
285 scoped_ptr<Feature> bookmarks(api->GetFeature("bookmarks"));
286 scoped_ptr<Feature> bookmarks_create(api->GetFeature("bookmarks.create"));
287
288 struct {
289 Feature* feature;
290 // TODO(aa): More stuff to test over time.
291 } test_data[] = {
292 { bookmarks.get() },
293 { bookmarks_create.get() }
294 };
295
296 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
297 Feature* feature = test_data[i].feature;
298 ASSERT_TRUE(feature) << i;
299
300 EXPECT_TRUE(feature->whitelist()->empty());
301 EXPECT_TRUE(feature->extension_types()->empty());
302
303 EXPECT_EQ(1u, feature->contexts()->size());
304 EXPECT_TRUE(feature->contexts()->count(
305 Feature::BLESSED_EXTENSION_CONTEXT));
306
307 EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location());
308 EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform());
309 EXPECT_EQ(0, feature->min_manifest_version());
310 EXPECT_EQ(0, feature->max_manifest_version());
311 }
312 }
313
314 TEST(ExtensionAPI, FeaturesRequireContexts) {
315 scoped_ptr<ListValue> schema1(new ListValue());
316 DictionaryValue* feature_definition = new DictionaryValue();
317 schema1->Append(feature_definition);
318 feature_definition->SetString("namespace", "test");
319 feature_definition->SetBoolean("uses_feature_system", true);
320
321 scoped_ptr<ListValue> schema2(schema1->DeepCopy());
322
323 ListValue* contexts = new ListValue();
324 contexts->Append(Value::CreateStringValue("content_script"));
325 feature_definition->Set("contexts", contexts);
326
327 struct {
328 ListValue* schema;
329 bool expect_success;
330 } test_data[] = {
331 { schema1.get(), true },
332 { schema2.get(), false }
333 };
334
335 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
336 std::string schema_source;
337 base::JSONWriter::Write(test_data[i].schema, &schema_source);
338
339 ExtensionAPI api;
340 api.RegisterSchema("test", base::StringPiece(schema_source));
341
342 scoped_ptr<Feature> feature(api.GetFeature("test"));
343 EXPECT_EQ(test_data[i].expect_success, feature.get() != NULL) << i;
344 }
193 } 345 }
194 346
195 } // namespace 347 } // namespace
196 } // namespace extensions 348 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698