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