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/content_settings/host_content_settings_map_factory.h"
7 #include "chrome/browser/extensions/extension_install_prompt.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/tab_helper.h"
10 #include "chrome/browser/extensions/webstore_inline_installer.h"
11 #include "chrome/browser/extensions/webstore_inline_installer_factory.h"
12 #include "chrome/browser/extensions/webstore_installer_test.h"
13 #include "chrome/browser/extensions/webstore_standalone_installer.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "components/content_settings/core/browser/host_content_settings_map.h"
20 #include "content/public/browser/web_contents.h"
21 #include "extensions/browser/extension_registry.h"
22 #include "extensions/browser/extension_system.h"
25 using content::WebContents
;
27 namespace extensions
{
31 const char kWebstoreDomain
[] = "cws.com";
32 const char kAppDomain
[] = "app.com";
33 const char kNonAppDomain
[] = "nonapp.com";
34 const char kTestExtensionId
[] = "ecglahbcnmdpdciemllbhojghbkagdje";
35 const char kTestDataPath
[] = "extensions/api_test/webstore_inline_install";
36 const char kCrxFilename
[] = "extension.crx";
40 class WebstoreInlineInstallerTest
: public WebstoreInstallerTest
{
42 WebstoreInlineInstallerTest()
43 : WebstoreInstallerTest(
51 class ProgrammableInstallPrompt
: public ExtensionInstallPrompt
{
53 explicit ProgrammableInstallPrompt(WebContents
* contents
)
54 : ExtensionInstallPrompt(contents
)
57 ~ProgrammableInstallPrompt() override
{}
59 void ConfirmStandaloneInstall(
61 const Extension
* extension
,
63 scoped_refptr
<ExtensionInstallPrompt::Prompt
> prompt
) override
{
68 return delegate_
!= NULL
;
71 static void Accept() {
72 delegate_
->InstallUIProceed();
75 static void Reject() {
76 delegate_
->InstallUIAbort(true);
80 static Delegate
* delegate_
;
83 ExtensionInstallPrompt::Delegate
* ProgrammableInstallPrompt::delegate_
;
85 // Fake inline installer which creates a programmable prompt in place of
86 // the normal dialog UI.
87 class WebstoreInlineInstallerForTest
: public WebstoreInlineInstaller
{
89 WebstoreInlineInstallerForTest(WebContents
* contents
,
90 const std::string
& extension_id
,
91 const GURL
& requestor_url
,
92 const Callback
& callback
)
93 : WebstoreInlineInstaller(
97 base::Bind(DummyCallback
)),
98 programmable_prompt_(NULL
) {
101 scoped_ptr
<ExtensionInstallPrompt
> CreateInstallUI() override
{
102 programmable_prompt_
= new ProgrammableInstallPrompt(web_contents());
103 return make_scoped_ptr(programmable_prompt_
);
107 ~WebstoreInlineInstallerForTest() override
{}
109 friend class base::RefCountedThreadSafe
<WebstoreStandaloneInstaller
>;
111 static void DummyCallback(bool success
,
112 const std::string
& error
,
113 webstore_install::Result result
) {
116 ProgrammableInstallPrompt
* programmable_prompt_
;
119 class WebstoreInlineInstallerForTestFactory
:
120 public WebstoreInlineInstallerFactory
{
121 ~WebstoreInlineInstallerForTestFactory() override
{}
122 WebstoreInlineInstaller
* CreateInstaller(
123 WebContents
* contents
,
124 const std::string
& webstore_item_id
,
125 const GURL
& requestor_url
,
126 const WebstoreStandaloneInstaller::Callback
& callback
) override
{
127 return new WebstoreInlineInstallerForTest(
128 contents
, webstore_item_id
, requestor_url
, callback
);
132 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest
,
133 CloseTabBeforeInstallConfirmation
) {
134 GURL install_url
= GenerateTestServerUrl(kAppDomain
, "install.html");
135 ui_test_utils::NavigateToURL(browser(), install_url
);
136 WebContents
* web_contents
=
137 browser()->tab_strip_model()->GetActiveWebContents();
138 TabHelper
* tab_helper
= TabHelper::FromWebContents(web_contents
);
139 tab_helper
->SetWebstoreInlineInstallerFactoryForTests(
140 new WebstoreInlineInstallerForTestFactory());
141 RunTestAsync("runTest");
142 while (!ProgrammableInstallPrompt::Ready())
143 base::RunLoop().RunUntilIdle();
144 web_contents
->Close();
145 ProgrammableInstallPrompt::Accept();
148 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest
,
149 ShouldBlockInlineInstallFromPopupWindow
) {
151 GenerateTestServerUrl(kAppDomain
, "install_from_popup.html");
152 // Disable popup blocking for the test url.
153 HostContentSettingsMapFactory::GetForProfile(browser()->profile())
154 ->SetContentSetting(ContentSettingsPattern::FromURL(install_url
),
155 ContentSettingsPattern::Wildcard(),
156 CONTENT_SETTINGS_TYPE_POPUPS
,
158 CONTENT_SETTING_ALLOW
);
159 ui_test_utils::NavigateToURL(browser(), install_url
);
160 // The test page opens a popup which is a new |browser| window.
161 Browser
* popup_browser
= chrome::FindLastActiveWithProfile(
162 browser()->profile(), chrome::GetActiveDesktop());
163 WebContents
* popup_contents
=
164 popup_browser
->tab_strip_model()->GetActiveWebContents();
165 EXPECT_EQ(base::ASCIIToUTF16("POPUP"), popup_contents
->GetTitle());
166 RunTest(popup_contents
, "runTest");
169 // Ensure that inline-installing a disabled extension simply re-enables it.
170 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest
,
171 ReinstallDisabledExtension
) {
172 // Install an extension via inline install, and confirm it is successful.
174 ui_test_utils::NavigateToURL(
175 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
177 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
178 ASSERT_TRUE(registry
->enabled_extensions().GetByID(kTestExtensionId
));
180 // Disable the extension.
181 ExtensionService
* extension_service
=
182 ExtensionSystem::Get(browser()->profile())->extension_service();
183 extension_service
->DisableExtension(kTestExtensionId
,
184 Extension::DISABLE_USER_ACTION
);
185 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kTestExtensionId
));
187 // Revisit the inline install site and reinstall the extension. It should
188 // simply be re-enabled, rather than try to install again.
189 ui_test_utils::NavigateToURL(
190 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
192 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kTestExtensionId
));
193 // Since it was disabled by user action, the prompt should have just been the
194 // inline install prompt.
195 EXPECT_EQ(ExtensionInstallPrompt::INLINE_INSTALL_PROMPT
,
196 ExtensionInstallPrompt::g_last_prompt_type_for_tests
);
198 // Disable the extension due to a permissions increase.
199 extension_service
->DisableExtension(kTestExtensionId
,
200 Extension::DISABLE_PERMISSIONS_INCREASE
);
201 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kTestExtensionId
));
202 ui_test_utils::NavigateToURL(
203 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
205 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kTestExtensionId
));
206 // The displayed prompt should be for the permissions increase, versus a
207 // normal inline install prompt.
208 EXPECT_EQ(ExtensionInstallPrompt::RE_ENABLE_PROMPT
,
209 ExtensionInstallPrompt::g_last_prompt_type_for_tests
);
211 ExtensionInstallPrompt::g_last_prompt_type_for_tests
=
212 ExtensionInstallPrompt::UNSET_PROMPT_TYPE
;
213 ui_test_utils::NavigateToURL(
214 browser(), GenerateTestServerUrl(kAppDomain
, "install.html"));
216 // If the extension was already enabled, we should still display an inline
217 // install prompt (until we come up with something better).
218 EXPECT_EQ(ExtensionInstallPrompt::INLINE_INSTALL_PROMPT
,
219 ExtensionInstallPrompt::g_last_prompt_type_for_tests
);
222 class WebstoreInlineInstallerListenerTest
: public WebstoreInlineInstallerTest
{
224 WebstoreInlineInstallerListenerTest() {}
225 ~WebstoreInlineInstallerListenerTest() override
{}
228 void RunTest(const std::string
& file_name
) {
230 ui_test_utils::NavigateToURL(browser(),
231 GenerateTestServerUrl(kAppDomain
, file_name
));
232 WebstoreInstallerTest::RunTest("runTest");
236 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest
,
237 InstallStageListenerTest
) {
238 RunTest("install_stage_listener.html");
241 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest
,
242 DownloadProgressListenerTest
) {
243 RunTest("download_progress_listener.html");
246 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest
, BothListenersTest
) {
247 RunTest("both_listeners.html");
250 } // namespace extensions