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 33namespace { 34 35class 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(file_util::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 68class 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(dist_->GetAppShortCutName() + installer::kLnkExt); 121 string16 alternate_shortcut_name( 122 dist_->GetAlternateApplicationName() + installer::kLnkExt); 123 124 user_desktop_shortcut_ = 125 fake_user_desktop_.path().Append(shortcut_name); 126 user_quick_launch_shortcut_ = 127 fake_user_quick_launch_.path().Append(shortcut_name); 128 user_start_menu_shortcut_ = 129 fake_start_menu_.path().Append(dist_->GetAppShortCutName()) 130 .Append(shortcut_name); 131 system_desktop_shortcut_ = 132 fake_common_desktop_.path().Append(shortcut_name); 133 system_quick_launch_shortcut_ = 134 fake_default_user_quick_launch_.path().Append(shortcut_name); 135 system_start_menu_shortcut_ = 136 fake_common_start_menu_.path().Append(dist_->GetAppShortCutName()) 137 .Append(shortcut_name); 138 user_alternate_desktop_shortcut_ = 139 fake_user_desktop_.path().Append(alternate_shortcut_name); 140 } 141 142 virtual void TearDown() OVERRIDE { 143 // Try to unpin potentially pinned shortcuts (although pinning isn't tested, 144 // the call itself might still have pinned the Start Menu shortcuts). 145 base::win::TaskbarUnpinShortcutLink( 146 user_start_menu_shortcut_.value().c_str()); 147 base::win::TaskbarUnpinShortcutLink( 148 system_start_menu_shortcut_.value().c_str()); 149 CoUninitialize(); 150 } 151 152 installer::MasterPreferences* GetFakeMasterPrefs( 153 bool do_not_create_desktop_shortcut, 154 bool do_not_create_quick_launch_shortcut, 155 bool alternate_desktop_shortcut) { 156 const struct { 157 const char* pref_name; 158 bool is_desired; 159 } desired_prefs[] = { 160 { installer::master_preferences::kDoNotCreateDesktopShortcut, 161 do_not_create_desktop_shortcut }, 162 { installer::master_preferences::kDoNotCreateQuickLaunchShortcut, 163 do_not_create_quick_launch_shortcut }, 164 { installer::master_preferences::kAltShortcutText, 165 alternate_desktop_shortcut }, 166 }; 167 168 std::string master_prefs("{\"distribution\":{"); 169 for (size_t i = 0; i < arraysize(desired_prefs); ++i) { 170 master_prefs += (i == 0 ? "\"" : ",\""); 171 master_prefs += desired_prefs[i].pref_name; 172 master_prefs += "\":"; 173 master_prefs += desired_prefs[i].is_desired ? "true" : "false"; 174 } 175 master_prefs += "}}"; 176 177 return new installer::MasterPreferences(master_prefs); 178 } 179 180 base::win::ShortcutProperties expected_properties_; 181 base::win::ShortcutProperties expected_start_menu_properties_; 182 183 BrowserDistribution* dist_; 184 base::FilePath chrome_exe_; 185 scoped_ptr<installer::Product> product_; 186 scoped_ptr<installer::MasterPreferences> prefs_; 187 188 base::ScopedTempDir temp_dir_; 189 base::ScopedTempDir fake_user_desktop_; 190 base::ScopedTempDir fake_common_desktop_; 191 base::ScopedTempDir fake_user_quick_launch_; 192 base::ScopedTempDir fake_default_user_quick_launch_; 193 base::ScopedTempDir fake_start_menu_; 194 base::ScopedTempDir fake_common_start_menu_; 195 scoped_ptr<base::ScopedPathOverride> user_desktop_override_; 196 scoped_ptr<base::ScopedPathOverride> common_desktop_override_; 197 scoped_ptr<base::ScopedPathOverride> user_quick_launch_override_; 198 scoped_ptr<base::ScopedPathOverride> default_user_quick_launch_override_; 199 scoped_ptr<base::ScopedPathOverride> start_menu_override_; 200 scoped_ptr<base::ScopedPathOverride> common_start_menu_override_; 201 202 base::FilePath user_desktop_shortcut_; 203 base::FilePath user_quick_launch_shortcut_; 204 base::FilePath user_start_menu_shortcut_; 205 base::FilePath system_desktop_shortcut_; 206 base::FilePath system_quick_launch_shortcut_; 207 base::FilePath system_start_menu_shortcut_; 208 base::FilePath user_alternate_desktop_shortcut_; 209}; 210 211} // namespace 212 213// Test that VisualElementsManifest.xml is not created when VisualElements are 214// not present. 215TEST_F(CreateVisualElementsManifestTest, VisualElementsManifestNotCreated) { 216 ASSERT_TRUE( 217 installer::CreateVisualElementsManifest(test_dir_.path(), version_)); 218 ASSERT_FALSE(base::PathExists(manifest_path_)); 219} 220 221// Test that VisualElementsManifest.xml is created with the correct content when 222// VisualElements are present. 223TEST_F(CreateVisualElementsManifestTest, VisualElementsManifestCreated) { 224 ASSERT_TRUE(file_util::CreateDirectory( 225 version_dir_.Append(installer::kVisualElements))); 226 ASSERT_TRUE( 227 installer::CreateVisualElementsManifest(test_dir_.path(), version_)); 228 ASSERT_TRUE(base::PathExists(manifest_path_)); 229 230 std::string read_manifest; 231 ASSERT_TRUE(file_util::ReadFileToString(manifest_path_, &read_manifest)); 232 233 static const char kExpectedManifest[] = 234 "<Application>\r\n" 235 " <VisualElements\r\n" 236 " DisplayName='Google Chrome'\r\n" 237 " Logo='0.0.0.0\\VisualElements\\Logo.png'\r\n" 238 " SmallLogo='0.0.0.0\\VisualElements\\SmallLogo.png'\r\n" 239 " ForegroundText='light'\r\n" 240 " BackgroundColor='white'>\r\n" 241 " <DefaultTile ShowName='allLogos'/>\r\n" 242 " <SplashScreen Image='0.0.0.0\\VisualElements\\splash-620x300.png'/>" 243 "\r\n" 244 " </VisualElements>\r\n" 245 "</Application>"; 246 247 ASSERT_STREQ(kExpectedManifest, read_manifest.c_str()); 248} 249 250TEST_F(InstallShortcutTest, CreateAllShortcuts) { 251 installer::CreateOrUpdateShortcuts( 252 chrome_exe_, *product_, *prefs_, installer::CURRENT_USER, 253 installer::INSTALL_SHORTCUT_CREATE_ALL); 254 base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_); 255 base::win::ValidateShortcut(user_quick_launch_shortcut_, 256 expected_properties_); 257 base::win::ValidateShortcut(user_start_menu_shortcut_, 258 expected_start_menu_properties_); 259} 260 261TEST_F(InstallShortcutTest, CreateAllShortcutsSystemLevel) { 262 installer::CreateOrUpdateShortcuts( 263 chrome_exe_, *product_, *prefs_, installer::ALL_USERS, 264 installer::INSTALL_SHORTCUT_CREATE_ALL); 265 base::win::ValidateShortcut(system_desktop_shortcut_, expected_properties_); 266 base::win::ValidateShortcut(system_quick_launch_shortcut_, 267 expected_properties_); 268 base::win::ValidateShortcut(system_start_menu_shortcut_, 269 expected_start_menu_properties_); 270} 271 272TEST_F(InstallShortcutTest, CreateAllShortcutsAlternateDesktopName) { 273 scoped_ptr<installer::MasterPreferences> prefs_alt_desktop( 274 GetFakeMasterPrefs(false, false, true)); 275 installer::CreateOrUpdateShortcuts( 276 chrome_exe_, *product_, *prefs_alt_desktop, installer::CURRENT_USER, 277 installer::INSTALL_SHORTCUT_CREATE_ALL); 278 base::win::ValidateShortcut(user_alternate_desktop_shortcut_, 279 expected_properties_); 280 base::win::ValidateShortcut(user_quick_launch_shortcut_, 281 expected_properties_); 282 base::win::ValidateShortcut(user_start_menu_shortcut_, 283 expected_start_menu_properties_); 284} 285 286TEST_F(InstallShortcutTest, CreateAllShortcutsButDesktopShortcut) { 287 scoped_ptr<installer::MasterPreferences> prefs_no_desktop( 288 GetFakeMasterPrefs(true, false, false)); 289 installer::CreateOrUpdateShortcuts( 290 chrome_exe_, *product_, *prefs_no_desktop, installer::CURRENT_USER, 291 installer::INSTALL_SHORTCUT_CREATE_ALL); 292 ASSERT_FALSE(base::PathExists(user_desktop_shortcut_)); 293 base::win::ValidateShortcut(user_quick_launch_shortcut_, 294 expected_properties_); 295 base::win::ValidateShortcut(user_start_menu_shortcut_, 296 expected_start_menu_properties_); 297} 298 299TEST_F(InstallShortcutTest, CreateAllShortcutsButQuickLaunchShortcut) { 300 scoped_ptr<installer::MasterPreferences> prefs_no_ql( 301 GetFakeMasterPrefs(false, true, false)); 302 installer::CreateOrUpdateShortcuts( 303 chrome_exe_, *product_, *prefs_no_ql, installer::CURRENT_USER, 304 installer::INSTALL_SHORTCUT_CREATE_ALL); 305 base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_); 306 ASSERT_FALSE(base::PathExists(user_quick_launch_shortcut_)); 307 base::win::ValidateShortcut(user_start_menu_shortcut_, 308 expected_start_menu_properties_); 309} 310 311TEST_F(InstallShortcutTest, ReplaceAll) { 312 base::win::ShortcutProperties dummy_properties; 313 base::FilePath dummy_target; 314 ASSERT_TRUE( 315 file_util::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target)); 316 dummy_properties.set_target(dummy_target); 317 dummy_properties.set_working_dir(fake_user_desktop_.path()); 318 dummy_properties.set_arguments(L"--dummy --args"); 319 dummy_properties.set_app_id(L"El.Dummiest"); 320 321 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 322 user_desktop_shortcut_, dummy_properties, 323 base::win::SHORTCUT_CREATE_ALWAYS)); 324 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 325 user_quick_launch_shortcut_, dummy_properties, 326 base::win::SHORTCUT_CREATE_ALWAYS)); 327 ASSERT_TRUE(file_util::CreateDirectory(user_start_menu_shortcut_.DirName())); 328 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 329 user_start_menu_shortcut_, dummy_properties, 330 base::win::SHORTCUT_CREATE_ALWAYS)); 331 332 installer::CreateOrUpdateShortcuts( 333 chrome_exe_, *product_, *prefs_, installer::CURRENT_USER, 334 installer::INSTALL_SHORTCUT_REPLACE_EXISTING); 335 base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_); 336 base::win::ValidateShortcut(user_quick_launch_shortcut_, 337 expected_properties_); 338 base::win::ValidateShortcut(user_start_menu_shortcut_, 339 expected_start_menu_properties_); 340} 341 342TEST_F(InstallShortcutTest, ReplaceExisting) { 343 base::win::ShortcutProperties dummy_properties; 344 base::FilePath dummy_target; 345 ASSERT_TRUE( 346 file_util::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target)); 347 dummy_properties.set_target(dummy_target); 348 dummy_properties.set_working_dir(fake_user_desktop_.path()); 349 dummy_properties.set_arguments(L"--dummy --args"); 350 dummy_properties.set_app_id(L"El.Dummiest"); 351 352 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 353 user_desktop_shortcut_, dummy_properties, 354 base::win::SHORTCUT_CREATE_ALWAYS)); 355 ASSERT_TRUE(file_util::CreateDirectory(user_start_menu_shortcut_.DirName())); 356 357 installer::CreateOrUpdateShortcuts( 358 chrome_exe_, *product_, *prefs_, installer::CURRENT_USER, 359 installer::INSTALL_SHORTCUT_REPLACE_EXISTING); 360 base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_); 361 ASSERT_FALSE(base::PathExists(user_quick_launch_shortcut_)); 362 ASSERT_FALSE(base::PathExists(user_start_menu_shortcut_)); 363} 364 365TEST_F(InstallShortcutTest, CreateIfNoSystemLevelAllSystemShortcutsExist) { 366 base::win::ShortcutProperties dummy_properties; 367 base::FilePath dummy_target; 368 ASSERT_TRUE( 369 file_util::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target)); 370 dummy_properties.set_target(dummy_target); 371 372 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 373 system_desktop_shortcut_, dummy_properties, 374 base::win::SHORTCUT_CREATE_ALWAYS)); 375 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 376 system_quick_launch_shortcut_, dummy_properties, 377 base::win::SHORTCUT_CREATE_ALWAYS)); 378 ASSERT_TRUE(file_util::CreateDirectory( 379 system_start_menu_shortcut_.DirName())); 380 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 381 system_start_menu_shortcut_, dummy_properties, 382 base::win::SHORTCUT_CREATE_ALWAYS)); 383 384 installer::CreateOrUpdateShortcuts( 385 chrome_exe_, *product_, *prefs_, installer::CURRENT_USER, 386 installer::INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL); 387 ASSERT_FALSE(base::PathExists(user_desktop_shortcut_)); 388 ASSERT_FALSE(base::PathExists(user_quick_launch_shortcut_)); 389 ASSERT_FALSE(base::PathExists(user_start_menu_shortcut_)); 390} 391 392TEST_F(InstallShortcutTest, CreateIfNoSystemLevelNoSystemShortcutsExist) { 393 installer::CreateOrUpdateShortcuts( 394 chrome_exe_, *product_, *prefs_, installer::CURRENT_USER, 395 installer::INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL); 396 base::win::ValidateShortcut(user_desktop_shortcut_, expected_properties_); 397 base::win::ValidateShortcut(user_quick_launch_shortcut_, 398 expected_properties_); 399 base::win::ValidateShortcut(user_start_menu_shortcut_, 400 expected_start_menu_properties_); 401} 402 403TEST_F(InstallShortcutTest, CreateIfNoSystemLevelSomeSystemShortcutsExist) { 404 base::win::ShortcutProperties dummy_properties; 405 base::FilePath dummy_target; 406 ASSERT_TRUE( 407 file_util::CreateTemporaryFileInDir(temp_dir_.path(), &dummy_target)); 408 dummy_properties.set_target(dummy_target); 409 410 ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink( 411 system_desktop_shortcut_, dummy_properties, 412 base::win::SHORTCUT_CREATE_ALWAYS)); 413 414 installer::CreateOrUpdateShortcuts( 415 chrome_exe_, *product_, *prefs_, installer::CURRENT_USER, 416 installer::INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL); 417 ASSERT_FALSE(base::PathExists(user_desktop_shortcut_)); 418 base::win::ValidateShortcut(user_quick_launch_shortcut_, 419 expected_properties_); 420 base::win::ValidateShortcut(user_start_menu_shortcut_, 421 expected_start_menu_properties_); 422} 423 424TEST(EscapeXmlAttributeValueTest, EscapeCrazyValue) { 425 string16 val(L"This has 'crazy' \"chars\" && < and > signs."); 426 static const wchar_t kExpectedEscapedVal[] = 427 L"This has 'crazy' \"chars\" && < and > signs."; 428 installer::EscapeXmlAttributeValueInSingleQuotes(&val); 429 ASSERT_STREQ(kExpectedEscapedVal, val.c_str()); 430} 431 432TEST(EscapeXmlAttributeValueTest, DontEscapeNormalValue) { 433 string16 val(L"Google Chrome"); 434 static const wchar_t kExpectedEscapedVal[] = L"Google Chrome"; 435 installer::EscapeXmlAttributeValueInSingleQuotes(&val); 436 ASSERT_STREQ(kExpectedEscapedVal, val.c_str()); 437} 438