Home | History | Annotate | Download | only in webstore_private
      1 // Copyright (c) 2012 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 <vector>
      6 
      7 #include "base/file_util.h"
      8 #include "base/files/file_path.h"
      9 #include "base/strings/stringprintf.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/browser/chrome_notification_types.h"
     12 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h"
     13 #include "chrome/browser/extensions/extension_apitest.h"
     14 #include "chrome/browser/extensions/extension_function_test_utils.h"
     15 #include "chrome/browser/extensions/extension_install_prompt.h"
     16 #include "chrome/browser/extensions/extension_install_ui.h"
     17 #include "chrome/browser/extensions/extension_service.h"
     18 #include "chrome/browser/extensions/webstore_installer.h"
     19 #include "chrome/browser/profiles/profile.h"
     20 #include "chrome/browser/ui/browser.h"
     21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     22 #include "chrome/common/chrome_switches.h"
     23 #include "chrome/test/base/ui_test_utils.h"
     24 #include "content/public/browser/gpu_data_manager.h"
     25 #include "content/public/browser/notification_observer.h"
     26 #include "content/public/browser/notification_registrar.h"
     27 #include "content/public/test/browser_test_utils.h"
     28 #include "gpu/config/gpu_feature_type.h"
     29 #include "gpu/config/gpu_info.h"
     30 #include "net/dns/mock_host_resolver.h"
     31 #include "ui/gl/gl_switches.h"
     32 
     33 using gpu::GpuFeatureType;
     34 
     35 namespace utils = extension_function_test_utils;
     36 
     37 namespace extensions {
     38 
     39 namespace {
     40 
     41 class WebstoreInstallListener : public WebstoreInstaller::Delegate {
     42  public:
     43   WebstoreInstallListener()
     44       : received_failure_(false), received_success_(false), waiting_(false) {}
     45 
     46   virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE {
     47     received_success_ = true;
     48     id_ = id;
     49 
     50     if (waiting_) {
     51       waiting_ = false;
     52       base::MessageLoopForUI::current()->Quit();
     53     }
     54   }
     55 
     56   virtual void OnExtensionInstallFailure(
     57       const std::string& id,
     58       const std::string& error,
     59       WebstoreInstaller::FailureReason reason) OVERRIDE {
     60     received_failure_ = true;
     61     id_ = id;
     62     error_ = error;
     63 
     64     if (waiting_) {
     65       waiting_ = false;
     66       base::MessageLoopForUI::current()->Quit();
     67     }
     68   }
     69 
     70   void Wait() {
     71     if (received_success_ || received_failure_)
     72       return;
     73 
     74     waiting_ = true;
     75     content::RunMessageLoop();
     76   }
     77   bool received_success() const { return received_success_; }
     78   const std::string& id() const { return id_; }
     79 
     80  private:
     81   bool received_failure_;
     82   bool received_success_;
     83   bool waiting_;
     84   std::string id_;
     85   std::string error_;
     86 };
     87 
     88 }  // namespace
     89 
     90 // A base class for tests below.
     91 class ExtensionWebstorePrivateApiTest : public ExtensionApiTest {
     92  public:
     93   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     94     ExtensionApiTest::SetUpCommandLine(command_line);
     95     command_line->AppendSwitchASCII(
     96         switches::kAppsGalleryURL,
     97         "http://www.example.com/files/extensions/api_test");
     98     command_line->AppendSwitchASCII(
     99         switches::kAppsGalleryInstallAutoConfirmForTests, "accept");
    100   }
    101 
    102   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    103     // Start up the test server and get us ready for calling the install
    104     // API functions.
    105     host_resolver()->AddRule("www.example.com", "127.0.0.1");
    106     ASSERT_TRUE(test_server()->Start());
    107     ExtensionInstallUI::set_disable_failure_ui_for_tests();
    108   }
    109 
    110  protected:
    111   // Returns a test server URL, but with host 'www.example.com' so it matches
    112   // the web store app's extent that we set up via command line flags.
    113   virtual GURL GetTestServerURL(const std::string& path) {
    114     GURL url = test_server()->GetURL(
    115         std::string("files/extensions/api_test/webstore_private/") + path);
    116 
    117     // Replace the host with 'www.example.com' so it matches the web store
    118     // app's extent.
    119     GURL::Replacements replace_host;
    120     std::string host_str("www.example.com");
    121     replace_host.SetHostStr(host_str);
    122 
    123     return url.ReplaceComponents(replace_host);
    124   }
    125 
    126   // Navigates to |page| and runs the Extension API test there. Any downloads
    127   // of extensions will return the contents of |crx_file|.
    128   bool RunInstallTest(const std::string& page, const std::string& crx_file) {
    129 #if defined(OS_WIN) && !defined(NDEBUG)
    130     // See http://crbug.com/177163 for details.
    131     return true;
    132 #else
    133     GURL crx_url = GetTestServerURL(crx_file);
    134     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
    135         switches::kAppsGalleryUpdateURL, crx_url.spec());
    136 
    137     GURL page_url = GetTestServerURL(page);
    138     return RunPageTest(page_url.spec());
    139 #endif
    140   }
    141 
    142   ExtensionService* service() {
    143     return browser()->profile()->GetExtensionService();
    144   }
    145 };
    146 
    147 // Test cases for webstore origin frame blocking.
    148 // TODO(mkwst): Disabled until new X-Frame-Options behavior rolls into
    149 // Chromium, see crbug.com/226018.
    150 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
    151                        DISABLED_FrameWebstorePageBlocked) {
    152   content::WebContents* contents =
    153       browser()->tab_strip_model()->GetActiveWebContents();
    154   base::string16 expected_title = UTF8ToUTF16("PASS: about:blank");
    155   base::string16 failure_title = UTF8ToUTF16("FAIL");
    156   content::TitleWatcher watcher(contents, expected_title);
    157   watcher.AlsoWaitForTitle(failure_title);
    158   GURL url = test_server()->GetURL(
    159       "files/extensions/api_test/webstore_private/noframe.html");
    160   ui_test_utils::NavigateToURL(browser(), url);
    161   base::string16 final_title = watcher.WaitAndGetTitle();
    162   EXPECT_EQ(expected_title, final_title);
    163 }
    164 
    165 // TODO(mkwst): Disabled until new X-Frame-Options behavior rolls into
    166 // Chromium, see crbug.com/226018.
    167 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
    168                        DISABLED_FrameErrorPageBlocked) {
    169   content::WebContents* contents =
    170       browser()->tab_strip_model()->GetActiveWebContents();
    171   base::string16 expected_title = UTF8ToUTF16("PASS: about:blank");
    172   base::string16 failure_title = UTF8ToUTF16("FAIL");
    173   content::TitleWatcher watcher(contents, expected_title);
    174   watcher.AlsoWaitForTitle(failure_title);
    175   GURL url = test_server()->GetURL(
    176       "files/extensions/api_test/webstore_private/noframe2.html");
    177   ui_test_utils::NavigateToURL(browser(), url);
    178   base::string16 final_title = watcher.WaitAndGetTitle();
    179   EXPECT_EQ(expected_title, final_title);
    180 }
    181 
    182 // Test cases where the user accepts the install confirmation dialog.
    183 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallAccepted) {
    184   ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
    185 }
    186 
    187 // Test having the default download directory missing.
    188  IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MissingDownloadDir) {
    189   // Set a non-existent directory as the download path.
    190   base::ScopedTempDir temp_dir;
    191   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
    192   base::FilePath missing_directory = temp_dir.Take();
    193   EXPECT_TRUE(base::DeleteFile(missing_directory, true));
    194   WebstoreInstaller::SetDownloadDirectoryForTests(&missing_directory);
    195 
    196   // Now run the install test, which should succeed.
    197   ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
    198 
    199   // Cleanup.
    200   if (base::DirectoryExists(missing_directory))
    201     EXPECT_TRUE(base::DeleteFile(missing_directory, true));
    202 }
    203 
    204 // Tests passing a localized name.
    205 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallLocalized) {
    206   ASSERT_TRUE(RunInstallTest("localized.html", "localized_extension.crx"));
    207 }
    208 
    209 // Now test the case where the user cancels the confirmation dialog.
    210 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallCancelled) {
    211   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
    212       switches::kAppsGalleryInstallAutoConfirmForTests, "cancel");
    213   ASSERT_TRUE(RunInstallTest("cancelled.html", "extension.crx"));
    214 }
    215 
    216 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest1) {
    217   ASSERT_TRUE(RunInstallTest("incorrect_manifest1.html", "extension.crx"));
    218 }
    219 
    220 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest2) {
    221   ASSERT_TRUE(RunInstallTest("incorrect_manifest2.html", "extension.crx"));
    222 }
    223 
    224 // Disabled: http://crbug.com/174399 and http://crbug.com/177163
    225 #if defined(OS_WIN) && (defined(USE_AURA) || !defined(NDEBUG))
    226 #define MAYBE_AppInstallBubble DISABLED_AppInstallBubble
    227 #else
    228 #define MAYBE_AppInstallBubble AppInstallBubble
    229 #endif
    230 
    231 // Tests that we can request an app installed bubble (instead of the default
    232 // UI when an app is installed).
    233 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
    234                        MAYBE_AppInstallBubble) {
    235   WebstoreInstallListener listener;
    236   WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
    237   ASSERT_TRUE(RunInstallTest("app_install_bubble.html", "app.crx"));
    238   listener.Wait();
    239   ASSERT_TRUE(listener.received_success());
    240   ASSERT_EQ("iladmdjkfniedhfhcfoefgojhgaiaccc", listener.id());
    241 }
    242 
    243 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsInIncognitoMode) {
    244   GURL page_url = GetTestServerURL("incognito.html");
    245   ASSERT_TRUE(
    246       RunPageTest(page_url.spec(), ExtensionApiTest::kFlagUseIncognito));
    247 }
    248 
    249 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsNotInIncognitoMode) {
    250   GURL page_url = GetTestServerURL("not_incognito.html");
    251   ASSERT_TRUE(RunPageTest(page_url.spec()));
    252 }
    253 
    254 // Fails often on Windows dbg bots. http://crbug.com/177163.
    255 #if defined(OS_WIN)
    256 #define MAYBE_IconUrl DISABLED_IconUrl
    257 #else
    258 #define MAYBE_IconUrl IconUrl
    259 #endif  // defined(OS_WIN)
    260 // Tests using the iconUrl parameter to the install function.
    261 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_IconUrl) {
    262   ASSERT_TRUE(RunInstallTest("icon_url.html", "extension.crx"));
    263 }
    264 
    265 // http://crbug.com/177163
    266 #if defined(OS_WIN) && !defined(NDEBUG)
    267 #define MAYBE_BeginInstall DISABLED_BeginInstall
    268 #else
    269 #define MAYBE_BeginInstall BeginInstall
    270 #endif
    271 // Tests that the Approvals are properly created in beginInstall.
    272 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_BeginInstall) {
    273   std::string appId = "iladmdjkfniedhfhcfoefgojhgaiaccc";
    274   std::string extensionId = "enfkhcelefdadlmkffamgdlgplcionje";
    275   ASSERT_TRUE(RunInstallTest("begin_install.html", "extension.crx"));
    276 
    277   scoped_ptr<WebstoreInstaller::Approval> approval =
    278       WebstorePrivateApi::PopApprovalForTesting(browser()->profile(), appId);
    279   EXPECT_EQ(appId, approval->extension_id);
    280   EXPECT_TRUE(approval->use_app_installed_bubble);
    281   EXPECT_FALSE(approval->skip_post_install_ui);
    282   EXPECT_EQ(browser()->profile(), approval->profile);
    283 
    284   approval = WebstorePrivateApi::PopApprovalForTesting(
    285       browser()->profile(), extensionId);
    286   EXPECT_EQ(extensionId, approval->extension_id);
    287   EXPECT_FALSE(approval->use_app_installed_bubble);
    288   EXPECT_FALSE(approval->skip_post_install_ui);
    289   EXPECT_EQ(browser()->profile(), approval->profile);
    290 }
    291 
    292 // http://crbug.com/177163
    293 #if defined(OS_WIN) && !defined(NDEBUG)
    294 #define MAYBE_InstallTheme DISABLED_InstallTheme
    295 #else
    296 #define MAYBE_InstallTheme InstallTheme
    297 #endif
    298 // Tests that themes are installed without an install prompt.
    299 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_InstallTheme) {
    300   WebstoreInstallListener listener;
    301   WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
    302   ASSERT_TRUE(RunInstallTest("theme.html", "../../theme.crx"));
    303   listener.Wait();
    304   ASSERT_TRUE(listener.received_success());
    305   ASSERT_EQ("iamefpfkojoapidjnbafmgkgncegbkad", listener.id());
    306 }
    307 
    308 // Tests that an error is properly reported when an empty crx is returned.
    309 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, EmptyCrx) {
    310   ASSERT_TRUE(RunInstallTest("empty.html", "empty.crx"));
    311 }
    312 
    313 class ExtensionWebstoreGetWebGLStatusTest : public InProcessBrowserTest {
    314  protected:
    315   void RunTest(bool webgl_allowed) {
    316     // If Gpu access is disallowed then WebGL will not be available.
    317     if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL))
    318       webgl_allowed = false;
    319 
    320     static const char kEmptyArgs[] = "[]";
    321     static const char kWebGLStatusAllowed[] = "webgl_allowed";
    322     static const char kWebGLStatusBlocked[] = "webgl_blocked";
    323     scoped_refptr<WebstorePrivateGetWebGLStatusFunction> function =
    324         new WebstorePrivateGetWebGLStatusFunction();
    325     scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
    326             function.get(), kEmptyArgs, browser()));
    327     ASSERT_TRUE(result);
    328     EXPECT_EQ(base::Value::TYPE_STRING, result->GetType());
    329     std::string webgl_status;
    330     EXPECT_TRUE(result->GetAsString(&webgl_status));
    331     EXPECT_STREQ(webgl_allowed ? kWebGLStatusAllowed : kWebGLStatusBlocked,
    332                  webgl_status.c_str());
    333   }
    334 };
    335 
    336 // Tests getWebGLStatus function when WebGL is allowed.
    337 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Allowed) {
    338   bool webgl_allowed = true;
    339   RunTest(webgl_allowed);
    340 }
    341 
    342 // Tests getWebGLStatus function when WebGL is blacklisted.
    343 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Blocked) {
    344   static const std::string json_blacklist =
    345       "{\n"
    346       "  \"name\": \"gpu blacklist\",\n"
    347       "  \"version\": \"1.0\",\n"
    348       "  \"entries\": [\n"
    349       "    {\n"
    350       "      \"id\": 1,\n"
    351       "      \"features\": [\n"
    352       "        \"webgl\"\n"
    353       "      ]\n"
    354       "    }\n"
    355       "  ]\n"
    356       "}";
    357   gpu::GPUInfo gpu_info;
    358   content::GpuDataManager::GetInstance()->InitializeForTesting(
    359       json_blacklist, gpu_info);
    360   EXPECT_TRUE(content::GpuDataManager::GetInstance()->IsFeatureBlacklisted(
    361       gpu::GPU_FEATURE_TYPE_WEBGL));
    362 
    363   bool webgl_allowed = false;
    364   RunTest(webgl_allowed);
    365 }
    366 
    367 }  // namespace extensions
    368