Home | History | Annotate | Download | only in util
      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/synchronization/cancellation_flag.h"
     19 #include "base/test/scoped_path_override.h"
     20 #include "base/test/test_shortcut_win.h"
     21 #include "base/win/shortcut.h"
     22 #include "base/win/windows_version.h"
     23 #include "chrome/installer/util/browser_distribution.h"
     24 #include "chrome/installer/util/product.h"
     25 #include "chrome/installer/util/util_constants.h"
     26 #include "testing/gtest/include/gtest/gtest.h"
     27 
     28 namespace {
     29 
     30 const wchar_t kManganeseExe[] = L"manganese.exe";
     31 const wchar_t kIronExe[] = L"iron.exe";
     32 const wchar_t kOtherIco[] = L"other.ico";
     33 
     34 // TODO(huangs): Separate this into generic shortcut tests and Chrome-specific
     35 // tests. Specifically, we should not overly rely on getting shortcut properties
     36 // from product_->AddDefaultShortcutProperties().
     37 class ShellUtilShortcutTest : public testing::Test {
     38  protected:
     39   ShellUtilShortcutTest() : test_properties_(ShellUtil::CURRENT_USER) {}
     40 
     41   virtual void SetUp() OVERRIDE {
     42     dist_ = BrowserDistribution::GetDistribution();
     43     ASSERT_TRUE(dist_ != NULL);
     44     product_.reset(new installer::Product(dist_));
     45 
     46     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     47     chrome_exe_ = temp_dir_.path().Append(installer::kChromeExe);
     48     EXPECT_EQ(0, base::WriteFile(chrome_exe_, "", 0));
     49 
     50     manganese_exe_ = temp_dir_.path().Append(kManganeseExe);
     51     EXPECT_EQ(0, base::WriteFile(manganese_exe_, "", 0));
     52 
     53     iron_exe_ = temp_dir_.path().Append(kIronExe);
     54     EXPECT_EQ(0, base::WriteFile(iron_exe_, "", 0));
     55 
     56     other_ico_ = temp_dir_.path().Append(kOtherIco);
     57     EXPECT_EQ(0, base::WriteFile(other_ico_, "", 0));
     58 
     59     ASSERT_TRUE(fake_user_desktop_.CreateUniqueTempDir());
     60     ASSERT_TRUE(fake_common_desktop_.CreateUniqueTempDir());
     61     ASSERT_TRUE(fake_user_quick_launch_.CreateUniqueTempDir());
     62     ASSERT_TRUE(fake_default_user_quick_launch_.CreateUniqueTempDir());
     63     ASSERT_TRUE(fake_start_menu_.CreateUniqueTempDir());
     64     ASSERT_TRUE(fake_common_start_menu_.CreateUniqueTempDir());
     65     user_desktop_override_.reset(
     66         new base::ScopedPathOverride(base::DIR_USER_DESKTOP,
     67                                      fake_user_desktop_.path()));
     68     common_desktop_override_.reset(
     69         new base::ScopedPathOverride(base::DIR_COMMON_DESKTOP,
     70                                      fake_common_desktop_.path()));
     71     user_quick_launch_override_.reset(
     72         new base::ScopedPathOverride(base::DIR_USER_QUICK_LAUNCH,
     73                                      fake_user_quick_launch_.path()));
     74     default_user_quick_launch_override_.reset(
     75         new base::ScopedPathOverride(base::DIR_DEFAULT_USER_QUICK_LAUNCH,
     76                                      fake_default_user_quick_launch_.path()));
     77     start_menu_override_.reset(
     78         new base::ScopedPathOverride(base::DIR_START_MENU,
     79                                      fake_start_menu_.path()));
     80     common_start_menu_override_.reset(
     81         new base::ScopedPathOverride(base::DIR_COMMON_START_MENU,
     82                                      fake_common_start_menu_.path()));
     83 
     84     base::FilePath icon_path;
     85     base::CreateTemporaryFileInDir(temp_dir_.path(), &icon_path);
     86     test_properties_.set_target(chrome_exe_);
     87     test_properties_.set_arguments(L"--test --chrome");
     88     test_properties_.set_description(L"Makes polar bears dance.");
     89     test_properties_.set_icon(icon_path, 7);
     90     test_properties_.set_app_id(L"Polar.Bear");
     91     test_properties_.set_dual_mode(true);
     92   }
     93 
     94   // Returns the expected path of a test shortcut. Returns an empty FilePath on
     95   // failure.
     96   base::FilePath GetExpectedShortcutPath(
     97       ShellUtil::ShortcutLocation location,
     98       BrowserDistribution* dist,
     99       const ShellUtil::ShortcutProperties& properties) {
    100     base::FilePath expected_path;
    101     switch (location) {
    102       case ShellUtil::SHORTCUT_LOCATION_DESKTOP:
    103         expected_path = (properties.level == ShellUtil::CURRENT_USER) ?
    104             fake_user_desktop_.path() : fake_common_desktop_.path();
    105         break;
    106       case ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH:
    107         expected_path = (properties.level == ShellUtil::CURRENT_USER) ?
    108             fake_user_quick_launch_.path() :
    109             fake_default_user_quick_launch_.path();
    110         break;
    111       case ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR:
    112         expected_path = (properties.level == ShellUtil::CURRENT_USER) ?
    113             fake_start_menu_.path() : fake_common_start_menu_.path();
    114         expected_path = expected_path.Append(
    115             dist_->GetStartMenuShortcutSubfolder(
    116                 BrowserDistribution::SUBFOLDER_CHROME));
    117         break;
    118       default:
    119         ADD_FAILURE() << "Unknown location";
    120         return base::FilePath();
    121     }
    122 
    123     base::string16 shortcut_name = properties.has_shortcut_name() ?
    124         properties.shortcut_name :
    125         dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME);
    126     shortcut_name.append(installer::kLnkExt);
    127     return expected_path.Append(shortcut_name);
    128   }
    129 
    130   // Validates that the shortcut at |location| matches |properties| (and
    131   // implicit default properties) for |dist|.
    132   // Note: This method doesn't verify the |pin_to_taskbar| property as it
    133   // implies real (non-mocked) state which is flaky to test.
    134   void ValidateChromeShortcut(
    135       ShellUtil::ShortcutLocation location,
    136       BrowserDistribution* dist,
    137       const ShellUtil::ShortcutProperties& properties) {
    138     base::FilePath expected_path(
    139         GetExpectedShortcutPath(location, dist, properties));
    140 
    141     base::win::ShortcutProperties expected_properties;
    142     if (properties.has_target()) {
    143       expected_properties.set_target(properties.target);
    144       expected_properties.set_working_dir(properties.target.DirName());
    145     } else {
    146       expected_properties.set_target(chrome_exe_);
    147       expected_properties.set_working_dir(chrome_exe_.DirName());
    148     }
    149 
    150     if (properties.has_arguments())
    151       expected_properties.set_arguments(properties.arguments);
    152     else
    153       expected_properties.set_arguments(base::string16());
    154 
    155     if (properties.has_description())
    156       expected_properties.set_description(properties.description);
    157     else
    158       expected_properties.set_description(dist->GetAppDescription());
    159 
    160     if (properties.has_icon()) {
    161       expected_properties.set_icon(properties.icon, properties.icon_index);
    162     } else {
    163       int icon_index = dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME);
    164       expected_properties.set_icon(chrome_exe_, icon_index);
    165     }
    166 
    167     if (properties.has_app_id()) {
    168       expected_properties.set_app_id(properties.app_id);
    169     } else {
    170       // Tests are always seen as user-level installs in ShellUtil.
    171       expected_properties.set_app_id(ShellUtil::GetBrowserModelId(dist, true));
    172     }
    173 
    174     if (properties.has_dual_mode())
    175       expected_properties.set_dual_mode(properties.dual_mode);
    176     else
    177       expected_properties.set_dual_mode(false);
    178 
    179     base::win::ValidateShortcut(expected_path, expected_properties);
    180   }
    181 
    182   BrowserDistribution* dist_;
    183   scoped_ptr<installer::Product> product_;
    184 
    185   // A ShellUtil::ShortcutProperties object with common properties set already.
    186   ShellUtil::ShortcutProperties test_properties_;
    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 chrome_exe_;
    203   base::FilePath manganese_exe_;
    204   base::FilePath iron_exe_;
    205   base::FilePath other_ico_;
    206 };
    207 
    208 }  // namespace
    209 
    210 TEST_F(ShellUtilShortcutTest, GetShortcutPath) {
    211   base::FilePath path;
    212   ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    213                              ShellUtil::CURRENT_USER, &path);
    214   EXPECT_EQ(fake_user_desktop_.path(), path);
    215   ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    216                              ShellUtil::SYSTEM_LEVEL, &path);
    217   EXPECT_EQ(fake_common_desktop_.path(), path);
    218   ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
    219                              ShellUtil::CURRENT_USER, &path);
    220   EXPECT_EQ(fake_user_quick_launch_.path(), path);
    221   ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
    222                              ShellUtil::SYSTEM_LEVEL, &path);
    223   EXPECT_EQ(fake_default_user_quick_launch_.path(), path);
    224   base::string16 start_menu_subfolder =
    225       dist_->GetStartMenuShortcutSubfolder(
    226           BrowserDistribution::SUBFOLDER_CHROME);
    227   ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    228                              dist_, ShellUtil::CURRENT_USER, &path);
    229   EXPECT_EQ(fake_start_menu_.path().Append(start_menu_subfolder),
    230             path);
    231   ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    232                              dist_, ShellUtil::SYSTEM_LEVEL, &path);
    233   EXPECT_EQ(fake_common_start_menu_.path().Append(start_menu_subfolder),
    234             path);
    235 }
    236 
    237 TEST_F(ShellUtilShortcutTest, CreateChromeExeShortcutWithDefaultProperties) {
    238   ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
    239   product_->AddDefaultShortcutProperties(chrome_exe_, &properties);
    240   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    241                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, properties,
    242                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    243   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    244                          properties);
    245 }
    246 
    247 TEST_F(ShellUtilShortcutTest, CreateStartMenuShortcutWithAllProperties) {
    248   test_properties_.set_shortcut_name(L"Bobo le shortcut");
    249   test_properties_.level = ShellUtil::SYSTEM_LEVEL;
    250   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    251                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    252                   dist_, test_properties_,
    253                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    254   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    255                          dist_, test_properties_);
    256 }
    257 
    258 TEST_F(ShellUtilShortcutTest, ReplaceSystemLevelQuickLaunchShortcut) {
    259   test_properties_.level = ShellUtil::SYSTEM_LEVEL;
    260   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    261                   ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
    262                   dist_, test_properties_,
    263                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    264 
    265   ShellUtil::ShortcutProperties new_properties(ShellUtil::SYSTEM_LEVEL);
    266   product_->AddDefaultShortcutProperties(chrome_exe_, &new_properties);
    267   new_properties.set_description(L"New description");
    268   new_properties.set_arguments(L"--new-arguments");
    269   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    270                   ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
    271                   dist_, new_properties,
    272                   ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING));
    273 
    274   // Expect the properties set in |new_properties| to be set as above and
    275   // properties that don't have a default value to be set back to their default
    276   // (as validated in ValidateChromeShortcut()) or unset if they don't .
    277   ShellUtil::ShortcutProperties expected_properties(new_properties);
    278   expected_properties.set_dual_mode(false);
    279 
    280   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
    281                          expected_properties);
    282 }
    283 
    284 TEST_F(ShellUtilShortcutTest, UpdateQuickLaunchShortcutArguments) {
    285   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    286                   ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
    287                   dist_, test_properties_,
    288                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    289 
    290   // Only changing one property, don't need all the defaults.
    291   ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER);
    292   updated_properties.set_arguments(L"--updated --arguments");
    293   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    294                   ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
    295                   dist_, updated_properties,
    296                   ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING));
    297 
    298   // Expect the properties set in |updated_properties| to be set as above and
    299   // all other properties to remain unchanged.
    300   ShellUtil::ShortcutProperties expected_properties(test_properties_);
    301   expected_properties.set_arguments(updated_properties.arguments);
    302 
    303   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
    304                          expected_properties);
    305 }
    306 
    307 TEST_F(ShellUtilShortcutTest, UpdateAddDualModeToStartMenuShortcut) {
    308   ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
    309   product_->AddDefaultShortcutProperties(chrome_exe_, &properties);
    310   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    311                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_,
    312                   properties, ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    313 
    314   ShellUtil::ShortcutProperties added_properties(ShellUtil::CURRENT_USER);
    315   added_properties.set_dual_mode(true);
    316   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    317                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_,
    318                   added_properties, ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING));
    319 
    320   ShellUtil::ShortcutProperties expected_properties(properties);
    321   expected_properties.set_dual_mode(true);
    322 
    323   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    324                          dist_, expected_properties);
    325 }
    326 
    327 TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevel) {
    328   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    329                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    330                   ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL));
    331   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    332                          test_properties_);
    333 }
    334 
    335 TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelWithSystemLevelPresent) {
    336   base::string16 shortcut_name(
    337       dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
    338       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_IF_NO_SYSTEM_LEVEL));
    351   ASSERT_FALSE(base::PathExists(
    352       fake_user_desktop_.path().Append(shortcut_name)));
    353 }
    354 
    355 TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelStartMenu) {
    356   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    357                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    358                   dist_, test_properties_,
    359                   ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL));
    360   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    361                          dist_, test_properties_);
    362 }
    363 
    364 TEST_F(ShellUtilShortcutTest, CreateAlwaysUserWithSystemLevelPresent) {
    365   base::string16 shortcut_name(
    366       dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
    367       installer::kLnkExt);
    368 
    369   test_properties_.level = ShellUtil::SYSTEM_LEVEL;
    370   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    371                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    372                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    373   ASSERT_TRUE(base::PathExists(
    374       fake_common_desktop_.path().Append(shortcut_name)));
    375 
    376   test_properties_.level = ShellUtil::CURRENT_USER;
    377   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    378                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    379                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    380   ASSERT_TRUE(base::PathExists(
    381       fake_user_desktop_.path().Append(shortcut_name)));
    382 }
    383 
    384 TEST_F(ShellUtilShortcutTest, RemoveChromeShortcut) {
    385   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    386                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    387                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    388   base::FilePath shortcut_path = GetExpectedShortcutPath(
    389       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    390   ASSERT_TRUE(base::PathExists(shortcut_path));
    391 
    392   ASSERT_TRUE(ShellUtil::RemoveShortcuts(
    393       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
    394       chrome_exe_));
    395   ASSERT_FALSE(base::PathExists(shortcut_path));
    396   ASSERT_TRUE(base::PathExists(shortcut_path.DirName()));
    397 }
    398 
    399 TEST_F(ShellUtilShortcutTest, RemoveSystemLevelChromeShortcut) {
    400   test_properties_.level = ShellUtil::SYSTEM_LEVEL;
    401   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    402                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    403                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    404   base::FilePath shortcut_path = GetExpectedShortcutPath(
    405       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    406   ASSERT_TRUE(base::PathExists(shortcut_path));
    407 
    408   ASSERT_TRUE(ShellUtil::RemoveShortcuts(
    409       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL,
    410       chrome_exe_));
    411   ASSERT_FALSE(base::PathExists(shortcut_path));
    412   ASSERT_TRUE(base::PathExists(shortcut_path.DirName()));
    413 }
    414 
    415 TEST_F(ShellUtilShortcutTest, RemoveMultipleChromeShortcuts) {
    416   // Shortcut 1: targets "chrome.exe"; no arguments.
    417   test_properties_.set_shortcut_name(L"Chrome 1");
    418   test_properties_.set_arguments(L"");
    419   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    420                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    421                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    422   base::FilePath shortcut1_path = GetExpectedShortcutPath(
    423       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    424   ASSERT_TRUE(base::PathExists(shortcut1_path));
    425 
    426   // Shortcut 2: targets "chrome.exe"; has arguments; icon set to "other.ico".
    427   test_properties_.set_shortcut_name(L"Chrome 2");
    428   test_properties_.set_arguments(L"--profile-directory=\"Profile 2\"");
    429   test_properties_.set_icon(other_ico_, 0);
    430   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    431                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    432                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    433   base::FilePath shortcut2_path = GetExpectedShortcutPath(
    434       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    435   ASSERT_TRUE(base::PathExists(shortcut2_path));
    436 
    437   // Shortcut 3: targets "iron.exe"; has arguments; icon set to "chrome.exe".
    438   test_properties_.set_shortcut_name(L"Iron 3");
    439   test_properties_.set_target(iron_exe_);
    440   test_properties_.set_icon(chrome_exe_, 3);
    441   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    442                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    443                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    444   base::FilePath shortcut3_path = GetExpectedShortcutPath(
    445       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    446   ASSERT_TRUE(base::PathExists(shortcut3_path));
    447 
    448   // Remove shortcuts that target "chrome.exe".
    449   ASSERT_TRUE(ShellUtil::RemoveShortcuts(
    450       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
    451       chrome_exe_));
    452   ASSERT_FALSE(base::PathExists(shortcut1_path));
    453   ASSERT_FALSE(base::PathExists(shortcut2_path));
    454   ASSERT_TRUE(base::PathExists(shortcut3_path));
    455   ASSERT_TRUE(base::PathExists(shortcut1_path.DirName()));
    456 }
    457 
    458 TEST_F(ShellUtilShortcutTest, RetargetShortcutsWithArgs) {
    459   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    460                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    461                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    462   ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
    463       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
    464 
    465   base::FilePath new_exe = manganese_exe_;
    466   // Relies on the fact that |test_properties_| has non-empty arguments.
    467   ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
    468       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
    469       chrome_exe_, new_exe));
    470 
    471   ShellUtil::ShortcutProperties expected_properties(test_properties_);
    472   expected_properties.set_target(new_exe);
    473   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    474                          expected_properties);
    475 }
    476 
    477 TEST_F(ShellUtilShortcutTest, RetargetSystemLevelChromeShortcutsWithArgs) {
    478   test_properties_.level = ShellUtil::SYSTEM_LEVEL;
    479   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    480                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    481                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    482   ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
    483       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
    484 
    485   base::FilePath new_exe = manganese_exe_;
    486   // Relies on the fact that |test_properties_| has non-empty arguments.
    487   ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
    488       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL,
    489       chrome_exe_, new_exe));
    490 
    491   ShellUtil::ShortcutProperties expected_properties(test_properties_);
    492   expected_properties.set_target(new_exe);
    493   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    494                          expected_properties);
    495 }
    496 
    497 TEST_F(ShellUtilShortcutTest, RetargetChromeShortcutsWithArgsEmpty) {
    498   // Shortcut 1: targets "chrome.exe"; no arguments.
    499   test_properties_.set_shortcut_name(L"Chrome 1");
    500   test_properties_.set_arguments(L"");
    501   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    502                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    503                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    504   ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
    505       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
    506   ShellUtil::ShortcutProperties expected_properties1(test_properties_);
    507 
    508   // Shortcut 2: targets "chrome.exe"; has arguments.
    509   test_properties_.set_shortcut_name(L"Chrome 2");
    510   test_properties_.set_arguments(L"--profile-directory=\"Profile 2\"");
    511   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    512                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    513                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    514   ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
    515       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
    516   ShellUtil::ShortcutProperties expected_properties2(test_properties_);
    517 
    518   // Retarget shortcuts: replace "chrome.exe" with "manganese.exe". Only
    519   // shortcuts with non-empty arguments (i.e., shortcut 2) gets updated.
    520   base::FilePath new_exe = manganese_exe_;
    521   ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
    522       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
    523       chrome_exe_, new_exe));
    524 
    525   // Verify shortcut 1: no change.
    526   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    527                          expected_properties1);
    528 
    529   // Verify shortcut 2: target => "manganese.exe".
    530   expected_properties2.set_target(new_exe);
    531   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    532                          expected_properties2);
    533 }
    534 
    535 TEST_F(ShellUtilShortcutTest, RetargetChromeShortcutsWithArgsIcon) {
    536   const int kTestIconIndex1 = 3;
    537   const int kTestIconIndex2 = 5;
    538   const int kTestIconIndex3 = 8;
    539 
    540   // Shortcut 1: targets "chrome.exe"; icon same as target.
    541   test_properties_.set_shortcut_name(L"Chrome 1");
    542   test_properties_.set_icon(test_properties_.target, kTestIconIndex1);
    543   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    544                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    545                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    546   ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
    547       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
    548   ShellUtil::ShortcutProperties expected_properties1(test_properties_);
    549 
    550   // Shortcut 2: targets "chrome.exe"; icon set to "other.ico".
    551   test_properties_.set_shortcut_name(L"Chrome 2");
    552   test_properties_.set_icon(other_ico_, kTestIconIndex2);
    553   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    554                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    555                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    556   ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
    557       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
    558   ShellUtil::ShortcutProperties expected_properties2(test_properties_);
    559 
    560   // Shortcut 3: targets "iron.exe"; icon set to "chrome.exe".
    561   test_properties_.set_target(iron_exe_);
    562   test_properties_.set_shortcut_name(L"Iron 3");
    563   test_properties_.set_icon(chrome_exe_, kTestIconIndex3);
    564   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    565                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    566                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    567   ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
    568       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
    569   ShellUtil::ShortcutProperties expected_properties3(test_properties_);
    570 
    571   // Retarget shortcuts: replace "chrome.exe" with "manganese.exe".
    572   // Relies on the fact that |test_properties_| has non-empty arguments.
    573   base::FilePath new_exe = manganese_exe_;
    574   ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
    575       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
    576       chrome_exe_, new_exe));
    577 
    578   // Verify shortcut 1: target & icon => "manganese.exe", kept same icon index.
    579   expected_properties1.set_target(new_exe);
    580   expected_properties1.set_icon(new_exe, kTestIconIndex1);
    581   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    582                          expected_properties1);
    583 
    584   // Verify shortcut 2: target => "manganese.exe", kept icon.
    585   expected_properties2.set_target(new_exe);
    586   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    587                          expected_properties2);
    588 
    589   // Verify shortcut 3: no change, since target doesn't match.
    590   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    591                          expected_properties3);
    592 }
    593 
    594 TEST_F(ShellUtilShortcutTest, ClearShortcutArguments) {
    595   // Shortcut 1: targets "chrome.exe"; no arguments.
    596   test_properties_.set_shortcut_name(L"Chrome 1");
    597   test_properties_.set_arguments(L"");
    598   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    599                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    600                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    601   base::FilePath shortcut1_path = GetExpectedShortcutPath(
    602       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    603   ASSERT_TRUE(base::PathExists(shortcut1_path));
    604   ShellUtil::ShortcutProperties expected_properties1(test_properties_);
    605 
    606   // Shortcut 2: targets "chrome.exe"; has 1 whitelisted argument.
    607   test_properties_.set_shortcut_name(L"Chrome 2");
    608   test_properties_.set_arguments(L"--profile-directory=\"Profile 2\"");
    609   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    610                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    611                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    612   base::FilePath shortcut2_path = GetExpectedShortcutPath(
    613       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    614   ASSERT_TRUE(base::PathExists(shortcut2_path));
    615   ShellUtil::ShortcutProperties expected_properties2(test_properties_);
    616 
    617   // Shortcut 3: targets "chrome.exe"; has an unknown argument.
    618   test_properties_.set_shortcut_name(L"Chrome 3");
    619   test_properties_.set_arguments(L"foo.com");
    620   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    621                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    622                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    623   base::FilePath shortcut3_path = GetExpectedShortcutPath(
    624       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    625   ASSERT_TRUE(base::PathExists(shortcut3_path));
    626   ShellUtil::ShortcutProperties expected_properties3(test_properties_);
    627 
    628   // Shortcut 4: targets "chrome.exe"; has both unknown and known arguments.
    629   test_properties_.set_shortcut_name(L"Chrome 4");
    630   test_properties_.set_arguments(L"foo.com --show-app-list");
    631   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    632                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    633                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    634   base::FilePath shortcut4_path = GetExpectedShortcutPath(
    635       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
    636   ASSERT_TRUE(base::PathExists(shortcut4_path));
    637   ShellUtil::ShortcutProperties expected_properties4(test_properties_);
    638 
    639   // List the shortcuts.
    640   std::vector<std::pair<base::FilePath, base::string16> > shortcuts;
    641   EXPECT_TRUE(ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
    642       ShellUtil::SHORTCUT_LOCATION_DESKTOP,
    643       dist_,
    644       ShellUtil::CURRENT_USER,
    645       chrome_exe_,
    646       false,
    647       NULL,
    648       &shortcuts));
    649   ASSERT_EQ(2u, shortcuts.size());
    650   std::pair<base::FilePath, base::string16> shortcut3 =
    651       shortcuts[0].first == shortcut3_path ? shortcuts[0] : shortcuts[1];
    652   std::pair<base::FilePath, base::string16> shortcut4 =
    653       shortcuts[0].first == shortcut4_path ? shortcuts[0] : shortcuts[1];
    654   EXPECT_EQ(shortcut3_path, shortcut3.first);
    655   EXPECT_EQ(L"foo.com", shortcut3.second);
    656   EXPECT_EQ(shortcut4_path, shortcut4.first);
    657   EXPECT_EQ(L"foo.com --show-app-list", shortcut4.second);
    658 
    659   // Clear shortcuts.
    660   shortcuts.clear();
    661   EXPECT_TRUE(ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
    662       ShellUtil::SHORTCUT_LOCATION_DESKTOP,
    663       dist_,
    664       ShellUtil::CURRENT_USER,
    665       chrome_exe_,
    666       true,
    667       NULL,
    668       &shortcuts));
    669   ASSERT_EQ(2u, shortcuts.size());
    670   shortcut3 = shortcuts[0].first == shortcut3_path ? shortcuts[0] :
    671                                                      shortcuts[1];
    672   shortcut4 = shortcuts[0].first == shortcut4_path ? shortcuts[0] :
    673                                                      shortcuts[1];
    674   EXPECT_EQ(shortcut3_path, shortcut3.first);
    675   EXPECT_EQ(L"foo.com", shortcut3.second);
    676   EXPECT_EQ(shortcut4_path, shortcut4.first);
    677   EXPECT_EQ(L"foo.com --show-app-list", shortcut4.second);
    678 
    679   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    680                          expected_properties1);
    681   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    682                          expected_properties2);
    683   expected_properties3.set_arguments(base::string16());
    684   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    685                          expected_properties3);
    686   expected_properties4.set_arguments(L"--show-app-list");
    687   ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
    688                          expected_properties4);
    689 }
    690 
    691 TEST_F(ShellUtilShortcutTest, CreateMultipleStartMenuShortcutsAndRemoveFolder) {
    692   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    693                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    694                   dist_, test_properties_,
    695                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    696   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    697                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR,
    698                   dist_, test_properties_,
    699                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    700   test_properties_.set_shortcut_name(L"A second shortcut");
    701   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    702                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
    703                   dist_, test_properties_,
    704                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    705   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    706                   ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR,
    707                   dist_, test_properties_,
    708                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    709 
    710   base::FilePath chrome_shortcut_folder(
    711       fake_start_menu_.path().Append(
    712           dist_->GetStartMenuShortcutSubfolder(
    713               BrowserDistribution::SUBFOLDER_CHROME)));
    714   base::FilePath chrome_apps_shortcut_folder(
    715       fake_start_menu_.path().Append(
    716           dist_->GetStartMenuShortcutSubfolder(
    717               BrowserDistribution::SUBFOLDER_APPS)));
    718 
    719   base::FileEnumerator chrome_file_counter(chrome_shortcut_folder, false,
    720                                            base::FileEnumerator::FILES);
    721   int count = 0;
    722   while (!chrome_file_counter.Next().empty())
    723     ++count;
    724   EXPECT_EQ(2, count);
    725 
    726   base::FileEnumerator chrome_apps_file_counter(chrome_apps_shortcut_folder,
    727                                                 false,
    728                                                 base::FileEnumerator::FILES);
    729   count = 0;
    730   while (!chrome_apps_file_counter.Next().empty())
    731     ++count;
    732   EXPECT_EQ(2, count);
    733 
    734   ASSERT_TRUE(base::PathExists(chrome_shortcut_folder));
    735   ASSERT_TRUE(ShellUtil::RemoveShortcuts(
    736       ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_,
    737       ShellUtil::CURRENT_USER, chrome_exe_));
    738   ASSERT_FALSE(base::PathExists(chrome_shortcut_folder));
    739 
    740   ASSERT_TRUE(base::PathExists(chrome_apps_shortcut_folder));
    741   ASSERT_TRUE(ShellUtil::RemoveShortcuts(
    742       ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR, dist_,
    743       ShellUtil::CURRENT_USER, chrome_exe_));
    744   ASSERT_FALSE(base::PathExists(chrome_apps_shortcut_folder));
    745 }
    746 
    747 TEST_F(ShellUtilShortcutTest,
    748        DeleteStartMenuRootShortcutWithoutRemovingFolder) {
    749   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    750                   ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT,
    751                   dist_, test_properties_,
    752                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    753 
    754   base::string16 shortcut_name(
    755       dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
    756       installer::kLnkExt);
    757   base::FilePath shortcut_path(
    758       fake_start_menu_.path().Append(shortcut_name));
    759 
    760   ASSERT_TRUE(base::PathExists(fake_start_menu_.path()));
    761   ASSERT_TRUE(base::PathExists(shortcut_path));
    762   ASSERT_TRUE(ShellUtil::RemoveShortcuts(
    763       ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT, dist_,
    764       ShellUtil::CURRENT_USER, chrome_exe_));
    765   // The shortcut should be removed but the "Start Menu" root directory should
    766   // remain.
    767   ASSERT_TRUE(base::PathExists(fake_start_menu_.path()));
    768   ASSERT_FALSE(base::PathExists(shortcut_path));
    769 }
    770 
    771 TEST_F(ShellUtilShortcutTest, DontRemoveChromeShortcutIfPointsToAnotherChrome) {
    772   base::ScopedTempDir other_exe_dir;
    773   ASSERT_TRUE(other_exe_dir.CreateUniqueTempDir());
    774   base::FilePath other_chrome_exe =
    775       other_exe_dir.path().Append(installer::kChromeExe);
    776   EXPECT_EQ(0, base::WriteFile(other_chrome_exe, "", 0));
    777 
    778   test_properties_.set_target(other_chrome_exe);
    779   ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
    780                   ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
    781                   ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
    782 
    783   base::string16 shortcut_name(
    784       dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
    785       installer::kLnkExt);
    786   base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name));
    787   ASSERT_TRUE(base::PathExists(shortcut_path));
    788 
    789   // The shortcut shouldn't be removed as it was installed pointing to
    790   // |other_chrome_exe| and RemoveChromeShortcut() is being told that the
    791   // removed shortcut should point to |chrome_exe_|.
    792   ASSERT_TRUE(ShellUtil::RemoveShortcuts(
    793       ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
    794       chrome_exe_));
    795   ASSERT_TRUE(base::PathExists(shortcut_path));
    796   ASSERT_TRUE(base::PathExists(shortcut_path.DirName()));
    797 }
    798 
    799 TEST(ShellUtilTest, BuildAppModelIdBasic) {
    800   std::vector<base::string16> components;
    801   BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    802   const base::string16 base_app_id(dist->GetBaseAppId());
    803   components.push_back(base_app_id);
    804   ASSERT_EQ(base_app_id, ShellUtil::BuildAppModelId(components));
    805 }
    806 
    807 TEST(ShellUtilTest, BuildAppModelIdManySmall) {
    808   std::vector<base::string16> components;
    809   BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    810   const base::string16 suffixed_app_id(dist->GetBaseAppId().append(L".gab"));
    811   components.push_back(suffixed_app_id);
    812   components.push_back(L"Default");
    813   components.push_back(L"Test");
    814   ASSERT_EQ(suffixed_app_id + L".Default.Test",
    815             ShellUtil::BuildAppModelId(components));
    816 }
    817 
    818 TEST(ShellUtilTest, BuildAppModelIdLongUsernameNormalProfile) {
    819   std::vector<base::string16> components;
    820   const base::string16 long_appname(
    821       L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_"
    822       L"that_goes_over_64_characters");
    823   components.push_back(long_appname);
    824   components.push_back(L"Default");
    825   ASSERT_EQ(L"Chrome.a_user_wer_64_characters.Default",
    826             ShellUtil::BuildAppModelId(components));
    827 }
    828 
    829 TEST(ShellUtilTest, BuildAppModelIdLongEverything) {
    830   std::vector<base::string16> components;
    831   const base::string16 long_appname(L"Chrome.a_user_who_has_a_crazy_long_name_"
    832                                     L"with_some_weird@symbols_in_"
    833                                     L"it_" L"that_goes_over_64_characters");
    834   components.push_back(long_appname);
    835   components.push_back(
    836       L"A_crazy_profile_name_not_even_sure_whether_that_is_possible");
    837   const base::string16 constructed_app_id(
    838       ShellUtil::BuildAppModelId(components));
    839   ASSERT_LE(constructed_app_id.length(), installer::kMaxAppModelIdLength);
    840   ASSERT_EQ(L"Chrome.a_user_wer_64_characters.A_crazy_profilethat_is_possible",
    841             constructed_app_id);
    842 }
    843 
    844 TEST(ShellUtilTest, GetUserSpecificRegistrySuffix) {
    845   base::string16 suffix;
    846   ASSERT_TRUE(ShellUtil::GetUserSpecificRegistrySuffix(&suffix));
    847   ASSERT_TRUE(StartsWith(suffix, L".", true));
    848   ASSERT_EQ(27, suffix.length());
    849   ASSERT_TRUE(base::ContainsOnlyChars(suffix.substr(1),
    850                                       L"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"));
    851 }
    852 
    853 TEST(ShellUtilTest, GetOldUserSpecificRegistrySuffix) {
    854   base::string16 suffix;
    855   ASSERT_TRUE(ShellUtil::GetOldUserSpecificRegistrySuffix(&suffix));
    856   ASSERT_TRUE(StartsWith(suffix, L".", true));
    857 
    858   wchar_t user_name[256];
    859   DWORD size = arraysize(user_name);
    860   ASSERT_NE(0, ::GetUserName(user_name, &size));
    861   ASSERT_GE(size, 1U);
    862   ASSERT_STREQ(user_name, suffix.substr(1).c_str());
    863 }
    864 
    865 TEST(ShellUtilTest, ByteArrayToBase32) {
    866   // Tests from http://tools.ietf.org/html/rfc4648#section-10.
    867   const unsigned char test_array[] = { 'f', 'o', 'o', 'b', 'a', 'r' };
    868 
    869   const base::string16 expected[] = { L"", L"MY", L"MZXQ", L"MZXW6", L"MZXW6YQ",
    870                                 L"MZXW6YTB", L"MZXW6YTBOI"};
    871 
    872   // Run the tests, with one more letter in the input every pass.
    873   for (int i = 0; i < arraysize(expected); ++i) {
    874     ASSERT_EQ(expected[i],
    875               ShellUtil::ByteArrayToBase32(test_array, i));
    876   }
    877 }
    878