Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / extensions / extension_reenabler_unittest.cc
blob9e5d8831f8a678fd2dd7498fb4a6ab0b6b7e349f
1 // Copyright 2014 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/run_loop.h"
6 #include "chrome/browser/extensions/extension_install_prompt.h"
7 #include "chrome/browser/extensions/extension_reenabler.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_service_test_base.h"
10 #include "chrome/browser/extensions/extension_system_factory.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "components/crx_file/id_util.h"
14 #include "extensions/browser/extension_registry.h"
15 #include "extensions/browser/management_policy.h"
16 #include "extensions/browser/test_extensions_browser_client.h"
17 #include "extensions/common/extension.h"
18 #include "extensions/common/extension_builder.h"
19 #include "extensions/common/value_builder.h"
21 namespace extensions {
23 namespace {
25 // A simple provider that says all extensions must remain disabled.
26 class TestManagementProvider : public ManagementPolicy::Provider {
27 public:
28 TestManagementProvider() {}
29 ~TestManagementProvider() override {}
31 private:
32 // MananagementPolicy::Provider:
33 std::string GetDebugPolicyProviderName() const override { return "test"; }
34 bool MustRemainDisabled(const Extension* extension,
35 Extension::DisableReason* reason,
36 base::string16* error) const override {
37 return true;
40 DISALLOW_COPY_AND_ASSIGN(TestManagementProvider);
43 // A helper class for all the various callbacks associated with reenabling an
44 // extension. This class also helps store the results of the run.
45 class CallbackHelper {
46 public:
47 CallbackHelper() {}
48 ~CallbackHelper() {}
50 // Get a callback to run on the completion of the reenable process and reset
51 // |result_|.
52 ExtensionReenabler::Callback GetCallback() {
53 result_.reset();
54 return base::Bind(&CallbackHelper::OnComplete,
55 base::Unretained(this));
58 // Check if we have receved any result, and if it matches the expected one.
59 bool has_result() const { return result_.get() != nullptr; }
60 bool result_matches(ExtensionReenabler::ReenableResult expected) const {
61 return result_.get() && *result_ == expected;
64 // Create a test ExtensionInstallPrompt that will not display any UI (which
65 // causes unit tests to crash), but rather runs the given |quit_closure| (with
66 // the prompt still active|.
67 scoped_ptr<ExtensionInstallPrompt> CreateTestPrompt(
68 content::WebContents* web_contents,
69 const base::Closure& quit_closure) {
70 quit_closure_ = quit_closure;
71 scoped_ptr<ExtensionInstallPrompt> prompt(
72 new ExtensionInstallPrompt(web_contents));
73 prompt->set_callback_for_test(base::Bind(&CallbackHelper::OnShow,
74 base::Unretained(this)));
75 return prompt.Pass();
78 private:
79 // The callback to run once the reenable process finishes.
80 void OnComplete(ExtensionReenabler::ReenableResult result) {
81 result_.reset(new ExtensionReenabler::ReenableResult(result));
84 // The callback to run when a test ExtensionInstallPrompt is ready to show.
85 void OnShow(ExtensionInstallPromptShowParams* show_params,
86 ExtensionInstallPrompt::Delegate* delegate,
87 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) {
88 DCHECK(!quit_closure_.is_null());
89 quit_closure_.Run();
90 quit_closure_ = base::Closure();
93 // The closure to quit the currently-running loop; used with test
94 // ExtensionInstallPrompts.
95 base::Closure quit_closure_;
97 // The result of the reenable process, or null if the process hasn't finished.
98 scoped_ptr<ExtensionReenabler::ReenableResult> result_;
100 DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
103 } // namespace
105 class ExtensionReenablerUnitTest : public ExtensionServiceTestBase {
106 public:
107 ExtensionReenablerUnitTest() {}
108 ~ExtensionReenablerUnitTest() override {}
110 private:
111 void SetUp() override;
112 void TearDown() override;
114 scoped_ptr<TestExtensionsBrowserClient> test_browser_client_;
116 DISALLOW_COPY_AND_ASSIGN(ExtensionReenablerUnitTest);
119 void ExtensionReenablerUnitTest::SetUp() {
120 ExtensionServiceTestBase::SetUp();
121 InitializeEmptyExtensionService();
122 // We need a TestExtensionsBrowserClient because the real one tries to
123 // implicitly convert any browser context to a (non-Testing)Profile.
124 test_browser_client_.reset(new TestExtensionsBrowserClient(profile()));
125 test_browser_client_->set_extension_system_factory(
126 ExtensionSystemFactory::GetInstance());
127 ExtensionsBrowserClient::Set(test_browser_client_.get());
130 void ExtensionReenablerUnitTest::TearDown() {
131 profile_.reset();
132 ExtensionsBrowserClient::Set(nullptr);
133 test_browser_client_.reset();
134 ExtensionServiceTestBase::TearDown();
137 // Test that the ExtensionReenabler reenables disabled extensions.
138 TEST_F(ExtensionReenablerUnitTest, TestReenablingDisabledExtension) {
139 // Create a simple extension and add it to the service.
140 scoped_refptr<const Extension> extension =
141 ExtensionBuilder().
142 SetManifest(DictionaryBuilder().Set("name", "test ext").
143 Set("version", "1.0").
144 Set("manifest_version", 2).
145 Set("description", "a test ext")).
146 SetID(crx_file::id_util::GenerateId("test ext")).
147 Build();
148 service()->AddExtension(extension.get());
149 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
151 CallbackHelper callback_helper;
153 // Check that the ExtensionReenabler can re-enable disabled extensions.
155 // Disable the extension due to a permissions increase (the only type of
156 // disablement we handle with the ExtensionReenabler so far).
157 service()->DisableExtension(extension->id(),
158 Extension::DISABLE_PERMISSIONS_INCREASE);
159 // Sanity check that it's disabled.
160 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension->id()));
162 // Automatically confirm install prompts.
163 ExtensionInstallPrompt::g_auto_confirm_for_tests =
164 ExtensionInstallPrompt::ACCEPT;
166 // Run the ExtensionReenabler.
167 scoped_ptr<ExtensionReenabler> extension_reenabler =
168 ExtensionReenabler::PromptForReenable(extension,
169 profile(),
170 nullptr, // No web contents.
171 GURL(), // No referrer.
172 callback_helper.GetCallback());
173 base::RunLoop().RunUntilIdle();
175 // The extension should be enabled.
176 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
177 EXPECT_TRUE(
178 callback_helper.result_matches(ExtensionReenabler::REENABLE_SUCCESS));
181 // Check that we don't re-enable extensions that must remain disabled, and
182 // that the re-enabler reports failure correctly.
184 ManagementPolicy* management_policy =
185 ExtensionSystem::Get(browser_context())->management_policy();
186 ASSERT_TRUE(management_policy);
187 TestManagementProvider test_provider;
188 management_policy->RegisterProvider(&test_provider);
189 service()->DisableExtension(extension->id(),
190 Extension::DISABLE_PERMISSIONS_INCREASE);
192 scoped_ptr<ExtensionReenabler> extension_reenabler =
193 ExtensionReenabler::PromptForReenable(extension,
194 profile(),
195 nullptr, // No web contents.
196 GURL(), // No referrer.
197 callback_helper.GetCallback());
198 base::RunLoop().RunUntilIdle();
200 // The extension should be enabled.
201 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension->id()));
202 EXPECT_TRUE(
203 callback_helper.result_matches(ExtensionReenabler::NOT_ALLOWED));
205 management_policy->UnregisterProvider(&test_provider);
208 // Check that canceling the re-enable prompt doesn't re-enable the extension.
210 // Disable it again, and try canceling the prompt.
211 service()->DisableExtension(extension->id(),
212 Extension::DISABLE_PERMISSIONS_INCREASE);
213 ExtensionInstallPrompt::g_auto_confirm_for_tests =
214 ExtensionInstallPrompt::CANCEL;
215 scoped_ptr<ExtensionReenabler> extension_reenabler =
216 ExtensionReenabler::PromptForReenable(extension,
217 profile(),
218 nullptr, // No web contents.
219 GURL(), // No referrer.
220 callback_helper.GetCallback());
221 base::RunLoop().RunUntilIdle();
223 // The extension should remain disabled.
224 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension->id()));
225 EXPECT_TRUE(
226 callback_helper.result_matches(ExtensionReenabler::USER_CANCELED));
229 // Test that if the extension is re-enabled while the prompt is active, the
230 // prompt exits and reports success.
232 // Don't auto-confirm, so that the prompt "stays around".
233 ExtensionInstallPrompt::g_auto_confirm_for_tests =
234 ExtensionInstallPrompt::NONE;
235 base::RunLoop run_loop;
236 scoped_ptr<ExtensionReenabler> extension_reenabler =
237 ExtensionReenabler::PromptForReenableWithPromptForTest(
238 extension,
239 profile(),
240 callback_helper.GetCallback(),
241 callback_helper.CreateTestPrompt(nullptr, run_loop.QuitClosure()));
242 run_loop.Run();
244 // We shouldn't have any result yet (the user hasn't confirmed or canceled).
245 EXPECT_FALSE(callback_helper.has_result());
247 // Reenable the extension. This should count as a success for reenabling.
248 service()->GrantPermissionsAndEnableExtension(extension.get());
249 EXPECT_TRUE(
250 callback_helper.result_matches(ExtensionReenabler::REENABLE_SUCCESS));
253 // Test that prematurely destroying the re-enable prompt doesn't crash and
254 // reports an "aborted" result.
256 // Disable again, and create another prompt.
257 service()->DisableExtension(extension->id(),
258 Extension::DISABLE_PERMISSIONS_INCREASE);
259 base::RunLoop run_loop;
260 scoped_ptr<ExtensionReenabler> extension_reenabler =
261 ExtensionReenabler::PromptForReenableWithPromptForTest(
262 extension,
263 profile(),
264 callback_helper.GetCallback(),
265 callback_helper.CreateTestPrompt(nullptr, run_loop.QuitClosure()));
266 run_loop.Run();
267 EXPECT_FALSE(callback_helper.has_result());
268 // Destroy the reenabler to simulate the owning context being shut down
269 // (e.g., the tab closing).
270 extension_reenabler.reset();
271 EXPECT_TRUE(
272 callback_helper.result_matches(ExtensionReenabler::ABORTED));
276 } // namespace extensions