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

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: fixed memory leak Created 7 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 #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
26 class TestFeatureProvider : public FeatureProvider { 30 SimpleFeature* CreateAPIFeature() {
27 public: 31 return new APIFeature();
28 explicit TestFeatureProvider(Feature::Context context) 32 }
29 : context_(context) {
30 }
31
32 virtual Feature* GetFeature(const std::string& name) OVERRIDE {
33 SimpleFeature* result = new SimpleFeature();
34 result->set_name(name);
35 result->extension_types()->insert(Manifest::TYPE_EXTENSION);
36 result->GetContexts()->insert(context_);
37 to_destroy_.push_back(make_linked_ptr(result));
38 return result;
39 }
40
41 private:
42 std::vector<linked_ptr<Feature> > to_destroy_;
43 Feature::Context context_;
44 };
45 33
46 TEST(ExtensionAPI, Creation) { 34 TEST(ExtensionAPI, Creation) {
47 ExtensionAPI* shared_instance = ExtensionAPI::GetSharedInstance(); 35 ExtensionAPI* shared_instance = ExtensionAPI::GetSharedInstance();
48 EXPECT_EQ(shared_instance, ExtensionAPI::GetSharedInstance()); 36 EXPECT_EQ(shared_instance, ExtensionAPI::GetSharedInstance());
49 37
50 scoped_ptr<ExtensionAPI> new_instance( 38 scoped_ptr<ExtensionAPI> new_instance(
51 ExtensionAPI::CreateWithDefaultConfiguration()); 39 ExtensionAPI::CreateWithDefaultConfiguration());
52 EXPECT_NE(new_instance.get(), 40 EXPECT_NE(new_instance.get(),
53 scoped_ptr<ExtensionAPI>( 41 scoped_ptr<ExtensionAPI>(
54 ExtensionAPI::CreateWithDefaultConfiguration()).get()); 42 ExtensionAPI::CreateWithDefaultConfiguration()).get());
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled")); 106 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled"));
119 EXPECT_FALSE(extension_api->IsPrivileged("storage.local")); 107 EXPECT_FALSE(extension_api->IsPrivileged("storage.local"));
120 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged")); 108 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged"));
121 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set")); 109 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set"));
122 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS")); 110 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS"));
123 EXPECT_FALSE(extension_api->IsPrivileged("storage.set")); 111 EXPECT_FALSE(extension_api->IsPrivileged("storage.set"));
124 } 112 }
125 113
126 TEST(ExtensionAPI, IsPrivilegedFeatures) { 114 TEST(ExtensionAPI, IsPrivilegedFeatures) {
127 struct { 115 struct {
128 std::string filename;
129 std::string api_full_name; 116 std::string api_full_name;
130 bool expect_is_privilged; 117 bool expect_is_privilged;
131 Feature::Context test2_contexts;
132 } test_data[] = { 118 } test_data[] = {
133 { "is_privileged_features_1.json", "test", false, 119 { "test1", false },
134 Feature::UNSPECIFIED_CONTEXT }, 120 { "test1.foo", true },
135 { "is_privileged_features_2.json", "test", true, 121 { "test2", true },
136 Feature::UNSPECIFIED_CONTEXT }, 122 { "test2.foo", false },
137 { "is_privileged_features_3.json", "test", false, 123 { "test2.bar", false },
138 Feature::UNSPECIFIED_CONTEXT }, 124 { "test2.baz", true },
139 { "is_privileged_features_4.json", "test.bar", false, 125 { "test3", false },
140 Feature::UNSPECIFIED_CONTEXT }, 126 { "test3.foo", true },
141 { "is_privileged_features_5.json", "test.bar", true, 127 { "test4", false }
142 Feature::BLESSED_EXTENSION_CONTEXT },
143 { "is_privileged_features_5.json", "test.bar", false,
144 Feature::UNBLESSED_EXTENSION_CONTEXT }
145 }; 128 };
146 129
130 base::FilePath api_features_path;
131 PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
132 api_features_path = api_features_path.AppendASCII("extensions")
133 .AppendASCII("extension_api_unittest")
134 .AppendASCII("privileged_api_features.json");
135
136 std::string api_features_str;
137 ASSERT_TRUE(file_util::ReadFileToString(
138 api_features_path, &api_features_str)) << "privileged_api_features.json";
139
140 scoped_ptr<base::DictionaryValue> value(static_cast<DictionaryValue*>(
141 base::JSONReader::Read(api_features_str)));
142 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);
143
147 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 144 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; 145 ExtensionAPI api;
159 api.RegisterSchema("test", manifest_str); 146 api.RegisterDependencyProvider("api", &api_feature_provider);
160
161 TestFeatureProvider test2_provider(test_data[i].test2_contexts);
162 if (test_data[i].test2_contexts != Feature::UNSPECIFIED_CONTEXT) {
163 api.RegisterDependencyProvider("test2", &test2_provider);
164 }
165
166 EXPECT_EQ(test_data[i].expect_is_privilged, 147 EXPECT_EQ(test_data[i].expect_is_privilged,
167 api.IsPrivileged(test_data[i].api_full_name)) << i; 148 api.IsPrivileged(test_data[i].api_full_name)) << i;
168 } 149 }
169 } 150 }
170 151
152 TEST(ExtensionAPI, APIFeatures) {
153 struct {
154 std::string api_full_name;
155 bool expect_is_available;
156 Feature::Context context;
157 GURL url;
158 } test_data[] = {
159 { "test1", false, Feature::WEB_PAGE_CONTEXT, GURL() },
160 { "test1", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
161 { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
162 { "test1", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
163 { "test2", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
164 { "test2", false, Feature::BLESSED_EXTENSION_CONTEXT,
165 GURL("http://google.com") },
166 { "test2.foo", false, Feature::WEB_PAGE_CONTEXT,
167 GURL("http://google.com") },
168 { "test2.foo", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
169 { "test3", false, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
170 { "test3.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
171 { "test3.foo", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
172 { "test4", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
173 { "test4.foo", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
174 { "test4.foo", false, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
175 { "test4.foo.foo", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
176 { "test5", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
177 { "test5", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
178 { "test5.blah", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
179 { "test5.blah", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
180 { "test6", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
181 { "test6.foo", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
182 { "test7", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
183 { "test7.foo", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
184 { "test7.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
185 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
186 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") }
187 };
188
189 base::FilePath api_features_path;
190 PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
191 api_features_path = api_features_path.AppendASCII("extensions")
192 .AppendASCII("extension_api_unittest")
193 .AppendASCII("api_features.json");
194
195 std::string api_features_str;
196 ASSERT_TRUE(file_util::ReadFileToString(
197 api_features_path, &api_features_str)) << "api_features.json";
198
199 scoped_ptr<base::DictionaryValue> value(static_cast<DictionaryValue*>(
200 base::JSONReader::Read(api_features_str)));
201 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);
202
203 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
204 ExtensionAPI api;
205 api.RegisterDependencyProvider("api", &api_feature_provider);
206 for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd();
207 iter.Advance()) {
208 if (iter.key().find(".") == std::string::npos)
209 api.RegisterSchema(iter.key(), "");
210 }
211
212 EXPECT_EQ(test_data[i].expect_is_available,
213 api.IsAvailable(test_data[i].api_full_name,
214 NULL,
215 test_data[i].context,
216 test_data[i].url).is_available()) << i;
217 }
218 }
219
171 TEST(ExtensionAPI, LazyGetSchema) { 220 TEST(ExtensionAPI, LazyGetSchema) {
172 scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration()); 221 scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration());
173 222
174 EXPECT_EQ(NULL, apis->GetSchema("")); 223 EXPECT_EQ(NULL, apis->GetSchema(""));
175 EXPECT_EQ(NULL, apis->GetSchema("")); 224 EXPECT_EQ(NULL, apis->GetSchema(""));
176 EXPECT_EQ(NULL, apis->GetSchema("experimental")); 225 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
177 EXPECT_EQ(NULL, apis->GetSchema("experimental")); 226 EXPECT_EQ(NULL, apis->GetSchema("experimental"));
178 EXPECT_EQ(NULL, apis->GetSchema("foo")); 227 EXPECT_EQ(NULL, apis->GetSchema("foo"));
179 EXPECT_EQ(NULL, apis->GetSchema("foo")); 228 EXPECT_EQ(NULL, apis->GetSchema("foo"));
180 229
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 std::string api_name = api->GetAPINameFromFullName(test_data[i].input, 418 std::string api_name = api->GetAPINameFromFullName(test_data[i].input,
370 &child_name); 419 &child_name);
371 EXPECT_EQ(test_data[i].api_name, api_name) << test_data[i].input; 420 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; 421 EXPECT_EQ(test_data[i].child_name, child_name) << test_data[i].input;
373 } 422 }
374 } 423 }
375 424
376 TEST(ExtensionAPI, DefaultConfigurationFeatures) { 425 TEST(ExtensionAPI, DefaultConfigurationFeatures) {
377 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration()); 426 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
378 427
379 SimpleFeature* bookmarks = 428 SimpleFeature* bookmarks = static_cast<SimpleFeature*>(
380 static_cast<SimpleFeature*>(api->GetFeature("bookmarks")); 429 api->GetFeatureDependency("api:bookmarks"));
381 SimpleFeature* bookmarks_create = 430 SimpleFeature* bookmarks_create = static_cast<SimpleFeature*>(
382 static_cast<SimpleFeature*>(api->GetFeature("bookmarks.create")); 431 api->GetFeatureDependency("api:bookmarks.create"));
383 432
384 struct { 433 struct {
385 SimpleFeature* feature; 434 SimpleFeature* feature;
386 // TODO(aa): More stuff to test over time. 435 // TODO(aa): More stuff to test over time.
387 } test_data[] = { 436 } test_data[] = {
388 { bookmarks }, 437 { bookmarks },
389 { bookmarks_create } 438 { bookmarks_create }
390 }; 439 };
391 440
392 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 441 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
393 SimpleFeature* feature = test_data[i].feature; 442 SimpleFeature* feature = test_data[i].feature;
394 ASSERT_TRUE(feature) << i; 443 ASSERT_TRUE(feature) << i;
395 444
396 EXPECT_TRUE(feature->whitelist()->empty()); 445 EXPECT_TRUE(feature->whitelist()->empty());
397 EXPECT_TRUE(feature->extension_types()->empty()); 446 EXPECT_TRUE(feature->extension_types()->empty());
398 447
399 EXPECT_EQ(1u, feature->GetContexts()->size()); 448 EXPECT_EQ(1u, feature->GetContexts()->size());
400 EXPECT_TRUE(feature->GetContexts()->count( 449 EXPECT_TRUE(feature->GetContexts()->count(
401 Feature::BLESSED_EXTENSION_CONTEXT)); 450 Feature::BLESSED_EXTENSION_CONTEXT));
402 451
403 EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location()); 452 EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location());
404 EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform()); 453 EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform());
405 EXPECT_EQ(0, feature->min_manifest_version()); 454 EXPECT_EQ(0, feature->min_manifest_version());
406 EXPECT_EQ(0, feature->max_manifest_version()); 455 EXPECT_EQ(0, feature->max_manifest_version());
407 } 456 }
408 } 457 }
409 458
410 TEST(ExtensionAPI, FeaturesRequireContexts) { 459 TEST(ExtensionAPI, FeaturesRequireContexts) {
411 scoped_ptr<base::ListValue> schema1(new base::ListValue()); 460 // TODO(cduvall): Make this check API featues.
412 base::DictionaryValue* feature_definition = new base::DictionaryValue(); 461 scoped_ptr<base::DictionaryValue> api_features1(new base::DictionaryValue());
413 schema1->Append(feature_definition); 462 scoped_ptr<base::DictionaryValue> api_features2(new base::DictionaryValue());
414 feature_definition->SetString("namespace", "test"); 463 base::DictionaryValue* test1 = new base::DictionaryValue();
415 feature_definition->SetBoolean("uses_feature_system", true); 464 base::DictionaryValue* test2 = new base::DictionaryValue();
416
417 scoped_ptr<base::ListValue> schema2(schema1->DeepCopy());
418
419 base::ListValue* contexts = new base::ListValue(); 465 base::ListValue* contexts = new base::ListValue();
420 contexts->Append(new base::StringValue("content_script")); 466 contexts->Append(new base::StringValue("content_script"));
421 feature_definition->Set("contexts", contexts); 467 test1->Set("contexts", contexts);
468 api_features1->Set("test", test1);
469 api_features2->Set("test", test2);
422 470
423 struct { 471 struct {
424 base::ListValue* schema; 472 base::DictionaryValue* api_features;
425 bool expect_success; 473 bool expect_success;
426 } test_data[] = { 474 } test_data[] = {
427 { schema1.get(), true }, 475 { api_features1.get(), true },
428 { schema2.get(), false } 476 { api_features2.get(), false }
429 }; 477 };
430 478
479
431 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 480 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
432 std::string schema_source; 481 BaseFeatureProvider api_feature_provider(*test_data[i].api_features,
433 base::JSONWriter::Write(test_data[i].schema, &schema_source); 482 CreateAPIFeature);
434 483 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; 484 EXPECT_EQ(test_data[i].expect_success, feature != NULL) << i;
440 } 485 }
441 } 486 }
442 487
443 static void GetDictionaryFromList(const base::DictionaryValue* schema, 488 static void GetDictionaryFromList(const base::DictionaryValue* schema,
444 const std::string& list_name, 489 const std::string& list_name,
445 const int list_index, 490 const int list_index,
446 const base::DictionaryValue** out) { 491 const base::DictionaryValue** out) {
447 const base::ListValue* list; 492 const base::ListValue* list;
448 EXPECT_TRUE(schema->GetList(list_name, &list)); 493 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); 548 GetDictionaryFromList(dict, "parameters", 0, &sub_dict);
504 EXPECT_TRUE(sub_dict->GetString("$ref", &type)); 549 EXPECT_TRUE(sub_dict->GetString("$ref", &type));
505 EXPECT_EQ("test.foo.TestType", type); 550 EXPECT_EQ("test.foo.TestType", type);
506 GetDictionaryFromList(dict, "parameters", 1, &sub_dict); 551 GetDictionaryFromList(dict, "parameters", 1, &sub_dict);
507 EXPECT_TRUE(sub_dict->GetString("$ref", &type)); 552 EXPECT_TRUE(sub_dict->GetString("$ref", &type));
508 EXPECT_EQ("fully.qualified.Type", type); 553 EXPECT_EQ("fully.qualified.Type", type);
509 } 554 }
510 555
511 } // namespace 556 } // namespace
512 } // namespace extensions 557 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/api/extension_api.cc ('k') | chrome/common/extensions/api/webstore.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698