Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / management / management_api_browsertest.cc
blobf1bed3804a732b304f725c2e4c5046d09f60fa30
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
3 // found in the LICENSE file.
5 #include "base/files/file_path.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/strings/pattern.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/browser/extensions/extension_browsertest.h"
11 #include "chrome/browser/extensions/extension_function_test_utils.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/common/url_constants.h"
18 #include "content/public/test/browser_test_utils.h"
19 #include "content/public/test/test_utils.h"
20 #include "extensions/browser/api/management/management_api.h"
21 #include "extensions/browser/api/management/management_api_constants.h"
22 #include "extensions/browser/extension_dialog_auto_confirm.h"
23 #include "extensions/browser/extension_host.h"
24 #include "extensions/browser/extension_prefs.h"
25 #include "extensions/browser/extension_system.h"
26 #include "extensions/browser/notification_types.h"
27 #include "extensions/common/test_util.h"
28 #include "extensions/test/extension_test_message_listener.h"
30 namespace keys = extension_management_api_constants;
31 namespace util = extension_function_test_utils;
33 namespace extensions {
35 class ExtensionManagementApiBrowserTest : public ExtensionBrowserTest {
36 protected:
37 bool CrashEnabledExtension(const std::string& extension_id) {
38 ExtensionHost* background_host =
39 ProcessManager::Get(browser()->profile())
40 ->GetBackgroundHostForExtension(extension_id);
41 if (!background_host)
42 return false;
43 content::CrashTab(background_host->host_contents());
44 return true;
48 // We test this here instead of in an ExtensionApiTest because normal extensions
49 // are not allowed to call the install function.
50 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, InstallEvent) {
51 ExtensionTestMessageListener listener1("ready", false);
52 ASSERT_TRUE(LoadExtension(
53 test_data_dir_.AppendASCII("management/install_event")));
54 ASSERT_TRUE(listener1.WaitUntilSatisfied());
56 ExtensionTestMessageListener listener2("got_event", false);
57 ASSERT_TRUE(LoadExtension(
58 test_data_dir_.AppendASCII("api_test/management/enabled_extension")));
59 ASSERT_TRUE(listener2.WaitUntilSatisfied());
62 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, LaunchApp) {
63 ExtensionTestMessageListener listener1("app_launched", false);
64 ExtensionTestMessageListener listener2("got_expected_error", false);
65 ASSERT_TRUE(LoadExtension(
66 test_data_dir_.AppendASCII("management/simple_extension")));
67 ASSERT_TRUE(LoadExtension(
68 test_data_dir_.AppendASCII("management/packaged_app")));
69 ASSERT_TRUE(LoadExtension(
70 test_data_dir_.AppendASCII("management/launch_app")));
71 ASSERT_TRUE(listener1.WaitUntilSatisfied());
72 ASSERT_TRUE(listener2.WaitUntilSatisfied());
75 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
76 LaunchAppFromBackground) {
77 ExtensionTestMessageListener listener1("success", false);
78 ASSERT_TRUE(LoadExtension(
79 test_data_dir_.AppendASCII("management/packaged_app")));
80 ASSERT_TRUE(LoadExtension(
81 test_data_dir_.AppendASCII("management/launch_app_from_background")));
82 ASSERT_TRUE(listener1.WaitUntilSatisfied());
85 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
86 SelfUninstall) {
87 ExtensionTestMessageListener listener1("success", false);
88 ASSERT_TRUE(LoadExtension(
89 test_data_dir_.AppendASCII("management/self_uninstall_helper")));
90 ASSERT_TRUE(LoadExtension(
91 test_data_dir_.AppendASCII("management/self_uninstall")));
92 ASSERT_TRUE(listener1.WaitUntilSatisfied());
95 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
96 SelfUninstallNoPermissions) {
97 ExtensionTestMessageListener listener1("success", false);
98 ASSERT_TRUE(LoadExtension(
99 test_data_dir_.AppendASCII("management/self_uninstall_helper")));
100 ASSERT_TRUE(LoadExtension(
101 test_data_dir_.AppendASCII("management/self_uninstall_noperm")));
102 ASSERT_TRUE(listener1.WaitUntilSatisfied());
105 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
106 GetSelfNoPermissions) {
107 ExtensionTestMessageListener listener1("success", false);
108 ASSERT_TRUE(LoadExtension(
109 test_data_dir_.AppendASCII("management/get_self")));
110 ASSERT_TRUE(listener1.WaitUntilSatisfied());
113 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
114 CreateAppShortcutConfirmDialog) {
115 const Extension* app = InstallExtension(
116 test_data_dir_.AppendASCII("api_test/management/packaged_app"), 1);
117 ASSERT_TRUE(app);
119 const std::string app_id = app->id();
121 scoped_refptr<ManagementCreateAppShortcutFunction> create_shortcut_function(
122 new ManagementCreateAppShortcutFunction());
123 create_shortcut_function->set_user_gesture(true);
124 ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(true);
125 util::RunFunctionAndReturnSingleResult(
126 create_shortcut_function.get(),
127 base::StringPrintf("[\"%s\"]", app_id.c_str()),
128 browser());
130 create_shortcut_function = new ManagementCreateAppShortcutFunction();
131 create_shortcut_function->set_user_gesture(true);
132 ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(false);
133 EXPECT_TRUE(base::MatchPattern(
134 util::RunFunctionAndReturnError(
135 create_shortcut_function.get(),
136 base::StringPrintf("[\"%s\"]", app_id.c_str()),
137 browser()),
138 keys::kCreateShortcutCanceledError));
141 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
142 GetAllIncludesTerminated) {
143 // Load an extension with a background page, so that we know it has a process
144 // running.
145 ExtensionTestMessageListener listener("ready", false);
146 const Extension* extension = LoadExtension(
147 test_data_dir_.AppendASCII("management/install_event"));
148 ASSERT_TRUE(extension);
149 ASSERT_TRUE(listener.WaitUntilSatisfied());
151 // The management API should list this extension.
152 scoped_refptr<ManagementGetAllFunction> function =
153 new ManagementGetAllFunction();
154 scoped_ptr<base::Value> result(util::RunFunctionAndReturnSingleResult(
155 function.get(), "[]", browser()));
156 base::ListValue* list;
157 ASSERT_TRUE(result->GetAsList(&list));
158 EXPECT_EQ(1U, list->GetSize());
160 // And it should continue to do so even after it crashes.
161 ASSERT_TRUE(CrashEnabledExtension(extension->id()));
163 function = new ManagementGetAllFunction();
164 result.reset(util::RunFunctionAndReturnSingleResult(
165 function.get(), "[]", browser()));
166 ASSERT_TRUE(result->GetAsList(&list));
167 EXPECT_EQ(1U, list->GetSize());
170 class ExtensionManagementApiEscalationTest :
171 public ExtensionManagementApiBrowserTest {
172 protected:
173 // The id of the permissions escalation test extension we use.
174 static const char kId[];
176 void SetUpOnMainThread() override {
177 EXPECT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
178 base::FilePath pem_path = test_data_dir_.
179 AppendASCII("permissions_increase").AppendASCII("permissions.pem");
180 base::FilePath path_v1 = PackExtensionWithOptions(
181 test_data_dir_.AppendASCII("permissions_increase").AppendASCII("v1"),
182 scoped_temp_dir_.path().AppendASCII("permissions1.crx"),
183 pem_path,
184 base::FilePath());
185 base::FilePath path_v2 = PackExtensionWithOptions(
186 test_data_dir_.AppendASCII("permissions_increase").AppendASCII("v2"),
187 scoped_temp_dir_.path().AppendASCII("permissions2.crx"),
188 pem_path,
189 base::FilePath());
191 ExtensionService* service = ExtensionSystem::Get(browser()->profile())->
192 extension_service();
194 // Install low-permission version of the extension.
195 ASSERT_TRUE(InstallExtension(path_v1, 1));
196 EXPECT_TRUE(service->GetExtensionById(kId, false) != NULL);
198 // Update to a high-permission version - it should get disabled.
199 EXPECT_FALSE(UpdateExtension(kId, path_v2, -1));
200 EXPECT_TRUE(service->GetExtensionById(kId, false) == NULL);
201 EXPECT_TRUE(service->GetExtensionById(kId, true) != NULL);
202 EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile())
203 ->DidExtensionEscalatePermissions(kId));
206 void SetEnabled(bool enabled, bool user_gesture,
207 const std::string& expected_error) {
208 scoped_refptr<ManagementSetEnabledFunction> function(
209 new ManagementSetEnabledFunction);
210 const char* const enabled_string = enabled ? "true" : "false";
211 if (user_gesture)
212 function->set_user_gesture(true);
213 function->SetRenderFrameHost(browser()->tab_strip_model()->
214 GetActiveWebContents()->GetMainFrame());
215 bool response = util::RunFunction(
216 function.get(),
217 base::StringPrintf("[\"%s\", %s]", kId, enabled_string),
218 browser(),
219 util::NONE);
220 if (expected_error.empty()) {
221 EXPECT_EQ(true, response);
222 } else {
223 EXPECT_TRUE(response == false);
224 EXPECT_EQ(expected_error, function->GetError());
229 private:
230 base::ScopedTempDir scoped_temp_dir_;
233 const char ExtensionManagementApiEscalationTest::kId[] =
234 "pgdpcfcocojkjfbgpiianjngphoopgmo";
236 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiEscalationTest,
237 DisabledReason) {
238 scoped_refptr<ManagementGetFunction> function =
239 new ManagementGetFunction();
240 scoped_ptr<base::Value> result(util::RunFunctionAndReturnSingleResult(
241 function.get(),
242 base::StringPrintf("[\"%s\"]", kId),
243 browser()));
244 ASSERT_TRUE(result.get() != NULL);
245 ASSERT_TRUE(result->IsType(base::Value::TYPE_DICTIONARY));
246 base::DictionaryValue* dict =
247 static_cast<base::DictionaryValue*>(result.get());
248 std::string reason;
249 EXPECT_TRUE(dict->GetStringASCII(keys::kDisabledReasonKey, &reason));
250 EXPECT_EQ(reason, std::string(keys::kDisabledReasonPermissionsIncrease));
253 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiEscalationTest,
254 SetEnabled) {
255 // Expect an error about no gesture.
256 SetEnabled(true, false, keys::kGestureNeededForEscalationError);
259 // Expect an error that user cancelled the dialog.
260 ScopedTestDialogAutoConfirm auto_confirm(
261 ScopedTestDialogAutoConfirm::CANCEL);
262 SetEnabled(true, true, keys::kUserDidNotReEnableError);
266 // This should succeed when user accepts dialog. We must wait for the
267 // process to connect *and* for the channel to finish initializing before
268 // trying to crash it. (NOTIFICATION_RENDERER_PROCESS_CREATED does not wait
269 // for the latter and can cause KillProcess to fail on Windows.)
270 content::WindowedNotificationObserver observer(
271 extensions::NOTIFICATION_EXTENSION_HOST_CREATED,
272 content::NotificationService::AllSources());
273 ScopedTestDialogAutoConfirm auto_confirm(
274 ScopedTestDialogAutoConfirm::ACCEPT);
275 SetEnabled(true, true, std::string());
276 observer.Wait();
280 // Crash the extension. Mock a reload by disabling and then enabling. The
281 // extension should be reloaded and enabled.
282 ScopedTestDialogAutoConfirm auto_confirm(
283 ScopedTestDialogAutoConfirm::ACCEPT);
284 ASSERT_TRUE(CrashEnabledExtension(kId));
285 SetEnabled(false, true, std::string());
286 SetEnabled(true, true, std::string());
287 const Extension* extension = ExtensionSystem::Get(browser()->profile())
288 ->extension_service()
289 ->GetExtensionById(kId, false);
290 EXPECT_TRUE(extension);
294 } // namespace extensions