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 "chrome/browser/extensions/extension_install_prompt.h"
      6 #include "chrome/browser/extensions/extension_service.h"
      7 #include "chrome/browser/extensions/tab_helper.h"
      8 #include "chrome/browser/extensions/webstore_inline_installer.h"
      9 #include "chrome/browser/extensions/webstore_inline_installer_factory.h"
     10 #include "chrome/browser/extensions/webstore_installer_test.h"
     11 #include "chrome/browser/extensions/webstore_standalone_installer.h"
     12 #include "chrome/browser/profiles/profile.h"
     13 #include "chrome/browser/ui/browser.h"
     14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     15 #include "chrome/test/base/ui_test_utils.h"
     16 #include "content/public/browser/web_contents.h"
     17 #include "extensions/browser/extension_system.h"
     18 #include "url/gurl.h"
     19 
     20 using content::WebContents;
     21 
     22 namespace extensions {
     23 
     24 namespace {
     25 
     26 const char kWebstoreDomain[] = "cws.com";
     27 const char kAppDomain[] = "app.com";
     28 const char kNonAppDomain[] = "nonapp.com";
     29 const char kTestExtensionId[] = "ecglahbcnmdpdciemllbhojghbkagdje";
     30 const char kTestDataPath[] = "extensions/api_test/webstore_inline_install";
     31 const char kCrxFilename[] = "extension.crx";
     32 
     33 }  // namespace
     34 
     35 class WebstoreInlineInstallerTest : public WebstoreInstallerTest {
     36  public:
     37   WebstoreInlineInstallerTest()
     38       : WebstoreInstallerTest(
     39             kWebstoreDomain,
     40             kTestDataPath,
     41             kCrxFilename,
     42             kAppDomain,
     43             kNonAppDomain) {}
     44 };
     45 
     46 class ProgrammableInstallPrompt : public ExtensionInstallPrompt {
     47  public:
     48   explicit ProgrammableInstallPrompt(WebContents* contents)
     49       : ExtensionInstallPrompt(contents)
     50   {}
     51 
     52   virtual ~ProgrammableInstallPrompt() {}
     53 
     54   virtual void ConfirmStandaloneInstall(
     55       Delegate* delegate,
     56       const Extension* extension,
     57       SkBitmap* icon,
     58       scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) OVERRIDE {
     59     delegate_ = delegate;
     60   }
     61 
     62   static bool Ready() {
     63     return delegate_ != NULL;
     64   }
     65 
     66   static void Accept() {
     67     delegate_->InstallUIProceed();
     68   }
     69 
     70   static void Reject() {
     71     delegate_->InstallUIAbort(true);
     72   }
     73 
     74  private:
     75   static Delegate* delegate_;
     76 };
     77 
     78 ExtensionInstallPrompt::Delegate* ProgrammableInstallPrompt::delegate_;
     79 
     80 // Fake inline installer which creates a programmable prompt in place of
     81 // the normal dialog UI.
     82 class WebstoreInlineInstallerForTest : public WebstoreInlineInstaller {
     83  public:
     84   WebstoreInlineInstallerForTest(WebContents* contents,
     85                                  const std::string& extension_id,
     86                                  const GURL& requestor_url,
     87                                  const Callback& callback)
     88       : WebstoreInlineInstaller(
     89             contents,
     90             kTestExtensionId,
     91             requestor_url,
     92             base::Bind(DummyCallback)),
     93         programmable_prompt_(NULL) {
     94   }
     95 
     96   virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI() OVERRIDE {
     97     programmable_prompt_ = new ProgrammableInstallPrompt(web_contents());
     98     return make_scoped_ptr(programmable_prompt_).
     99         PassAs<ExtensionInstallPrompt>();
    100   }
    101 
    102  private:
    103   virtual ~WebstoreInlineInstallerForTest() {}
    104 
    105   friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;
    106 
    107   static void DummyCallback(bool success,
    108                             const std::string& error,
    109                             webstore_install::Result result) {
    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   ExtensionInstallPrompt::g_auto_confirm_for_tests =
    149       ExtensionInstallPrompt::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     ExtensionInstallPrompt::g_auto_confirm_for_tests =
    178         ExtensionInstallPrompt::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