Home | History | Annotate | Download | only in setup
      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 <objbase.h>
      6 
      7 #include <string>
      8 
      9 #include "base/file_util.h"
     10 #include "base/files/file_path.h"
     11 #include "base/files/scoped_temp_dir.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/path_service.h"
     14 #include "base/platform_file.h"
     15 #include "base/strings/string16.h"
     16 #include "base/strings/utf_string_conversions.h"
     17 #include "base/test/scoped_path_override.h"
     18 #include "base/test/test_shortcut_win.h"
     19 #include "base/version.h"
     20 #include "base/win/shortcut.h"
     21 #include "chrome/installer/setup/install.h"
     22 #include "chrome/installer/setup/install_worker.h"
     23 #include "chrome/installer/setup/setup_constants.h"
     24 #include "chrome/installer/util/browser_distribution.h"
     25 #include "chrome/installer/util/installer_state.h"
     26 #include "chrome/installer/util/master_preferences.h"
     27 #include "chrome/installer/util/master_preferences_constants.h"
     28 #include "chrome/installer/util/product.h"
     29 #include "chrome/installer/util/shell_util.h"
     30 #include "chrome/installer/util/util_constants.h"
     31 #include "testing/gtest/include/gtest/gtest.h"
     32 
     33 namespace {
     34 
     35 class CreateVisualElementsManifestTest : public testing::Test {
     36  protected:
     37   virtual void SetUp() OVERRIDE {
     38     // Create a temp directory for testing.
     39     ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
     40 
     41     version_ = Version("0.0.0.0");
     42 
     43     version_dir_ = test_dir_.path().AppendASCII(version_.GetString());
     44     ASSERT_TRUE(base::CreateDirectory(version_dir_));
     45 
     46     manifest_path_ =
     47         test_dir_.path().Append(installer::kVisualElementsManifest);
     48   }
     49 
     50   virtual void TearDown() OVERRIDE {
     51     // Clean up test directory manually so we can fail if it leaks.
     52     ASSERT_TRUE(test_dir_.Delete());
     53   }
     54 
     55   // The temporary directory used to contain the test operations.
     56   base::ScopedTempDir test_dir_;
     57 
     58   // A dummy version number used to create the version directory.
     59   Version version_;
     60 
     61   // The path to |test_dir_|\|version_|.
     62   base::FilePath version_dir_;
     63 
     64   // The path to VisualElementsManifest.xml.
     65   base::FilePath manifest_path_;
     66 };
     67 
     68 class InstallShortcutTest : public testing::Test {
     69  protected:
     70   virtual void SetUp() OVERRIDE {
     71     EXPECT_EQ(S_OK, CoInitialize(NULL));
     72 
     73     dist_ = BrowserDistribution::GetDistribution();
     74     ASSERT_TRUE(dist_ != NULL);
     75     product_.reset(new installer::Product(dist_));
     76 
     77     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     78     chrome_exe_ = temp_dir_.path().Append(installer::kChromeExe);
     79     EXPECT_EQ(0, file_util::WriteFile(chrome_exe_, "", 0));
     80 
     81     ShellUtil::ShortcutProperties chrome_properties(ShellUtil::CURRENT_USER);
     82     product_->AddDefaultShortcutProperties(chrome_exe_, &chrome_properties);
     83 
     84     expected_properties_.set_target(chrome_exe_);
     85     expected_properties_.set_icon(chrome_properties.icon,
     86                                   chrome_properties.icon_index);
     87     expected_properties_.set_app_id(chrome_properties.app_id);
     88     expected_properties_.set_description(chrome_properties.description);
     89     expected_properties_.set_dual_mode(false);
     90     expected_start_menu_properties_ = expected_properties_;
     91     expected_start_menu_properties_.set_dual_mode(true);
     92 
     93     prefs_.reset(GetFakeMasterPrefs(false, false, false));
     94 
     95     ASSERT_TRUE(fake_user_desktop_.CreateUniqueTempDir());
     96     ASSERT_TRUE(fake_common_desktop_.CreateUniqueTempDir());
     97     ASSERT_TRUE(fake_user_quick_launch_.CreateUniqueTempDir());
     98     ASSERT_TRUE(fake_default_user_quick_launch_.CreateUniqueTempDir());
     99     ASSERT_TRUE(fake_start_menu_.CreateUniqueTempDir());
    100     ASSERT_TRUE(fake_common_start_menu_.CreateUniqueTempDir());
    101     user_desktop_override_.reset(
    102         new base::ScopedPathOverride(base::DIR_USER_DESKTOP,
    103                                      fake_user_desktop_.path()));
    104     common_desktop_override_.reset(
    105         new base::ScopedPathOverride(base::DIR_COMMON_DESKTOP,
    106                                      fake_common_desktop_.path()));
    107     user_quick_launch_override_.reset(
    108         new base::ScopedPathOverride(base::DIR_USER_QUICK_LAUNCH,
    109                                      fake_user_quick_launch_.path()));
    110     default_user_quick_launch_override_.reset(
    111         new base::ScopedPathOverride(base::DIR_DEFAULT_USER_QUICK_LAUNCH,
    112                                      fake_default_user_quick_launch_.path()));
    113     start_menu_override_.reset(
    114         new base::ScopedPathOverride(base::DIR_START_MENU,
    115                                      fake_start_menu_.path()));
    116     common_start_menu_override_.reset(
    117         new base::ScopedPathOverride(base::DIR_COMMON_START_MENU,
    118                                      fake_common_start_menu_.path()));
    119 
    120     string16 shortcut_name(
    121         dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
    122         installer::kLnkExt);
    123     string16 alternate_shortcut_name(
    124         dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME_ALTERNATE) +
    125         installer::kLnkExt);
    126 
    127     user_desktop_shortcut_ =
    128         fake_user_desktop_.path().Append(shortcut_name);
    129     user_quick_launch_shortcut_ =
    130         fake_user_quick_launch_.path().Append(shortcut_name);
    131     user_start_menu_shortcut_ =
    132         fake_start_menu_.path().Append(
    133             dist_->GetStartMenuShortcutSubfolder(
    134                 BrowserDistribution::SUBFOLDER_CHROME))
    135         .Append(shortcut_name);
    136     system_desktop_shortcut_ =
    137         fake_common_desktop_.path().Append(shortcut_name);
    138     system_quick_launch_shortcut_ =
    139         fake_default_user_quick_launch_.path().Append(shortcut_name);
    140     system_start_menu_shortcut_ =
    141         fake_common_start_menu_.path().Append(
    142             dist_->GetStartMenuShortcutSubfolder(
    143                 BrowserDistribution::SUBFOLDER_CHROME))
    144         .Append(shortcut_name);
    145     user_alternate_desktop_shortcut_ =
    146         fake_user_desktop_.path().Append(alternate_shortcut_name);
    147   }
    148 
    149   virtual void TearDown() OVERRIDE {
    150     // Try to unpin potentially pinned shortcuts (although pinning isn't tested,
    151     // the call itself might still have pinned the Start Menu shortcuts).
    152     base::win::TaskbarUnpinShortcutLink(
    153         user_start_menu_shortcut_.value().c_str());
    154     base::win::TaskbarUnpinShortcutLink(
    155         system_start_menu_shortcut_.value().c_str());
    156     CoUninitialize();
    157   }
    158 
    159   installer::MasterPreferences* GetFakeMasterPrefs(
    160       bool do_not_create_desktop_shortcut,
    161       bool do_not_create_quick_launch_shortcut,
    162       bool alternate_desktop_shortcut) {
    163     const struct {
    164       const char* pref_name;
    165       bool is_desired;
    166     } desired_prefs[] = {
    167       { installer::master_preferences::kDoNotCreateDesktopShortcut,
    168         do_not_create_desktop_shortcut },
    169       { installer::master_preferences::kDoNotCreateQuickLaunchShortcut,
    170         do_not_create_quick_launch_shortcut },
    171       { installer::master_preferences::kAltShortcutText,
    172         alternate_desktop_shortcut },
    173     };
    174 
    175     std::string master_prefs("{\"distribution\":{");
    176     for (size_t i = 0; i < arraysize(desired_prefs); ++i) {
    177       master_prefs += (i == 0 ? "\"" : ",\"");
    178       master_prefs += desired_prefs[i].pref_name;
    179       master_prefs += "\":";
    180       master_prefs += desired_prefs[i].is_desired ? "true" : "false";
    181     }
    182     master_prefs += "}}";
    183 
    184     return new installer::MasterPreferences(master_prefs);
    185   }
    186 
    187   base::win::ShortcutProperties expected_properties_;
    188   base::win::ShortcutProperties expected_start_menu_properties_;
    189 
    190   BrowserDistribution* dist_;
    191   base::FilePath chrome_exe_;
    192   scoped_ptr<installer::Product> product_;
    193   scoped_ptr<installer::MasterPreferences> prefs_;
    194 
    195   base::ScopedTempDir temp_dir_;
    196   base::ScopedTempDir fake_user_desktop_;
    197   base::ScopedTempDir fake_common_desktop_;
    198   base::ScopedTempDir fake_user_quick_launch_;
    199   base::ScopedTempDir fake_default_user_quick_launch_;
    200   base::ScopedTempDir fake_start_menu_;
    201   base::ScopedTempDir fake_common_start_menu_;
    202   scoped_ptr<base::ScopedPathOverride> user_desktop_override_;
    203   scoped_ptr<base::ScopedPathOverride> common_desktop_override_;
    204   scoped_ptr<base::ScopedPathOverride> user_quick_launch_override_;
    205   scoped_ptr<base::ScopedPathOverride> default_user_quick_launch_override_;
    206   scoped_ptr<base::ScopedPathOverride> start_menu_override_;
    207   scoped_ptr<base::ScopedPathOverride> common_start_menu_override_;
    208 
    209   base::FilePath user_desktop_shortcut_;
    210   base::FilePath user_quick_launch_shortcut_;
    211   base::FilePath user_start_menu_shortcut_;
    212   base::FilePath system_desktop_shortcut_;
    213   base::FilePath system_quick_launch_shortcut_;
    214   base::FilePath system_start_menu_shortcut_;
    215   base::FilePath user_alternate_desktop_shortcut_;
    216 };
    217 
    218 }  // namespace
    219 
    220 // Test that VisualElementsManifest.xml is not created when VisualElements are
    221 // not present.
    222 TEST_F(CreateVisualElementsManifestTest, VisualElementsManifestNotCreated) {
    223   ASSERT_TRUE(
    224       installer::CreateVisualElementsManifest(test_dir_.path(), version_));
    225   ASSERT_FALSE(base::PathExists(manifest_path_));
    226 }
    227 
    228 // Test that VisualElementsManifest.xml is created with the correct content when
    229 // VisualElements are present.
    230 TEST_F(CreateVisualElementsManifestTest, VisualElementsManifestCreated) {
    231   ASSERT_TRUE(base::CreateDirectory(
    232       version_dir_.Append(installer::kVisualElements)));
    233   ASSERT_TRUE(
    234       installer::CreateVisualElementsManifest(test_dir_.path(), version_));
    235   ASSERT_TRUE(base::PathExists(manifest_path_));
    236 
    237   std::string read_manifest;
    238   ASSERT_TRUE(base::ReadFileToString(manifest_path_, &read_manifest));
    239 
    240   static const char kExpectedManifest[] =
    241       "<Application>\r\n"
    242       "  <VisualElements\r\n"
    243       "      DisplayName='Google Chrome'\r\n"
    244       "      Logo='0.0.0.0\\VisualElements\\Logo.png'\r\n"
    245       "      SmallLogo='0.0.0.0\\VisualElements\\SmallLogo.png'\r\n"
    246       "      ForegroundText='light'\r\n"
    247       "      BackgroundColor='white'>\r\n"
    248       "    <DefaultTile ShowName='allLogos'/>\r\n"
    249       "    <SplashScreen Image='0.0.0.0\\VisualElements\\splash-620x300.png'/>"
    250       "\r\n"
    251       "  </VisualElements>\r\n"
    252       "</Application>";
    253 
    254   ASSERT_STREQ(kExpectedManifest, read_manifest.c_str());
    255 }
    256 
    257 TEST_F(InstallShortcutTest, CreateAllShortcuts) {
    258   installer::CreateOrUpdateShortcuts(
    259       chrome_exe_, *product_, *prefs_, installer::CURRENT_USER,
    260       installer::INSTALL_SHORTCUT_CREATE_ALL);
    261   base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_);
    262   base::win::ValidateShortcut(user_quick_launch_shortcut_,
    263                               expected_properties_);
    264   base::win::ValidateShortcut(user_start_menu_shortcut_,
    265                               expected_start_menu_properties_);
    266 }
    267 
    268 TEST_F(InstallShortcutTest, CreateAllShortcutsSystemLevel) {
    269   installer::CreateOrUpdateShortcuts(
    270       chrome_exe_, *product_, *prefs_, installer::ALL_USERS,
    271       installer::INSTALL_SHORTCUT_CREATE_ALL);
    272   base::win::ValidateShortcut(system_desktop_shortcut_, expected_properties_);
    273   base::win::ValidateShortcut(system_quick_launch_shortcut_,
    274                               expected_properties_);
    275   base::win::ValidateShortcut(system_start_menu_shortcut_,
    276                               expected_start_menu_properties_);
    277 }
    278 
    279 TEST_F(InstallShortcutTest, CreateAllShortcutsAlternateDesktopName) {
    280   scoped_ptr<installer::MasterPreferences> prefs_alt_desktop(
    281       GetFakeMasterPrefs(false, false, true));
    282   installer::CreateOrUpdateShortcuts(
    283       chrome_exe_, *product_, *prefs_alt_desktop, installer::CURRENT_USER,
    284       installer::INSTALL_SHORTCUT_CREATE_ALL);
    285   base::win::ValidateShortcut(user_alternate_desktop_shortcut_,
    286                               expected_properties_);
    287   base::win::ValidateShortcut(user_quick_launch_shortcut_,
    288                               expected_properties_);
    289   base::win::ValidateShortcut(user_start_menu_shortcut_,
    290                               expected_start_menu_properties_);
    291 }
    292 
    293 TEST_F(InstallShortcutTest, CreateAllShortcutsButDesktopShortcut) {
    294   scoped_ptr<installer::MasterPreferences> prefs_no_desktop(
    295       GetFakeMasterPrefs(true, false, false));
    296   installer::CreateOrUpdateShortcuts(
    297       chrome_exe_, *product_, *prefs_no_desktop, installer::CURRENT_USER,
    298       installer::INSTALL_SHORTCUT_CREATE_ALL);
    299   ASSERT_FALSE(base::PathExists(user_desktop_shortcut_));
    300   base::win::ValidateShortcut(user_quick_launch_shortcut_,
    301                               expected_properties_);
    302   base::win::ValidateShortcut(user_start_menu_shortcut_,
    303                               expected_start_menu_properties_);
    304 }
    305 
    306 TEST_F(InstallShortcutTest, CreateAllShortcutsButQuickLaunchShortcut) {
    307   scoped_ptr<installer::MasterPreferences> prefs_no_ql(
    308       GetFakeMasterPrefs(false, true, false));
    309   installer::CreateOrUpdateShortcuts(
    310       chrome_exe_, *product_, *prefs_no_ql, installer::CURRENT_USER,
    311       installer::INSTALL_SHORTCUT_CREATE_ALL);
    312   base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_);
    313   ASSERT_FALSE(base::PathExists(user_quick_launch_shortcut_));
    314   base::win::ValidateShortcut(user_start_menu_shortcut_,
    315                               expected_start_menu_properties_);
    316 }
    317 
    318 TEST_F(InstallShortcutTest, ReplaceAll) {
    319   base::win::ShortcutProperties dummy_properties;
    320   base::FilePath dummy_target;
    321   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target));
    322   dummy_properties.set_target(dummy_target);
    323   dummy_properties.set_working_dir(fake_user_desktop_.path());
    324   dummy_properties.set_arguments(L"--dummy --args");
    325   dummy_properties.set_app_id(L"El.Dummiest");
    326 
    327   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    328                   user_desktop_shortcut_, dummy_properties,
    329                   base::win::SHORTCUT_CREATE_ALWAYS));
    330   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    331                   user_quick_launch_shortcut_, dummy_properties,
    332                   base::win::SHORTCUT_CREATE_ALWAYS));
    333   ASSERT_TRUE(base::CreateDirectory(user_start_menu_shortcut_.DirName()));
    334   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    335                   user_start_menu_shortcut_, dummy_properties,
    336                   base::win::SHORTCUT_CREATE_ALWAYS));
    337 
    338   installer::CreateOrUpdateShortcuts(
    339       chrome_exe_, *product_, *prefs_, installer::CURRENT_USER,
    340       installer::INSTALL_SHORTCUT_REPLACE_EXISTING);
    341   base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_);
    342   base::win::ValidateShortcut(user_quick_launch_shortcut_,
    343                               expected_properties_);
    344   base::win::ValidateShortcut(user_start_menu_shortcut_,
    345                               expected_start_menu_properties_);
    346 }
    347 
    348 TEST_F(InstallShortcutTest, ReplaceExisting) {
    349   base::win::ShortcutProperties dummy_properties;
    350   base::FilePath dummy_target;
    351   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target));
    352   dummy_properties.set_target(dummy_target);
    353   dummy_properties.set_working_dir(fake_user_desktop_.path());
    354   dummy_properties.set_arguments(L"--dummy --args");
    355   dummy_properties.set_app_id(L"El.Dummiest");
    356 
    357   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    358                   user_desktop_shortcut_, dummy_properties,
    359                   base::win::SHORTCUT_CREATE_ALWAYS));
    360   ASSERT_TRUE(base::CreateDirectory(user_start_menu_shortcut_.DirName()));
    361 
    362   installer::CreateOrUpdateShortcuts(
    363       chrome_exe_, *product_, *prefs_, installer::CURRENT_USER,
    364       installer::INSTALL_SHORTCUT_REPLACE_EXISTING);
    365   base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_);
    366   ASSERT_FALSE(base::PathExists(user_quick_launch_shortcut_));
    367   ASSERT_FALSE(base::PathExists(user_start_menu_shortcut_));
    368 }
    369 
    370 TEST_F(InstallShortcutTest, CreateIfNoSystemLevelAllSystemShortcutsExist) {
    371   base::win::ShortcutProperties dummy_properties;
    372   base::FilePath dummy_target;
    373   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target));
    374   dummy_properties.set_target(dummy_target);
    375 
    376   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    377                   system_desktop_shortcut_, dummy_properties,
    378                   base::win::SHORTCUT_CREATE_ALWAYS));
    379   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    380                   system_quick_launch_shortcut_, dummy_properties,
    381                   base::win::SHORTCUT_CREATE_ALWAYS));
    382   ASSERT_TRUE(base::CreateDirectory(
    383         system_start_menu_shortcut_.DirName()));
    384   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    385                   system_start_menu_shortcut_, dummy_properties,
    386                   base::win::SHORTCUT_CREATE_ALWAYS));
    387 
    388   installer::CreateOrUpdateShortcuts(
    389       chrome_exe_, *product_, *prefs_, installer::CURRENT_USER,
    390       installer::INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL);
    391   ASSERT_FALSE(base::PathExists(user_desktop_shortcut_));
    392   ASSERT_FALSE(base::PathExists(user_quick_launch_shortcut_));
    393   ASSERT_FALSE(base::PathExists(user_start_menu_shortcut_));
    394 }
    395 
    396 TEST_F(InstallShortcutTest, CreateIfNoSystemLevelNoSystemShortcutsExist) {
    397   installer::CreateOrUpdateShortcuts(
    398       chrome_exe_, *product_, *prefs_, installer::CURRENT_USER,
    399       installer::INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL);
    400   base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_);
    401   base::win::ValidateShortcut(user_quick_launch_shortcut_,
    402                               expected_properties_);
    403   base::win::ValidateShortcut(user_start_menu_shortcut_,
    404                               expected_start_menu_properties_);
    405 }
    406 
    407 TEST_F(InstallShortcutTest, CreateIfNoSystemLevelSomeSystemShortcutsExist) {
    408   base::win::ShortcutProperties dummy_properties;
    409   base::FilePath dummy_target;
    410   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target));
    411   dummy_properties.set_target(dummy_target);
    412 
    413   ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
    414                   system_desktop_shortcut_, dummy_properties,
    415                   base::win::SHORTCUT_CREATE_ALWAYS));
    416 
    417   installer::CreateOrUpdateShortcuts(
    418       chrome_exe_, *product_, *prefs_, installer::CURRENT_USER,
    419       installer::INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL);
    420   ASSERT_FALSE(base::PathExists(user_desktop_shortcut_));
    421   base::win::ValidateShortcut(user_quick_launch_shortcut_,
    422                               expected_properties_);
    423   base::win::ValidateShortcut(user_start_menu_shortcut_,
    424                               expected_start_menu_properties_);
    425 }
    426 
    427 TEST(EscapeXmlAttributeValueTest, EscapeCrazyValue) {
    428   string16 val(L"This has 'crazy' \"chars\" && < and > signs.");
    429   static const wchar_t kExpectedEscapedVal[] =
    430       L"This has &apos;crazy&apos; \"chars\" &amp;&amp; &lt; and > signs.";
    431   installer::EscapeXmlAttributeValueInSingleQuotes(&val);
    432   ASSERT_STREQ(kExpectedEscapedVal, val.c_str());
    433 }
    434 
    435 TEST(EscapeXmlAttributeValueTest, DontEscapeNormalValue) {
    436   string16 val(L"Google Chrome");
    437   static const wchar_t kExpectedEscapedVal[] = L"Google Chrome";
    438   installer::EscapeXmlAttributeValueInSingleQuotes(&val);
    439   ASSERT_STREQ(kExpectedEscapedVal, val.c_str());
    440 }
    441