| Index: chrome/common/extensions/api/extension_api_unittest.cc
|
| diff --git a/chrome/common/extensions/api/extension_api_unittest.cc b/chrome/common/extensions/api/extension_api_unittest.cc
|
| index 70982f790cb1e7bc9db9560a16bf95935405b48c..3f4a0afe6a68e2b5fb7a216c55f2afa9ccf10e8d 100644
|
| --- a/chrome/common/extensions/api/extension_api_unittest.cc
|
| +++ b/chrome/common/extensions/api/extension_api_unittest.cc
|
| @@ -13,7 +13,10 @@
|
| #include "chrome/common/extensions/extension.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +namespace {
|
| +
|
| using extensions::ExtensionAPI;
|
| +using extensions::Feature;
|
|
|
| TEST(ExtensionAPI, IsPrivileged) {
|
| ExtensionAPI* extension_api = ExtensionAPI::GetInstance();
|
| @@ -33,6 +36,8 @@ TEST(ExtensionAPI, IsPrivileged) {
|
| EXPECT_TRUE(extension_api->IsPrivileged("history.search"));
|
|
|
| // Whole APIs that are unprivileged.
|
| + EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails"));
|
| + EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled"));
|
| EXPECT_FALSE(extension_api->IsPrivileged("storage.local"));
|
| EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged"));
|
| EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set"));
|
| @@ -40,34 +45,18 @@ TEST(ExtensionAPI, IsPrivileged) {
|
| EXPECT_FALSE(extension_api->IsPrivileged("storage.set"));
|
| }
|
|
|
| -TEST(ExtensionAPI, IsWholeAPIPrivileged) {
|
| - ExtensionAPI* extension_api = ExtensionAPI::GetInstance();
|
| -
|
| - // Completely unprivileged.
|
| - EXPECT_FALSE(extension_api->IsWholeAPIPrivileged("storage"));
|
| -
|
| - // Partially unprivileged.
|
| - EXPECT_FALSE(extension_api->IsWholeAPIPrivileged("extension"));
|
| - EXPECT_FALSE(extension_api->IsWholeAPIPrivileged("test"));
|
| -
|
| - // Nothing unprivileged.
|
| - EXPECT_TRUE(extension_api->IsWholeAPIPrivileged("history"));
|
| -
|
| - // Paranoid above... paranoid here, too.
|
| - EXPECT_TRUE(extension_api->IsWholeAPIPrivileged(""));
|
| - EXPECT_TRUE(extension_api->IsWholeAPIPrivileged("<unknown-namespace>"));
|
| -}
|
| -
|
| -TEST(ExtensionAPI, Depends) {
|
| - // Fake extension with the "ttsEngine" permission but not the "tts"
|
| - // permission; it must load TTS.
|
| +scoped_refptr<Extension> CreateExtensionWithPermissions(
|
| + const std::set<std::string>& permissions) {
|
| DictionaryValue manifest;
|
| - manifest.SetString("name", "test extension");
|
| + manifest.SetString("name", "extension");
|
| manifest.SetString("version", "1.0");
|
| {
|
| - scoped_ptr<ListValue> permissions(new ListValue());
|
| - permissions->Append(Value::CreateStringValue("ttsEngine"));
|
| - manifest.Set("permissions", permissions.release());
|
| + scoped_ptr<ListValue> permissions_list(new ListValue());
|
| + for (std::set<std::string>::const_iterator i = permissions.begin();
|
| + i != permissions.end(); ++i) {
|
| + permissions_list->Append(Value::CreateStringValue(*i));
|
| + }
|
| + manifest.Set("permissions", permissions_list.release());
|
| }
|
|
|
| std::string error;
|
| @@ -76,8 +65,105 @@ TEST(ExtensionAPI, Depends) {
|
| CHECK(extension.get());
|
| CHECK(error.empty());
|
|
|
| - ExtensionAPI::SchemaMap schemas;
|
| - ExtensionAPI::GetInstance()->GetSchemasForExtension(
|
| - *extension, ExtensionAPI::ALL, &schemas);
|
| - EXPECT_EQ(1u, schemas.count("tts"));
|
| + return extension;
|
| +}
|
| +
|
| +scoped_refptr<Extension> CreateExtensionWithPermission(
|
| + const std::string& permission) {
|
| + std::set<std::string> permissions;
|
| + permissions.insert(permission);
|
| + return CreateExtensionWithPermissions(permissions);
|
| +}
|
| +
|
| +TEST(ExtensionAPI, ExtensionWithUnprivilegedAPIs) {
|
| + scoped_refptr<Extension> extension;
|
| + {
|
| + std::set<std::string> permissions;
|
| + permissions.insert("storage");
|
| + permissions.insert("history");
|
| + extension = CreateExtensionWithPermissions(permissions);
|
| + }
|
| +
|
| + scoped_ptr<std::set<std::string> > privileged_apis =
|
| + ExtensionAPI::GetInstance()->GetAPIsForContext(
|
| + Feature::PRIVILEGED_CONTEXT, extension.get(), GURL());
|
| +
|
| + scoped_ptr<std::set<std::string> > unprivileged_apis =
|
| + ExtensionAPI::GetInstance()->GetAPIsForContext(
|
| + Feature::UNPRIVILEGED_CONTEXT, extension.get(), GURL());
|
| +
|
| + scoped_ptr<std::set<std::string> > content_script_apis =
|
| + ExtensionAPI::GetInstance()->GetAPIsForContext(
|
| + Feature::CONTENT_SCRIPT_CONTEXT, extension.get(), GURL());
|
| +
|
| + // "storage" is completely unprivileged.
|
| + EXPECT_EQ(1u, privileged_apis->count("storage"));
|
| + EXPECT_EQ(1u, unprivileged_apis->count("storage"));
|
| + EXPECT_EQ(1u, content_script_apis->count("storage"));
|
| +
|
| + // "extension" is partially unprivileged.
|
| + EXPECT_EQ(1u, privileged_apis->count("extension"));
|
| + EXPECT_EQ(1u, unprivileged_apis->count("extension"));
|
| + EXPECT_EQ(1u, content_script_apis->count("extension"));
|
| +
|
| + // "history" is entirely privileged.
|
| + EXPECT_EQ(1u, privileged_apis->count("history"));
|
| + EXPECT_EQ(0u, unprivileged_apis->count("history"));
|
| + EXPECT_EQ(0u, content_script_apis->count("history"));
|
| +}
|
| +
|
| +TEST(ExtensionAPI, ExtensionWithDependencies) {
|
| + // Extension with the "ttsEngine" permission but not the "tts" permission; it
|
| + // must load TTS.
|
| + {
|
| + scoped_refptr<Extension> extension =
|
| + CreateExtensionWithPermission("ttsEngine");
|
| + scoped_ptr<std::set<std::string> > apis =
|
| + ExtensionAPI::GetInstance()->GetAPIsForContext(
|
| + Feature::PRIVILEGED_CONTEXT, extension.get(), GURL());
|
| + EXPECT_EQ(1u, apis->count("ttsEngine"));
|
| + EXPECT_EQ(1u, apis->count("tts"));
|
| + }
|
| +
|
| + // Conversely, extension with the "tts" permission but not the "ttsEngine"
|
| + // permission shouldn't get the "ttsEngine" permission.
|
| + {
|
| + scoped_refptr<Extension> extension =
|
| + CreateExtensionWithPermission("tts");
|
| + scoped_ptr<std::set<std::string> > apis =
|
| + ExtensionAPI::GetInstance()->GetAPIsForContext(
|
| + Feature::PRIVILEGED_CONTEXT, extension.get(), GURL());
|
| + EXPECT_EQ(0u, apis->count("ttsEngine"));
|
| + EXPECT_EQ(1u, apis->count("tts"));
|
| + }
|
| +}
|
| +
|
| +bool MatchesURL(const std::string& api_name, const std::string& url) {
|
| + scoped_ptr<std::set<std::string> > apis =
|
| + ExtensionAPI::GetInstance()->GetAPIsForContext(
|
| + Feature::WEB_PAGE_CONTEXT, NULL, GURL(url));
|
| + return apis->count(api_name);
|
| +}
|
| +
|
| +TEST(ExtensionAPI, URLMatching) {
|
| + // "app" API is available to all URLs that content scripts can be injected.
|
| + EXPECT_TRUE(MatchesURL("app", "http://example.com/example.html"));
|
| + EXPECT_TRUE(MatchesURL("app", "https://blah.net"));
|
| + EXPECT_TRUE(MatchesURL("app", "file://somefile.html"));
|
| +
|
| + // But not internal URLs (for chrome-extension:// the app API is injected by
|
| + // GetSchemasForExtension).
|
| + EXPECT_FALSE(MatchesURL("app", "about:flags"));
|
| + EXPECT_FALSE(MatchesURL("app", "chrome://flags"));
|
| + EXPECT_FALSE(MatchesURL("app", "chrome-extension://fakeextension"));
|
| +
|
| + // "storage" API (for example) isn't available to any URLs.
|
| + EXPECT_FALSE(MatchesURL("storage", "http://example.com/example.html"));
|
| + EXPECT_FALSE(MatchesURL("storage", "https://blah.net"));
|
| + EXPECT_FALSE(MatchesURL("storage", "file://somefile.html"));
|
| + EXPECT_FALSE(MatchesURL("storage", "about:flags"));
|
| + EXPECT_FALSE(MatchesURL("storage", "chrome://flags"));
|
| + EXPECT_FALSE(MatchesURL("storage", "chrome-extension://fakeextension"));
|
| }
|
| +
|
| +} // namespace
|
|
|