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

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

Issue 12846011: Implement API features for the Extension API feature system (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tests and comments Created 7 years, 9 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 #include <vector> 8 #include <vector>
9 9
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/json/json_reader.h"
12 #include "base/json/json_writer.h" 13 #include "base/json/json_writer.h"
13 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/stringprintf.h"
16 #include "base/values.h" 18 #include "base/values.h"
17 #include "chrome/common/chrome_paths.h" 19 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/extensions/extension.h" 20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/features/api_feature.h"
22 #include "chrome/common/extensions/features/base_feature_provider.h"
19 #include "chrome/common/extensions/features/simple_feature.h" 23 #include "chrome/common/extensions/features/simple_feature.h"
20 #include "chrome/common/extensions/manifest.h" 24 #include "chrome/common/extensions/manifest.h"
21 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
22 26
23 namespace extensions { 27 namespace extensions {
24 namespace { 28 namespace {
25 29
30 SimpleFeature* CreateAPIFeature() {
31 return new APIFeature();
32 }
33
26 class TestFeatureProvider : public FeatureProvider { 34 class TestFeatureProvider : public FeatureProvider {
27 public: 35 public:
28 explicit TestFeatureProvider(Feature::Context context) 36 explicit TestFeatureProvider(Feature::Context context)
29 : context_(context) { 37 : context_(context) {
30 } 38 }
31 39
32 virtual Feature* GetFeature(const std::string& name) OVERRIDE { 40 virtual Feature* GetFeature(const std::string& name) OVERRIDE {
33 SimpleFeature* result = new SimpleFeature(); 41 SimpleFeature* result = new SimpleFeature();
34 result->set_name(name); 42 result->set_name(name);
35 result->extension_types()->insert(Manifest::TYPE_EXTENSION); 43 result->extension_types()->insert(Manifest::TYPE_EXTENSION);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled")); 126 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled"));
119 EXPECT_FALSE(extension_api->IsPrivileged("storage.local")); 127 EXPECT_FALSE(extension_api->IsPrivileged("storage.local"));
120 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged")); 128 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged"));
121 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set")); 129 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set"));
122 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS")); 130 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS"));
123 EXPECT_FALSE(extension_api->IsPrivileged("storage.set")); 131 EXPECT_FALSE(extension_api->IsPrivileged("storage.set"));
124 } 132 }
125 133
126 TEST(ExtensionAPI, IsPrivilegedFeatures) { 134 TEST(ExtensionAPI, IsPrivilegedFeatures) {
127 struct { 135 struct {
128 std::string filename;
129 std::string api_full_name; 136 std::string api_full_name;
130 bool expect_is_privilged; 137 bool expect_is_privilged;
131 Feature::Context test2_contexts; 138 Feature::Context test2_contexts;
132 } test_data[] = { 139 } test_data[] = {
133 { "is_privileged_features_1.json", "test", false, 140 { "test1", false, Feature::UNSPECIFIED_CONTEXT },
134 Feature::UNSPECIFIED_CONTEXT }, 141 { "test1.foo", true, Feature::UNSPECIFIED_CONTEXT },
135 { "is_privileged_features_2.json", "test", true, 142 { "test2", true, Feature::UNSPECIFIED_CONTEXT },
136 Feature::UNSPECIFIED_CONTEXT }, 143 { "test3", false, Feature::UNSPECIFIED_CONTEXT },
137 { "is_privileged_features_3.json", "test", false, 144 { "test4.bar", false, Feature::UNSPECIFIED_CONTEXT },
138 Feature::UNSPECIFIED_CONTEXT }, 145 { "test4.baz", false, Feature::UNSPECIFIED_CONTEXT },
139 { "is_privileged_features_4.json", "test.bar", false, 146 { "test5.foo", true, Feature::BLESSED_EXTENSION_CONTEXT },
140 Feature::UNSPECIFIED_CONTEXT }, 147 { "test5.foo", false, Feature::UNBLESSED_EXTENSION_CONTEXT },
141 { "is_privileged_features_5.json", "test.bar", true, 148 { "test5.bar", true, Feature::BLESSED_EXTENSION_CONTEXT },
142 Feature::BLESSED_EXTENSION_CONTEXT }, 149 { "test5.bar", false, Feature::UNBLESSED_EXTENSION_CONTEXT },
143 { "is_privileged_features_5.json", "test.bar", false, 150 { "test5.bar.foo", true, Feature::BLESSED_EXTENSION_CONTEXT },
144 Feature::UNBLESSED_EXTENSION_CONTEXT } 151 { "test5.bar.foo", false, Feature::UNBLESSED_EXTENSION_CONTEXT }
145 }; 152 };
146 153
154 base::FilePath api_features_path;
155 PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
156 api_features_path = api_features_path.AppendASCII("extensions")
157 .AppendASCII("extension_api_unittest")
158 .AppendASCII("privileged_api_features.json");
159
160 std::string api_features_str;
161 ASSERT_TRUE(file_util::ReadFileToString(
162 api_features_path, &api_features_str)) << "privileged_api_features.json";
163
164 base::DictionaryValue* value = static_cast<DictionaryValue*>(
165 base::JSONReader::Read(api_features_str));
166 BaseFeatureProvider api_feature_provider(*value, NULL);
167
147 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 168 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
148 base::FilePath manifest_path;
149 PathService::Get(chrome::DIR_TEST_DATA, &manifest_path);
150 manifest_path = manifest_path.AppendASCII("extensions")
151 .AppendASCII("extension_api_unittest")
152 .AppendASCII(test_data[i].filename);
153
154 std::string manifest_str;
155 ASSERT_TRUE(file_util::ReadFileToString(manifest_path, &manifest_str))
156 << test_data[i].filename;
157
158 ExtensionAPI api; 169 ExtensionAPI api;
159 api.RegisterSchema("test", manifest_str); 170 api.RegisterDependencyProvider("api", &api_feature_provider);
160 171
161 TestFeatureProvider test2_provider(test_data[i].test2_contexts); 172 TestFeatureProvider test2_provider(test_data[i].test2_contexts);
173
162 if (test_data[i].test2_contexts != Feature::UNSPECIFIED_CONTEXT) { 174 if (test_data[i].test2_contexts != Feature::UNSPECIFIED_CONTEXT) {
163 api.RegisterDependencyProvider("test2", &test2_provider); 175 api.RegisterDependencyProvider("test2", &test2_provider);
164 } 176 }
165 177
166 EXPECT_EQ(test_data[i].expect_is_privilged, 178 EXPECT_EQ(test_data[i].expect_is_privilged,
167 api.IsPrivileged(test_data[i].api_full_name)) << i; 179 api.IsPrivileged(test_data[i].api_full_name)) << i;
168 } 180 }
169 } 181 }
170 182
183 /*scoped_refptr<Extension> CreateExtensionWithType(Manifest::Type type) {
not at google - send to devlin 2013/03/26 21:31:21 hm?
cduvall 2013/03/26 22:08:48 Oops
184 base::DictionaryValue manifest;
185 manifest.SetString("name", "extension");
186 manifest.SetString("version", "1.0");
187 manifest.SetInteger("manifest_version", 2);
188
189 std::string error;
190 scoped_refptr<Extension> extension(Extension::Create(
191 base::FilePath(), Manifest::UNPACKED,
192 manifest, Extension::NO_FLAGS, &error));
193 CHECK(extension.get());
194 CHECK(error.empty());
195
196 extension
197 return extension;
198 }*/
199
200 TEST(ExtensionAPI, APIFeatures) {
201 struct {
202 std::string api_full_name;
203 bool expect_is_available;
204 Feature::Context context;
205 GURL url;
206 } test_data[] = {
207 { "test1", false, Feature::WEB_PAGE_CONTEXT, GURL() },
208 { "test1", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
209 { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
210 { "test1", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
211 { "test2", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
212 { "test2", false, Feature::BLESSED_EXTENSION_CONTEXT,
213 GURL("http://google.com") },
214 { "test2.foo", false, Feature::WEB_PAGE_CONTEXT,
215 GURL("http://google.com") },
216 { "test2.foo", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
217 { "test3", false, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
218 { "test3.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
219 { "test3.foo", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
220 { "test4", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
221 { "test4.foo", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
222 { "test4.foo", false, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
223 { "test4.foo.foo", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
224 { "test5", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
225 { "test5", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
226 { "test5.blah", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
227 { "test5.blah", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
228 { "test6", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
229 { "test6.foo", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
230 { "test7", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
231 { "test7.foo", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
232 { "test7.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
233 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
234 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") }
235 };
236
237 base::FilePath api_features_path;
238 PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
239 api_features_path = api_features_path.AppendASCII("extensions")
240 .AppendASCII("extension_api_unittest")
241 .AppendASCII("api_features.json");
242
243 std::string api_features_str;
244 ASSERT_TRUE(file_util::ReadFileToString(
245 api_features_path, &api_features_str)) << "api_features.json";
246
247 base::DictionaryValue* value = static_cast<DictionaryValue*>(
248 base::JSONReader::Read(api_features_str));
249 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);
250
251 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
252 ExtensionAPI api;
253 api.RegisterDependencyProvider("api", &api_feature_provider);
254 for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd();
255 iter.Advance()) {
256 if (iter.key().find(".") == std::string::npos)
257 api.RegisterSchema(iter.key(), "");
258 }
259
260 EXPECT_EQ(test_data[i].expect_is_available,
261 api.IsAvailable(test_data[i].api_full_name,
262 NULL,
263 test_data[i].context,
264 test_data[i].url).is_available()) << i;
265 }
266 }
267
171 TEST(ExtensionAPI, LazyGetSchema) { 268 TEST(ExtensionAPI, LazyGetSchema) {
172 scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration()); 269 scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration());
173 270
174 EXPECT_EQ(NULL, apis->GetSchema("")); 271 EXPECT_EQ(NULL, apis->GetSchema(""));
175 EXPECT_EQ(NULL, apis->GetSchema("")); 272 EXPECT_EQ(NULL, apis->GetSchema(""));
176 EXPECT_EQ(NULL, apis->GetSchema("experimental")); 273 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
177 EXPECT_EQ(NULL, apis->GetSchema("experimental")); 274 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
178 EXPECT_EQ(NULL, apis->GetSchema("foo")); 275 EXPECT_EQ(NULL, apis->GetSchema("foo"));
179 EXPECT_EQ(NULL, apis->GetSchema("foo")); 276 EXPECT_EQ(NULL, apis->GetSchema("foo"));
180 277
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 std::string api_name = api->GetAPINameFromFullName(test_data[i].input, 466 std::string api_name = api->GetAPINameFromFullName(test_data[i].input,
370 &child_name); 467 &child_name);
371 EXPECT_EQ(test_data[i].api_name, api_name) << test_data[i].input; 468 EXPECT_EQ(test_data[i].api_name, api_name) << test_data[i].input;
372 EXPECT_EQ(test_data[i].child_name, child_name) << test_data[i].input; 469 EXPECT_EQ(test_data[i].child_name, child_name) << test_data[i].input;
373 } 470 }
374 } 471 }
375 472
376 TEST(ExtensionAPI, DefaultConfigurationFeatures) { 473 TEST(ExtensionAPI, DefaultConfigurationFeatures) {
377 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration()); 474 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
378 475
379 SimpleFeature* bookmarks = 476 SimpleFeature* bookmarks = static_cast<SimpleFeature*>(
380 static_cast<SimpleFeature*>(api->GetFeature("bookmarks")); 477 api->GetFeatureDependency("api:bookmarks"));
381 SimpleFeature* bookmarks_create = 478 SimpleFeature* bookmarks_create = static_cast<SimpleFeature*>(
382 static_cast<SimpleFeature*>(api->GetFeature("bookmarks.create")); 479 api->GetFeatureDependency("api:bookmarks.create"));
383 480
384 struct { 481 struct {
385 SimpleFeature* feature; 482 SimpleFeature* feature;
386 // TODO(aa): More stuff to test over time. 483 // TODO(aa): More stuff to test over time.
387 } test_data[] = { 484 } test_data[] = {
388 { bookmarks }, 485 { bookmarks },
389 { bookmarks_create } 486 { bookmarks_create }
390 }; 487 };
391 488
392 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 489 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
393 SimpleFeature* feature = test_data[i].feature; 490 SimpleFeature* feature = test_data[i].feature;
394 ASSERT_TRUE(feature) << i; 491 ASSERT_TRUE(feature) << i;
395 492
396 EXPECT_TRUE(feature->whitelist()->empty()); 493 EXPECT_TRUE(feature->whitelist()->empty());
397 EXPECT_TRUE(feature->extension_types()->empty()); 494 EXPECT_TRUE(feature->extension_types()->empty());
398 495
399 EXPECT_EQ(1u, feature->GetContexts()->size()); 496 EXPECT_EQ(1u, feature->GetContexts()->size());
400 EXPECT_TRUE(feature->GetContexts()->count( 497 EXPECT_TRUE(feature->GetContexts()->count(
401 Feature::BLESSED_EXTENSION_CONTEXT)); 498 Feature::BLESSED_EXTENSION_CONTEXT));
402 499
403 EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location()); 500 EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location());
404 EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform()); 501 EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform());
405 EXPECT_EQ(0, feature->min_manifest_version()); 502 EXPECT_EQ(0, feature->min_manifest_version());
406 EXPECT_EQ(0, feature->max_manifest_version()); 503 EXPECT_EQ(0, feature->max_manifest_version());
407 } 504 }
408 } 505 }
409 506
410 TEST(ExtensionAPI, FeaturesRequireContexts) { 507 TEST(ExtensionAPI, FeaturesRequireContexts) {
411 scoped_ptr<base::ListValue> schema1(new base::ListValue()); 508 // TODO(cduvall): Make this check API featues.
412 base::DictionaryValue* feature_definition = new base::DictionaryValue(); 509 scoped_ptr<base::DictionaryValue> api_features1(new base::DictionaryValue());
413 schema1->Append(feature_definition); 510 scoped_ptr<base::DictionaryValue> api_features2(new base::DictionaryValue());
414 feature_definition->SetString("namespace", "test"); 511 base::DictionaryValue* test1 = new base::DictionaryValue();
415 feature_definition->SetBoolean("uses_feature_system", true); 512 base::DictionaryValue* test2 = new base::DictionaryValue();
416
417 scoped_ptr<base::ListValue> schema2(schema1->DeepCopy());
418
419 base::ListValue* contexts = new base::ListValue(); 513 base::ListValue* contexts = new base::ListValue();
420 contexts->Append(new base::StringValue("content_script")); 514 contexts->Append(new base::StringValue("content_script"));
421 feature_definition->Set("contexts", contexts); 515 test1->Set("contexts", contexts);
516 api_features1->Set("test", test1);
517 api_features2->Set("test", test2);
422 518
423 struct { 519 struct {
424 base::ListValue* schema; 520 base::DictionaryValue* api_features;
425 bool expect_success; 521 bool expect_success;
426 } test_data[] = { 522 } test_data[] = {
427 { schema1.get(), true }, 523 { api_features1.get(), true },
428 { schema2.get(), false } 524 { api_features2.get(), false }
429 }; 525 };
430 526
527
431 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 528 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
432 std::string schema_source; 529 BaseFeatureProvider api_feature_provider(*test_data[i].api_features,
433 base::JSONWriter::Write(test_data[i].schema, &schema_source); 530 CreateAPIFeature);
434 531 Feature* feature = api_feature_provider.GetFeature("test");
435 ExtensionAPI api;
436 api.RegisterSchema("test", base::StringPiece(schema_source));
437
438 Feature* feature = api.GetFeature("test");
439 EXPECT_EQ(test_data[i].expect_success, feature != NULL) << i; 532 EXPECT_EQ(test_data[i].expect_success, feature != NULL) << i;
440 } 533 }
441 } 534 }
442 535
443 static void GetDictionaryFromList(const base::DictionaryValue* schema, 536 static void GetDictionaryFromList(const base::DictionaryValue* schema,
444 const std::string& list_name, 537 const std::string& list_name,
445 const int list_index, 538 const int list_index,
446 const base::DictionaryValue** out) { 539 const base::DictionaryValue** out) {
447 const base::ListValue* list; 540 const base::ListValue* list;
448 EXPECT_TRUE(schema->GetList(list_name, &list)); 541 EXPECT_TRUE(schema->GetList(list_name, &list));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 GetDictionaryFromList(dict, "parameters", 0, &sub_dict); 596 GetDictionaryFromList(dict, "parameters", 0, &sub_dict);
504 EXPECT_TRUE(sub_dict->GetString("$ref", &type)); 597 EXPECT_TRUE(sub_dict->GetString("$ref", &type));
505 EXPECT_EQ("test.foo.TestType", type); 598 EXPECT_EQ("test.foo.TestType", type);
506 GetDictionaryFromList(dict, "parameters", 1, &sub_dict); 599 GetDictionaryFromList(dict, "parameters", 1, &sub_dict);
507 EXPECT_TRUE(sub_dict->GetString("$ref", &type)); 600 EXPECT_TRUE(sub_dict->GetString("$ref", &type));
508 EXPECT_EQ("fully.qualified.Type", type); 601 EXPECT_EQ("fully.qualified.Type", type);
509 } 602 }
510 603
511 } // namespace 604 } // namespace
512 } // namespace extensions 605 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698