shell_util_unittest.cc revision c2db58bd994c04d98e4ee2cd7565b71548655fe3
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 "chrome/installer/util/shell_util.h" 6 7#include <vector> 8 9#include "base/base_paths.h" 10#include "base/base_paths_win.h" 11#include "base/file_util.h" 12#include "base/files/file_enumerator.h" 13#include "base/files/scoped_temp_dir.h" 14#include "base/md5.h" 15#include "base/memory/scoped_ptr.h" 16#include "base/strings/string16.h" 17#include "base/strings/string_util.h" 18#include "base/test/scoped_path_override.h" 19#include "base/test/test_shortcut_win.h" 20#include "base/win/shortcut.h" 21#include "base/win/windows_version.h" 22#include "chrome/installer/util/browser_distribution.h" 23#include "chrome/installer/util/product.h" 24#include "chrome/installer/util/util_constants.h" 25#include "testing/gtest/include/gtest/gtest.h" 26 27namespace { 28 29const wchar_t kManganeseExe[] = L"manganese.exe"; 30 31// TODO(huangs): Separate this into generic shortcut tests and Chrome-specific 32// tests. Specifically, we should not overly rely on getting shortcut properties 33// from product_->AddDefaultShortcutProperties(). 34class ShellUtilShortcutTest : public testing::Test { 35 protected: 36 ShellUtilShortcutTest() : test_properties_(ShellUtil::CURRENT_USER) {} 37 38 virtual void SetUp() OVERRIDE { 39 dist_ = BrowserDistribution::GetDistribution(); 40 ASSERT_TRUE(dist_ != NULL); 41 product_.reset(new installer::Product(dist_)); 42 43 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 44 chrome_exe_ = temp_dir_.path().Append(installer::kChromeExe); 45 EXPECT_EQ(0, file_util::WriteFile(chrome_exe_, "", 0)); 46 47 manganese_exe_ = temp_dir_.path().Append(kManganeseExe); 48 EXPECT_EQ(0, file_util::WriteFile(manganese_exe_, "", 0)); 49 50 ASSERT_TRUE(fake_user_desktop_.CreateUniqueTempDir()); 51 ASSERT_TRUE(fake_common_desktop_.CreateUniqueTempDir()); 52 ASSERT_TRUE(fake_user_quick_launch_.CreateUniqueTempDir()); 53 ASSERT_TRUE(fake_default_user_quick_launch_.CreateUniqueTempDir()); 54 ASSERT_TRUE(fake_start_menu_.CreateUniqueTempDir()); 55 ASSERT_TRUE(fake_common_start_menu_.CreateUniqueTempDir()); 56 user_desktop_override_.reset( 57 new base::ScopedPathOverride(base::DIR_USER_DESKTOP, 58 fake_user_desktop_.path())); 59 common_desktop_override_.reset( 60 new base::ScopedPathOverride(base::DIR_COMMON_DESKTOP, 61 fake_common_desktop_.path())); 62 user_quick_launch_override_.reset( 63 new base::ScopedPathOverride(base::DIR_USER_QUICK_LAUNCH, 64 fake_user_quick_launch_.path())); 65 default_user_quick_launch_override_.reset( 66 new base::ScopedPathOverride(base::DIR_DEFAULT_USER_QUICK_LAUNCH, 67 fake_default_user_quick_launch_.path())); 68 start_menu_override_.reset( 69 new base::ScopedPathOverride(base::DIR_START_MENU, 70 fake_start_menu_.path())); 71 common_start_menu_override_.reset( 72 new base::ScopedPathOverride(base::DIR_COMMON_START_MENU, 73 fake_common_start_menu_.path())); 74 75 base::FilePath icon_path; 76 file_util::CreateTemporaryFileInDir(temp_dir_.path(), &icon_path); 77 test_properties_.set_target(chrome_exe_); 78 test_properties_.set_arguments(L"--test --chrome"); 79 test_properties_.set_description(L"Makes polar bears dance."); 80 test_properties_.set_icon(icon_path, 0); 81 test_properties_.set_app_id(L"Polar.Bear"); 82 test_properties_.set_dual_mode(true); 83 } 84 85 // Validates that the shortcut at |location| matches |properties| (and 86 // implicit default properties) for |dist|. 87 // Note: This method doesn't verify the |pin_to_taskbar| property as it 88 // implies real (non-mocked) state which is flaky to test. 89 void ValidateChromeShortcut( 90 ShellUtil::ShortcutLocation location, 91 BrowserDistribution* dist, 92 const ShellUtil::ShortcutProperties& properties) { 93 base::FilePath expected_path; 94 switch (location) { 95 case ShellUtil::SHORTCUT_LOCATION_DESKTOP: 96 expected_path = (properties.level == ShellUtil::CURRENT_USER) ? 97 fake_user_desktop_.path() : fake_common_desktop_.path(); 98 break; 99 case ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH: 100 expected_path = (properties.level == ShellUtil::CURRENT_USER) ? 101 fake_user_quick_launch_.path() : 102 fake_default_user_quick_launch_.path(); 103 break; 104 case ShellUtil::SHORTCUT_LOCATION_START_MENU: 105 expected_path = (properties.level == ShellUtil::CURRENT_USER) ? 106 fake_start_menu_.path() : fake_common_start_menu_.path(); 107 expected_path = expected_path.Append(dist_->GetAppShortCutName()); 108 break; 109 default: 110 ADD_FAILURE() << "Unknown location"; 111 return; 112 } 113 114 string16 shortcut_name; 115 if (properties.has_shortcut_name()) 116 shortcut_name = properties.shortcut_name; 117 else 118 shortcut_name = dist_->GetAppShortCutName(); 119 shortcut_name.append(installer::kLnkExt); 120 expected_path = expected_path.Append(shortcut_name); 121 122 base::win::ShortcutProperties expected_properties; 123 if (properties.has_target()) { 124 expected_properties.set_target(properties.target); 125 expected_properties.set_working_dir(properties.target.DirName()); 126 } else { 127 expected_properties.set_target(chrome_exe_); 128 expected_properties.set_working_dir(chrome_exe_.DirName()); 129 } 130 131 if (properties.has_arguments()) 132 expected_properties.set_arguments(properties.arguments); 133 else 134 expected_properties.set_arguments(string16()); 135 136 if (properties.has_description()) 137 expected_properties.set_description(properties.description); 138 else 139 expected_properties.set_description(dist->GetAppDescription()); 140 141 if (properties.has_icon()) { 142 expected_properties.set_icon(properties.icon, 0); 143 } else { 144 int icon_index = dist->GetIconIndex(); 145 expected_properties.set_icon(chrome_exe_, icon_index); 146 } 147 148 if (properties.has_app_id()) { 149 expected_properties.set_app_id(properties.app_id); 150 } else { 151 // Tests are always seen as user-level installs in ShellUtil. 152 expected_properties.set_app_id(ShellUtil::GetBrowserModelId(dist, true)); 153 } 154 155 if (properties.has_dual_mode()) 156 expected_properties.set_dual_mode(properties.dual_mode); 157 else 158 expected_properties.set_dual_mode(false); 159 160 base::win::ValidateShortcut(expected_path, expected_properties); 161 } 162 163 BrowserDistribution* dist_; 164 scoped_ptr<installer::Product> product_; 165 166 // A ShellUtil::ShortcutProperties object with common properties set already. 167 ShellUtil::ShortcutProperties test_properties_; 168 169 base::ScopedTempDir temp_dir_; 170 base::ScopedTempDir fake_user_desktop_; 171 base::ScopedTempDir fake_common_desktop_; 172 base::ScopedTempDir fake_user_quick_launch_; 173 base::ScopedTempDir fake_default_user_quick_launch_; 174 base::ScopedTempDir fake_start_menu_; 175 base::ScopedTempDir fake_common_start_menu_; 176 scoped_ptr<base::ScopedPathOverride> user_desktop_override_; 177 scoped_ptr<base::ScopedPathOverride> common_desktop_override_; 178 scoped_ptr<base::ScopedPathOverride> user_quick_launch_override_; 179 scoped_ptr<base::ScopedPathOverride> default_user_quick_launch_override_; 180 scoped_ptr<base::ScopedPathOverride> start_menu_override_; 181 scoped_ptr<base::ScopedPathOverride> common_start_menu_override_; 182 183 base::FilePath chrome_exe_; 184 base::FilePath manganese_exe_; 185}; 186 187} // namespace 188 189TEST_F(ShellUtilShortcutTest, GetShortcutPath) { 190 base::FilePath path; 191 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 192 ShellUtil::CURRENT_USER, &path); 193 EXPECT_EQ(fake_user_desktop_.path(), path); 194 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 195 ShellUtil::SYSTEM_LEVEL, &path); 196 EXPECT_EQ(fake_common_desktop_.path(), path); 197 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, 198 ShellUtil::CURRENT_USER, &path); 199 EXPECT_EQ(fake_user_quick_launch_.path(), path); 200 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, 201 ShellUtil::SYSTEM_LEVEL, &path); 202 EXPECT_EQ(fake_default_user_quick_launch_.path(), path); 203 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, 204 ShellUtil::CURRENT_USER, &path); 205 EXPECT_EQ(fake_start_menu_.path().Append(dist_->GetAppShortCutName()), path); 206 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, 207 ShellUtil::SYSTEM_LEVEL, &path); 208 EXPECT_EQ(fake_common_start_menu_.path().Append(dist_->GetAppShortCutName()), 209 path); 210} 211 212TEST_F(ShellUtilShortcutTest, CreateChromeExeShortcutWithDefaultProperties) { 213 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); 214 product_->AddDefaultShortcutProperties(chrome_exe_, &properties); 215 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 216 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, properties, 217 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 218 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 219 properties); 220} 221 222TEST_F(ShellUtilShortcutTest, CreateStartMenuShortcutWithAllProperties) { 223 test_properties_.set_shortcut_name(L"Bobo le shortcut"); 224 test_properties_.level = ShellUtil::SYSTEM_LEVEL; 225 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 226 ShellUtil::SHORTCUT_LOCATION_START_MENU, 227 dist_, test_properties_, 228 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 229 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, 230 test_properties_); 231} 232 233TEST_F(ShellUtilShortcutTest, ReplaceSystemLevelQuickLaunchShortcut) { 234 test_properties_.level = ShellUtil::SYSTEM_LEVEL; 235 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 236 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, 237 dist_, test_properties_, 238 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 239 240 ShellUtil::ShortcutProperties new_properties(ShellUtil::SYSTEM_LEVEL); 241 product_->AddDefaultShortcutProperties(chrome_exe_, &new_properties); 242 new_properties.set_description(L"New description"); 243 new_properties.set_arguments(L"--new-arguments"); 244 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 245 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, 246 dist_, new_properties, 247 ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING)); 248 249 // Expect the properties set in |new_properties| to be set as above and 250 // properties that don't have a default value to be set back to their default 251 // (as validated in ValidateChromeShortcut()) or unset if they don't . 252 ShellUtil::ShortcutProperties expected_properties(new_properties); 253 expected_properties.set_dual_mode(false); 254 255 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, 256 expected_properties); 257} 258 259TEST_F(ShellUtilShortcutTest, UpdateQuickLaunchShortcutArguments) { 260 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 261 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, 262 dist_, test_properties_, 263 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 264 265 // Only changing one property, don't need all the defaults. 266 ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); 267 updated_properties.set_arguments(L"--updated --arguments"); 268 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 269 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, 270 dist_, updated_properties, 271 ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING)); 272 273 // Expect the properties set in |updated_properties| to be set as above and 274 // all other properties to remain unchanged. 275 ShellUtil::ShortcutProperties expected_properties(test_properties_); 276 expected_properties.set_arguments(updated_properties.arguments); 277 278 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, 279 expected_properties); 280} 281 282TEST_F(ShellUtilShortcutTest, UpdateAddDualModeToStartMenuShortcut) { 283 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); 284 product_->AddDefaultShortcutProperties(chrome_exe_, &properties); 285 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 286 ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, properties, 287 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 288 289 ShellUtil::ShortcutProperties added_properties(ShellUtil::CURRENT_USER); 290 added_properties.set_dual_mode(true); 291 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 292 ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, 293 added_properties, ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING)); 294 295 ShellUtil::ShortcutProperties expected_properties(properties); 296 expected_properties.set_dual_mode(true); 297 298 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, 299 expected_properties); 300} 301 302TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevel) { 303 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 304 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 305 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL)); 306 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 307 test_properties_); 308} 309 310TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelWithSystemLevelPresent) { 311 string16 shortcut_name(dist_->GetAppShortCutName() + installer::kLnkExt); 312 313 test_properties_.level = ShellUtil::SYSTEM_LEVEL; 314 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 315 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 316 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 317 ASSERT_TRUE(base::PathExists( 318 fake_common_desktop_.path().Append(shortcut_name))); 319 320 test_properties_.level = ShellUtil::CURRENT_USER; 321 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 322 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 323 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL)); 324 ASSERT_FALSE(base::PathExists( 325 fake_user_desktop_.path().Append(shortcut_name))); 326} 327 328TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelStartMenu) { 329 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 330 ShellUtil::SHORTCUT_LOCATION_START_MENU, 331 dist_, test_properties_, 332 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL)); 333 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, 334 test_properties_); 335} 336 337TEST_F(ShellUtilShortcutTest, CreateAlwaysUserWithSystemLevelPresent) { 338 string16 shortcut_name(dist_->GetAppShortCutName() + installer::kLnkExt); 339 340 test_properties_.level = ShellUtil::SYSTEM_LEVEL; 341 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 342 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 343 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 344 ASSERT_TRUE(base::PathExists( 345 fake_common_desktop_.path().Append(shortcut_name))); 346 347 test_properties_.level = ShellUtil::CURRENT_USER; 348 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 349 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 350 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 351 ASSERT_TRUE(base::PathExists( 352 fake_user_desktop_.path().Append(shortcut_name))); 353} 354 355TEST_F(ShellUtilShortcutTest, RemoveChromeShortcut) { 356 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 357 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 358 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 359 360 string16 shortcut_name(dist_->GetAppShortCutName() + installer::kLnkExt); 361 base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name)); 362 ASSERT_TRUE(base::PathExists(shortcut_path)); 363 364 ASSERT_TRUE(ShellUtil::RemoveShortcuts( 365 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, 366 chrome_exe_)); 367 ASSERT_FALSE(base::PathExists(shortcut_path)); 368 ASSERT_TRUE(base::PathExists(shortcut_path.DirName())); 369} 370 371TEST_F(ShellUtilShortcutTest, RemoveSystemLevelChromeShortcut) { 372 test_properties_.level = ShellUtil::SYSTEM_LEVEL; 373 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 374 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 375 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 376 377 string16 shortcut_name(dist_->GetAppShortCutName() + installer::kLnkExt); 378 base::FilePath shortcut_path( 379 fake_common_desktop_.path().Append(shortcut_name)); 380 ASSERT_TRUE(base::PathExists(shortcut_path)); 381 382 ASSERT_TRUE(ShellUtil::RemoveShortcuts( 383 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL, 384 chrome_exe_)); 385 ASSERT_FALSE(base::PathExists(shortcut_path)); 386 ASSERT_TRUE(base::PathExists(shortcut_path.DirName())); 387} 388 389TEST_F(ShellUtilShortcutTest, RemoveMultipleChromeShortcuts) { 390 const wchar_t kShortcutName1[] = L"Chrome 1"; 391 const wchar_t kShortcutName2[] = L"Chrome 2"; 392 393 test_properties_.set_shortcut_name(kShortcutName1); 394 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 395 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 396 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 397 string16 shortcut1_name( 398 string16(kShortcutName1).append(installer::kLnkExt)); 399 base::FilePath shortcut1_path( 400 fake_user_desktop_.path().Append(shortcut1_name)); 401 ASSERT_TRUE(base::PathExists(shortcut1_path)); 402 403 test_properties_.set_shortcut_name(kShortcutName2); 404 test_properties_.set_arguments(L"--profile-directory=\"Profile 2\""); 405 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 406 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 407 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 408 string16 shortcut2_name(string16(kShortcutName2).append(installer::kLnkExt)); 409 base::FilePath shortcut2_path( 410 fake_user_desktop_.path().Append(shortcut2_name)); 411 ASSERT_TRUE(base::PathExists(shortcut2_path)); 412 413 ASSERT_TRUE(ShellUtil::RemoveShortcuts( 414 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, 415 chrome_exe_)); 416 ASSERT_FALSE(base::PathExists(shortcut1_path)); 417 ASSERT_FALSE(base::PathExists(shortcut2_path)); 418 ASSERT_TRUE(base::PathExists(shortcut1_path.DirName())); 419} 420 421TEST_F(ShellUtilShortcutTest, UpdateChromeShortcut) { 422 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 423 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 424 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 425 426 string16 shortcut_name(dist_->GetAppShortCutName() + installer::kLnkExt); 427 base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name)); 428 ASSERT_TRUE(base::PathExists(shortcut_path)); 429 430 base::FilePath new_exe = temp_dir_.path().Append(kManganeseExe); 431 ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); 432 updated_properties.set_target(new_exe); 433 434 ASSERT_TRUE(ShellUtil::UpdateShortcuts( 435 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, 436 chrome_exe_, updated_properties)); 437 438 ShellUtil::ShortcutProperties expected_properties(test_properties_); 439 expected_properties.set_target(new_exe); 440 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 441 expected_properties); 442} 443 444TEST_F(ShellUtilShortcutTest, UpdateSystemLevelChromeShortcut) { 445 test_properties_.level = ShellUtil::SYSTEM_LEVEL; 446 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 447 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 448 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 449 450 string16 shortcut_name(dist_->GetAppShortCutName() + installer::kLnkExt); 451 base::FilePath shortcut_path( 452 fake_common_desktop_.path().Append(shortcut_name)); 453 ASSERT_TRUE(base::PathExists(shortcut_path)); 454 455 base::FilePath new_exe = temp_dir_.path().Append(kManganeseExe); 456 ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); 457 updated_properties.set_target(new_exe); 458 459 ASSERT_TRUE(ShellUtil::UpdateShortcuts( 460 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL, 461 chrome_exe_, updated_properties)); 462 463 ShellUtil::ShortcutProperties expected_properties(test_properties_); 464 expected_properties.set_target(new_exe); 465 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 466 expected_properties); 467} 468 469TEST_F(ShellUtilShortcutTest, UpdateMultipleChromeShortcuts) { 470 const wchar_t kShortcutName1[] = L"Chrome 1"; 471 const wchar_t kShortcutName2[] = L"Chrome 2"; 472 473 // Setup shortcut 1. 474 test_properties_.set_shortcut_name(kShortcutName1); 475 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 476 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 477 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 478 string16 shortcut1_name( 479 string16(kShortcutName1).append(installer::kLnkExt)); 480 base::FilePath shortcut1_path( 481 fake_user_desktop_.path().Append(shortcut1_name)); 482 ShellUtil::ShortcutProperties expected_properties1(test_properties_); 483 484 // Setup shortcut 2, which also has arguments. 485 string16 shortcut2_args = L"--profile-directory=\"Profile 2\""; 486 test_properties_.set_shortcut_name(kShortcutName2); 487 test_properties_.set_arguments(shortcut2_args); 488 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 489 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 490 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 491 string16 shortcut2_name(string16(kShortcutName2).append(installer::kLnkExt)); 492 base::FilePath shortcut2_path( 493 fake_user_desktop_.path().Append(shortcut2_name)); 494 ASSERT_TRUE(base::PathExists(shortcut2_path)); 495 ShellUtil::ShortcutProperties expected_properties2(test_properties_); 496 497 // Update shortcuts: target "manganese.exe" instead of "chrome.exe". 498 base::FilePath new_exe = temp_dir_.path().Append(kManganeseExe); 499 ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); 500 updated_properties.set_target(new_exe); 501 ASSERT_TRUE(ShellUtil::UpdateShortcuts( 502 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, 503 chrome_exe_, updated_properties)); 504 505 // Verify shortcut 1. 506 expected_properties1.set_target(new_exe); 507 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 508 expected_properties1); 509 510 // Verify shortcut 2. 511 expected_properties2.set_target(new_exe); 512 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, 513 expected_properties2); 514} 515 516TEST_F(ShellUtilShortcutTest, CreateMultipleStartMenuShortcutsAndRemoveFolder) { 517 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 518 ShellUtil::SHORTCUT_LOCATION_START_MENU, 519 dist_, test_properties_, 520 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 521 test_properties_.set_shortcut_name(L"A second shortcut"); 522 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 523 ShellUtil::SHORTCUT_LOCATION_START_MENU, 524 dist_, test_properties_, 525 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 526 527 base::FilePath shortcut_folder( 528 fake_start_menu_.path().Append(dist_->GetAppShortCutName())); 529 base::FileEnumerator file_counter(shortcut_folder, false, 530 base::FileEnumerator::FILES); 531 int count = 0; 532 while (!file_counter.Next().empty()) 533 ++count; 534 EXPECT_EQ(2, count); 535 536 ASSERT_TRUE(base::PathExists(shortcut_folder)); 537 ASSERT_TRUE(ShellUtil::RemoveShortcuts( 538 ShellUtil::SHORTCUT_LOCATION_START_MENU, dist_, ShellUtil::CURRENT_USER, 539 chrome_exe_)); 540 ASSERT_FALSE(base::PathExists(shortcut_folder)); 541} 542 543TEST_F(ShellUtilShortcutTest, DontRemoveChromeShortcutIfPointsToAnotherChrome) { 544 base::ScopedTempDir other_exe_dir; 545 ASSERT_TRUE(other_exe_dir.CreateUniqueTempDir()); 546 base::FilePath other_chrome_exe = 547 other_exe_dir.path().Append(installer::kChromeExe); 548 EXPECT_EQ(0, file_util::WriteFile(other_chrome_exe, "", 0)); 549 550 test_properties_.set_target(other_chrome_exe); 551 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( 552 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, 553 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); 554 555 string16 shortcut_name(dist_->GetAppShortCutName() + installer::kLnkExt); 556 base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name)); 557 ASSERT_TRUE(base::PathExists(shortcut_path)); 558 559 // The shortcut shouldn't be removed as it was installed pointing to 560 // |other_chrome_exe| and RemoveChromeShortcut() is being told that the 561 // removed shortcut should point to |chrome_exe_|. 562 ASSERT_TRUE(ShellUtil::RemoveShortcuts( 563 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, 564 chrome_exe_)); 565 ASSERT_TRUE(base::PathExists(shortcut_path)); 566 ASSERT_TRUE(base::PathExists(shortcut_path.DirName())); 567} 568 569TEST(ShellUtilTest, BuildAppModelIdBasic) { 570 std::vector<string16> components; 571 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 572 const string16 base_app_id(dist->GetBaseAppId()); 573 components.push_back(base_app_id); 574 ASSERT_EQ(base_app_id, ShellUtil::BuildAppModelId(components)); 575} 576 577TEST(ShellUtilTest, BuildAppModelIdManySmall) { 578 std::vector<string16> components; 579 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 580 const string16 suffixed_app_id(dist->GetBaseAppId().append(L".gab")); 581 components.push_back(suffixed_app_id); 582 components.push_back(L"Default"); 583 components.push_back(L"Test"); 584 ASSERT_EQ(suffixed_app_id + L".Default.Test", 585 ShellUtil::BuildAppModelId(components)); 586} 587 588TEST(ShellUtilTest, BuildAppModelIdLongUsernameNormalProfile) { 589 std::vector<string16> components; 590 const string16 long_appname( 591 L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_" 592 L"that_goes_over_64_characters"); 593 components.push_back(long_appname); 594 components.push_back(L"Default"); 595 ASSERT_EQ(L"Chrome.a_user_wer_64_characters.Default", 596 ShellUtil::BuildAppModelId(components)); 597} 598 599TEST(ShellUtilTest, BuildAppModelIdLongEverything) { 600 std::vector<string16> components; 601 const string16 long_appname( 602 L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_" 603 L"that_goes_over_64_characters"); 604 components.push_back(long_appname); 605 components.push_back( 606 L"A_crazy_profile_name_not_even_sure_whether_that_is_possible"); 607 const string16 constructed_app_id(ShellUtil::BuildAppModelId(components)); 608 ASSERT_LE(constructed_app_id.length(), installer::kMaxAppModelIdLength); 609 ASSERT_EQ(L"Chrome.a_user_wer_64_characters.A_crazy_profilethat_is_possible", 610 constructed_app_id); 611} 612 613TEST(ShellUtilTest, GetUserSpecificRegistrySuffix) { 614 string16 suffix; 615 ASSERT_TRUE(ShellUtil::GetUserSpecificRegistrySuffix(&suffix)); 616 ASSERT_TRUE(StartsWith(suffix, L".", true)); 617 ASSERT_EQ(27, suffix.length()); 618 ASSERT_TRUE(ContainsOnlyChars(suffix.substr(1), 619 L"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")); 620} 621 622TEST(ShellUtilTest, GetOldUserSpecificRegistrySuffix) { 623 string16 suffix; 624 ASSERT_TRUE(ShellUtil::GetOldUserSpecificRegistrySuffix(&suffix)); 625 ASSERT_TRUE(StartsWith(suffix, L".", true)); 626 627 wchar_t user_name[256]; 628 DWORD size = arraysize(user_name); 629 ASSERT_NE(0, ::GetUserName(user_name, &size)); 630 ASSERT_GE(size, 1U); 631 ASSERT_STREQ(user_name, suffix.substr(1).c_str()); 632} 633 634TEST(ShellUtilTest, ByteArrayToBase32) { 635 // Tests from http://tools.ietf.org/html/rfc4648#section-10. 636 const unsigned char test_array[] = { 'f', 'o', 'o', 'b', 'a', 'r' }; 637 638 const string16 expected[] = { L"", L"MY", L"MZXQ", L"MZXW6", L"MZXW6YQ", 639 L"MZXW6YTB", L"MZXW6YTBOI"}; 640 641 // Run the tests, with one more letter in the input every pass. 642 for (int i = 0; i < arraysize(expected); ++i) { 643 ASSERT_EQ(expected[i], 644 ShellUtil::ByteArrayToBase32(test_array, i)); 645 } 646} 647