Add a webstorePrivate API to show a permission prompt for delegated bundle installs
[chromium-blink-merge.git] / chrome / browser / extensions / webstore_inline_installer_browsertest.cc
blob352f17f6d62f6a6acaa09c6cc7ec9fa1b6c9d943
1 // Copyright 2013 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/strings/utf_string_conversions.h"
6 #include "chrome/browser/extensions/extension_install_prompt.h"
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/extensions/tab_helper.h"
9 #include "chrome/browser/extensions/webstore_inline_installer.h"
10 #include "chrome/browser/extensions/webstore_inline_installer_factory.h"
11 #include "chrome/browser/extensions/webstore_installer_test.h"
12 #include "chrome/browser/extensions/webstore_standalone_installer.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "components/content_settings/core/browser/host_content_settings_map.h"
19 #include "content/public/browser/web_contents.h"
20 #include "extensions/browser/extension_registry.h"
21 #include "extensions/browser/extension_system.h"
22 #include "url/gurl.h"
24 using content::WebContents;
26 namespace extensions {
28 namespace {
30 const char kWebstoreDomain[] = "cws.com";
31 const char kAppDomain[] = "app.com";
32 const char kNonAppDomain[] = "nonapp.com";
33 const char kTestExtensionId[] = "ecglahbcnmdpdciemllbhojghbkagdje";
34 const char kTestDataPath[] = "extensions/api_test/webstore_inline_install";
35 const char kCrxFilename[] = "extension.crx";
37 } // namespace
39 class WebstoreInlineInstallerTest : public WebstoreInstallerTest {
40 public:
41 WebstoreInlineInstallerTest()
42 : WebstoreInstallerTest(
43 kWebstoreDomain,
44 kTestDataPath,
45 kCrxFilename,
46 kAppDomain,
47 kNonAppDomain) {}
50 class ProgrammableInstallPrompt : public ExtensionInstallPrompt {
51 public:
52 explicit ProgrammableInstallPrompt(WebContents* contents)
53 : ExtensionInstallPrompt(contents)
56 ~ProgrammableInstallPrompt() override {}
58 void ConfirmStandaloneInstall(
59 Delegate* delegate,
60 const Extension* extension,
61 SkBitmap* icon,
62 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) override {
63 delegate_ = delegate;
66 static bool Ready() {
67 return delegate_ != NULL;
70 static void Accept() {
71 delegate_->InstallUIProceed();
74 static void Reject() {
75 delegate_->InstallUIAbort(true);
78 private:
79 static Delegate* delegate_;
82 ExtensionInstallPrompt::Delegate* ProgrammableInstallPrompt::delegate_;
84 // Fake inline installer which creates a programmable prompt in place of
85 // the normal dialog UI.
86 class WebstoreInlineInstallerForTest : public WebstoreInlineInstaller {
87 public:
88 WebstoreInlineInstallerForTest(WebContents* contents,
89 const std::string& extension_id,
90 const GURL& requestor_url,
91 const Callback& callback)
92 : WebstoreInlineInstaller(
93 contents,
94 kTestExtensionId,
95 requestor_url,
96 base::Bind(DummyCallback)),
97 programmable_prompt_(NULL) {
100 scoped_ptr<ExtensionInstallPrompt> CreateInstallUI() override {
101 programmable_prompt_ = new ProgrammableInstallPrompt(web_contents());
102 return make_scoped_ptr(programmable_prompt_);
105 private:
106 ~WebstoreInlineInstallerForTest() override {}
108 friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;
110 static void DummyCallback(bool success,
111 const std::string& error,
112 webstore_install::Result result) {
115 ProgrammableInstallPrompt* programmable_prompt_;
118 class WebstoreInlineInstallerForTestFactory :
119 public WebstoreInlineInstallerFactory {
120 ~WebstoreInlineInstallerForTestFactory() override {}
121 WebstoreInlineInstaller* CreateInstaller(
122 WebContents* contents,
123 const std::string& webstore_item_id,
124 const GURL& requestor_url,
125 const WebstoreStandaloneInstaller::Callback& callback) override {
126 return new WebstoreInlineInstallerForTest(
127 contents, webstore_item_id, requestor_url, callback);
131 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest,
132 CloseTabBeforeInstallConfirmation) {
133 GURL install_url = GenerateTestServerUrl(kAppDomain, "install.html");
134 ui_test_utils::NavigateToURL(browser(), install_url);
135 WebContents* web_contents =
136 browser()->tab_strip_model()->GetActiveWebContents();
137 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents);
138 tab_helper->SetWebstoreInlineInstallerFactoryForTests(
139 new WebstoreInlineInstallerForTestFactory());
140 RunTestAsync("runTest");
141 while (!ProgrammableInstallPrompt::Ready())
142 base::RunLoop().RunUntilIdle();
143 web_contents->Close();
144 ProgrammableInstallPrompt::Accept();
147 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest,
148 ShouldBlockInlineInstallFromPopupWindow) {
149 GURL install_url =
150 GenerateTestServerUrl(kAppDomain, "install_from_popup.html");
151 // Disable popup blocking for the test url.
152 browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
153 ContentSettingsPattern::FromURL(install_url),
154 ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_POPUPS,
155 std::string(), CONTENT_SETTING_ALLOW);
156 ui_test_utils::NavigateToURL(browser(), install_url);
157 // The test page opens a popup which is a new |browser| window.
158 Browser* popup_browser = chrome::FindLastActiveWithProfile(
159 browser()->profile(), chrome::GetActiveDesktop());
160 WebContents* popup_contents =
161 popup_browser->tab_strip_model()->GetActiveWebContents();
162 EXPECT_EQ(base::ASCIIToUTF16("POPUP"), popup_contents->GetTitle());
163 RunTest(popup_contents, "runTest");
166 // Ensure that inline-installing a disabled extension simply re-enables it.
167 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest,
168 ReinstallDisabledExtension) {
169 // Install an extension via inline install, and confirm it is successful.
170 AutoAcceptInstall();
171 ui_test_utils::NavigateToURL(
172 browser(), GenerateTestServerUrl(kAppDomain, "install.html"));
173 RunTest("runTest");
174 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
175 ASSERT_TRUE(registry->enabled_extensions().GetByID(kTestExtensionId));
177 // Disable the extension.
178 ExtensionService* extension_service =
179 ExtensionSystem::Get(browser()->profile())->extension_service();
180 extension_service->DisableExtension(kTestExtensionId,
181 Extension::DISABLE_USER_ACTION);
182 EXPECT_TRUE(registry->disabled_extensions().GetByID(kTestExtensionId));
184 // Revisit the inline install site and reinstall the extension. It should
185 // simply be re-enabled, rather than try to install again.
186 ui_test_utils::NavigateToURL(
187 browser(), GenerateTestServerUrl(kAppDomain, "install.html"));
188 RunTest("runTest");
189 EXPECT_TRUE(registry->enabled_extensions().GetByID(kTestExtensionId));
190 // Since it was disabled by user action, the prompt should have just been the
191 // inline install prompt.
192 EXPECT_EQ(ExtensionInstallPrompt::INLINE_INSTALL_PROMPT,
193 ExtensionInstallPrompt::g_last_prompt_type_for_tests);
195 // Disable the extension due to a permissions increase.
196 extension_service->DisableExtension(kTestExtensionId,
197 Extension::DISABLE_PERMISSIONS_INCREASE);
198 EXPECT_TRUE(registry->disabled_extensions().GetByID(kTestExtensionId));
199 ui_test_utils::NavigateToURL(
200 browser(), GenerateTestServerUrl(kAppDomain, "install.html"));
201 RunTest("runTest");
202 EXPECT_TRUE(registry->enabled_extensions().GetByID(kTestExtensionId));
203 // The displayed prompt should be for the permissions increase, versus a
204 // normal inline install prompt.
205 EXPECT_EQ(ExtensionInstallPrompt::RE_ENABLE_PROMPT,
206 ExtensionInstallPrompt::g_last_prompt_type_for_tests);
208 ExtensionInstallPrompt::g_last_prompt_type_for_tests =
209 ExtensionInstallPrompt::UNSET_PROMPT_TYPE;
210 ui_test_utils::NavigateToURL(
211 browser(), GenerateTestServerUrl(kAppDomain, "install.html"));
212 RunTest("runTest");
213 // If the extension was already enabled, we should still display an inline
214 // install prompt (until we come up with something better).
215 EXPECT_EQ(ExtensionInstallPrompt::INLINE_INSTALL_PROMPT,
216 ExtensionInstallPrompt::g_last_prompt_type_for_tests);
219 class WebstoreInlineInstallerListenerTest : public WebstoreInlineInstallerTest {
220 public:
221 WebstoreInlineInstallerListenerTest() {}
222 ~WebstoreInlineInstallerListenerTest() override {}
224 protected:
225 void RunTest(const std::string& file_name) {
226 AutoAcceptInstall();
227 ui_test_utils::NavigateToURL(browser(),
228 GenerateTestServerUrl(kAppDomain, file_name));
229 WebstoreInstallerTest::RunTest("runTest");
233 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,
234 InstallStageListenerTest) {
235 RunTest("install_stage_listener.html");
238 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,
239 DownloadProgressListenerTest) {
240 RunTest("download_progress_listener.html");
243 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest, BothListenersTest) {
244 RunTest("both_listeners.html");
247 } // namespace extensions