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