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