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

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

Issue 9969136: Reland r130462: Implement FeatureProvider for ExtensionAPI." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase 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/file_util.h"
11 #include "base/json/json_writer.h"
12 #include "base/message_loop.h"
10 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #include "base/path_service.h"
12 #include "base/values.h" 16 #include "base/values.h"
17 #include "chrome/common/chrome_paths.h"
13 #include "chrome/common/extensions/extension.h" 18 #include "chrome/common/extensions/extension.h"
19 #include "content/test/test_browser_thread.h"
14 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
15 21
22 using content::BrowserThread;
23
16 namespace extensions { 24 namespace extensions {
17 namespace { 25 namespace {
18 26
27 class TestFeatureProvider : public FeatureProvider {
28 public:
29 explicit TestFeatureProvider(Feature::Context context)
30 : context_(context) {
31 }
32
33 virtual scoped_ptr<Feature> GetFeature(const std::string& name) OVERRIDE {
34 scoped_ptr<Feature> result(new Feature());
35 result->set_name(name);
36 result->extension_types()->insert(Extension::TYPE_EXTENSION);
37 result->contexts()->insert(context_);
38 return result.Pass();
39 }
40
41 private:
42 Feature::Context context_;
43 };
44
45 TEST(ExtensionAPI, Creation) {
46 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
47 content::TestBrowserThread ui_thread(BrowserThread::UI, &loop);
48
49 ExtensionAPI* shared_instance = ExtensionAPI::GetSharedInstance();
50 EXPECT_EQ(shared_instance, ExtensionAPI::GetSharedInstance());
51
52 scoped_ptr<ExtensionAPI> new_instance(
53 ExtensionAPI::CreateWithDefaultConfiguration());
54 EXPECT_NE(new_instance.get(),
55 scoped_ptr<ExtensionAPI>(
56 ExtensionAPI::CreateWithDefaultConfiguration()).get());
57
58 ExtensionAPI empty_instance;
59
60 struct {
61 ExtensionAPI* api;
62 bool expect_populated;
63 } test_data[] = {
64 { shared_instance, true },
65 { new_instance.get(), true },
66 { &empty_instance, false }
67 };
68
69 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
70 EXPECT_EQ(test_data[i].expect_populated,
71 test_data[i].api->GetSchema("bookmarks.create") != NULL);
72 }
73 }
74
75 TEST(ExtensionAPI, SplitDependencyName) {
76 struct {
77 std::string input;
78 std::string expected_feature_type;
79 std::string expected_feature_name;
80 } test_data[] = {
81 { "", "api", "" }, // assumes "api" when no type is present
82 { "foo", "api", "foo" },
83 { "foo:", "foo", "" },
84 { ":foo", "", "foo" },
85 { "foo:bar", "foo", "bar" },
86 { "foo:bar.baz", "foo", "bar.baz" }
87 };
88
89 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
90 std::string feature_type;
91 std::string feature_name;
92 ExtensionAPI::SplitDependencyName(test_data[i].input, &feature_type,
93 &feature_name);
94 EXPECT_EQ(test_data[i].expected_feature_type, feature_type) << i;
95 EXPECT_EQ(test_data[i].expected_feature_name, feature_name) << i;
96 }
97 }
98
19 TEST(ExtensionAPI, IsPrivileged) { 99 TEST(ExtensionAPI, IsPrivileged) {
20 ExtensionAPI extension_api; 100 scoped_ptr<ExtensionAPI> extension_api(
101 ExtensionAPI::CreateWithDefaultConfiguration());
21 102
22 EXPECT_FALSE(extension_api.IsPrivileged("extension.connect")); 103 EXPECT_FALSE(extension_api->IsPrivileged("extension.connect"));
23 EXPECT_FALSE(extension_api.IsPrivileged("extension.onConnect")); 104 EXPECT_FALSE(extension_api->IsPrivileged("extension.onConnect"));
24 105
25 // Properties are not supported yet. 106 // Properties are not supported yet.
26 EXPECT_TRUE(extension_api.IsPrivileged("extension.lastError")); 107 EXPECT_TRUE(extension_api->IsPrivileged("extension.lastError"));
27 108
28 // Default unknown names to privileged for paranoia's sake. 109 // Default unknown names to privileged for paranoia's sake.
29 EXPECT_TRUE(extension_api.IsPrivileged("<unknown-namespace>")); 110 EXPECT_TRUE(extension_api->IsPrivileged(""));
30 EXPECT_TRUE(extension_api.IsPrivileged("extension.<unknown-member>")); 111 EXPECT_TRUE(extension_api->IsPrivileged("<unknown-namespace>"));
112 EXPECT_TRUE(extension_api->IsPrivileged("extension.<unknown-member>"));
31 113
32 // Exists, but privileged. 114 // Exists, but privileged.
33 EXPECT_TRUE(extension_api.IsPrivileged("extension.getViews")); 115 EXPECT_TRUE(extension_api->IsPrivileged("extension.getViews"));
34 EXPECT_TRUE(extension_api.IsPrivileged("history.search")); 116 EXPECT_TRUE(extension_api->IsPrivileged("history.search"));
35 117
36 // Whole APIs that are unprivileged. 118 // Whole APIs that are unprivileged.
37 EXPECT_FALSE(extension_api.IsPrivileged("app.getDetails")); 119 EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails"));
38 EXPECT_FALSE(extension_api.IsPrivileged("app.isInstalled")); 120 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled"));
39 EXPECT_FALSE(extension_api.IsPrivileged("storage.local")); 121 EXPECT_FALSE(extension_api->IsPrivileged("storage.local"));
40 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.onChanged")); 122 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged"));
41 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.set")); 123 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set"));
42 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.MAX_ITEMS")); 124 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS"));
43 EXPECT_FALSE(extension_api.IsPrivileged("storage.set")); 125 EXPECT_FALSE(extension_api->IsPrivileged("storage.set"));
126 }
127
128 TEST(ExtensionAPI, IsPrivilegedFeatures) {
129 struct {
130 std::string filename;
131 std::string api_full_name;
132 bool expect_is_privilged;
133 Feature::Context test2_contexts;
134 } test_data[] = {
135 { "is_privileged_features_1.json", "test", false,
136 Feature::UNSPECIFIED_CONTEXT },
137 { "is_privileged_features_2.json", "test", true,
138 Feature::UNSPECIFIED_CONTEXT },
139 { "is_privileged_features_3.json", "test", false,
140 Feature::UNSPECIFIED_CONTEXT },
141 { "is_privileged_features_4.json", "test.bar", false,
142 Feature::UNSPECIFIED_CONTEXT },
143 { "is_privileged_features_5.json", "test.bar", true,
144 Feature::BLESSED_EXTENSION_CONTEXT },
145 { "is_privileged_features_5.json", "test.bar", false,
146 Feature::UNBLESSED_EXTENSION_CONTEXT }
147 };
148
149 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
150 FilePath manifest_path;
151 PathService::Get(chrome::DIR_TEST_DATA, &manifest_path);
152 manifest_path = manifest_path.AppendASCII("extensions")
153 .AppendASCII("extension_api_unittest")
154 .AppendASCII(test_data[i].filename);
155
156 std::string manifest_str;
157 ASSERT_TRUE(file_util::ReadFileToString(manifest_path, &manifest_str))
158 << test_data[i].filename;
159
160 ExtensionAPI api;
161 api.RegisterSchema("test", manifest_str);
162
163 TestFeatureProvider test2_provider(test_data[i].test2_contexts);
164 if (test_data[i].test2_contexts != Feature::UNSPECIFIED_CONTEXT) {
165 api.RegisterDependencyProvider("test2", &test2_provider);
166 }
167
168 api.LoadAllSchemas();
169 EXPECT_EQ(test_data[i].expect_is_privilged,
170 api.IsPrivileged(test_data[i].api_full_name)) << i;
171 }
44 } 172 }
45 173
46 TEST(ExtensionAPI, LazyGetSchema) { 174 TEST(ExtensionAPI, LazyGetSchema) {
47 ExtensionAPI apis; 175 scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration());
48 176
49 EXPECT_EQ(NULL, apis.GetSchema("")); 177 EXPECT_EQ(NULL, apis->GetSchema(""));
50 EXPECT_EQ(NULL, apis.GetSchema("")); 178 EXPECT_EQ(NULL, apis->GetSchema(""));
51 EXPECT_EQ(NULL, apis.GetSchema("experimental")); 179 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
52 EXPECT_EQ(NULL, apis.GetSchema("experimental")); 180 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
53 EXPECT_EQ(NULL, apis.GetSchema("foo")); 181 EXPECT_EQ(NULL, apis->GetSchema("foo"));
54 EXPECT_EQ(NULL, apis.GetSchema("foo")); 182 EXPECT_EQ(NULL, apis->GetSchema("foo"));
55 183
56 EXPECT_TRUE(apis.GetSchema("experimental.dns")); 184 EXPECT_TRUE(apis->GetSchema("experimental.dns"));
57 EXPECT_TRUE(apis.GetSchema("experimental.dns")); 185 EXPECT_TRUE(apis->GetSchema("experimental.dns"));
58 EXPECT_TRUE(apis.GetSchema("experimental.infobars")); 186 EXPECT_TRUE(apis->GetSchema("experimental.infobars"));
59 EXPECT_TRUE(apis.GetSchema("experimental.infobars")); 187 EXPECT_TRUE(apis->GetSchema("experimental.infobars"));
60 EXPECT_TRUE(apis.GetSchema("extension")); 188 EXPECT_TRUE(apis->GetSchema("extension"));
61 EXPECT_TRUE(apis.GetSchema("extension")); 189 EXPECT_TRUE(apis->GetSchema("extension"));
62 EXPECT_TRUE(apis.GetSchema("omnibox")); 190 EXPECT_TRUE(apis->GetSchema("omnibox"));
63 EXPECT_TRUE(apis.GetSchema("omnibox")); 191 EXPECT_TRUE(apis->GetSchema("omnibox"));
64 EXPECT_TRUE(apis.GetSchema("storage")); 192 EXPECT_TRUE(apis->GetSchema("storage"));
65 EXPECT_TRUE(apis.GetSchema("storage")); 193 EXPECT_TRUE(apis->GetSchema("storage"));
66 } 194 }
67 195
68 scoped_refptr<Extension> CreateExtensionWithPermissions( 196 scoped_refptr<Extension> CreateExtensionWithPermissions(
69 const std::set<std::string>& permissions) { 197 const std::set<std::string>& permissions) {
70 DictionaryValue manifest; 198 DictionaryValue manifest;
71 manifest.SetString("name", "extension"); 199 manifest.SetString("name", "extension");
72 manifest.SetString("version", "1.0"); 200 manifest.SetString("version", "1.0");
73 manifest.SetInteger("manifest_version", 2); 201 manifest.SetInteger("manifest_version", 2);
74 { 202 {
75 scoped_ptr<ListValue> permissions_list(new ListValue()); 203 scoped_ptr<ListValue> permissions_list(new ListValue());
(...skipping 22 matching lines...) Expand all
98 226
99 TEST(ExtensionAPI, ExtensionWithUnprivilegedAPIs) { 227 TEST(ExtensionAPI, ExtensionWithUnprivilegedAPIs) {
100 scoped_refptr<Extension> extension; 228 scoped_refptr<Extension> extension;
101 { 229 {
102 std::set<std::string> permissions; 230 std::set<std::string> permissions;
103 permissions.insert("storage"); 231 permissions.insert("storage");
104 permissions.insert("history"); 232 permissions.insert("history");
105 extension = CreateExtensionWithPermissions(permissions); 233 extension = CreateExtensionWithPermissions(permissions);
106 } 234 }
107 235
108 ExtensionAPI extension_api; 236 scoped_ptr<ExtensionAPI> extension_api(
237 ExtensionAPI::CreateWithDefaultConfiguration());
109 238
110 scoped_ptr<std::set<std::string> > privileged_apis = 239 scoped_ptr<std::set<std::string> > privileged_apis =
111 extension_api.GetAPIsForContext( 240 extension_api->GetAPIsForContext(
112 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 241 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
113 242
114 scoped_ptr<std::set<std::string> > unprivileged_apis = 243 scoped_ptr<std::set<std::string> > unprivileged_apis =
115 extension_api.GetAPIsForContext( 244 extension_api->GetAPIsForContext(
116 Feature::UNBLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 245 Feature::UNBLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
117 246
118 scoped_ptr<std::set<std::string> > content_script_apis = 247 scoped_ptr<std::set<std::string> > content_script_apis =
119 extension_api.GetAPIsForContext( 248 extension_api->GetAPIsForContext(
120 Feature::CONTENT_SCRIPT_CONTEXT, extension.get(), GURL()); 249 Feature::CONTENT_SCRIPT_CONTEXT, extension.get(), GURL());
121 250
122 // "storage" is completely unprivileged. 251 // "storage" is completely unprivileged.
123 EXPECT_EQ(1u, privileged_apis->count("storage")); 252 EXPECT_EQ(1u, privileged_apis->count("storage"));
124 EXPECT_EQ(1u, unprivileged_apis->count("storage")); 253 EXPECT_EQ(1u, unprivileged_apis->count("storage"));
125 EXPECT_EQ(1u, content_script_apis->count("storage")); 254 EXPECT_EQ(1u, content_script_apis->count("storage"));
126 255
127 // "extension" is partially unprivileged. 256 // "extension" is partially unprivileged.
128 EXPECT_EQ(1u, privileged_apis->count("extension")); 257 EXPECT_EQ(1u, privileged_apis->count("extension"));
129 EXPECT_EQ(1u, unprivileged_apis->count("extension")); 258 EXPECT_EQ(1u, unprivileged_apis->count("extension"));
130 EXPECT_EQ(1u, content_script_apis->count("extension")); 259 EXPECT_EQ(1u, content_script_apis->count("extension"));
131 260
132 // "history" is entirely privileged. 261 // "history" is entirely privileged.
133 EXPECT_EQ(1u, privileged_apis->count("history")); 262 EXPECT_EQ(1u, privileged_apis->count("history"));
134 EXPECT_EQ(0u, unprivileged_apis->count("history")); 263 EXPECT_EQ(0u, unprivileged_apis->count("history"));
135 EXPECT_EQ(0u, content_script_apis->count("history")); 264 EXPECT_EQ(0u, content_script_apis->count("history"));
136 } 265 }
137 266
138 TEST(ExtensionAPI, ExtensionWithDependencies) { 267 TEST(ExtensionAPI, ExtensionWithDependencies) {
139 // Extension with the "ttsEngine" permission but not the "tts" permission; it 268 // Extension with the "ttsEngine" permission but not the "tts" permission; it
140 // must load TTS. 269 // must load TTS.
141 { 270 {
142 scoped_refptr<Extension> extension = 271 scoped_refptr<Extension> extension =
143 CreateExtensionWithPermission("ttsEngine"); 272 CreateExtensionWithPermission("ttsEngine");
144 scoped_ptr<std::set<std::string> > apis = 273 scoped_ptr<ExtensionAPI> api(
145 ExtensionAPI().GetAPIsForContext( 274 ExtensionAPI::CreateWithDefaultConfiguration());
146 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 275 scoped_ptr<std::set<std::string> > apis = api->GetAPIsForContext(
276 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
147 EXPECT_EQ(1u, apis->count("ttsEngine")); 277 EXPECT_EQ(1u, apis->count("ttsEngine"));
148 EXPECT_EQ(1u, apis->count("tts")); 278 EXPECT_EQ(1u, apis->count("tts"));
149 } 279 }
150 280
151 // Conversely, extension with the "tts" permission but not the "ttsEngine" 281 // Conversely, extension with the "tts" permission but not the "ttsEngine"
152 // permission shouldn't get the "ttsEngine" permission. 282 // permission shouldn't get the "ttsEngine" permission.
153 { 283 {
154 scoped_refptr<Extension> extension = 284 scoped_refptr<Extension> extension =
155 CreateExtensionWithPermission("tts"); 285 CreateExtensionWithPermission("tts");
156 scoped_ptr<std::set<std::string> > apis = 286 scoped_ptr<ExtensionAPI> api(
157 ExtensionAPI().GetAPIsForContext( 287 ExtensionAPI::CreateWithDefaultConfiguration());
158 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); 288 scoped_ptr<std::set<std::string> > apis = api->GetAPIsForContext(
289 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL());
159 EXPECT_EQ(0u, apis->count("ttsEngine")); 290 EXPECT_EQ(0u, apis->count("ttsEngine"));
160 EXPECT_EQ(1u, apis->count("tts")); 291 EXPECT_EQ(1u, apis->count("tts"));
161 } 292 }
162 } 293 }
163 294
164 bool MatchesURL( 295 bool MatchesURL(
165 ExtensionAPI* api, const std::string& api_name, const std::string& url) { 296 ExtensionAPI* api, const std::string& api_name, const std::string& url) {
166 scoped_ptr<std::set<std::string> > apis = 297 scoped_ptr<std::set<std::string> > apis =
167 api->GetAPIsForContext(Feature::WEB_PAGE_CONTEXT, NULL, GURL(url)); 298 api->GetAPIsForContext(Feature::WEB_PAGE_CONTEXT, NULL, GURL(url));
168 return apis->count(api_name); 299 return apis->count(api_name);
169 } 300 }
170 301
171 TEST(ExtensionAPI, URLMatching) { 302 TEST(ExtensionAPI, URLMatching) {
172 ExtensionAPI api; 303 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
173 304
174 // "app" API is available to all URLs that content scripts can be injected. 305 // "app" API is available to all URLs that content scripts can be injected.
175 EXPECT_TRUE(MatchesURL(&api, "app", "http://example.com/example.html")); 306 EXPECT_TRUE(MatchesURL(api.get(), "app", "http://example.com/example.html"));
176 EXPECT_TRUE(MatchesURL(&api, "app", "https://blah.net")); 307 EXPECT_TRUE(MatchesURL(api.get(), "app", "https://blah.net"));
177 EXPECT_TRUE(MatchesURL(&api, "app", "file://somefile.html")); 308 EXPECT_TRUE(MatchesURL(api.get(), "app", "file://somefile.html"));
178 309
179 // But not internal URLs (for chrome-extension:// the app API is injected by 310 // But not internal URLs (for chrome-extension:// the app API is injected by
180 // GetSchemasForExtension). 311 // GetSchemasForExtension).
181 EXPECT_FALSE(MatchesURL(&api, "app", "about:flags")); 312 EXPECT_FALSE(MatchesURL(api.get(), "app", "about:flags"));
182 EXPECT_FALSE(MatchesURL(&api, "app", "chrome://flags")); 313 EXPECT_FALSE(MatchesURL(api.get(), "app", "chrome://flags"));
183 EXPECT_FALSE(MatchesURL(&api, "app", "chrome-extension://fakeextension")); 314 EXPECT_FALSE(MatchesURL(api.get(), "app",
315 "chrome-extension://fakeextension"));
184 316
185 // "storage" API (for example) isn't available to any URLs. 317 // "storage" API (for example) isn't available to any URLs.
186 EXPECT_FALSE(MatchesURL(&api, "storage", "http://example.com/example.html")); 318 EXPECT_FALSE(MatchesURL(api.get(), "storage",
187 EXPECT_FALSE(MatchesURL(&api, "storage", "https://blah.net")); 319 "http://example.com/example.html"));
188 EXPECT_FALSE(MatchesURL(&api, "storage", "file://somefile.html")); 320 EXPECT_FALSE(MatchesURL(api.get(), "storage", "https://blah.net"));
189 EXPECT_FALSE(MatchesURL(&api, "storage", "about:flags")); 321 EXPECT_FALSE(MatchesURL(api.get(), "storage", "file://somefile.html"));
190 EXPECT_FALSE(MatchesURL(&api, "storage", "chrome://flags")); 322 EXPECT_FALSE(MatchesURL(api.get(), "storage", "about:flags"));
191 EXPECT_FALSE(MatchesURL(&api, "storage", "chrome-extension://fakeextension")); 323 EXPECT_FALSE(MatchesURL(api.get(), "storage", "chrome://flags"));
324 EXPECT_FALSE(MatchesURL(api.get(), "storage",
325 "chrome-extension://fakeextension"));
326 }
327
328 TEST(ExtensionAPI, GetAPINameFromFullName) {
329 struct {
330 std::string input;
331 std::string api_name;
332 std::string child_name;
333 } test_data[] = {
334 { "", "", "" },
335 { "unknown", "", "" },
336 { "bookmarks", "bookmarks", "" },
337 { "bookmarks.", "bookmarks", "" },
338 { ".bookmarks", "", "" },
339 { "bookmarks.create", "bookmarks", "create" },
340 { "bookmarks.create.", "bookmarks", "create." },
341 { "bookmarks.create.monkey", "bookmarks", "create.monkey" },
342 { "experimental.bookmarkManager", "experimental.bookmarkManager", "" },
343 { "experimental.bookmarkManager.copy", "experimental.bookmarkManager",
344 "copy" }
345 };
346
347 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
348 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
349 std::string child_name;
350 std::string api_name = api->GetAPINameFromFullName(test_data[i].input,
351 &child_name);
352 EXPECT_EQ(test_data[i].api_name, api_name) << test_data[i].input;
353 EXPECT_EQ(test_data[i].child_name, child_name) << test_data[i].input;
354 }
355 }
356
357 TEST(ExtensionAPI, DefaultConfigurationFeatures) {
358 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
359
360 scoped_ptr<Feature> bookmarks(api->GetFeature("bookmarks"));
361 scoped_ptr<Feature> bookmarks_create(api->GetFeature("bookmarks.create"));
362
363 struct {
364 Feature* feature;
365 // TODO(aa): More stuff to test over time.
366 } test_data[] = {
367 { bookmarks.get() },
368 { bookmarks_create.get() }
369 };
370
371 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
372 Feature* feature = test_data[i].feature;
373 ASSERT_TRUE(feature) << i;
374
375 EXPECT_TRUE(feature->whitelist()->empty());
376 EXPECT_TRUE(feature->extension_types()->empty());
377
378 EXPECT_EQ(1u, feature->contexts()->size());
379 EXPECT_TRUE(feature->contexts()->count(
380 Feature::BLESSED_EXTENSION_CONTEXT));
381
382 EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location());
383 EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform());
384 EXPECT_EQ(0, feature->min_manifest_version());
385 EXPECT_EQ(0, feature->max_manifest_version());
386 }
387 }
388
389 TEST(ExtensionAPI, FeaturesRequireContexts) {
390 scoped_ptr<ListValue> schema1(new ListValue());
391 DictionaryValue* feature_definition = new DictionaryValue();
392 schema1->Append(feature_definition);
393 feature_definition->SetString("namespace", "test");
394 feature_definition->SetBoolean("uses_feature_system", true);
395
396 scoped_ptr<ListValue> schema2(schema1->DeepCopy());
397
398 ListValue* contexts = new ListValue();
399 contexts->Append(Value::CreateStringValue("content_script"));
400 feature_definition->Set("contexts", contexts);
401
402 struct {
403 ListValue* schema;
404 bool expect_success;
405 } test_data[] = {
406 { schema1.get(), true },
407 { schema2.get(), false }
408 };
409
410 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
411 std::string schema_source;
412 base::JSONWriter::Write(test_data[i].schema, &schema_source);
413
414 ExtensionAPI api;
415 api.RegisterSchema("test", base::StringPiece(schema_source));
416 api.LoadAllSchemas();
417
418 scoped_ptr<Feature> feature(api.GetFeature("test"));
419 EXPECT_EQ(test_data[i].expect_success, feature.get() != NULL) << i;
420 }
192 } 421 }
193 422
194 } // namespace 423 } // namespace
195 } // namespace extensions 424 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698