blob: c6690d238a7ccdb929bc4471639d91fa95cddbe5 [file] [log] [blame]
[email protected]83048a22011-03-29 00:14:131// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]4361c7c2010-09-30 21:57:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]005bab02011-10-07 18:36:005#include "base/json/json_value_serializer.h"
[email protected]4361c7c2010-09-30 21:57:536#include "base/message_loop.h"
7#include "base/path_service.h"
[email protected]4361c7c2010-09-30 21:57:538#include "chrome/browser/extensions/extension_info_map.h"
9#include "chrome/common/chrome_paths.h"
[email protected]6f229e82010-11-02 17:47:2610#include "chrome/common/extensions/extension.h"
[email protected]c38831a12011-10-28 12:44:4911#include "content/test/test_browser_thread.h"
[email protected]4361c7c2010-09-30 21:57:5312#include "testing/gtest/include/gtest/gtest.h"
13
[email protected]631bb742011-11-02 11:29:3914using content::BrowserThread;
15
[email protected]4361c7c2010-09-30 21:57:5316namespace keys = extension_manifest_keys;
17
18namespace {
19
20class ExtensionInfoMapTest : public testing::Test {
21 public:
22 ExtensionInfoMapTest()
[email protected]ca4b5fa32010-10-09 12:42:1823 : ui_thread_(BrowserThread::UI, &message_loop_),
24 io_thread_(BrowserThread::IO, &message_loop_) {
[email protected]4361c7c2010-09-30 21:57:5325 }
26
27 private:
28 MessageLoop message_loop_;
[email protected]c38831a12011-10-28 12:44:4929 content::TestBrowserThread ui_thread_;
30 content::TestBrowserThread io_thread_;
[email protected]4361c7c2010-09-30 21:57:5331};
32
33// Returns a barebones test Extension object with the given name.
[email protected]66e4eb32010-10-27 20:37:4134static scoped_refptr<Extension> CreateExtension(const std::string& name) {
[email protected]4361c7c2010-09-30 21:57:5335#if defined(OS_WIN)
36 FilePath path(FILE_PATH_LITERAL("c:\\foo"));
37#elif defined(OS_POSIX)
38 FilePath path(FILE_PATH_LITERAL("/foo"));
39#endif
40
[email protected]4361c7c2010-09-30 21:57:5341 DictionaryValue manifest;
42 manifest.SetString(keys::kVersion, "1.0.0.0");
43 manifest.SetString(keys::kName, name);
44
45 std::string error;
[email protected]66e4eb32010-10-27 20:37:4146 scoped_refptr<Extension> extension = Extension::Create(
[email protected]83048a22011-03-29 00:14:1347 path.AppendASCII(name), Extension::INVALID, manifest,
48 Extension::STRICT_ERROR_CHECKS, &error);
[email protected]66e4eb32010-10-27 20:37:4149 EXPECT_TRUE(extension) << error;
[email protected]4361c7c2010-09-30 21:57:5350
[email protected]66e4eb32010-10-27 20:37:4151 return extension;
[email protected]4361c7c2010-09-30 21:57:5352}
53
[email protected]66e4eb32010-10-27 20:37:4154static scoped_refptr<Extension> LoadManifest(const std::string& dir,
55 const std::string& test_file) {
[email protected]4361c7c2010-09-30 21:57:5356 FilePath path;
57 PathService::Get(chrome::DIR_TEST_DATA, &path);
58 path = path.AppendASCII("extensions")
59 .AppendASCII(dir)
60 .AppendASCII(test_file);
61
62 JSONFileValueSerializer serializer(path);
63 scoped_ptr<Value> result(serializer.Deserialize(NULL, NULL));
64 if (!result.get())
65 return NULL;
66
67 std::string error;
[email protected]66e4eb32010-10-27 20:37:4168 scoped_refptr<Extension> extension = Extension::Create(
69 path, Extension::INVALID, *static_cast<DictionaryValue*>(result.get()),
[email protected]83048a22011-03-29 00:14:1370 Extension::STRICT_ERROR_CHECKS, &error);
[email protected]66e4eb32010-10-27 20:37:4171 EXPECT_TRUE(extension) << error;
[email protected]4361c7c2010-09-30 21:57:5372
[email protected]66e4eb32010-10-27 20:37:4173 return extension;
[email protected]4361c7c2010-09-30 21:57:5374}
75
[email protected]4361c7c2010-09-30 21:57:5376// Test that the ExtensionInfoMap handles refcounting properly.
77TEST_F(ExtensionInfoMapTest, RefCounting) {
78 scoped_refptr<ExtensionInfoMap> info_map(new ExtensionInfoMap());
79
[email protected]6f229e82010-11-02 17:47:2680 // New extensions should have a single reference holding onto them.
[email protected]66e4eb32010-10-27 20:37:4181 scoped_refptr<Extension> extension1(CreateExtension("extension1"));
82 scoped_refptr<Extension> extension2(CreateExtension("extension2"));
83 scoped_refptr<Extension> extension3(CreateExtension("extension3"));
[email protected]6f229e82010-11-02 17:47:2684 EXPECT_TRUE(extension1->HasOneRef());
85 EXPECT_TRUE(extension2->HasOneRef());
86 EXPECT_TRUE(extension3->HasOneRef());
[email protected]4361c7c2010-09-30 21:57:5387
[email protected]05cc4e72011-03-08 21:29:4888 // Add a ref to each extension and give it to the info map.
[email protected]c357acb42011-06-09 20:52:4289 info_map->AddExtension(extension1, base::Time(), false);
90 info_map->AddExtension(extension2, base::Time(), false);
91 info_map->AddExtension(extension3, base::Time(), false);
[email protected]4361c7c2010-09-30 21:57:5392
[email protected]6f229e82010-11-02 17:47:2693 // Release extension1, and the info map should have the only ref.
94 const Extension* weak_extension1 = extension1;
[email protected]66e4eb32010-10-27 20:37:4195 extension1 = NULL;
[email protected]6f229e82010-11-02 17:47:2696 EXPECT_TRUE(weak_extension1->HasOneRef());
[email protected]4361c7c2010-09-30 21:57:5397
98 // Remove extension2, and the extension2 object should have the only ref.
[email protected]814a7bf0f2011-08-13 05:30:5999 info_map->RemoveExtension(
100 extension2->id(), extension_misc::UNLOAD_REASON_UNINSTALL);
[email protected]6f229e82010-11-02 17:47:26101 EXPECT_TRUE(extension2->HasOneRef());
[email protected]4361c7c2010-09-30 21:57:53102
103 // Delete the info map, and the extension3 object should have the only ref.
104 info_map = NULL;
[email protected]6f229e82010-11-02 17:47:26105 EXPECT_TRUE(extension3->HasOneRef());
[email protected]4361c7c2010-09-30 21:57:53106}
107
108// Tests that we can query a few extension properties from the ExtensionInfoMap.
109TEST_F(ExtensionInfoMapTest, Properties) {
110 scoped_refptr<ExtensionInfoMap> info_map(new ExtensionInfoMap());
111
[email protected]66e4eb32010-10-27 20:37:41112 scoped_refptr<Extension> extension1(CreateExtension("extension1"));
113 scoped_refptr<Extension> extension2(CreateExtension("extension2"));
[email protected]4361c7c2010-09-30 21:57:53114
[email protected]c357acb42011-06-09 20:52:42115 info_map->AddExtension(extension1, base::Time(), false);
116 info_map->AddExtension(extension2, base::Time(), false);
[email protected]4361c7c2010-09-30 21:57:53117
[email protected]be0a2cfd2011-06-02 21:36:42118 EXPECT_EQ(2u, info_map->extensions().size());
119 EXPECT_EQ(extension1.get(), info_map->extensions().GetByID(extension1->id()));
120 EXPECT_EQ(extension2.get(), info_map->extensions().GetByID(extension2->id()));
[email protected]4361c7c2010-09-30 21:57:53121}
122
123// Tests CheckURLAccessToExtensionPermission given both extension and app URLs.
124TEST_F(ExtensionInfoMapTest, CheckPermissions) {
125 scoped_refptr<ExtensionInfoMap> info_map(new ExtensionInfoMap());
126
[email protected]66e4eb32010-10-27 20:37:41127 scoped_refptr<Extension> app(LoadManifest("manifest_tests",
[email protected]be0a2cfd2011-06-02 21:36:42128 "valid_app.json"));
[email protected]66e4eb32010-10-27 20:37:41129 scoped_refptr<Extension> extension(LoadManifest("manifest_tests",
[email protected]be0a2cfd2011-06-02 21:36:42130 "tabs_extension.json"));
[email protected]4361c7c2010-09-30 21:57:53131
132 GURL app_url("http://www.google.com/mail/foo.html");
133 ASSERT_TRUE(app->is_app());
[email protected]cced75a2011-05-20 08:31:12134 ASSERT_TRUE(app->web_extent().MatchesURL(app_url));
[email protected]4361c7c2010-09-30 21:57:53135
[email protected]c357acb42011-06-09 20:52:42136 info_map->AddExtension(app, base::Time(), false);
137 info_map->AddExtension(extension, base::Time(), false);
[email protected]4361c7c2010-09-30 21:57:53138
139 // The app should have the notifications permission, either from a
140 // chrome-extension URL or from its web extent.
[email protected]be0a2cfd2011-06-02 21:36:42141 const Extension* match = info_map->extensions().GetByURL(
142 app->GetResourceURL("a.html"));
143 EXPECT_TRUE(match &&
[email protected]0d3e4a22011-06-23 19:02:52144 match->HasAPIPermission(ExtensionAPIPermission::kNotification));
[email protected]be0a2cfd2011-06-02 21:36:42145 match = info_map->extensions().GetByURL(app_url);
146 EXPECT_TRUE(match &&
[email protected]0d3e4a22011-06-23 19:02:52147 match->HasAPIPermission(ExtensionAPIPermission::kNotification));
[email protected]be0a2cfd2011-06-02 21:36:42148 EXPECT_FALSE(match &&
[email protected]0d3e4a22011-06-23 19:02:52149 match->HasAPIPermission(ExtensionAPIPermission::kTab));
[email protected]4361c7c2010-09-30 21:57:53150
151 // The extension should have the tabs permission.
[email protected]be0a2cfd2011-06-02 21:36:42152 match = info_map->extensions().GetByURL(extension->GetResourceURL("a.html"));
153 EXPECT_TRUE(match &&
[email protected]0d3e4a22011-06-23 19:02:52154 match->HasAPIPermission(ExtensionAPIPermission::kTab));
[email protected]be0a2cfd2011-06-02 21:36:42155 EXPECT_FALSE(match &&
[email protected]0d3e4a22011-06-23 19:02:52156 match->HasAPIPermission(ExtensionAPIPermission::kNotification));
[email protected]4361c7c2010-09-30 21:57:53157
158 // Random URL should not have any permissions.
[email protected]be0a2cfd2011-06-02 21:36:42159 match = info_map->extensions().GetByURL(GURL("http://evil.com/a.html"));
160 EXPECT_FALSE(match);
[email protected]4361c7c2010-09-30 21:57:53161}
[email protected]5eaba82a2010-10-01 20:55:53162
163} // namespace