| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/installer/util/shell_util.h" |
| |
| #include <vector> |
| |
| #include "base/base_paths.h" |
| #include "base/base_paths_win.h" |
| #include "base/file_util.h" |
| #include "base/files/file_enumerator.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/md5.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/string_util.h" |
| #include "base/test/scoped_path_override.h" |
| #include "base/test/test_shortcut_win.h" |
| #include "base/win/shortcut.h" |
| #include "base/win/windows_version.h" |
| #include "chrome/installer/util/browser_distribution.h" |
| #include "chrome/installer/util/product.h" |
| #include "chrome/installer/util/util_constants.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| const wchar_t kManganeseExe[] = L"manganese.exe"; |
| |
| // TODO(huangs): Separate this into generic shortcut tests and Chrome-specific |
| // tests. Specifically, we should not overly rely on getting shortcut properties |
| // from product_->AddDefaultShortcutProperties(). |
| class ShellUtilShortcutTest : public testing::Test { |
| protected: |
| ShellUtilShortcutTest() : test_properties_(ShellUtil::CURRENT_USER) {} |
| |
| virtual void SetUp() OVERRIDE { |
| dist_ = BrowserDistribution::GetDistribution(); |
| ASSERT_TRUE(dist_ != NULL); |
| product_.reset(new installer::Product(dist_)); |
| |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| chrome_exe_ = temp_dir_.path().Append(installer::kChromeExe); |
| EXPECT_EQ(0, file_util::WriteFile(chrome_exe_, "", 0)); |
| |
| manganese_exe_ = temp_dir_.path().Append(kManganeseExe); |
| EXPECT_EQ(0, file_util::WriteFile(manganese_exe_, "", 0)); |
| |
| ASSERT_TRUE(fake_user_desktop_.CreateUniqueTempDir()); |
| ASSERT_TRUE(fake_common_desktop_.CreateUniqueTempDir()); |
| ASSERT_TRUE(fake_user_quick_launch_.CreateUniqueTempDir()); |
| ASSERT_TRUE(fake_default_user_quick_launch_.CreateUniqueTempDir()); |
| ASSERT_TRUE(fake_start_menu_.CreateUniqueTempDir()); |
| ASSERT_TRUE(fake_common_start_menu_.CreateUniqueTempDir()); |
| user_desktop_override_.reset( |
| new base::ScopedPathOverride(base::DIR_USER_DESKTOP, |
| fake_user_desktop_.path())); |
| common_desktop_override_.reset( |
| new base::ScopedPathOverride(base::DIR_COMMON_DESKTOP, |
| fake_common_desktop_.path())); |
| user_quick_launch_override_.reset( |
| new base::ScopedPathOverride(base::DIR_USER_QUICK_LAUNCH, |
| fake_user_quick_launch_.path())); |
| default_user_quick_launch_override_.reset( |
| new base::ScopedPathOverride(base::DIR_DEFAULT_USER_QUICK_LAUNCH, |
| fake_default_user_quick_launch_.path())); |
| start_menu_override_.reset( |
| new base::ScopedPathOverride(base::DIR_START_MENU, |
| fake_start_menu_.path())); |
| common_start_menu_override_.reset( |
| new base::ScopedPathOverride(base::DIR_COMMON_START_MENU, |
| fake_common_start_menu_.path())); |
| |
| base::FilePath icon_path; |
| base::CreateTemporaryFileInDir(temp_dir_.path(), &icon_path); |
| test_properties_.set_target(chrome_exe_); |
| test_properties_.set_arguments(L"--test --chrome"); |
| test_properties_.set_description(L"Makes polar bears dance."); |
| test_properties_.set_icon(icon_path, 0); |
| test_properties_.set_app_id(L"Polar.Bear"); |
| test_properties_.set_dual_mode(true); |
| } |
| |
| // Validates that the shortcut at |location| matches |properties| (and |
| // implicit default properties) for |dist|. |
| // Note: This method doesn't verify the |pin_to_taskbar| property as it |
| // implies real (non-mocked) state which is flaky to test. |
| void ValidateChromeShortcut( |
| ShellUtil::ShortcutLocation location, |
| BrowserDistribution* dist, |
| const ShellUtil::ShortcutProperties& properties) { |
| base::FilePath expected_path; |
| switch (location) { |
| case ShellUtil::SHORTCUT_LOCATION_DESKTOP: |
| expected_path = (properties.level == ShellUtil::CURRENT_USER) ? |
| fake_user_desktop_.path() : fake_common_desktop_.path(); |
| break; |
| case ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH: |
| expected_path = (properties.level == ShellUtil::CURRENT_USER) ? |
| fake_user_quick_launch_.path() : |
| fake_default_user_quick_launch_.path(); |
| break; |
| case ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR: |
| expected_path = (properties.level == ShellUtil::CURRENT_USER) ? |
| fake_start_menu_.path() : fake_common_start_menu_.path(); |
| expected_path = expected_path.Append( |
| dist_->GetStartMenuShortcutSubfolder( |
| BrowserDistribution::SUBFOLDER_CHROME)); |
| break; |
| default: |
| ADD_FAILURE() << "Unknown location"; |
| return; |
| } |
| |
| string16 shortcut_name; |
| if (properties.has_shortcut_name()) { |
| shortcut_name = properties.shortcut_name; |
| } else { |
| shortcut_name = |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME); |
| } |
| shortcut_name.append(installer::kLnkExt); |
| expected_path = expected_path.Append(shortcut_name); |
| |
| base::win::ShortcutProperties expected_properties; |
| if (properties.has_target()) { |
| expected_properties.set_target(properties.target); |
| expected_properties.set_working_dir(properties.target.DirName()); |
| } else { |
| expected_properties.set_target(chrome_exe_); |
| expected_properties.set_working_dir(chrome_exe_.DirName()); |
| } |
| |
| if (properties.has_arguments()) |
| expected_properties.set_arguments(properties.arguments); |
| else |
| expected_properties.set_arguments(string16()); |
| |
| if (properties.has_description()) |
| expected_properties.set_description(properties.description); |
| else |
| expected_properties.set_description(dist->GetAppDescription()); |
| |
| if (properties.has_icon()) { |
| expected_properties.set_icon(properties.icon, 0); |
| } else { |
| int icon_index = dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME); |
| expected_properties.set_icon(chrome_exe_, icon_index); |
| } |
| |
| if (properties.has_app_id()) { |
| expected_properties.set_app_id(properties.app_id); |
| } else { |
| // Tests are always seen as user-level installs in ShellUtil. |
| expected_properties.set_app_id(ShellUtil::GetBrowserModelId(dist, true)); |
| } |
| |
| if (properties.has_dual_mode()) |
| expected_properties.set_dual_mode(properties.dual_mode); |
| else |
| expected_properties.set_dual_mode(false); |
| |
| base::win::ValidateShortcut(expected_path, expected_properties); |
| } |
| |
| BrowserDistribution* dist_; |
| scoped_ptr<installer::Product> product_; |
| |
| // A ShellUtil::ShortcutProperties object with common properties set already. |
| ShellUtil::ShortcutProperties test_properties_; |
| |
| base::ScopedTempDir temp_dir_; |
| base::ScopedTempDir fake_user_desktop_; |
| base::ScopedTempDir fake_common_desktop_; |
| base::ScopedTempDir fake_user_quick_launch_; |
| base::ScopedTempDir fake_default_user_quick_launch_; |
| base::ScopedTempDir fake_start_menu_; |
| base::ScopedTempDir fake_common_start_menu_; |
| scoped_ptr<base::ScopedPathOverride> user_desktop_override_; |
| scoped_ptr<base::ScopedPathOverride> common_desktop_override_; |
| scoped_ptr<base::ScopedPathOverride> user_quick_launch_override_; |
| scoped_ptr<base::ScopedPathOverride> default_user_quick_launch_override_; |
| scoped_ptr<base::ScopedPathOverride> start_menu_override_; |
| scoped_ptr<base::ScopedPathOverride> common_start_menu_override_; |
| |
| base::FilePath chrome_exe_; |
| base::FilePath manganese_exe_; |
| }; |
| |
| } // namespace |
| |
| TEST_F(ShellUtilShortcutTest, GetShortcutPath) { |
| base::FilePath path; |
| ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| ShellUtil::CURRENT_USER, &path); |
| EXPECT_EQ(fake_user_desktop_.path(), path); |
| ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| ShellUtil::SYSTEM_LEVEL, &path); |
| EXPECT_EQ(fake_common_desktop_.path(), path); |
| ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, |
| ShellUtil::CURRENT_USER, &path); |
| EXPECT_EQ(fake_user_quick_launch_.path(), path); |
| ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, |
| ShellUtil::SYSTEM_LEVEL, &path); |
| EXPECT_EQ(fake_default_user_quick_launch_.path(), path); |
| string16 start_menu_subfolder = |
| dist_->GetStartMenuShortcutSubfolder( |
| BrowserDistribution::SUBFOLDER_CHROME); |
| ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, ShellUtil::CURRENT_USER, &path); |
| EXPECT_EQ(fake_start_menu_.path().Append(start_menu_subfolder), |
| path); |
| ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, ShellUtil::SYSTEM_LEVEL, &path); |
| EXPECT_EQ(fake_common_start_menu_.path().Append(start_menu_subfolder), |
| path); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, CreateChromeExeShortcutWithDefaultProperties) { |
| ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); |
| product_->AddDefaultShortcutProperties(chrome_exe_, &properties); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, properties, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| properties); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, CreateStartMenuShortcutWithAllProperties) { |
| test_properties_.set_shortcut_name(L"Bobo le shortcut"); |
| test_properties_.level = ShellUtil::SYSTEM_LEVEL; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, test_properties_); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, ReplaceSystemLevelQuickLaunchShortcut) { |
| test_properties_.level = ShellUtil::SYSTEM_LEVEL; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| ShellUtil::ShortcutProperties new_properties(ShellUtil::SYSTEM_LEVEL); |
| product_->AddDefaultShortcutProperties(chrome_exe_, &new_properties); |
| new_properties.set_description(L"New description"); |
| new_properties.set_arguments(L"--new-arguments"); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, |
| dist_, new_properties, |
| ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING)); |
| |
| // Expect the properties set in |new_properties| to be set as above and |
| // properties that don't have a default value to be set back to their default |
| // (as validated in ValidateChromeShortcut()) or unset if they don't . |
| ShellUtil::ShortcutProperties expected_properties(new_properties); |
| expected_properties.set_dual_mode(false); |
| |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, |
| expected_properties); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, UpdateQuickLaunchShortcutArguments) { |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| // Only changing one property, don't need all the defaults. |
| ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); |
| updated_properties.set_arguments(L"--updated --arguments"); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, |
| dist_, updated_properties, |
| ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING)); |
| |
| // Expect the properties set in |updated_properties| to be set as above and |
| // all other properties to remain unchanged. |
| ShellUtil::ShortcutProperties expected_properties(test_properties_); |
| expected_properties.set_arguments(updated_properties.arguments); |
| |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_, |
| expected_properties); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, UpdateAddDualModeToStartMenuShortcut) { |
| ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); |
| product_->AddDefaultShortcutProperties(chrome_exe_, &properties); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_, |
| properties, ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| ShellUtil::ShortcutProperties added_properties(ShellUtil::CURRENT_USER); |
| added_properties.set_dual_mode(true); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_, |
| added_properties, ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING)); |
| |
| ShellUtil::ShortcutProperties expected_properties(properties); |
| expected_properties.set_dual_mode(true); |
| |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, expected_properties); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevel) { |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL)); |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| test_properties_); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelWithSystemLevelPresent) { |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| |
| test_properties_.level = ShellUtil::SYSTEM_LEVEL; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| ASSERT_TRUE(base::PathExists( |
| fake_common_desktop_.path().Append(shortcut_name))); |
| |
| test_properties_.level = ShellUtil::CURRENT_USER; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL)); |
| ASSERT_FALSE(base::PathExists( |
| fake_user_desktop_.path().Append(shortcut_name))); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelStartMenu) { |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL)); |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, test_properties_); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, CreateAlwaysUserWithSystemLevelPresent) { |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| |
| test_properties_.level = ShellUtil::SYSTEM_LEVEL; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| ASSERT_TRUE(base::PathExists( |
| fake_common_desktop_.path().Append(shortcut_name))); |
| |
| test_properties_.level = ShellUtil::CURRENT_USER; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| ASSERT_TRUE(base::PathExists( |
| fake_user_desktop_.path().Append(shortcut_name))); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, RemoveChromeShortcut) { |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name)); |
| ASSERT_TRUE(base::PathExists(shortcut_path)); |
| |
| ASSERT_TRUE(ShellUtil::RemoveShortcuts( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, |
| chrome_exe_)); |
| ASSERT_FALSE(base::PathExists(shortcut_path)); |
| ASSERT_TRUE(base::PathExists(shortcut_path.DirName())); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, RemoveSystemLevelChromeShortcut) { |
| test_properties_.level = ShellUtil::SYSTEM_LEVEL; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| base::FilePath shortcut_path( |
| fake_common_desktop_.path().Append(shortcut_name)); |
| ASSERT_TRUE(base::PathExists(shortcut_path)); |
| |
| ASSERT_TRUE(ShellUtil::RemoveShortcuts( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL, |
| chrome_exe_)); |
| ASSERT_FALSE(base::PathExists(shortcut_path)); |
| ASSERT_TRUE(base::PathExists(shortcut_path.DirName())); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, RemoveMultipleChromeShortcuts) { |
| const wchar_t kShortcutName1[] = L"Chrome 1"; |
| const wchar_t kShortcutName2[] = L"Chrome 2"; |
| |
| test_properties_.set_shortcut_name(kShortcutName1); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| string16 shortcut1_name( |
| string16(kShortcutName1).append(installer::kLnkExt)); |
| base::FilePath shortcut1_path( |
| fake_user_desktop_.path().Append(shortcut1_name)); |
| ASSERT_TRUE(base::PathExists(shortcut1_path)); |
| |
| test_properties_.set_shortcut_name(kShortcutName2); |
| test_properties_.set_arguments(L"--profile-directory=\"Profile 2\""); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| string16 shortcut2_name(string16(kShortcutName2).append(installer::kLnkExt)); |
| base::FilePath shortcut2_path( |
| fake_user_desktop_.path().Append(shortcut2_name)); |
| ASSERT_TRUE(base::PathExists(shortcut2_path)); |
| |
| ASSERT_TRUE(ShellUtil::RemoveShortcuts( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, |
| chrome_exe_)); |
| ASSERT_FALSE(base::PathExists(shortcut1_path)); |
| ASSERT_FALSE(base::PathExists(shortcut2_path)); |
| ASSERT_TRUE(base::PathExists(shortcut1_path.DirName())); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, UpdateChromeShortcutsWithArgs) { |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name)); |
| ASSERT_TRUE(base::PathExists(shortcut_path)); |
| |
| base::FilePath new_exe = temp_dir_.path().Append(kManganeseExe); |
| ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); |
| updated_properties.set_target(new_exe); |
| // |updated_properties| has arguments. |
| ASSERT_TRUE(ShellUtil::UpdateShortcutsWithArgs( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, |
| chrome_exe_, updated_properties)); |
| |
| ShellUtil::ShortcutProperties expected_properties(test_properties_); |
| expected_properties.set_target(new_exe); |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| expected_properties); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, UpdateSystemLevelChromeShortcutsWithArgs) { |
| test_properties_.level = ShellUtil::SYSTEM_LEVEL; |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| base::FilePath shortcut_path( |
| fake_common_desktop_.path().Append(shortcut_name)); |
| ASSERT_TRUE(base::PathExists(shortcut_path)); |
| |
| base::FilePath new_exe = temp_dir_.path().Append(kManganeseExe); |
| ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); |
| updated_properties.set_target(new_exe); |
| // |updated_properties| has arguments. |
| ASSERT_TRUE(ShellUtil::UpdateShortcutsWithArgs( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL, |
| chrome_exe_, updated_properties)); |
| |
| ShellUtil::ShortcutProperties expected_properties(test_properties_); |
| expected_properties.set_target(new_exe); |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| expected_properties); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, UpdateMultipleChromeShortcutsWithArgs) { |
| const wchar_t kShortcutName1[] = L"Chrome 1"; |
| const wchar_t kShortcutName2[] = L"Chrome 2"; |
| |
| // Setup shortcut 1, which has empty arguments. |
| test_properties_.set_shortcut_name(kShortcutName1); |
| test_properties_.set_arguments(L""); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| string16 shortcut1_name(string16(kShortcutName1).append(installer::kLnkExt)); |
| base::FilePath shortcut1_path( |
| fake_user_desktop_.path().Append(shortcut1_name)); |
| ShellUtil::ShortcutProperties expected_properties1(test_properties_); |
| |
| // Setup shortcut 2, which has non-empty arguments. |
| string16 shortcut2_args = L"--profile-directory=\"Profile 2\""; |
| test_properties_.set_shortcut_name(kShortcutName2); |
| test_properties_.set_arguments(shortcut2_args); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| string16 shortcut2_name(string16(kShortcutName2).append(installer::kLnkExt)); |
| base::FilePath shortcut2_path( |
| fake_user_desktop_.path().Append(shortcut2_name)); |
| ASSERT_TRUE(base::PathExists(shortcut2_path)); |
| ShellUtil::ShortcutProperties expected_properties2(test_properties_); |
| |
| // Update shortcuts: target "manganese.exe" instead of "chrome.exe". |
| base::FilePath new_exe = temp_dir_.path().Append(kManganeseExe); |
| ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER); |
| updated_properties.set_target(new_exe); |
| |
| // Only changing shrotcuts that have non-empty arguments, i.e., shortcut 2. |
| ASSERT_TRUE(ShellUtil::UpdateShortcutsWithArgs( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, |
| chrome_exe_, updated_properties)); |
| // Verify shortcut 1. |
| // |expected_properties1| was unchanged and still targets "chrome.exe", since |
| // it has empty target, yet we passed |require_args| = true. |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| expected_properties1); |
| // Verify shortcut 2. |
| expected_properties2.set_target(new_exe); |
| ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, |
| expected_properties2); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, CreateMultipleStartMenuShortcutsAndRemoveFolder) { |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| test_properties_.set_shortcut_name(L"A second shortcut"); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| base::FilePath chrome_shortcut_folder( |
| fake_start_menu_.path().Append( |
| dist_->GetStartMenuShortcutSubfolder( |
| BrowserDistribution::SUBFOLDER_CHROME))); |
| base::FilePath chrome_apps_shortcut_folder( |
| fake_start_menu_.path().Append( |
| dist_->GetStartMenuShortcutSubfolder( |
| BrowserDistribution::SUBFOLDER_APPS))); |
| |
| base::FileEnumerator chrome_file_counter(chrome_shortcut_folder, false, |
| base::FileEnumerator::FILES); |
| int count = 0; |
| while (!chrome_file_counter.Next().empty()) |
| ++count; |
| EXPECT_EQ(2, count); |
| |
| base::FileEnumerator chrome_apps_file_counter(chrome_apps_shortcut_folder, |
| false, |
| base::FileEnumerator::FILES); |
| count = 0; |
| while (!chrome_apps_file_counter.Next().empty()) |
| ++count; |
| EXPECT_EQ(2, count); |
| |
| ASSERT_TRUE(base::PathExists(chrome_shortcut_folder)); |
| ASSERT_TRUE(ShellUtil::RemoveShortcuts( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_, |
| ShellUtil::CURRENT_USER, chrome_exe_)); |
| ASSERT_FALSE(base::PathExists(chrome_shortcut_folder)); |
| |
| ASSERT_TRUE(base::PathExists(chrome_apps_shortcut_folder)); |
| ASSERT_TRUE(ShellUtil::RemoveShortcuts( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR, dist_, |
| ShellUtil::CURRENT_USER, chrome_exe_)); |
| ASSERT_FALSE(base::PathExists(chrome_apps_shortcut_folder)); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, |
| DeleteStartMenuRootShortcutWithoutRemovingFolder) { |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT, |
| dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| base::FilePath shortcut_path( |
| fake_start_menu_.path().Append(shortcut_name)); |
| |
| ASSERT_TRUE(base::PathExists(fake_start_menu_.path())); |
| ASSERT_TRUE(base::PathExists(shortcut_path)); |
| ASSERT_TRUE(ShellUtil::RemoveShortcuts( |
| ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT, dist_, |
| ShellUtil::CURRENT_USER, chrome_exe_)); |
| // The shortcut should be removed but the "Start Menu" root directory should |
| // remain. |
| ASSERT_TRUE(base::PathExists(fake_start_menu_.path())); |
| ASSERT_FALSE(base::PathExists(shortcut_path)); |
| } |
| |
| TEST_F(ShellUtilShortcutTest, DontRemoveChromeShortcutIfPointsToAnotherChrome) { |
| base::ScopedTempDir other_exe_dir; |
| ASSERT_TRUE(other_exe_dir.CreateUniqueTempDir()); |
| base::FilePath other_chrome_exe = |
| other_exe_dir.path().Append(installer::kChromeExe); |
| EXPECT_EQ(0, file_util::WriteFile(other_chrome_exe, "", 0)); |
| |
| test_properties_.set_target(other_chrome_exe); |
| ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_, |
| ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)); |
| |
| string16 shortcut_name( |
| dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) + |
| installer::kLnkExt); |
| base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name)); |
| ASSERT_TRUE(base::PathExists(shortcut_path)); |
| |
| // The shortcut shouldn't be removed as it was installed pointing to |
| // |other_chrome_exe| and RemoveChromeShortcut() is being told that the |
| // removed shortcut should point to |chrome_exe_|. |
| ASSERT_TRUE(ShellUtil::RemoveShortcuts( |
| ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER, |
| chrome_exe_)); |
| ASSERT_TRUE(base::PathExists(shortcut_path)); |
| ASSERT_TRUE(base::PathExists(shortcut_path.DirName())); |
| } |
| |
| TEST(ShellUtilTest, BuildAppModelIdBasic) { |
| std::vector<string16> components; |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| const string16 base_app_id(dist->GetBaseAppId()); |
| components.push_back(base_app_id); |
| ASSERT_EQ(base_app_id, ShellUtil::BuildAppModelId(components)); |
| } |
| |
| TEST(ShellUtilTest, BuildAppModelIdManySmall) { |
| std::vector<string16> components; |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| const string16 suffixed_app_id(dist->GetBaseAppId().append(L".gab")); |
| components.push_back(suffixed_app_id); |
| components.push_back(L"Default"); |
| components.push_back(L"Test"); |
| ASSERT_EQ(suffixed_app_id + L".Default.Test", |
| ShellUtil::BuildAppModelId(components)); |
| } |
| |
| TEST(ShellUtilTest, BuildAppModelIdLongUsernameNormalProfile) { |
| std::vector<string16> components; |
| const string16 long_appname( |
| L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_" |
| L"that_goes_over_64_characters"); |
| components.push_back(long_appname); |
| components.push_back(L"Default"); |
| ASSERT_EQ(L"Chrome.a_user_wer_64_characters.Default", |
| ShellUtil::BuildAppModelId(components)); |
| } |
| |
| TEST(ShellUtilTest, BuildAppModelIdLongEverything) { |
| std::vector<string16> components; |
| const string16 long_appname( |
| L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_" |
| L"that_goes_over_64_characters"); |
| components.push_back(long_appname); |
| components.push_back( |
| L"A_crazy_profile_name_not_even_sure_whether_that_is_possible"); |
| const string16 constructed_app_id(ShellUtil::BuildAppModelId(components)); |
| ASSERT_LE(constructed_app_id.length(), installer::kMaxAppModelIdLength); |
| ASSERT_EQ(L"Chrome.a_user_wer_64_characters.A_crazy_profilethat_is_possible", |
| constructed_app_id); |
| } |
| |
| TEST(ShellUtilTest, GetUserSpecificRegistrySuffix) { |
| string16 suffix; |
| ASSERT_TRUE(ShellUtil::GetUserSpecificRegistrySuffix(&suffix)); |
| ASSERT_TRUE(StartsWith(suffix, L".", true)); |
| ASSERT_EQ(27, suffix.length()); |
| ASSERT_TRUE(ContainsOnlyChars(suffix.substr(1), |
| L"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")); |
| } |
| |
| TEST(ShellUtilTest, GetOldUserSpecificRegistrySuffix) { |
| string16 suffix; |
| ASSERT_TRUE(ShellUtil::GetOldUserSpecificRegistrySuffix(&suffix)); |
| ASSERT_TRUE(StartsWith(suffix, L".", true)); |
| |
| wchar_t user_name[256]; |
| DWORD size = arraysize(user_name); |
| ASSERT_NE(0, ::GetUserName(user_name, &size)); |
| ASSERT_GE(size, 1U); |
| ASSERT_STREQ(user_name, suffix.substr(1).c_str()); |
| } |
| |
| TEST(ShellUtilTest, ByteArrayToBase32) { |
| // Tests from http://tools.ietf.org/html/rfc4648#section-10. |
| const unsigned char test_array[] = { 'f', 'o', 'o', 'b', 'a', 'r' }; |
| |
| const string16 expected[] = { L"", L"MY", L"MZXQ", L"MZXW6", L"MZXW6YQ", |
| L"MZXW6YTB", L"MZXW6YTBOI"}; |
| |
| // Run the tests, with one more letter in the input every pass. |
| for (int i = 0; i < arraysize(expected); ++i) { |
| ASSERT_EQ(expected[i], |
| ShellUtil::ByteArrayToBase32(test_array, i)); |
| } |
| } |