| 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" | |
| 12 #include "base/message_loop.h" | |
| 13 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| 14 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/path_service.h" | |
| 16 #include "base/values.h" | 12 #include "base/values.h" |
| 17 #include "chrome/common/chrome_paths.h" | |
| 18 #include "chrome/common/extensions/extension.h" | 13 #include "chrome/common/extensions/extension.h" |
| 19 #include "content/test/test_browser_thread.h" | |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 15 |
| 22 using content::BrowserThread; | |
| 23 | |
| 24 namespace extensions { | 16 namespace extensions { |
| 25 namespace { | 17 namespace { |
| 26 | 18 |
| 27 class TestFeatureProvider : public FeatureProvider { | 19 TEST(ExtensionAPI, IsPrivileged) { |
| 28 public: | 20 ExtensionAPI extension_api; |
| 29 explicit TestFeatureProvider(Feature::Context context) | |
| 30 : context_(context) { | |
| 31 } | |
| 32 | 21 |
| 33 virtual scoped_ptr<Feature> GetFeature(const std::string& name) OVERRIDE { | 22 EXPECT_FALSE(extension_api.IsPrivileged("extension.connect")); |
| 34 scoped_ptr<Feature> result(new Feature()); | 23 EXPECT_FALSE(extension_api.IsPrivileged("extension.onConnect")); |
| 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 | |
| 99 TEST(ExtensionAPI, IsPrivileged) { | |
| 100 scoped_ptr<ExtensionAPI> extension_api( | |
| 101 ExtensionAPI::CreateWithDefaultConfiguration()); | |
| 102 | |
| 103 EXPECT_FALSE(extension_api->IsPrivileged("extension.connect")); | |
| 104 EXPECT_FALSE(extension_api->IsPrivileged("extension.onConnect")); | |
| 105 | 24 |
| 106 // Properties are not supported yet. | 25 // Properties are not supported yet. |
| 107 EXPECT_TRUE(extension_api->IsPrivileged("extension.lastError")); | 26 EXPECT_TRUE(extension_api.IsPrivileged("extension.lastError")); |
| 108 | 27 |
| 109 // Default unknown names to privileged for paranoia's sake. | 28 // Default unknown names to privileged for paranoia's sake. |
| 110 EXPECT_TRUE(extension_api->IsPrivileged("")); | 29 EXPECT_TRUE(extension_api.IsPrivileged("<unknown-namespace>")); |
| 111 EXPECT_TRUE(extension_api->IsPrivileged("<unknown-namespace>")); | 30 EXPECT_TRUE(extension_api.IsPrivileged("extension.<unknown-member>")); |
| 112 EXPECT_TRUE(extension_api->IsPrivileged("extension.<unknown-member>")); | |
| 113 | 31 |
| 114 // Exists, but privileged. | 32 // Exists, but privileged. |
| 115 EXPECT_TRUE(extension_api->IsPrivileged("extension.getViews")); | 33 EXPECT_TRUE(extension_api.IsPrivileged("extension.getViews")); |
| 116 EXPECT_TRUE(extension_api->IsPrivileged("history.search")); | 34 EXPECT_TRUE(extension_api.IsPrivileged("history.search")); |
| 117 | 35 |
| 118 // Whole APIs that are unprivileged. | 36 // Whole APIs that are unprivileged. |
| 119 EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails")); | 37 EXPECT_FALSE(extension_api.IsPrivileged("app.getDetails")); |
| 120 EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled")); | 38 EXPECT_FALSE(extension_api.IsPrivileged("app.isInstalled")); |
| 121 EXPECT_FALSE(extension_api->IsPrivileged("storage.local")); | 39 EXPECT_FALSE(extension_api.IsPrivileged("storage.local")); |
| 122 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged")); | 40 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.onChanged")); |
| 123 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set")); | 41 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.set")); |
| 124 EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS")); | 42 EXPECT_FALSE(extension_api.IsPrivileged("storage.local.MAX_ITEMS")); |
| 125 EXPECT_FALSE(extension_api->IsPrivileged("storage.set")); | 43 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 } | |
| 172 } | 44 } |
| 173 | 45 |
| 174 TEST(ExtensionAPI, LazyGetSchema) { | 46 TEST(ExtensionAPI, LazyGetSchema) { |
| 175 scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration()); | 47 ExtensionAPI apis; |
| 176 | 48 |
| 177 EXPECT_EQ(NULL, apis->GetSchema("")); | 49 EXPECT_EQ(NULL, apis.GetSchema("")); |
| 178 EXPECT_EQ(NULL, apis->GetSchema("")); | 50 EXPECT_EQ(NULL, apis.GetSchema("")); |
| 179 EXPECT_EQ(NULL, apis->GetSchema("experimental")); | 51 EXPECT_EQ(NULL, apis.GetSchema("experimental")); |
| 180 EXPECT_EQ(NULL, apis->GetSchema("experimental")); | 52 EXPECT_EQ(NULL, apis.GetSchema("experimental")); |
| 181 EXPECT_EQ(NULL, apis->GetSchema("foo")); | 53 EXPECT_EQ(NULL, apis.GetSchema("foo")); |
| 182 EXPECT_EQ(NULL, apis->GetSchema("foo")); | 54 EXPECT_EQ(NULL, apis.GetSchema("foo")); |
| 183 | 55 |
| 184 EXPECT_TRUE(apis->GetSchema("experimental.dns")); | 56 EXPECT_TRUE(apis.GetSchema("experimental.dns")); |
| 185 EXPECT_TRUE(apis->GetSchema("experimental.dns")); | 57 EXPECT_TRUE(apis.GetSchema("experimental.dns")); |
| 186 EXPECT_TRUE(apis->GetSchema("experimental.infobars")); | 58 EXPECT_TRUE(apis.GetSchema("experimental.infobars")); |
| 187 EXPECT_TRUE(apis->GetSchema("experimental.infobars")); | 59 EXPECT_TRUE(apis.GetSchema("experimental.infobars")); |
| 188 EXPECT_TRUE(apis->GetSchema("extension")); | 60 EXPECT_TRUE(apis.GetSchema("extension")); |
| 189 EXPECT_TRUE(apis->GetSchema("extension")); | 61 EXPECT_TRUE(apis.GetSchema("extension")); |
| 190 EXPECT_TRUE(apis->GetSchema("omnibox")); | 62 EXPECT_TRUE(apis.GetSchema("omnibox")); |
| 191 EXPECT_TRUE(apis->GetSchema("omnibox")); | 63 EXPECT_TRUE(apis.GetSchema("omnibox")); |
| 192 EXPECT_TRUE(apis->GetSchema("storage")); | 64 EXPECT_TRUE(apis.GetSchema("storage")); |
| 193 EXPECT_TRUE(apis->GetSchema("storage")); | 65 EXPECT_TRUE(apis.GetSchema("storage")); |
| 194 } | 66 } |
| 195 | 67 |
| 196 scoped_refptr<Extension> CreateExtensionWithPermissions( | 68 scoped_refptr<Extension> CreateExtensionWithPermissions( |
| 197 const std::set<std::string>& permissions) { | 69 const std::set<std::string>& permissions) { |
| 198 DictionaryValue manifest; | 70 DictionaryValue manifest; |
| 199 manifest.SetString("name", "extension"); | 71 manifest.SetString("name", "extension"); |
| 200 manifest.SetString("version", "1.0"); | 72 manifest.SetString("version", "1.0"); |
| 201 manifest.SetInteger("manifest_version", 2); | 73 manifest.SetInteger("manifest_version", 2); |
| 202 { | 74 { |
| 203 scoped_ptr<ListValue> permissions_list(new ListValue()); | 75 scoped_ptr<ListValue> permissions_list(new ListValue()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 226 | 98 |
| 227 TEST(ExtensionAPI, ExtensionWithUnprivilegedAPIs) { | 99 TEST(ExtensionAPI, ExtensionWithUnprivilegedAPIs) { |
| 228 scoped_refptr<Extension> extension; | 100 scoped_refptr<Extension> extension; |
| 229 { | 101 { |
| 230 std::set<std::string> permissions; | 102 std::set<std::string> permissions; |
| 231 permissions.insert("storage"); | 103 permissions.insert("storage"); |
| 232 permissions.insert("history"); | 104 permissions.insert("history"); |
| 233 extension = CreateExtensionWithPermissions(permissions); | 105 extension = CreateExtensionWithPermissions(permissions); |
| 234 } | 106 } |
| 235 | 107 |
| 236 scoped_ptr<ExtensionAPI> extension_api( | 108 ExtensionAPI extension_api; |
| 237 ExtensionAPI::CreateWithDefaultConfiguration()); | |
| 238 | 109 |
| 239 scoped_ptr<std::set<std::string> > privileged_apis = | 110 scoped_ptr<std::set<std::string> > privileged_apis = |
| 240 extension_api->GetAPIsForContext( | 111 extension_api.GetAPIsForContext( |
| 241 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); | 112 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); |
| 242 | 113 |
| 243 scoped_ptr<std::set<std::string> > unprivileged_apis = | 114 scoped_ptr<std::set<std::string> > unprivileged_apis = |
| 244 extension_api->GetAPIsForContext( | 115 extension_api.GetAPIsForContext( |
| 245 Feature::UNBLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); | 116 Feature::UNBLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); |
| 246 | 117 |
| 247 scoped_ptr<std::set<std::string> > content_script_apis = | 118 scoped_ptr<std::set<std::string> > content_script_apis = |
| 248 extension_api->GetAPIsForContext( | 119 extension_api.GetAPIsForContext( |
| 249 Feature::CONTENT_SCRIPT_CONTEXT, extension.get(), GURL()); | 120 Feature::CONTENT_SCRIPT_CONTEXT, extension.get(), GURL()); |
| 250 | 121 |
| 251 // "storage" is completely unprivileged. | 122 // "storage" is completely unprivileged. |
| 252 EXPECT_EQ(1u, privileged_apis->count("storage")); | 123 EXPECT_EQ(1u, privileged_apis->count("storage")); |
| 253 EXPECT_EQ(1u, unprivileged_apis->count("storage")); | 124 EXPECT_EQ(1u, unprivileged_apis->count("storage")); |
| 254 EXPECT_EQ(1u, content_script_apis->count("storage")); | 125 EXPECT_EQ(1u, content_script_apis->count("storage")); |
| 255 | 126 |
| 256 // "extension" is partially unprivileged. | 127 // "extension" is partially unprivileged. |
| 257 EXPECT_EQ(1u, privileged_apis->count("extension")); | 128 EXPECT_EQ(1u, privileged_apis->count("extension")); |
| 258 EXPECT_EQ(1u, unprivileged_apis->count("extension")); | 129 EXPECT_EQ(1u, unprivileged_apis->count("extension")); |
| 259 EXPECT_EQ(1u, content_script_apis->count("extension")); | 130 EXPECT_EQ(1u, content_script_apis->count("extension")); |
| 260 | 131 |
| 261 // "history" is entirely privileged. | 132 // "history" is entirely privileged. |
| 262 EXPECT_EQ(1u, privileged_apis->count("history")); | 133 EXPECT_EQ(1u, privileged_apis->count("history")); |
| 263 EXPECT_EQ(0u, unprivileged_apis->count("history")); | 134 EXPECT_EQ(0u, unprivileged_apis->count("history")); |
| 264 EXPECT_EQ(0u, content_script_apis->count("history")); | 135 EXPECT_EQ(0u, content_script_apis->count("history")); |
| 265 } | 136 } |
| 266 | 137 |
| 267 TEST(ExtensionAPI, ExtensionWithDependencies) { | 138 TEST(ExtensionAPI, ExtensionWithDependencies) { |
| 268 // Extension with the "ttsEngine" permission but not the "tts" permission; it | 139 // Extension with the "ttsEngine" permission but not the "tts" permission; it |
| 269 // must load TTS. | 140 // must load TTS. |
| 270 { | 141 { |
| 271 scoped_refptr<Extension> extension = | 142 scoped_refptr<Extension> extension = |
| 272 CreateExtensionWithPermission("ttsEngine"); | 143 CreateExtensionWithPermission("ttsEngine"); |
| 273 scoped_ptr<ExtensionAPI> api( | 144 scoped_ptr<std::set<std::string> > apis = |
| 274 ExtensionAPI::CreateWithDefaultConfiguration()); | 145 ExtensionAPI().GetAPIsForContext( |
| 275 scoped_ptr<std::set<std::string> > apis = api->GetAPIsForContext( | 146 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); |
| 276 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); | |
| 277 EXPECT_EQ(1u, apis->count("ttsEngine")); | 147 EXPECT_EQ(1u, apis->count("ttsEngine")); |
| 278 EXPECT_EQ(1u, apis->count("tts")); | 148 EXPECT_EQ(1u, apis->count("tts")); |
| 279 } | 149 } |
| 280 | 150 |
| 281 // Conversely, extension with the "tts" permission but not the "ttsEngine" | 151 // Conversely, extension with the "tts" permission but not the "ttsEngine" |
| 282 // permission shouldn't get the "ttsEngine" permission. | 152 // permission shouldn't get the "ttsEngine" permission. |
| 283 { | 153 { |
| 284 scoped_refptr<Extension> extension = | 154 scoped_refptr<Extension> extension = |
| 285 CreateExtensionWithPermission("tts"); | 155 CreateExtensionWithPermission("tts"); |
| 286 scoped_ptr<ExtensionAPI> api( | 156 scoped_ptr<std::set<std::string> > apis = |
| 287 ExtensionAPI::CreateWithDefaultConfiguration()); | 157 ExtensionAPI().GetAPIsForContext( |
| 288 scoped_ptr<std::set<std::string> > apis = api->GetAPIsForContext( | 158 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); |
| 289 Feature::BLESSED_EXTENSION_CONTEXT, extension.get(), GURL()); | |
| 290 EXPECT_EQ(0u, apis->count("ttsEngine")); | 159 EXPECT_EQ(0u, apis->count("ttsEngine")); |
| 291 EXPECT_EQ(1u, apis->count("tts")); | 160 EXPECT_EQ(1u, apis->count("tts")); |
| 292 } | 161 } |
| 293 } | 162 } |
| 294 | 163 |
| 295 bool MatchesURL( | 164 bool MatchesURL( |
| 296 ExtensionAPI* api, const std::string& api_name, const std::string& url) { | 165 ExtensionAPI* api, const std::string& api_name, const std::string& url) { |
| 297 scoped_ptr<std::set<std::string> > apis = | 166 scoped_ptr<std::set<std::string> > apis = |
| 298 api->GetAPIsForContext(Feature::WEB_PAGE_CONTEXT, NULL, GURL(url)); | 167 api->GetAPIsForContext(Feature::WEB_PAGE_CONTEXT, NULL, GURL(url)); |
| 299 return apis->count(api_name); | 168 return apis->count(api_name); |
| 300 } | 169 } |
| 301 | 170 |
| 302 TEST(ExtensionAPI, URLMatching) { | 171 TEST(ExtensionAPI, URLMatching) { |
| 303 scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration()); | 172 ExtensionAPI api; |
| 304 | 173 |
| 305 // "app" API is available to all URLs that content scripts can be injected. | 174 // "app" API is available to all URLs that content scripts can be injected. |
| 306 EXPECT_TRUE(MatchesURL(api.get(), "app", "http://example.com/example.html")); | 175 EXPECT_TRUE(MatchesURL(&api, "app", "http://example.com/example.html")); |
| 307 EXPECT_TRUE(MatchesURL(api.get(), "app", "https://blah.net")); | 176 EXPECT_TRUE(MatchesURL(&api, "app", "https://blah.net")); |
| 308 EXPECT_TRUE(MatchesURL(api.get(), "app", "file://somefile.html")); | 177 EXPECT_TRUE(MatchesURL(&api, "app", "file://somefile.html")); |
| 309 | 178 |
| 310 // But not internal URLs (for chrome-extension:// the app API is injected by | 179 // But not internal URLs (for chrome-extension:// the app API is injected by |
| 311 // GetSchemasForExtension). | 180 // GetSchemasForExtension). |
| 312 EXPECT_FALSE(MatchesURL(api.get(), "app", "about:flags")); | 181 EXPECT_FALSE(MatchesURL(&api, "app", "about:flags")); |
| 313 EXPECT_FALSE(MatchesURL(api.get(), "app", "chrome://flags")); | 182 EXPECT_FALSE(MatchesURL(&api, "app", "chrome://flags")); |
| 314 EXPECT_FALSE(MatchesURL(api.get(), "app", | 183 EXPECT_FALSE(MatchesURL(&api, "app", "chrome-extension://fakeextension")); |
| 315 "chrome-extension://fakeextension")); | |
| 316 | 184 |
| 317 // "storage" API (for example) isn't available to any URLs. | 185 // "storage" API (for example) isn't available to any URLs. |
| 318 EXPECT_FALSE(MatchesURL(api.get(), "storage", | 186 EXPECT_FALSE(MatchesURL(&api, "storage", "http://example.com/example.html")); |
| 319 "http://example.com/example.html")); | 187 EXPECT_FALSE(MatchesURL(&api, "storage", "https://blah.net")); |
| 320 EXPECT_FALSE(MatchesURL(api.get(), "storage", "https://blah.net")); | 188 EXPECT_FALSE(MatchesURL(&api, "storage", "file://somefile.html")); |
| 321 EXPECT_FALSE(MatchesURL(api.get(), "storage", "file://somefile.html")); | 189 EXPECT_FALSE(MatchesURL(&api, "storage", "about:flags")); |
| 322 EXPECT_FALSE(MatchesURL(api.get(), "storage", "about:flags")); | 190 EXPECT_FALSE(MatchesURL(&api, "storage", "chrome://flags")); |
| 323 EXPECT_FALSE(MatchesURL(api.get(), "storage", "chrome://flags")); | 191 EXPECT_FALSE(MatchesURL(&api, "storage", "chrome-extension://fakeextension")); |
| 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 } | |
| 421 } | 192 } |
| 422 | 193 |
| 423 } // namespace | 194 } // namespace |
| 424 } // namespace extensions | 195 } // namespace extensions |
| OLD | NEW |