• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "base/command_line.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/tabs/tab_strip_model.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "content/public/browser/web_contents.h"
19 #include "extensions/browser/extension_system.h"
20 #include "url/gurl.h"
21 
22 using content::WebContents;
23 
24 namespace extensions {
25 
26 namespace {
27 
28 const char kWebstoreDomain[] = "cws.com";
29 const char kAppDomain[] = "app.com";
30 const char kNonAppDomain[] = "nonapp.com";
31 const char kTestExtensionId[] = "ecglahbcnmdpdciemllbhojghbkagdje";
32 const char kTestDataPath[] = "extensions/api_test/webstore_inline_install";
33 const char kCrxFilename[] = "extension.crx";
34 
35 }  // namespace
36 
37 class WebstoreInlineInstallerTest : public WebstoreInstallerTest {
38  public:
WebstoreInlineInstallerTest()39   WebstoreInlineInstallerTest()
40       : WebstoreInstallerTest(
41             kWebstoreDomain,
42             kTestDataPath,
43             kCrxFilename,
44             kAppDomain,
45             kNonAppDomain) {}
46 };
47 
48 class ProgrammableInstallPrompt : public ExtensionInstallPrompt {
49  public:
ProgrammableInstallPrompt(WebContents * contents)50   explicit ProgrammableInstallPrompt(WebContents* contents)
51       : ExtensionInstallPrompt(contents)
52   {}
53 
~ProgrammableInstallPrompt()54   virtual ~ProgrammableInstallPrompt() {}
55 
ConfirmStandaloneInstall(Delegate * delegate,const Extension * extension,SkBitmap * icon,scoped_refptr<ExtensionInstallPrompt::Prompt> prompt)56   virtual void ConfirmStandaloneInstall(
57       Delegate* delegate,
58       const Extension* extension,
59       SkBitmap* icon,
60       scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) OVERRIDE {
61     delegate_ = delegate;
62   }
63 
Ready()64   static bool Ready() {
65     return delegate_ != NULL;
66   }
67 
Accept()68   static void Accept() {
69     delegate_->InstallUIProceed();
70   }
71 
Reject()72   static void Reject() {
73     delegate_->InstallUIAbort(true);
74   }
75 
76  private:
77   static Delegate* delegate_;
78 };
79 
80 ExtensionInstallPrompt::Delegate* ProgrammableInstallPrompt::delegate_;
81 
82 // Fake inline installer which creates a programmable prompt in place of
83 // the normal dialog UI.
84 class WebstoreInlineInstallerForTest : public WebstoreInlineInstaller {
85  public:
WebstoreInlineInstallerForTest(WebContents * contents,const std::string & extension_id,const GURL & requestor_url,const Callback & callback)86   WebstoreInlineInstallerForTest(WebContents* contents,
87                                  const std::string& extension_id,
88                                  const GURL& requestor_url,
89                                  const Callback& callback)
90       : WebstoreInlineInstaller(
91             contents,
92             kTestExtensionId,
93             requestor_url,
94             base::Bind(DummyCallback)),
95         programmable_prompt_(NULL) {
96   }
97 
CreateInstallUI()98   virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI() OVERRIDE {
99     programmable_prompt_ = new ProgrammableInstallPrompt(web_contents());
100     return make_scoped_ptr(programmable_prompt_).
101         PassAs<ExtensionInstallPrompt>();
102   }
103 
104  private:
~WebstoreInlineInstallerForTest()105   virtual ~WebstoreInlineInstallerForTest() {}
106 
107   friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;
108 
DummyCallback(bool,const std::string &)109   static void DummyCallback(bool /*success*/, const std::string& /*error*/) {
110   }
111 
112   ProgrammableInstallPrompt* programmable_prompt_;
113 };
114 
115 class WebstoreInlineInstallerForTestFactory :
116     public WebstoreInlineInstallerFactory {
~WebstoreInlineInstallerForTestFactory()117   virtual ~WebstoreInlineInstallerForTestFactory() {}
CreateInstaller(WebContents * contents,const std::string & webstore_item_id,const GURL & requestor_url,const WebstoreStandaloneInstaller::Callback & callback)118   virtual WebstoreInlineInstaller* CreateInstaller(
119       WebContents* contents,
120       const std::string& webstore_item_id,
121       const GURL& requestor_url,
122       const WebstoreStandaloneInstaller::Callback& callback) OVERRIDE {
123     return new WebstoreInlineInstallerForTest(
124         contents, webstore_item_id, requestor_url, callback);
125   }
126 };
127 
IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest,CloseTabBeforeInstallConfirmation)128 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest,
129     CloseTabBeforeInstallConfirmation) {
130   GURL install_url = GenerateTestServerUrl(kAppDomain, "install.html");
131   ui_test_utils::NavigateToURL(browser(), install_url);
132   WebContents* web_contents =
133       browser()->tab_strip_model()->GetActiveWebContents();
134   TabHelper* tab_helper = TabHelper::FromWebContents(web_contents);
135   tab_helper->SetWebstoreInlineInstallerFactoryForTests(
136       new WebstoreInlineInstallerForTestFactory());
137   RunTestAsync("runTest");
138   while (!ProgrammableInstallPrompt::Ready())
139     base::RunLoop().RunUntilIdle();
140   web_contents->Close();
141   ProgrammableInstallPrompt::Accept();
142 }
143 
144 // Ensure that inline-installing a disabled extension simply re-enables it.
IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest,ReinstallDisabledExtension)145 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest,
146                        ReinstallDisabledExtension) {
147   // Install an extension via inline install, and confirm it is successful.
148   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
149       switches::kAppsGalleryInstallAutoConfirmForTests, "accept");
150   ui_test_utils::NavigateToURL(
151       browser(), GenerateTestServerUrl(kAppDomain, "install.html"));
152   RunTest("runTest");
153   ExtensionService* extension_service =
154       ExtensionSystem::Get(browser()->profile())->extension_service();
155   ASSERT_TRUE(extension_service->GetExtensionById(kTestExtensionId, false));
156 
157   // Disable the extension.
158   extension_service->DisableExtension(kTestExtensionId,
159                                       Extension::DISABLE_USER_ACTION);
160   ASSERT_FALSE(extension_service->IsExtensionEnabled(kTestExtensionId));
161 
162   // Revisit the inline install site and reinstall the extension. It should
163   // simply be re-enabled, rather than try to install again.
164   ui_test_utils::NavigateToURL(
165       browser(), GenerateTestServerUrl(kAppDomain, "install.html"));
166   RunTest("runTest");
167   ASSERT_TRUE(extension_service->IsExtensionEnabled(kTestExtensionId));
168 }
169 
170 class WebstoreInlineInstallerListenerTest : public WebstoreInlineInstallerTest {
171  public:
WebstoreInlineInstallerListenerTest()172   WebstoreInlineInstallerListenerTest() {}
~WebstoreInlineInstallerListenerTest()173   virtual ~WebstoreInlineInstallerListenerTest() {}
174 
175  protected:
RunTest(const std::string & file_name)176   void RunTest(const std::string& file_name) {
177     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
178         switches::kAppsGalleryInstallAutoConfirmForTests, "accept");
179     ui_test_utils::NavigateToURL(browser(),
180                                  GenerateTestServerUrl(kAppDomain, file_name));
181     WebstoreInstallerTest::RunTest("runTest");
182   }
183 };
184 
IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,InstallStageListenerTest)185 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,
186                        InstallStageListenerTest) {
187   RunTest("install_stage_listener.html");
188 }
189 
IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,DownloadProgressListenerTest)190 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,
191                        DownloadProgressListenerTest) {
192   RunTest("download_progress_listener.html");
193 }
194 
IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,BothListenersTest)195 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest, BothListenersTest) {
196   RunTest("both_listeners.html");
197 }
198 
199 }  // namespace extensions
200