Home | History | Annotate | Download | only in extensions
      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:
     39   WebstoreInlineInstallerTest()
     40       : WebstoreInstallerTest(
     41             kWebstoreDomain,
     42             kTestDataPath,
     43             kCrxFilename,
     44             kAppDomain,
     45             kNonAppDomain) {}
     46 };
     47 
     48 class ProgrammableInstallPrompt : public ExtensionInstallPrompt {
     49  public:
     50   explicit ProgrammableInstallPrompt(WebContents* contents)
     51       : ExtensionInstallPrompt(contents)
     52   {}
     53 
     54   virtual ~ProgrammableInstallPrompt() {}
     55 
     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 
     64   static bool Ready() {
     65     return delegate_ != NULL;
     66   }
     67 
     68   static void Accept() {
     69     delegate_->InstallUIProceed();
     70   }
     71 
     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:
     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 
     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:
    105   virtual ~WebstoreInlineInstallerForTest() {}
    106 
    107   friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;
    108 
    109   static void DummyCallback(bool /*success*/, const std::string& /*error*/) {
    110   }
    111 
    112   ProgrammableInstallPrompt* programmable_prompt_;
    113 };
    114 
    115 class WebstoreInlineInstallerForTestFactory :
    116     public WebstoreInlineInstallerFactory {
    117   virtual ~WebstoreInlineInstallerForTestFactory() {}
    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 
    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.
    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:
    172   WebstoreInlineInstallerListenerTest() {}
    173   virtual ~WebstoreInlineInstallerListenerTest() {}
    174 
    175  protected:
    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 
    185 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,
    186                        InstallStageListenerTest) {
    187   RunTest("install_stage_listener.html");
    188 }
    189 
    190 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest,
    191                        DownloadProgressListenerTest) {
    192   RunTest("download_progress_listener.html");
    193 }
    194 
    195 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest, BothListenersTest) {
    196   RunTest("both_listeners.html");
    197 }
    198 
    199 }  // namespace extensions
    200