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/command_line.h"
12 #include "base/files/file_enumerator.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/strings/string16.h"
19 #include "base/strings/string_util.h"
20 #include "base/synchronization/cancellation_flag.h"
21 #include "base/test/scoped_path_override.h"
22 #include "base/test/test_reg_util_win.h"
23 #include "base/test/test_shortcut_win.h"
24 #include "base/win/registry.h"
25 #include "base/win/shortcut.h"
26 #include "base/win/windows_version.h"
27 #include "chrome/installer/util/browser_distribution.h"
28 #include "chrome/installer/util/product.h"
29 #include "chrome/installer/util/util_constants.h"
30 #include "testing/gtest/include/gtest/gtest.h"
34 const wchar_t kManganeseExe
[] = L
"manganese.exe";
35 const wchar_t kIronExe
[] = L
"iron.exe";
36 const wchar_t kOtherIco
[] = L
"other.ico";
38 // For registry tests.
39 const wchar_t kTestProgid
[] = L
"TestApp";
40 const wchar_t kTestOpenCommand
[] = L
"C:\\test.exe";
41 const wchar_t kTestFileTypeName
[] = L
"Test File Type";
42 const wchar_t kTestIconPath
[] = L
"D:\\test.ico";
43 const wchar_t* kTestFileExtensions
[] = {
48 // TODO(huangs): Separate this into generic shortcut tests and Chrome-specific
49 // tests. Specifically, we should not overly rely on getting shortcut properties
50 // from product_->AddDefaultShortcutProperties().
51 class ShellUtilShortcutTest
: public testing::Test
{
53 ShellUtilShortcutTest() : test_properties_(ShellUtil::CURRENT_USER
) {}
55 void SetUp() override
{
56 dist_
= BrowserDistribution::GetDistribution();
57 ASSERT_TRUE(dist_
!= NULL
);
58 product_
.reset(new installer::Product(dist_
));
60 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
61 chrome_exe_
= temp_dir_
.path().Append(installer::kChromeExe
);
62 EXPECT_EQ(0, base::WriteFile(chrome_exe_
, "", 0));
64 manganese_exe_
= temp_dir_
.path().Append(kManganeseExe
);
65 EXPECT_EQ(0, base::WriteFile(manganese_exe_
, "", 0));
67 iron_exe_
= temp_dir_
.path().Append(kIronExe
);
68 EXPECT_EQ(0, base::WriteFile(iron_exe_
, "", 0));
70 other_ico_
= temp_dir_
.path().Append(kOtherIco
);
71 EXPECT_EQ(0, base::WriteFile(other_ico_
, "", 0));
73 ASSERT_TRUE(fake_user_desktop_
.CreateUniqueTempDir());
74 ASSERT_TRUE(fake_common_desktop_
.CreateUniqueTempDir());
75 ASSERT_TRUE(fake_user_quick_launch_
.CreateUniqueTempDir());
76 ASSERT_TRUE(fake_default_user_quick_launch_
.CreateUniqueTempDir());
77 ASSERT_TRUE(fake_start_menu_
.CreateUniqueTempDir());
78 ASSERT_TRUE(fake_common_start_menu_
.CreateUniqueTempDir());
79 user_desktop_override_
.reset(
80 new base::ScopedPathOverride(base::DIR_USER_DESKTOP
,
81 fake_user_desktop_
.path()));
82 common_desktop_override_
.reset(
83 new base::ScopedPathOverride(base::DIR_COMMON_DESKTOP
,
84 fake_common_desktop_
.path()));
85 user_quick_launch_override_
.reset(
86 new base::ScopedPathOverride(base::DIR_USER_QUICK_LAUNCH
,
87 fake_user_quick_launch_
.path()));
88 start_menu_override_
.reset(
89 new base::ScopedPathOverride(base::DIR_START_MENU
,
90 fake_start_menu_
.path()));
91 common_start_menu_override_
.reset(
92 new base::ScopedPathOverride(base::DIR_COMMON_START_MENU
,
93 fake_common_start_menu_
.path()));
95 base::FilePath icon_path
;
96 base::CreateTemporaryFileInDir(temp_dir_
.path(), &icon_path
);
97 test_properties_
.set_target(chrome_exe_
);
98 test_properties_
.set_arguments(L
"--test --chrome");
99 test_properties_
.set_description(L
"Makes polar bears dance.");
100 test_properties_
.set_icon(icon_path
, 7);
101 test_properties_
.set_app_id(L
"Polar.Bear");
102 test_properties_
.set_dual_mode(true);
105 // Returns the expected path of a test shortcut. Returns an empty FilePath on
107 base::FilePath
GetExpectedShortcutPath(
108 ShellUtil::ShortcutLocation location
,
109 BrowserDistribution
* dist
,
110 const ShellUtil::ShortcutProperties
& properties
) {
111 base::FilePath expected_path
;
113 case ShellUtil::SHORTCUT_LOCATION_DESKTOP
:
114 expected_path
= (properties
.level
== ShellUtil::CURRENT_USER
) ?
115 fake_user_desktop_
.path() : fake_common_desktop_
.path();
117 case ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH
:
118 expected_path
= fake_user_quick_launch_
.path();
120 case ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
:
121 expected_path
= (properties
.level
== ShellUtil::CURRENT_USER
) ?
122 fake_start_menu_
.path() : fake_common_start_menu_
.path();
123 expected_path
= expected_path
.Append(
124 dist_
->GetStartMenuShortcutSubfolder(
125 BrowserDistribution::SUBFOLDER_CHROME
));
128 ADD_FAILURE() << "Unknown location";
129 return base::FilePath();
132 base::string16 shortcut_name
= properties
.has_shortcut_name() ?
133 properties
.shortcut_name
:
134 dist_
->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME
);
135 shortcut_name
.append(installer::kLnkExt
);
136 return expected_path
.Append(shortcut_name
);
139 // Validates that the shortcut at |location| matches |properties| (and
140 // implicit default properties) for |dist|.
141 // Note: This method doesn't verify the |pin_to_taskbar| property as it
142 // implies real (non-mocked) state which is flaky to test.
143 void ValidateChromeShortcut(
144 ShellUtil::ShortcutLocation location
,
145 BrowserDistribution
* dist
,
146 const ShellUtil::ShortcutProperties
& properties
) {
147 base::FilePath
expected_path(
148 GetExpectedShortcutPath(location
, dist
, properties
));
150 base::win::ShortcutProperties expected_properties
;
151 if (properties
.has_target()) {
152 expected_properties
.set_target(properties
.target
);
153 expected_properties
.set_working_dir(properties
.target
.DirName());
155 expected_properties
.set_target(chrome_exe_
);
156 expected_properties
.set_working_dir(chrome_exe_
.DirName());
159 if (properties
.has_arguments())
160 expected_properties
.set_arguments(properties
.arguments
);
162 expected_properties
.set_arguments(base::string16());
164 if (properties
.has_description())
165 expected_properties
.set_description(properties
.description
);
167 expected_properties
.set_description(dist
->GetAppDescription());
169 if (properties
.has_icon()) {
170 expected_properties
.set_icon(properties
.icon
, properties
.icon_index
);
172 int icon_index
= dist
->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME
);
173 expected_properties
.set_icon(chrome_exe_
, icon_index
);
176 if (properties
.has_app_id()) {
177 expected_properties
.set_app_id(properties
.app_id
);
179 // Tests are always seen as user-level installs in ShellUtil.
180 expected_properties
.set_app_id(ShellUtil::GetBrowserModelId(dist
, true));
183 if (properties
.has_dual_mode())
184 expected_properties
.set_dual_mode(properties
.dual_mode
);
186 expected_properties
.set_dual_mode(false);
188 base::win::ValidateShortcut(expected_path
, expected_properties
);
191 BrowserDistribution
* dist_
;
192 scoped_ptr
<installer::Product
> product_
;
194 // A ShellUtil::ShortcutProperties object with common properties set already.
195 ShellUtil::ShortcutProperties test_properties_
;
197 base::ScopedTempDir temp_dir_
;
198 base::ScopedTempDir fake_user_desktop_
;
199 base::ScopedTempDir fake_common_desktop_
;
200 base::ScopedTempDir fake_user_quick_launch_
;
201 base::ScopedTempDir fake_default_user_quick_launch_
;
202 base::ScopedTempDir fake_start_menu_
;
203 base::ScopedTempDir fake_common_start_menu_
;
204 scoped_ptr
<base::ScopedPathOverride
> user_desktop_override_
;
205 scoped_ptr
<base::ScopedPathOverride
> common_desktop_override_
;
206 scoped_ptr
<base::ScopedPathOverride
> user_quick_launch_override_
;
207 scoped_ptr
<base::ScopedPathOverride
> start_menu_override_
;
208 scoped_ptr
<base::ScopedPathOverride
> common_start_menu_override_
;
210 base::FilePath chrome_exe_
;
211 base::FilePath manganese_exe_
;
212 base::FilePath iron_exe_
;
213 base::FilePath other_ico_
;
218 TEST_F(ShellUtilShortcutTest
, GetShortcutPath
) {
221 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
222 ShellUtil::CURRENT_USER
, &path
);
223 EXPECT_EQ(fake_user_desktop_
.path(), path
);
225 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
226 ShellUtil::SYSTEM_LEVEL
, &path
);
227 EXPECT_EQ(fake_common_desktop_
.path(), path
);
229 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH
, dist_
,
230 ShellUtil::CURRENT_USER
, &path
);
231 EXPECT_EQ(fake_user_quick_launch_
.path(), path
);
233 base::string16 start_menu_subfolder
=
234 dist_
->GetStartMenuShortcutSubfolder(
235 BrowserDistribution::SUBFOLDER_CHROME
);
236 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
237 dist_
, ShellUtil::CURRENT_USER
, &path
);
238 EXPECT_EQ(fake_start_menu_
.path().Append(start_menu_subfolder
),
241 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
242 dist_
, ShellUtil::SYSTEM_LEVEL
, &path
);
243 EXPECT_EQ(fake_common_start_menu_
.path().Append(start_menu_subfolder
),
247 TEST_F(ShellUtilShortcutTest
, CreateChromeExeShortcutWithDefaultProperties
) {
248 ShellUtil::ShortcutProperties
properties(ShellUtil::CURRENT_USER
);
249 product_
->AddDefaultShortcutProperties(chrome_exe_
, &properties
);
250 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
251 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, properties
,
252 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
253 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
257 TEST_F(ShellUtilShortcutTest
, CreateStartMenuShortcutWithAllProperties
) {
258 test_properties_
.set_shortcut_name(L
"Bobo le shortcut");
259 test_properties_
.level
= ShellUtil::SYSTEM_LEVEL
;
260 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
261 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
262 dist_
, test_properties_
,
263 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
264 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
265 dist_
, test_properties_
);
268 TEST_F(ShellUtilShortcutTest
, ReplaceSystemLevelDesktopShortcut
) {
269 test_properties_
.level
= ShellUtil::SYSTEM_LEVEL
;
270 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
271 ShellUtil::SHORTCUT_LOCATION_DESKTOP
,
272 dist_
, test_properties_
,
273 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
275 ShellUtil::ShortcutProperties
new_properties(ShellUtil::SYSTEM_LEVEL
);
276 product_
->AddDefaultShortcutProperties(chrome_exe_
, &new_properties
);
277 new_properties
.set_description(L
"New description");
278 new_properties
.set_arguments(L
"--new-arguments");
279 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
280 ShellUtil::SHORTCUT_LOCATION_DESKTOP
,
281 dist_
, new_properties
,
282 ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING
));
284 // Expect the properties set in |new_properties| to be set as above and
285 // properties that don't have a default value to be set back to their default
286 // (as validated in ValidateChromeShortcut()) or unset if they don't .
287 ShellUtil::ShortcutProperties
expected_properties(new_properties
);
288 expected_properties
.set_dual_mode(false);
290 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
291 expected_properties
);
294 TEST_F(ShellUtilShortcutTest
, UpdateQuickLaunchShortcutArguments
) {
295 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
296 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH
,
297 dist_
, test_properties_
,
298 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
300 // Only changing one property, don't need all the defaults.
301 ShellUtil::ShortcutProperties
updated_properties(ShellUtil::CURRENT_USER
);
302 updated_properties
.set_arguments(L
"--updated --arguments");
303 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
304 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH
,
305 dist_
, updated_properties
,
306 ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING
));
308 // Expect the properties set in |updated_properties| to be set as above and
309 // all other properties to remain unchanged.
310 ShellUtil::ShortcutProperties
expected_properties(test_properties_
);
311 expected_properties
.set_arguments(updated_properties
.arguments
);
313 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH
, dist_
,
314 expected_properties
);
317 TEST_F(ShellUtilShortcutTest
, UpdateAddDualModeToStartMenuShortcut
) {
318 ShellUtil::ShortcutProperties
properties(ShellUtil::CURRENT_USER
);
319 product_
->AddDefaultShortcutProperties(chrome_exe_
, &properties
);
320 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
321 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
, dist_
,
322 properties
, ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
324 ShellUtil::ShortcutProperties
added_properties(ShellUtil::CURRENT_USER
);
325 added_properties
.set_dual_mode(true);
326 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
327 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
, dist_
,
328 added_properties
, ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING
));
330 ShellUtil::ShortcutProperties
expected_properties(properties
);
331 expected_properties
.set_dual_mode(true);
333 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
334 dist_
, expected_properties
);
337 TEST_F(ShellUtilShortcutTest
, CreateIfNoSystemLevel
) {
338 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
339 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
340 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL
));
341 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
345 TEST_F(ShellUtilShortcutTest
, CreateIfNoSystemLevelWithSystemLevelPresent
) {
346 base::string16
shortcut_name(
347 dist_
->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME
) +
350 test_properties_
.level
= ShellUtil::SYSTEM_LEVEL
;
351 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
352 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
353 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
354 ASSERT_TRUE(base::PathExists(
355 fake_common_desktop_
.path().Append(shortcut_name
)));
357 test_properties_
.level
= ShellUtil::CURRENT_USER
;
358 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
359 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
360 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL
));
361 ASSERT_FALSE(base::PathExists(
362 fake_user_desktop_
.path().Append(shortcut_name
)));
365 TEST_F(ShellUtilShortcutTest
, CreateIfNoSystemLevelStartMenu
) {
366 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
367 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
368 dist_
, test_properties_
,
369 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL
));
370 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
371 dist_
, test_properties_
);
374 TEST_F(ShellUtilShortcutTest
, CreateAlwaysUserWithSystemLevelPresent
) {
375 base::string16
shortcut_name(
376 dist_
->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME
) +
379 test_properties_
.level
= ShellUtil::SYSTEM_LEVEL
;
380 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
381 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
382 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
383 ASSERT_TRUE(base::PathExists(
384 fake_common_desktop_
.path().Append(shortcut_name
)));
386 test_properties_
.level
= ShellUtil::CURRENT_USER
;
387 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
388 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
389 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
390 ASSERT_TRUE(base::PathExists(
391 fake_user_desktop_
.path().Append(shortcut_name
)));
394 TEST_F(ShellUtilShortcutTest
, RemoveChromeShortcut
) {
395 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
396 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
397 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
398 base::FilePath shortcut_path
= GetExpectedShortcutPath(
399 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
400 ASSERT_TRUE(base::PathExists(shortcut_path
));
402 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
403 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::CURRENT_USER
,
405 ASSERT_FALSE(base::PathExists(shortcut_path
));
406 ASSERT_TRUE(base::PathExists(shortcut_path
.DirName()));
409 TEST_F(ShellUtilShortcutTest
, RemoveSystemLevelChromeShortcut
) {
410 test_properties_
.level
= ShellUtil::SYSTEM_LEVEL
;
411 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
412 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
413 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
414 base::FilePath shortcut_path
= GetExpectedShortcutPath(
415 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
416 ASSERT_TRUE(base::PathExists(shortcut_path
));
418 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
419 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::SYSTEM_LEVEL
,
421 ASSERT_FALSE(base::PathExists(shortcut_path
));
422 ASSERT_TRUE(base::PathExists(shortcut_path
.DirName()));
425 TEST_F(ShellUtilShortcutTest
, RemoveMultipleChromeShortcuts
) {
426 // Shortcut 1: targets "chrome.exe"; no arguments.
427 test_properties_
.set_shortcut_name(L
"Chrome 1");
428 test_properties_
.set_arguments(L
"");
429 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
430 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
431 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
432 base::FilePath shortcut1_path
= GetExpectedShortcutPath(
433 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
434 ASSERT_TRUE(base::PathExists(shortcut1_path
));
436 // Shortcut 2: targets "chrome.exe"; has arguments; icon set to "other.ico".
437 test_properties_
.set_shortcut_name(L
"Chrome 2");
438 test_properties_
.set_arguments(L
"--profile-directory=\"Profile 2\"");
439 test_properties_
.set_icon(other_ico_
, 0);
440 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
441 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
442 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
443 base::FilePath shortcut2_path
= GetExpectedShortcutPath(
444 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
445 ASSERT_TRUE(base::PathExists(shortcut2_path
));
447 // Shortcut 3: targets "iron.exe"; has arguments; icon set to "chrome.exe".
448 test_properties_
.set_shortcut_name(L
"Iron 3");
449 test_properties_
.set_target(iron_exe_
);
450 test_properties_
.set_icon(chrome_exe_
, 3);
451 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
452 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
453 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
454 base::FilePath shortcut3_path
= GetExpectedShortcutPath(
455 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
456 ASSERT_TRUE(base::PathExists(shortcut3_path
));
458 // Remove shortcuts that target "chrome.exe".
459 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
460 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::CURRENT_USER
,
462 ASSERT_FALSE(base::PathExists(shortcut1_path
));
463 ASSERT_FALSE(base::PathExists(shortcut2_path
));
464 ASSERT_TRUE(base::PathExists(shortcut3_path
));
465 ASSERT_TRUE(base::PathExists(shortcut1_path
.DirName()));
468 TEST_F(ShellUtilShortcutTest
, RetargetShortcutsWithArgs
) {
469 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
470 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
471 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
472 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
473 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
)));
475 base::FilePath new_exe
= manganese_exe_
;
476 // Relies on the fact that |test_properties_| has non-empty arguments.
477 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
478 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::CURRENT_USER
,
479 chrome_exe_
, new_exe
));
481 ShellUtil::ShortcutProperties
expected_properties(test_properties_
);
482 expected_properties
.set_target(new_exe
);
483 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
484 expected_properties
);
487 TEST_F(ShellUtilShortcutTest
, RetargetSystemLevelChromeShortcutsWithArgs
) {
488 test_properties_
.level
= ShellUtil::SYSTEM_LEVEL
;
489 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
490 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
491 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
492 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
493 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
)));
495 base::FilePath new_exe
= manganese_exe_
;
496 // Relies on the fact that |test_properties_| has non-empty arguments.
497 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
498 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::SYSTEM_LEVEL
,
499 chrome_exe_
, new_exe
));
501 ShellUtil::ShortcutProperties
expected_properties(test_properties_
);
502 expected_properties
.set_target(new_exe
);
503 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
504 expected_properties
);
507 TEST_F(ShellUtilShortcutTest
, RetargetChromeShortcutsWithArgsEmpty
) {
508 // Shortcut 1: targets "chrome.exe"; no arguments.
509 test_properties_
.set_shortcut_name(L
"Chrome 1");
510 test_properties_
.set_arguments(L
"");
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_properties1(test_properties_
);
518 // Shortcut 2: targets "chrome.exe"; has arguments.
519 test_properties_
.set_shortcut_name(L
"Chrome 2");
520 test_properties_
.set_arguments(L
"--profile-directory=\"Profile 2\"");
521 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
522 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
523 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
524 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
525 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
)));
526 ShellUtil::ShortcutProperties
expected_properties2(test_properties_
);
528 // Retarget shortcuts: replace "chrome.exe" with "manganese.exe". Only
529 // shortcuts with non-empty arguments (i.e., shortcut 2) gets updated.
530 base::FilePath new_exe
= manganese_exe_
;
531 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
532 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::CURRENT_USER
,
533 chrome_exe_
, new_exe
));
535 // Verify shortcut 1: no change.
536 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
537 expected_properties1
);
539 // Verify shortcut 2: target => "manganese.exe".
540 expected_properties2
.set_target(new_exe
);
541 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
542 expected_properties2
);
545 TEST_F(ShellUtilShortcutTest
, RetargetChromeShortcutsWithArgsIcon
) {
546 const int kTestIconIndex1
= 3;
547 const int kTestIconIndex2
= 5;
548 const int kTestIconIndex3
= 8;
550 // Shortcut 1: targets "chrome.exe"; icon same as target.
551 test_properties_
.set_shortcut_name(L
"Chrome 1");
552 test_properties_
.set_icon(test_properties_
.target
, kTestIconIndex1
);
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_properties1(test_properties_
);
560 // Shortcut 2: targets "chrome.exe"; icon set to "other.ico".
561 test_properties_
.set_shortcut_name(L
"Chrome 2");
562 test_properties_
.set_icon(other_ico_
, kTestIconIndex2
);
563 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
564 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
565 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
566 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
567 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
)));
568 ShellUtil::ShortcutProperties
expected_properties2(test_properties_
);
570 // Shortcut 3: targets "iron.exe"; icon set to "chrome.exe".
571 test_properties_
.set_target(iron_exe_
);
572 test_properties_
.set_shortcut_name(L
"Iron 3");
573 test_properties_
.set_icon(chrome_exe_
, kTestIconIndex3
);
574 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
575 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
576 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
577 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
578 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
)));
579 ShellUtil::ShortcutProperties
expected_properties3(test_properties_
);
581 // Retarget shortcuts: replace "chrome.exe" with "manganese.exe".
582 // Relies on the fact that |test_properties_| has non-empty arguments.
583 base::FilePath new_exe
= manganese_exe_
;
584 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
585 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::CURRENT_USER
,
586 chrome_exe_
, new_exe
));
588 // Verify shortcut 1: target & icon => "manganese.exe", kept same icon index.
589 expected_properties1
.set_target(new_exe
);
590 expected_properties1
.set_icon(new_exe
, kTestIconIndex1
);
591 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
592 expected_properties1
);
594 // Verify shortcut 2: target => "manganese.exe", kept icon.
595 expected_properties2
.set_target(new_exe
);
596 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
597 expected_properties2
);
599 // Verify shortcut 3: no change, since target doesn't match.
600 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
601 expected_properties3
);
604 TEST_F(ShellUtilShortcutTest
, ClearShortcutArguments
) {
605 // Shortcut 1: targets "chrome.exe"; no arguments.
606 test_properties_
.set_shortcut_name(L
"Chrome 1");
607 test_properties_
.set_arguments(L
"");
608 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
609 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
610 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
611 base::FilePath shortcut1_path
= GetExpectedShortcutPath(
612 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
613 ASSERT_TRUE(base::PathExists(shortcut1_path
));
614 ShellUtil::ShortcutProperties
expected_properties1(test_properties_
);
616 // Shortcut 2: targets "chrome.exe"; has 1 whitelisted argument.
617 test_properties_
.set_shortcut_name(L
"Chrome 2");
618 test_properties_
.set_arguments(L
"--profile-directory=\"Profile 2\"");
619 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
620 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
621 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
622 base::FilePath shortcut2_path
= GetExpectedShortcutPath(
623 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
624 ASSERT_TRUE(base::PathExists(shortcut2_path
));
625 ShellUtil::ShortcutProperties
expected_properties2(test_properties_
);
627 // Shortcut 3: targets "chrome.exe"; has an unknown argument.
628 test_properties_
.set_shortcut_name(L
"Chrome 3");
629 test_properties_
.set_arguments(L
"foo.com");
630 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
631 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
632 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
633 base::FilePath shortcut3_path
= GetExpectedShortcutPath(
634 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
635 ASSERT_TRUE(base::PathExists(shortcut3_path
));
636 ShellUtil::ShortcutProperties
expected_properties3(test_properties_
);
638 // Shortcut 4: targets "chrome.exe"; has both unknown and known arguments.
639 test_properties_
.set_shortcut_name(L
"Chrome 4");
640 test_properties_
.set_arguments(L
"foo.com --show-app-list");
641 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
642 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
643 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
644 base::FilePath shortcut4_path
= GetExpectedShortcutPath(
645 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
);
646 ASSERT_TRUE(base::PathExists(shortcut4_path
));
647 ShellUtil::ShortcutProperties
expected_properties4(test_properties_
);
649 // List the shortcuts.
650 std::vector
<std::pair
<base::FilePath
, base::string16
> > shortcuts
;
651 EXPECT_TRUE(ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
652 ShellUtil::SHORTCUT_LOCATION_DESKTOP
,
654 ShellUtil::CURRENT_USER
,
659 ASSERT_EQ(2u, shortcuts
.size());
660 std::pair
<base::FilePath
, base::string16
> shortcut3
=
661 shortcuts
[0].first
== shortcut3_path
? shortcuts
[0] : shortcuts
[1];
662 std::pair
<base::FilePath
, base::string16
> shortcut4
=
663 shortcuts
[0].first
== shortcut4_path
? shortcuts
[0] : shortcuts
[1];
664 EXPECT_EQ(shortcut3_path
, shortcut3
.first
);
665 EXPECT_EQ(L
"foo.com", shortcut3
.second
);
666 EXPECT_EQ(shortcut4_path
, shortcut4
.first
);
667 EXPECT_EQ(L
"foo.com --show-app-list", shortcut4
.second
);
671 EXPECT_TRUE(ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
672 ShellUtil::SHORTCUT_LOCATION_DESKTOP
,
674 ShellUtil::CURRENT_USER
,
679 ASSERT_EQ(2u, shortcuts
.size());
680 shortcut3
= shortcuts
[0].first
== shortcut3_path
? shortcuts
[0] :
682 shortcut4
= shortcuts
[0].first
== shortcut4_path
? shortcuts
[0] :
684 EXPECT_EQ(shortcut3_path
, shortcut3
.first
);
685 EXPECT_EQ(L
"foo.com", shortcut3
.second
);
686 EXPECT_EQ(shortcut4_path
, shortcut4
.first
);
687 EXPECT_EQ(L
"foo.com --show-app-list", shortcut4
.second
);
689 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
690 expected_properties1
);
691 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
692 expected_properties2
);
693 expected_properties3
.set_arguments(base::string16());
694 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
695 expected_properties3
);
696 expected_properties4
.set_arguments(L
"--show-app-list");
697 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
,
698 expected_properties4
);
701 TEST_F(ShellUtilShortcutTest
, CreateMultipleStartMenuShortcutsAndRemoveFolder
) {
702 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
703 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
704 dist_
, test_properties_
,
705 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
706 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
707 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR
,
708 dist_
, test_properties_
,
709 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
710 test_properties_
.set_shortcut_name(L
"A second shortcut");
711 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
712 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
,
713 dist_
, test_properties_
,
714 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
715 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
716 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR
,
717 dist_
, test_properties_
,
718 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
720 base::FilePath
chrome_shortcut_folder(
721 fake_start_menu_
.path().Append(
722 dist_
->GetStartMenuShortcutSubfolder(
723 BrowserDistribution::SUBFOLDER_CHROME
)));
724 base::FilePath
chrome_apps_shortcut_folder(
725 fake_start_menu_
.path().Append(
726 dist_
->GetStartMenuShortcutSubfolder(
727 BrowserDistribution::SUBFOLDER_APPS
)));
729 base::FileEnumerator
chrome_file_counter(chrome_shortcut_folder
, false,
730 base::FileEnumerator::FILES
);
732 while (!chrome_file_counter
.Next().empty())
736 base::FileEnumerator
chrome_apps_file_counter(chrome_apps_shortcut_folder
,
738 base::FileEnumerator::FILES
);
740 while (!chrome_apps_file_counter
.Next().empty())
744 ASSERT_TRUE(base::PathExists(chrome_shortcut_folder
));
745 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
746 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR
, dist_
,
747 ShellUtil::CURRENT_USER
, chrome_exe_
));
748 ASSERT_FALSE(base::PathExists(chrome_shortcut_folder
));
750 ASSERT_TRUE(base::PathExists(chrome_apps_shortcut_folder
));
751 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
752 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR
, dist_
,
753 ShellUtil::CURRENT_USER
, chrome_exe_
));
754 ASSERT_FALSE(base::PathExists(chrome_apps_shortcut_folder
));
757 TEST_F(ShellUtilShortcutTest
,
758 DeleteStartMenuRootShortcutWithoutRemovingFolder
) {
759 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
760 ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT
,
761 dist_
, test_properties_
,
762 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
764 base::string16
shortcut_name(
765 dist_
->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME
) +
767 base::FilePath
shortcut_path(
768 fake_start_menu_
.path().Append(shortcut_name
));
770 ASSERT_TRUE(base::PathExists(fake_start_menu_
.path()));
771 ASSERT_TRUE(base::PathExists(shortcut_path
));
772 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
773 ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT
, dist_
,
774 ShellUtil::CURRENT_USER
, chrome_exe_
));
775 // The shortcut should be removed but the "Start Menu" root directory should
777 ASSERT_TRUE(base::PathExists(fake_start_menu_
.path()));
778 ASSERT_FALSE(base::PathExists(shortcut_path
));
781 TEST_F(ShellUtilShortcutTest
, DontRemoveChromeShortcutIfPointsToAnotherChrome
) {
782 base::ScopedTempDir other_exe_dir
;
783 ASSERT_TRUE(other_exe_dir
.CreateUniqueTempDir());
784 base::FilePath other_chrome_exe
=
785 other_exe_dir
.path().Append(installer::kChromeExe
);
786 EXPECT_EQ(0, base::WriteFile(other_chrome_exe
, "", 0));
788 test_properties_
.set_target(other_chrome_exe
);
789 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
790 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, test_properties_
,
791 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS
));
793 base::string16
shortcut_name(
794 dist_
->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME
) +
796 base::FilePath
shortcut_path(fake_user_desktop_
.path().Append(shortcut_name
));
797 ASSERT_TRUE(base::PathExists(shortcut_path
));
799 // The shortcut shouldn't be removed as it was installed pointing to
800 // |other_chrome_exe| and RemoveChromeShortcut() is being told that the
801 // removed shortcut should point to |chrome_exe_|.
802 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
803 ShellUtil::SHORTCUT_LOCATION_DESKTOP
, dist_
, ShellUtil::CURRENT_USER
,
805 ASSERT_TRUE(base::PathExists(shortcut_path
));
806 ASSERT_TRUE(base::PathExists(shortcut_path
.DirName()));
809 class ShellUtilRegistryTest
: public testing::Test
{
811 ShellUtilRegistryTest() {}
814 void SetUp() override
{
815 registry_overrides_
.OverrideRegistry(HKEY_CURRENT_USER
);
817 // .test2 files already have a default application.
818 base::win::RegKey key
;
822 HKEY_CURRENT_USER
, L
"Software\\Classes\\.test2", KEY_ALL_ACCESS
));
823 EXPECT_EQ(ERROR_SUCCESS
, key
.WriteValue(L
"", L
"SomeOtherApp"));
826 static base::CommandLine
OpenCommand() {
827 base::FilePath
open_command_path(kTestOpenCommand
);
828 base::CommandLine
open_command(open_command_path
);
829 // The "%1" should automatically be quoted.
830 open_command
.AppendArg("%1");
834 static std::set
<base::string16
> FileExtensions() {
835 std::set
<base::string16
> file_extensions
;
836 for (size_t i
= 0; i
< arraysize(kTestFileExtensions
); ++i
)
837 file_extensions
.insert(kTestFileExtensions
[i
]);
838 return file_extensions
;
842 registry_util::RegistryOverrideManager registry_overrides_
;
844 DISALLOW_COPY_AND_ASSIGN(ShellUtilRegistryTest
);
847 TEST_F(ShellUtilRegistryTest
, AddFileAssociations
) {
848 // Create file associations.
849 EXPECT_TRUE(ShellUtil::AddFileAssociations(kTestProgid
,
852 base::FilePath(kTestIconPath
),
855 // Ensure that the registry keys have been correctly set.
856 base::win::RegKey key
;
860 key
.Open(HKEY_CURRENT_USER
, L
"Software\\Classes\\TestApp", KEY_READ
));
861 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"", &value
));
862 EXPECT_EQ(L
"Test File Type", value
);
863 ASSERT_EQ(ERROR_SUCCESS
,
864 key
.Open(HKEY_CURRENT_USER
,
865 L
"Software\\Classes\\TestApp\\DefaultIcon",
867 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"", &value
));
868 EXPECT_EQ(L
"D:\\test.ico,0", value
);
869 ASSERT_EQ(ERROR_SUCCESS
,
870 key
.Open(HKEY_CURRENT_USER
,
871 L
"Software\\Classes\\TestApp\\shell\\open\\command",
873 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"", &value
));
874 EXPECT_EQ(L
"\"C:\\test.exe\" \"%1\"", value
);
876 // .test1 should be default-associated with our test app.
879 key
.Open(HKEY_CURRENT_USER
, L
"Software\\Classes\\.test1", KEY_READ
));
880 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"", &value
));
881 EXPECT_EQ(L
"TestApp", value
);
882 ASSERT_EQ(ERROR_SUCCESS
,
883 key
.Open(HKEY_CURRENT_USER
,
884 L
"Software\\Classes\\.test1\\OpenWithProgids",
886 EXPECT_TRUE(key
.HasValue(L
"TestApp"));
887 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"TestApp", &value
));
888 EXPECT_EQ(L
"", value
);
890 // .test2 should still be associated with the other app (should not have been
891 // overridden). But it should have our app in its Open With list.
894 key
.Open(HKEY_CURRENT_USER
, L
"Software\\Classes\\.test2", KEY_READ
));
895 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"", &value
));
896 EXPECT_EQ(L
"SomeOtherApp", value
);
897 ASSERT_EQ(ERROR_SUCCESS
,
898 key
.Open(HKEY_CURRENT_USER
,
899 L
"Software\\Classes\\.test2\\OpenWithProgids",
901 EXPECT_TRUE(key
.HasValue(L
"TestApp"));
902 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"TestApp", &value
));
903 EXPECT_EQ(L
"", value
);
906 TEST_F(ShellUtilRegistryTest
, DeleteFileAssociations
) {
907 // Create file associations.
908 EXPECT_TRUE(ShellUtil::AddFileAssociations(kTestProgid
,
911 base::FilePath(kTestIconPath
),
915 EXPECT_TRUE(ShellUtil::DeleteFileAssociations(kTestProgid
));
917 // The class key should have been completely deleted.
918 base::win::RegKey key
;
922 key
.Open(HKEY_CURRENT_USER
, L
"Software\\Classes\\TestApp", KEY_READ
));
924 // We don't currently delete the associations with the particular extensions.
925 // Still, ensure that .test2 is still associated with the other app.
926 // TODO(mgiuca): Update this expectation when we delete the associations.
929 key
.Open(HKEY_CURRENT_USER
, L
"Software\\Classes\\.test2", KEY_READ
));
930 EXPECT_EQ(ERROR_SUCCESS
, key
.ReadValue(L
"", &value
));
931 EXPECT_EQ(L
"SomeOtherApp", value
);
934 TEST(ShellUtilTest
, BuildAppModelIdBasic
) {
935 std::vector
<base::string16
> components
;
936 BrowserDistribution
* dist
= BrowserDistribution::GetDistribution();
937 const base::string16
base_app_id(dist
->GetBaseAppId());
938 components
.push_back(base_app_id
);
939 ASSERT_EQ(base_app_id
, ShellUtil::BuildAppModelId(components
));
942 TEST(ShellUtilTest
, BuildAppModelIdManySmall
) {
943 std::vector
<base::string16
> components
;
944 BrowserDistribution
* dist
= BrowserDistribution::GetDistribution();
945 const base::string16
suffixed_app_id(dist
->GetBaseAppId().append(L
".gab"));
946 components
.push_back(suffixed_app_id
);
947 components
.push_back(L
"Default");
948 components
.push_back(L
"Test");
949 ASSERT_EQ(suffixed_app_id
+ L
".Default.Test",
950 ShellUtil::BuildAppModelId(components
));
953 TEST(ShellUtilTest
, BuildAppModelIdLongUsernameNormalProfile
) {
954 std::vector
<base::string16
> components
;
955 const base::string16
long_appname(
956 L
"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_"
957 L
"that_goes_over_64_characters");
958 components
.push_back(long_appname
);
959 components
.push_back(L
"Default");
960 ASSERT_EQ(L
"Chrome.a_user_wer_64_characters.Default",
961 ShellUtil::BuildAppModelId(components
));
964 TEST(ShellUtilTest
, BuildAppModelIdLongEverything
) {
965 std::vector
<base::string16
> components
;
966 const base::string16
long_appname(L
"Chrome.a_user_who_has_a_crazy_long_name_"
967 L
"with_some_weird@symbols_in_"
968 L
"it_" L
"that_goes_over_64_characters");
969 components
.push_back(long_appname
);
970 components
.push_back(
971 L
"A_crazy_profile_name_not_even_sure_whether_that_is_possible");
972 const base::string16
constructed_app_id(
973 ShellUtil::BuildAppModelId(components
));
974 ASSERT_LE(constructed_app_id
.length(), installer::kMaxAppModelIdLength
);
975 ASSERT_EQ(L
"Chrome.a_user_wer_64_characters.A_crazy_profilethat_is_possible",
979 TEST(ShellUtilTest
, GetUserSpecificRegistrySuffix
) {
980 base::string16 suffix
;
981 ASSERT_TRUE(ShellUtil::GetUserSpecificRegistrySuffix(&suffix
));
982 ASSERT_TRUE(base::StartsWith(suffix
, L
".", base::CompareCase::SENSITIVE
));
983 ASSERT_EQ(27, suffix
.length());
984 ASSERT_TRUE(base::ContainsOnlyChars(suffix
.substr(1),
985 L
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"));
988 TEST(ShellUtilTest
, GetOldUserSpecificRegistrySuffix
) {
989 base::string16 suffix
;
990 ASSERT_TRUE(ShellUtil::GetOldUserSpecificRegistrySuffix(&suffix
));
991 ASSERT_TRUE(base::StartsWith(suffix
, L
".", base::CompareCase::SENSITIVE
));
993 wchar_t user_name
[256];
994 DWORD size
= arraysize(user_name
);
995 ASSERT_NE(0, ::GetUserName(user_name
, &size
));
997 ASSERT_STREQ(user_name
, suffix
.substr(1).c_str());
1000 TEST(ShellUtilTest
, ByteArrayToBase32
) {
1001 // Tests from http://tools.ietf.org/html/rfc4648#section-10.
1002 const unsigned char test_array
[] = { 'f', 'o', 'o', 'b', 'a', 'r' };
1004 const base::string16 expected
[] = { L
"", L
"MY", L
"MZXQ", L
"MZXW6", L
"MZXW6YQ",
1005 L
"MZXW6YTB", L
"MZXW6YTBOI"};
1007 // Run the tests, with one more letter in the input every pass.
1008 for (int i
= 0; i
< arraysize(expected
); ++i
) {
1009 ASSERT_EQ(expected
[i
],
1010 ShellUtil::ByteArrayToBase32(test_array
, i
));