Home | History | Annotate | Download | only in extensions
      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 "base/command_line.h"
      6 #include "base/strings/string_util.h"
      7 #include "chrome/app/chrome_command_ids.h"
      8 #include "chrome/browser/chrome_notification_types.h"
      9 #include "chrome/browser/extensions/extension_browsertest.h"
     10 #include "chrome/browser/extensions/extension_service.h"
     11 #include "chrome/browser/extensions/extension_sorting.h"
     12 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
     13 #include "chrome/browser/infobars/infobar_service.h"
     14 #include "chrome/browser/profiles/profile.h"
     15 #include "chrome/browser/themes/theme_service.h"
     16 #include "chrome/browser/themes/theme_service_factory.h"
     17 #include "chrome/browser/ui/browser.h"
     18 #include "chrome/browser/ui/browser_commands.h"
     19 #include "chrome/browser/ui/browser_finder.h"
     20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     21 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
     22 #include "chrome/common/url_constants.h"
     23 #include "chrome/test/base/test_switches.h"
     24 #include "chrome/test/base/ui_test_utils.h"
     25 #include "content/public/browser/web_contents.h"
     26 #include "content/public/test/browser_test_utils.h"
     27 #include "extensions/common/id_util.h"
     28 
     29 using content::WebContents;
     30 using extensions::Extension;
     31 
     32 class ExtensionInstallUIBrowserTest : public ExtensionBrowserTest {
     33  public:
     34   // Checks that a theme info bar is currently visible and issues an undo to
     35   // revert to the previous theme.
     36   void VerifyThemeInfoBarAndUndoInstall() {
     37     WebContents* web_contents =
     38         browser()->tab_strip_model()->GetActiveWebContents();
     39     ASSERT_TRUE(web_contents);
     40     InfoBarService* infobar_service =
     41         InfoBarService::FromWebContents(web_contents);
     42     ASSERT_EQ(1U, infobar_service->infobar_count());
     43     ConfirmInfoBarDelegate* delegate =
     44         infobar_service->infobar_at(0)->AsConfirmInfoBarDelegate();
     45     ASSERT_TRUE(delegate);
     46     delegate->Cancel();
     47     ASSERT_EQ(0U, infobar_service->infobar_count());
     48   }
     49 
     50   // Install the given theme from the data dir and verify expected name.
     51   void InstallThemeAndVerify(const char* theme_name,
     52                              const std::string& expected_name) {
     53     const base::FilePath theme_path = test_data_dir_.AppendASCII(theme_name);
     54     ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_path, 1, browser()));
     55     const Extension* theme = GetTheme();
     56     ASSERT_TRUE(theme);
     57     ASSERT_EQ(theme->name(), expected_name);
     58   }
     59 
     60   const Extension* GetTheme() const {
     61     return ThemeServiceFactory::GetThemeForProfile(browser()->profile());
     62   }
     63 };
     64 
     65 #if defined(OS_LINUX)
     66 // Fails consistently on bot chromium.chromiumos \ Linux.
     67 // See: http://crbug.com/120647.
     68 #define MAYBE_TestThemeInstallUndoResetsToDefault DISABLED_TestThemeInstallUndoResetsToDefault
     69 #else
     70 #define MAYBE_TestThemeInstallUndoResetsToDefault TestThemeInstallUndoResetsToDefault
     71 #endif
     72 
     73 IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
     74                        MAYBE_TestThemeInstallUndoResetsToDefault) {
     75 #if defined(OS_WIN) && defined(USE_ASH)
     76   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
     77   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
     78     return;
     79 #endif
     80 
     81   // Install theme once and undo to verify we go back to default theme.
     82   base::FilePath theme_crx = PackExtension(test_data_dir_.AppendASCII("theme"));
     83   ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_crx, 1, browser()));
     84   const Extension* theme = GetTheme();
     85   ASSERT_TRUE(theme);
     86   std::string theme_id = theme->id();
     87   VerifyThemeInfoBarAndUndoInstall();
     88   ASSERT_EQ(NULL, GetTheme());
     89 
     90   // Set the same theme twice and undo to verify we go back to default theme.
     91   ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_crx, 1, browser()));
     92   theme = GetTheme();
     93   ASSERT_TRUE(theme);
     94   ASSERT_EQ(theme_id, theme->id());
     95   ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_crx, 0, browser()));
     96   theme = GetTheme();
     97   ASSERT_TRUE(theme);
     98   ASSERT_EQ(theme_id, theme->id());
     99   VerifyThemeInfoBarAndUndoInstall();
    100   ASSERT_EQ(NULL, GetTheme());
    101 }
    102 
    103 IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
    104                        TestThemeInstallUndoResetsToPreviousTheme) {
    105 #if defined(OS_WIN) && defined(USE_ASH)
    106   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    107   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    108     return;
    109 #endif
    110 
    111   // Install first theme.
    112   InstallThemeAndVerify("theme", "camo theme");
    113   const Extension* theme = GetTheme();
    114   std::string theme_id = theme->id();
    115 
    116   // Then install second theme.
    117   InstallThemeAndVerify("theme2", "snowflake theme");
    118   const Extension* theme2 = GetTheme();
    119   EXPECT_FALSE(theme_id == theme2->id());
    120 
    121   // Undo second theme will revert to first theme.
    122   VerifyThemeInfoBarAndUndoInstall();
    123   EXPECT_EQ(theme, GetTheme());
    124 }
    125 
    126 IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
    127                        TestThemeReset) {
    128   InstallThemeAndVerify("theme", "camo theme");
    129 
    130   // Reset to default theme.
    131   ThemeServiceFactory::GetForProfile(browser()->profile())->UseDefaultTheme();
    132   ASSERT_FALSE(GetTheme());
    133 }
    134 
    135 IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
    136                        TestInstallThemeInFullScreen) {
    137   EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_FULLSCREEN));
    138   InstallThemeAndVerify("theme", "camo theme");
    139 }
    140 
    141 IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
    142                        AppInstallConfirmation) {
    143   int num_tabs = browser()->tab_strip_model()->count();
    144 
    145   base::FilePath app_dir = test_data_dir_.AppendASCII("app");
    146   ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(app_dir, 1, browser()));
    147 
    148   if (NewTabUI::ShouldShowApps()) {
    149     EXPECT_EQ(num_tabs + 1, browser()->tab_strip_model()->count());
    150     WebContents* web_contents =
    151         browser()->tab_strip_model()->GetActiveWebContents();
    152     ASSERT_TRUE(web_contents);
    153     EXPECT_TRUE(StartsWithASCII(web_contents->GetURL().spec(),
    154                                 "chrome://newtab/", false));
    155   } else {
    156     // TODO(xiyuan): Figure out how to test extension installed bubble?
    157   }
    158 }
    159 
    160 IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
    161                        AppInstallConfirmation_Incognito) {
    162   Browser* incognito_browser = CreateIncognitoBrowser();
    163 
    164   int num_incognito_tabs = incognito_browser->tab_strip_model()->count();
    165   int num_normal_tabs = browser()->tab_strip_model()->count();
    166 
    167   base::FilePath app_dir = test_data_dir_.AppendASCII("app");
    168   ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(app_dir, 1,
    169                                                 incognito_browser));
    170 
    171   EXPECT_EQ(num_incognito_tabs,
    172             incognito_browser->tab_strip_model()->count());
    173   if (NewTabUI::ShouldShowApps()) {
    174     EXPECT_EQ(num_normal_tabs + 1, browser()->tab_strip_model()->count());
    175     WebContents* web_contents =
    176         browser()->tab_strip_model()->GetActiveWebContents();
    177     ASSERT_TRUE(web_contents);
    178     EXPECT_TRUE(StartsWithASCII(web_contents->GetURL().spec(),
    179                                 "chrome://newtab/", false));
    180   } else {
    181     // TODO(xiyuan): Figure out how to test extension installed bubble?
    182   }
    183 }
    184 
    185 class NewTabUISortingBrowserTest : public ExtensionInstallUIBrowserTest {
    186  public:
    187   NewTabUISortingBrowserTest() {}
    188 
    189   virtual void Observe(int type,
    190                        const content::NotificationSource& source,
    191                        const content::NotificationDetails& details) OVERRIDE {
    192     if (type != chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED) {
    193       ExtensionInstallUIBrowserTest::Observe(type, source, details);
    194       return;
    195     }
    196     const std::string* id = content::Details<const std::string>(details).ptr();
    197     EXPECT_TRUE(id);
    198     last_reordered_extension_id_ = *id;
    199   }
    200 
    201  protected:
    202   std::string last_reordered_extension_id_;
    203   content::NotificationRegistrar registrar_;
    204 
    205  private:
    206   DISALLOW_COPY_AND_ASSIGN(NewTabUISortingBrowserTest);
    207 };
    208 
    209 IN_PROC_BROWSER_TEST_F(NewTabUISortingBrowserTest, ReorderDuringInstall) {
    210   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
    211   ExtensionService* service = extensions::ExtensionSystem::Get(
    212       browser()->profile())->extension_service();
    213   base::FilePath app_dir = test_data_dir_.AppendASCII("app");
    214   const std::string app_id = extensions::id_util::GenerateIdForPath(app_dir);
    215 
    216   const extensions::Extension* webstore_extension =
    217       service->GetInstalledExtension(extension_misc::kWebStoreAppId);
    218   EXPECT_TRUE(webstore_extension);
    219   ExtensionSorting* sorting = service->extension_prefs()->extension_sorting();
    220 
    221   // Register for notifications in the same way as AppLauncherHandler.
    222   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
    223       content::Source<ExtensionSorting>(sorting));
    224   // ExtensionAppItem calls this when an app install starts.
    225   sorting->EnsureValidOrdinals(app_id, syncer::StringOrdinal());
    226   // Vefify the app is not actually installed yet.
    227   EXPECT_FALSE(service->GetInstalledExtension(app_id));
    228   // Move the test app from the end to be before the web store.
    229   service->OnExtensionMoved(app_id,
    230                             std::string(),
    231                             extension_misc::kWebStoreAppId);
    232   EXPECT_EQ(app_id, last_reordered_extension_id_);
    233 
    234   // Now install the app.
    235   const extensions::Extension* test_app = LoadExtension(app_dir);
    236   ASSERT_TRUE(test_app);
    237   EXPECT_TRUE(service->GetInstalledExtension(app_id));
    238   EXPECT_EQ(app_id, test_app->id());
    239 }
    240