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"
24 using content::WebContents
;
26 namespace extensions
{
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";
39 class WebstoreInlineInstallerTest
: public WebstoreInstallerTest
{
41 WebstoreInlineInstallerTest()
42 : WebstoreInstallerTest(
50 class ProgrammableInstallPrompt
: public ExtensionInstallPrompt
{
52 explicit ProgrammableInstallPrompt(WebContents
* contents
)
53 : ExtensionInstallPrompt(contents
)
56 ~ProgrammableInstallPrompt() override
{}
58 void ConfirmStandaloneInstall(
60 const Extension
* extension
,
62 scoped_refptr
<ExtensionInstallPrompt::Prompt
> prompt
) override
{
67 return delegate_
!= NULL
;
70 static void Accept() {
71 delegate_
->InstallUIProceed();
74 static void Reject() {
75 delegate_
->InstallUIAbort(true);
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
{
88 WebstoreInlineInstallerForTest(WebContents
* contents
,
89 const std::string
& extension_id
,
90 const GURL
& requestor_url
,
91 const Callback
& callback
)
92 : WebstoreInlineInstaller(
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_
);
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 // http://crbug.com/517309
149 #define MAYBE_ShouldBlockInlineInstallFromPopupWindow DISABLED_ShouldBlockInlineInstallFromPopupWindow
151 #define MAYBE_ShouldBlockInlineInstallFromPopupWindow ShouldBlockInlineInstallFromPopupWindow
153 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest
,
154 MAYBE_ShouldBlockInlineInstallFromPopupWindow
) {
156 GenerateTestServerUrl(kAppDomain
, "install_from_popup.html");
157 // Disable popup blocking for the test url.
158 browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
159 ContentSettingsPattern::FromURL(install_url
),
160 ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_POPUPS
,
161 std::string(), CONTENT_SETTING_ALLOW
);
162 ui_test_utils::NavigateToURL(browser(), install_url
);
163 // The test page opens a popup which is a new |browser| window.
164 Browser
* popup_browser
= chrome::FindLastActiveWithProfile(
165 browser()->profile(), chrome::GetActiveDesktop());
166 WebContents
* popup_contents
=
167 popup_browser
->tab_strip_model()->GetActiveWebContents();
168 EXPECT_EQ(base::ASCIIToUTF16("POPUP"), popup_contents
->GetTitle());
169 RunTest(popup_contents
, "runTest");
172 // Ensure that inline-installing a disabled extension simply re-enables it.
173 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest
,
174 ReinstallDisabledExtension
) {
175 // Install an extension via inline install, and confirm it is successful.
177 ui_test_utils::NavigateToURL(
178 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
180 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
181 ASSERT_TRUE(registry
->enabled_extensions().GetByID(kTestExtensionId
));
183 // Disable the extension.
184 ExtensionService
* extension_service
=
185 ExtensionSystem::Get(browser()->profile())->extension_service();
186 extension_service
->DisableExtension(kTestExtensionId
,
187 Extension::DISABLE_USER_ACTION
);
188 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kTestExtensionId
));
190 // Revisit the inline install site and reinstall the extension. It should
191 // simply be re-enabled, rather than try to install again.
192 ui_test_utils::NavigateToURL(
193 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
195 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kTestExtensionId
));
196 // Since it was disabled by user action, the prompt should have just been the
197 // inline install prompt.
198 EXPECT_EQ(ExtensionInstallPrompt::INLINE_INSTALL_PROMPT
,
199 ExtensionInstallPrompt::g_last_prompt_type_for_tests
);
201 // Disable the extension due to a permissions increase.
202 extension_service
->DisableExtension(kTestExtensionId
,
203 Extension::DISABLE_PERMISSIONS_INCREASE
);
204 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kTestExtensionId
));
205 ui_test_utils::NavigateToURL(
206 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
208 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kTestExtensionId
));
209 // The displayed prompt should be for the permissions increase, versus a
210 // normal inline install prompt.
211 EXPECT_EQ(ExtensionInstallPrompt::RE_ENABLE_PROMPT
,
212 ExtensionInstallPrompt::g_last_prompt_type_for_tests
);
214 ExtensionInstallPrompt::g_last_prompt_type_for_tests
=
215 ExtensionInstallPrompt::UNSET_PROMPT_TYPE
;
216 ui_test_utils::NavigateToURL(
217 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
219 // If the extension was already enabled, we should still display an inline
220 // install prompt (until we come up with something better).
221 EXPECT_EQ(ExtensionInstallPrompt::INLINE_INSTALL_PROMPT
,
222 ExtensionInstallPrompt::g_last_prompt_type_for_tests
);
225 class WebstoreInlineInstallerListenerTest
: public WebstoreInlineInstallerTest
{
227 WebstoreInlineInstallerListenerTest() {}
228 ~WebstoreInlineInstallerListenerTest() override
{}
231 void RunTest(const std::string
& file_name
) {
233 ui_test_utils::NavigateToURL(browser(),
234 GenerateTestServerUrl(kAppDomain
, file_name
));
235 WebstoreInstallerTest::RunTest("runTest");
239 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest
,
240 InstallStageListenerTest
) {
241 RunTest("install_stage_listener.html");
244 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest
,
245 DownloadProgressListenerTest
) {
246 RunTest("download_progress_listener.html");
249 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest
, BothListenersTest
) {
250 RunTest("both_listeners.html");
253 } // namespace extensions