Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / management / management_api_unittest.cc
blob4d0a4d9fecbe9d0154b812092cfbe60c9b4647a5
1 // Copyright 2015 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/memory/scoped_ptr.h"
6 #include "chrome/browser/extensions/extension_function_test_utils.h"
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/extensions/extension_service_test_base.h"
9 #include "chrome/browser/extensions/test_extension_system.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/host_desktop.h"
12 #include "chrome/test/base/test_browser_window.h"
13 #include "extensions/browser/api/management/management_api.h"
14 #include "extensions/browser/api/management/management_api_constants.h"
15 #include "extensions/browser/event_router_factory.h"
16 #include "extensions/browser/extension_dialog_auto_confirm.h"
17 #include "extensions/browser/extension_prefs.h"
18 #include "extensions/browser/extension_registry.h"
19 #include "extensions/browser/extension_system.h"
20 #include "extensions/browser/management_policy.h"
21 #include "extensions/browser/test_management_policy.h"
22 #include "extensions/common/error_utils.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_set.h"
25 #include "extensions/common/test_util.h"
27 namespace extensions {
29 namespace {
31 scoped_ptr<KeyedService> BuildManagementApi(content::BrowserContext* context) {
32 return make_scoped_ptr(new ManagementAPI(context));
35 scoped_ptr<KeyedService> BuildEventRouter(content::BrowserContext* profile) {
36 return make_scoped_ptr(
37 new extensions::EventRouter(profile, ExtensionPrefs::Get(profile)));
40 } // namespace
42 namespace constants = extension_management_api_constants;
44 // TODO(devlin): Unittests are awesome. Test more with unittests and less with
45 // heavy api/browser tests.
46 class ManagementApiUnitTest : public ExtensionServiceTestBase {
47 protected:
48 ManagementApiUnitTest() {}
49 ~ManagementApiUnitTest() override {}
51 // A wrapper around extension_function_test_utils::RunFunction that runs with
52 // the associated browser, no flags, and can take stack-allocated arguments.
53 bool RunFunction(const scoped_refptr<UIThreadExtensionFunction>& function,
54 const base::ListValue& args);
56 Browser* browser() { return browser_.get(); }
58 private:
59 // ExtensionServiceTestBase:
60 void SetUp() override;
61 void TearDown() override;
63 // The browser (and accompanying window).
64 scoped_ptr<TestBrowserWindow> browser_window_;
65 scoped_ptr<Browser> browser_;
67 DISALLOW_COPY_AND_ASSIGN(ManagementApiUnitTest);
70 bool ManagementApiUnitTest::RunFunction(
71 const scoped_refptr<UIThreadExtensionFunction>& function,
72 const base::ListValue& args) {
73 return extension_function_test_utils::RunFunction(
74 function.get(),
75 make_scoped_ptr(args.DeepCopy()),
76 browser(),
77 extension_function_test_utils::NONE);
80 void ManagementApiUnitTest::SetUp() {
81 ExtensionServiceTestBase::SetUp();
82 InitializeEmptyExtensionService();
83 ManagementAPI::GetFactoryInstance()->SetTestingFactory(profile(),
84 &BuildManagementApi);
86 EventRouterFactory::GetInstance()->SetTestingFactory(profile(),
87 &BuildEventRouter);
89 browser_window_.reset(new TestBrowserWindow());
90 Browser::CreateParams params(profile(), chrome::HOST_DESKTOP_TYPE_NATIVE);
91 params.type = Browser::TYPE_TABBED;
92 params.window = browser_window_.get();
93 browser_.reset(new Browser(params));
96 void ManagementApiUnitTest::TearDown() {
97 browser_.reset();
98 browser_window_.reset();
99 ExtensionServiceTestBase::TearDown();
102 // Test the basic parts of management.setEnabled.
103 TEST_F(ManagementApiUnitTest, ManagementSetEnabled) {
104 scoped_refptr<const Extension> extension = test_util::CreateEmptyExtension();
105 service()->AddExtension(extension.get());
106 std::string extension_id = extension->id();
107 scoped_refptr<ManagementSetEnabledFunction> function(
108 new ManagementSetEnabledFunction());
110 base::ListValue disable_args;
111 disable_args.AppendString(extension_id);
112 disable_args.AppendBoolean(false);
114 // Test disabling an (enabled) extension.
115 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
116 EXPECT_TRUE(RunFunction(function, disable_args)) << function->GetError();
117 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id));
119 base::ListValue enable_args;
120 enable_args.AppendString(extension_id);
121 enable_args.AppendBoolean(true);
123 // Test re-enabling it.
124 function = new ManagementSetEnabledFunction();
125 EXPECT_TRUE(RunFunction(function, enable_args)) << function->GetError();
126 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
128 // Test that the enable function checks management policy, so that we can't
129 // disable an extension that is required.
130 TestManagementPolicyProvider provider(
131 TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
132 ManagementPolicy* policy =
133 ExtensionSystem::Get(profile())->management_policy();
134 policy->RegisterProvider(&provider);
136 function = new ManagementSetEnabledFunction();
137 EXPECT_FALSE(RunFunction(function, disable_args));
138 EXPECT_EQ(ErrorUtils::FormatErrorMessage(constants::kUserCantModifyError,
139 extension_id),
140 function->GetError());
141 policy->UnregisterProvider(&provider);
143 // TODO(devlin): We should also test enabling an extenion that has escalated
144 // permissions, but that needs a web contents (which is a bit of a pain in a
145 // unit test).
148 // Tests management.uninstall.
149 TEST_F(ManagementApiUnitTest, ManagementUninstall) {
150 // We need to be on the UI thread for this.
151 ResetThreadBundle(content::TestBrowserThreadBundle::DEFAULT);
152 scoped_refptr<const Extension> extension = test_util::CreateEmptyExtension();
153 service()->AddExtension(extension.get());
154 std::string extension_id = extension->id();
156 base::ListValue uninstall_args;
157 uninstall_args.AppendString(extension->id());
159 // Auto-accept any uninstalls.
161 ScopedTestDialogAutoConfirm auto_confirm(
162 ScopedTestDialogAutoConfirm::ACCEPT);
164 // Uninstall requires a user gesture, so this should fail.
165 scoped_refptr<UIThreadExtensionFunction> function(
166 new ManagementUninstallFunction());
167 EXPECT_FALSE(RunFunction(function, uninstall_args));
168 EXPECT_EQ(std::string(constants::kGestureNeededForUninstallError),
169 function->GetError());
171 ExtensionFunction::ScopedUserGestureForTests scoped_user_gesture;
173 function = new ManagementUninstallFunction();
174 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
175 EXPECT_TRUE(RunFunction(function, uninstall_args)) << function->GetError();
176 // The extension should be uninstalled.
177 EXPECT_FALSE(registry()->GetExtensionById(extension_id,
178 ExtensionRegistry::EVERYTHING));
181 // Install the extension again, and try uninstalling, auto-canceling the
182 // dialog.
184 ScopedTestDialogAutoConfirm auto_confirm(
185 ScopedTestDialogAutoConfirm::CANCEL);
186 ExtensionFunction::ScopedUserGestureForTests scoped_user_gesture;
188 service()->AddExtension(extension.get());
189 scoped_refptr<UIThreadExtensionFunction> function =
190 new ManagementUninstallFunction();
191 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
192 EXPECT_FALSE(RunFunction(function, uninstall_args));
193 // The uninstall should have failed.
194 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
195 EXPECT_EQ(ErrorUtils::FormatErrorMessage(constants::kUninstallCanceledError,
196 extension_id),
197 function->GetError());
199 // Try again, using showConfirmDialog: false.
200 scoped_ptr<base::DictionaryValue> options(new base::DictionaryValue());
201 options->SetBoolean("showConfirmDialog", false);
202 uninstall_args.Append(options.release());
203 function = new ManagementUninstallFunction();
204 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
205 EXPECT_FALSE(RunFunction(function, uninstall_args));
206 // This should still fail, since extensions can only suppress the dialog for
207 // uninstalling themselves.
208 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
209 EXPECT_EQ(ErrorUtils::FormatErrorMessage(constants::kUninstallCanceledError,
210 extension_id),
211 function->GetError());
213 // If we try uninstall the extension itself, the uninstall should succeed
214 // (even though we auto-cancel any dialog), because the dialog is never
215 // shown.
216 uninstall_args.Remove(0u, nullptr);
217 function = new ManagementUninstallSelfFunction();
218 function->set_extension(extension);
219 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id));
220 EXPECT_TRUE(RunFunction(function, uninstall_args)) << function->GetError();
221 EXPECT_FALSE(registry()->GetExtensionById(extension_id,
222 ExtensionRegistry::EVERYTHING));
226 } // namespace extensions