extension_info_map_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/message_loop.h" 6#include "base/path_service.h" 7#include "chrome/browser/extensions/extension_info_map.h" 8#include "chrome/common/chrome_paths.h" 9#include "chrome/common/extensions/extension.h" 10#include "chrome/common/json_value_serializer.h" 11#include "content/browser/browser_thread.h" 12#include "testing/gtest/include/gtest/gtest.h" 13 14namespace keys = extension_manifest_keys; 15 16namespace { 17 18class ExtensionInfoMapTest : public testing::Test { 19 public: 20 ExtensionInfoMapTest() 21 : ui_thread_(BrowserThread::UI, &message_loop_), 22 io_thread_(BrowserThread::IO, &message_loop_) { 23 } 24 25 private: 26 MessageLoop message_loop_; 27 BrowserThread ui_thread_; 28 BrowserThread io_thread_; 29}; 30 31// Returns a barebones test Extension object with the given name. 32static scoped_refptr<Extension> CreateExtension(const std::string& name) { 33#if defined(OS_WIN) 34 FilePath path(FILE_PATH_LITERAL("c:\\foo")); 35#elif defined(OS_POSIX) 36 FilePath path(FILE_PATH_LITERAL("/foo")); 37#endif 38 39 DictionaryValue manifest; 40 manifest.SetString(keys::kVersion, "1.0.0.0"); 41 manifest.SetString(keys::kName, name); 42 43 std::string error; 44 scoped_refptr<Extension> extension = Extension::Create( 45 path.AppendASCII(name), Extension::INVALID, manifest, false, true, 46 &error); 47 EXPECT_TRUE(extension) << error; 48 49 return extension; 50} 51 52static scoped_refptr<Extension> LoadManifest(const std::string& dir, 53 const std::string& test_file) { 54 FilePath path; 55 PathService::Get(chrome::DIR_TEST_DATA, &path); 56 path = path.AppendASCII("extensions") 57 .AppendASCII(dir) 58 .AppendASCII(test_file); 59 60 JSONFileValueSerializer serializer(path); 61 scoped_ptr<Value> result(serializer.Deserialize(NULL, NULL)); 62 if (!result.get()) 63 return NULL; 64 65 std::string error; 66 scoped_refptr<Extension> extension = Extension::Create( 67 path, Extension::INVALID, *static_cast<DictionaryValue*>(result.get()), 68 false, true, &error); 69 EXPECT_TRUE(extension) << error; 70 71 return extension; 72} 73 74// Test that the ExtensionInfoMap handles refcounting properly. 75TEST_F(ExtensionInfoMapTest, RefCounting) { 76 scoped_refptr<ExtensionInfoMap> info_map(new ExtensionInfoMap()); 77 78 // New extensions should have a single reference holding onto them. 79 scoped_refptr<Extension> extension1(CreateExtension("extension1")); 80 scoped_refptr<Extension> extension2(CreateExtension("extension2")); 81 scoped_refptr<Extension> extension3(CreateExtension("extension3")); 82 EXPECT_TRUE(extension1->HasOneRef()); 83 EXPECT_TRUE(extension2->HasOneRef()); 84 EXPECT_TRUE(extension3->HasOneRef()); 85 86 // Add a ref to each extension and give it to the info map. The info map 87 // expects the caller to add a ref for it, but then assumes ownership of that 88 // reference. 89 extension1->AddRef(); 90 info_map->AddExtension(extension1); 91 extension2->AddRef(); 92 info_map->AddExtension(extension2); 93 extension3->AddRef(); 94 info_map->AddExtension(extension3); 95 96 // Release extension1, and the info map should have the only ref. 97 const Extension* weak_extension1 = extension1; 98 extension1 = NULL; 99 EXPECT_TRUE(weak_extension1->HasOneRef()); 100 101 // Remove extension2, and the extension2 object should have the only ref. 102 info_map->RemoveExtension(extension2->id()); 103 EXPECT_TRUE(extension2->HasOneRef()); 104 105 // Delete the info map, and the extension3 object should have the only ref. 106 info_map = NULL; 107 EXPECT_TRUE(extension3->HasOneRef()); 108} 109 110// Tests that we can query a few extension properties from the ExtensionInfoMap. 111TEST_F(ExtensionInfoMapTest, Properties) { 112 scoped_refptr<ExtensionInfoMap> info_map(new ExtensionInfoMap()); 113 114 scoped_refptr<Extension> extension1(CreateExtension("extension1")); 115 scoped_refptr<Extension> extension2(CreateExtension("extension2")); 116 117 extension1->AddRef(); 118 info_map->AddExtension(extension1); 119 extension2->AddRef(); 120 info_map->AddExtension(extension2); 121 122 EXPECT_EQ(extension1->name(), 123 info_map->GetNameForExtension(extension1->id())); 124 EXPECT_EQ(extension2->name(), 125 info_map->GetNameForExtension(extension2->id())); 126 127 EXPECT_EQ(extension1->path().value(), 128 info_map->GetPathForExtension(extension1->id()).value()); 129 EXPECT_EQ(extension2->path().value(), 130 info_map->GetPathForExtension(extension2->id()).value()); 131} 132 133// Tests CheckURLAccessToExtensionPermission given both extension and app URLs. 134TEST_F(ExtensionInfoMapTest, CheckPermissions) { 135 scoped_refptr<ExtensionInfoMap> info_map(new ExtensionInfoMap()); 136 137 scoped_refptr<Extension> app(LoadManifest("manifest_tests", 138 "valid_app.json")); 139 scoped_refptr<Extension> extension(LoadManifest("manifest_tests", 140 "tabs_extension.json")); 141 142 GURL app_url("http://www.google.com/mail/foo.html"); 143 ASSERT_TRUE(app->is_app()); 144 ASSERT_TRUE(app->web_extent().ContainsURL(app_url)); 145 146 app->AddRef(); 147 info_map->AddExtension(app); 148 extension->AddRef(); 149 info_map->AddExtension(extension); 150 151 // The app should have the notifications permission, either from a 152 // chrome-extension URL or from its web extent. 153 EXPECT_TRUE(info_map->CheckURLAccessToExtensionPermission( 154 app->GetResourceURL("a.html"), Extension::kNotificationPermission)); 155 EXPECT_TRUE(info_map->CheckURLAccessToExtensionPermission( 156 app_url, Extension::kNotificationPermission)); 157 EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( 158 app_url, Extension::kTabPermission)); 159 160 // The extension should have the tabs permission. 161 EXPECT_TRUE(info_map->CheckURLAccessToExtensionPermission( 162 extension->GetResourceURL("a.html"), Extension::kTabPermission)); 163 EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( 164 extension->GetResourceURL("a.html"), Extension::kNotificationPermission)); 165 166 // Random URL should not have any permissions. 167 EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( 168 GURL("http://evil.com/a.html"), Extension::kNotificationPermission)); 169 EXPECT_FALSE(info_map->CheckURLAccessToExtensionPermission( 170 GURL("http://evil.com/a.html"), Extension::kTabPermission)); 171} 172 173} // namespace 174