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

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

Issue 15091002: Lazily load API schemas from resource files and convert all APIs to features (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 7 years, 7 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_reader.h"
13 #include "base/json/json_writer.h" 13 #include "base/json/json_writer.h"
14 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
18 #include "base/values.h" 18 #include "base/values.h"
19 #include "chrome/common/chrome_paths.h" 19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/extensions/extension.h" 20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_manifest_constants.h" 21 #include "chrome/common/extensions/extension_manifest_constants.h"
22 #include "chrome/common/extensions/features/api_feature.h" 22 #include "chrome/common/extensions/features/api_feature.h"
23 #include "chrome/common/extensions/features/base_feature_provider.h" 23 #include "chrome/common/extensions/features/base_feature_provider.h"
24 #include "chrome/common/extensions/features/simple_feature.h" 24 #include "chrome/common/extensions/features/simple_feature.h"
25 #include "chrome/common/extensions/manifest.h" 25 #include "chrome/common/extensions/manifest.h"
26 #include "testing/gtest/include/gtest/gtest.h" 26 #include "testing/gtest/include/gtest/gtest.h"
27 27
28 namespace extensions { 28 namespace extensions {
29 namespace {
30 29
31 SimpleFeature* CreateAPIFeature() { 30 SimpleFeature* CreateAPIFeature() {
32 return new APIFeature(); 31 return new APIFeature();
33 } 32 }
34 33
35 TEST(ExtensionAPITest, Creation) { 34 TEST(ExtensionAPITest, Creation) {
36 ExtensionAPI* shared_instance = ExtensionAPI::GetSharedInstance(); 35 ExtensionAPI* shared_instance = ExtensionAPI::GetSharedInstance();
37 EXPECT_EQ(shared_instance, ExtensionAPI::GetSharedInstance()); 36 EXPECT_EQ(shared_instance, ExtensionAPI::GetSharedInstance());
38 37
39 scoped_ptr<ExtensionAPI> new_instance( 38 scoped_ptr<ExtensionAPI> new_instance(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 scoped_ptr<ExtensionAPI> extension_api( 86 scoped_ptr<ExtensionAPI> extension_api(
88 ExtensionAPI::CreateWithDefaultConfiguration()); 87 ExtensionAPI::CreateWithDefaultConfiguration());
89 88
90 EXPECT_FALSE(extension_api->IsPrivileged("runtime.connect")); 89 EXPECT_FALSE(extension_api->IsPrivileged("runtime.connect"));
91 EXPECT_FALSE(extension_api->IsPrivileged("runtime.onConnect")); 90 EXPECT_FALSE(extension_api->IsPrivileged("runtime.onConnect"));
92 EXPECT_FALSE(extension_api->IsPrivileged("runtime.lastError")); 91 EXPECT_FALSE(extension_api->IsPrivileged("runtime.lastError"));
93 92
94 // Default unknown names to privileged for paranoia's sake. 93 // Default unknown names to privileged for paranoia's sake.
95 EXPECT_TRUE(extension_api->IsPrivileged(std::string())); 94 EXPECT_TRUE(extension_api->IsPrivileged(std::string()));
96 EXPECT_TRUE(extension_api->IsPrivileged("<unknown-namespace>")); 95 EXPECT_TRUE(extension_api->IsPrivileged("<unknown-namespace>"));
97 EXPECT_TRUE(extension_api->IsPrivileged("extension.<unknown-member>")); 96
97 // Child features that are unknown default to parent feature privilege.
98 EXPECT_FALSE(extension_api->IsPrivileged("extension.<unknown-member>"));
98 99
99 // Exists, but privileged. 100 // Exists, but privileged.
100 EXPECT_TRUE(extension_api->IsPrivileged("extension.getViews")); 101 EXPECT_TRUE(extension_api->IsPrivileged("extension.getViews"));
101 EXPECT_TRUE(extension_api->IsPrivileged("history.search")); 102 EXPECT_TRUE(extension_api->IsPrivileged("history.search"));
102 103
103 // Whole APIs that are unprivileged. 104 // Whole APIs that are unprivileged.
104 EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails")); 105 EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails"));
105 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled")); 106 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled"));
106 EXPECT_FALSE(extension_api->IsPrivileged("storage.local")); 107 EXPECT_FALSE(extension_api->IsPrivileged("storage.local"));
107 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged")); 108 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged"));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature); 142 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);
142 143
143 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 144 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
144 ExtensionAPI api; 145 ExtensionAPI api;
145 api.RegisterDependencyProvider("api", &api_feature_provider); 146 api.RegisterDependencyProvider("api", &api_feature_provider);
146 EXPECT_EQ(test_data[i].expect_is_privilged, 147 EXPECT_EQ(test_data[i].expect_is_privilged,
147 api.IsPrivileged(test_data[i].api_full_name)) << i; 148 api.IsPrivileged(test_data[i].api_full_name)) << i;
148 } 149 }
149 } 150 }
150 151
151 TEST(ExtensionAPI, APIFeatures) { 152 TEST(ExtensionAPITest, APIFeatures) {
152 struct { 153 struct {
153 std::string api_full_name; 154 std::string api_full_name;
154 bool expect_is_available; 155 bool expect_is_available;
155 Feature::Context context; 156 Feature::Context context;
156 GURL url; 157 GURL url;
157 } test_data[] = { 158 } test_data[] = {
158 { "test1", false, Feature::WEB_PAGE_CONTEXT, GURL() }, 159 { "test1", false, Feature::WEB_PAGE_CONTEXT, GURL() },
159 { "test1", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() }, 160 { "test1", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
160 { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() }, 161 { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
161 { "test1", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() }, 162 { "test1", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
(...skipping 17 matching lines...) Expand all
179 { "test5", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") }, 180 { "test5", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
180 { "test5", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") }, 181 { "test5", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
181 { "test5.blah", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") }, 182 { "test5.blah", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
182 { "test5.blah", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") }, 183 { "test5.blah", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
183 { "test6", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() }, 184 { "test6", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
184 { "test6.foo", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() }, 185 { "test6.foo", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
185 { "test7", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") }, 186 { "test7", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
186 { "test7.foo", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") }, 187 { "test7.foo", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
187 { "test7.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") }, 188 { "test7.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
188 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") }, 189 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
189 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") } 190 { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
191
192 // Test parent/child.
193 { "parent1", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
194 { "parent1", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
195 { "child1", false, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
196 { "child1", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
197 { "child2", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
198 { "child2", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
199 { "parent2", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
200 { "parent2", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
201 { "parent2", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
202 { "child3", false, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
203 { "child3", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
204 { "child3", false, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
205 { "child.child", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
206 { "child.child", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
207 { "child.child", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() }
190 }; 208 };
191 209
192 base::FilePath api_features_path; 210 base::FilePath api_features_path;
193 PathService::Get(chrome::DIR_TEST_DATA, &api_features_path); 211 PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
194 api_features_path = api_features_path.AppendASCII("extensions") 212 api_features_path = api_features_path.AppendASCII("extensions")
195 .AppendASCII("extension_api_unittest") 213 .AppendASCII("extension_api_unittest")
196 .AppendASCII("api_features.json"); 214 .AppendASCII("api_features.json");
197 215
198 std::string api_features_str; 216 std::string api_features_str;
199 ASSERT_TRUE(file_util::ReadFileToString( 217 ASSERT_TRUE(file_util::ReadFileToString(
200 api_features_path, &api_features_str)) << "api_features.json"; 218 api_features_path, &api_features_str)) << "api_features.json";
201 219
202 scoped_ptr<base::DictionaryValue> value(static_cast<DictionaryValue*>( 220 scoped_ptr<base::DictionaryValue> value(static_cast<DictionaryValue*>(
203 base::JSONReader::Read(api_features_str))); 221 base::JSONReader::Read(api_features_str)));
204 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature); 222 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);
205 223
206 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 224 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
207 ExtensionAPI api; 225 ExtensionAPI api;
208 api.RegisterDependencyProvider("api", &api_feature_provider); 226 api.RegisterDependencyProvider("api", &api_feature_provider);
209 for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd(); 227 for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd();
210 iter.Advance()) { 228 iter.Advance()) {
211 if (iter.key().find(".") == std::string::npos) 229 if (iter.key().find(".") == std::string::npos)
212 api.RegisterSchema(iter.key(), ""); 230 api.RegisterSchemaResource(iter.key(), 0);
213 } 231 }
214 232
215 EXPECT_EQ(test_data[i].expect_is_available, 233 EXPECT_EQ(test_data[i].expect_is_available,
216 api.IsAvailable(test_data[i].api_full_name, 234 api.IsAvailable(test_data[i].api_full_name,
217 NULL, 235 NULL,
218 test_data[i].context, 236 test_data[i].context,
219 test_data[i].url).is_available()) << i; 237 test_data[i].url).is_available()) << i;
220 } 238 }
221 } 239 }
222 240
223 TEST(ExtensionAPI, IsAnyFeatureAvailableToContext) { 241 TEST(ExtensionAPITest, IsAnyFeatureAvailableToContext) {
224 struct { 242 struct {
225 std::string api_full_name; 243 std::string api_full_name;
226 bool expect_is_available; 244 bool expect_is_available;
227 Feature::Context context; 245 Feature::Context context;
228 GURL url; 246 GURL url;
229 } test_data[] = { 247 } test_data[] = {
230 { "test1", false, Feature::WEB_PAGE_CONTEXT, GURL() }, 248 { "test1", false, Feature::WEB_PAGE_CONTEXT, GURL() },
231 { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() }, 249 { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
232 { "test2", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() }, 250 { "test2", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
233 { "test2", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") }, 251 { "test2", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
(...skipping 20 matching lines...) Expand all
254 scoped_ptr<base::DictionaryValue> value(static_cast<DictionaryValue*>( 272 scoped_ptr<base::DictionaryValue> value(static_cast<DictionaryValue*>(
255 base::JSONReader::Read(api_features_str))); 273 base::JSONReader::Read(api_features_str)));
256 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature); 274 BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);
257 275
258 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 276 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
259 ExtensionAPI api; 277 ExtensionAPI api;
260 api.RegisterDependencyProvider("api", &api_feature_provider); 278 api.RegisterDependencyProvider("api", &api_feature_provider);
261 for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd(); 279 for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd();
262 iter.Advance()) { 280 iter.Advance()) {
263 if (iter.key().find(".") == std::string::npos) 281 if (iter.key().find(".") == std::string::npos)
264 api.RegisterSchema(iter.key(), ""); 282 api.RegisterSchemaResource(iter.key(), 0);
265 } 283 }
266 284
267 EXPECT_EQ(test_data[i].expect_is_available, 285 EXPECT_EQ(test_data[i].expect_is_available,
268 api.IsAnyFeatureAvailableToContext(test_data[i].api_full_name, 286 api.IsAnyFeatureAvailableToContext(test_data[i].api_full_name,
269 test_data[i].context, 287 test_data[i].context,
270 test_data[i].url)) << i; 288 test_data[i].url)) << i;
271 } 289 }
272 } 290 }
273 291
274 TEST(ExtensionAPITest, LazyGetSchema) { 292 TEST(ExtensionAPITest, LazyGetSchema) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 PathService::Get(chrome::DIR_TEST_DATA, &manifest_path); 633 PathService::Get(chrome::DIR_TEST_DATA, &manifest_path);
616 manifest_path = manifest_path.AppendASCII("extensions") 634 manifest_path = manifest_path.AppendASCII("extensions")
617 .AppendASCII("extension_api_unittest") 635 .AppendASCII("extension_api_unittest")
618 .AppendASCII("types_have_namespace.json"); 636 .AppendASCII("types_have_namespace.json");
619 637
620 std::string manifest_str; 638 std::string manifest_str;
621 ASSERT_TRUE(file_util::ReadFileToString(manifest_path, &manifest_str)) 639 ASSERT_TRUE(file_util::ReadFileToString(manifest_path, &manifest_str))
622 << "Failed to load: " << manifest_path.value(); 640 << "Failed to load: " << manifest_path.value();
623 641
624 ExtensionAPI api; 642 ExtensionAPI api;
625 api.RegisterSchema("test.foo", manifest_str); 643 api.RegisterSchemaResource("test.foo", 0);
644 api.LoadSchema("test.foo", manifest_str);
626 645
627 const base::DictionaryValue* schema = api.GetSchema("test.foo"); 646 const base::DictionaryValue* schema = api.GetSchema("test.foo");
628 647
629 const base::DictionaryValue* dict; 648 const base::DictionaryValue* dict;
630 const base::DictionaryValue* sub_dict; 649 const base::DictionaryValue* sub_dict;
631 std::string type; 650 std::string type;
632 651
633 GetDictionaryFromList(schema, "types", 0, &dict); 652 GetDictionaryFromList(schema, "types", 0, &dict);
634 EXPECT_TRUE(dict->GetString("id", &type)); 653 EXPECT_TRUE(dict->GetString("id", &type));
635 EXPECT_EQ("test.foo.TestType", type); 654 EXPECT_EQ("test.foo.TestType", type);
(...skipping 26 matching lines...) Expand all
662 681
663 GetDictionaryFromList(schema, "events", 0, &dict); 682 GetDictionaryFromList(schema, "events", 0, &dict);
664 GetDictionaryFromList(dict, "parameters", 0, &sub_dict); 683 GetDictionaryFromList(dict, "parameters", 0, &sub_dict);
665 EXPECT_TRUE(sub_dict->GetString("$ref", &type)); 684 EXPECT_TRUE(sub_dict->GetString("$ref", &type));
666 EXPECT_EQ("test.foo.TestType", type); 685 EXPECT_EQ("test.foo.TestType", type);
667 GetDictionaryFromList(dict, "parameters", 1, &sub_dict); 686 GetDictionaryFromList(dict, "parameters", 1, &sub_dict);
668 EXPECT_TRUE(sub_dict->GetString("$ref", &type)); 687 EXPECT_TRUE(sub_dict->GetString("$ref", &type));
669 EXPECT_EQ("fully.qualified.Type", type); 688 EXPECT_EQ("fully.qualified.Type", type);
670 } 689 }
671 690
672 } // namespace
673 } // namespace extensions 691 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698