Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / installer / util / shell_util_unittest.cc
blob76ed7de5a32c753fbb7d5aba0cc3478d209dabd7
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"
7 #include <vector>
9 #include "base/base_paths.h"
10 #include "base/base_paths_win.h"
11 #include "base/file_util.h"
12 #include "base/files/file_enumerator.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/md5.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/strings/string16.h"
17 #include "base/strings/string_util.h"
18 #include "base/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"
27 namespace {
29 const wchar_t kManganeseExe[] = L"manganese.exe";
30 const wchar_t kIronExe[] = L"iron.exe";
31 const wchar_t kOtherIco[] = L"other.ico";
33 // TODO(huangs): Separate this into generic shortcut tests and Chrome-specific
34 // tests. Specifically, we should not overly rely on getting shortcut properties
35 // from product_->AddDefaultShortcutProperties().
36 class ShellUtilShortcutTest : public testing::Test {
37 protected:
38 ShellUtilShortcutTest() : test_properties_(ShellUtil::CURRENT_USER) {}
40 virtual void SetUp() OVERRIDE {
41 dist_ = BrowserDistribution::GetDistribution();
42 ASSERT_TRUE(dist_ != NULL);
43 product_.reset(new installer::Product(dist_));
45 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
46 chrome_exe_ = temp_dir_.path().Append(installer::kChromeExe);
47 EXPECT_EQ(0, file_util::WriteFile(chrome_exe_, "", 0));
49 manganese_exe_ = temp_dir_.path().Append(kManganeseExe);
50 EXPECT_EQ(0, file_util::WriteFile(manganese_exe_, "", 0));
52 iron_exe_ = temp_dir_.path().Append(kIronExe);
53 EXPECT_EQ(0, file_util::WriteFile(iron_exe_, "", 0));
55 other_ico_ = temp_dir_.path().Append(kOtherIco);
56 EXPECT_EQ(0, file_util::WriteFile(other_ico_, "", 0));
58 ASSERT_TRUE(fake_user_desktop_.CreateUniqueTempDir());
59 ASSERT_TRUE(fake_common_desktop_.CreateUniqueTempDir());
60 ASSERT_TRUE(fake_user_quick_launch_.CreateUniqueTempDir());
61 ASSERT_TRUE(fake_default_user_quick_launch_.CreateUniqueTempDir());
62 ASSERT_TRUE(fake_start_menu_.CreateUniqueTempDir());
63 ASSERT_TRUE(fake_common_start_menu_.CreateUniqueTempDir());
64 user_desktop_override_.reset(
65 new base::ScopedPathOverride(base::DIR_USER_DESKTOP,
66 fake_user_desktop_.path()));
67 common_desktop_override_.reset(
68 new base::ScopedPathOverride(base::DIR_COMMON_DESKTOP,
69 fake_common_desktop_.path()));
70 user_quick_launch_override_.reset(
71 new base::ScopedPathOverride(base::DIR_USER_QUICK_LAUNCH,
72 fake_user_quick_launch_.path()));
73 default_user_quick_launch_override_.reset(
74 new base::ScopedPathOverride(base::DIR_DEFAULT_USER_QUICK_LAUNCH,
75 fake_default_user_quick_launch_.path()));
76 start_menu_override_.reset(
77 new base::ScopedPathOverride(base::DIR_START_MENU,
78 fake_start_menu_.path()));
79 common_start_menu_override_.reset(
80 new base::ScopedPathOverride(base::DIR_COMMON_START_MENU,
81 fake_common_start_menu_.path()));
83 base::FilePath icon_path;
84 base::CreateTemporaryFileInDir(temp_dir_.path(), &icon_path);
85 test_properties_.set_target(chrome_exe_);
86 test_properties_.set_arguments(L"--test --chrome");
87 test_properties_.set_description(L"Makes polar bears dance.");
88 test_properties_.set_icon(icon_path, 7);
89 test_properties_.set_app_id(L"Polar.Bear");
90 test_properties_.set_dual_mode(true);
93 // Returns the expected path of a test shortcut. Returns an empty FilePath on
94 // failure.
95 base::FilePath GetExpectedShortcutPath(
96 ShellUtil::ShortcutLocation location,
97 BrowserDistribution* dist,
98 const ShellUtil::ShortcutProperties& properties) {
99 base::FilePath expected_path;
100 switch (location) {
101 case ShellUtil::SHORTCUT_LOCATION_DESKTOP:
102 expected_path = (properties.level == ShellUtil::CURRENT_USER) ?
103 fake_user_desktop_.path() : fake_common_desktop_.path();
104 break;
105 case ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH:
106 expected_path = (properties.level == ShellUtil::CURRENT_USER) ?
107 fake_user_quick_launch_.path() :
108 fake_default_user_quick_launch_.path();
109 break;
110 case ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR:
111 expected_path = (properties.level == ShellUtil::CURRENT_USER) ?
112 fake_start_menu_.path() : fake_common_start_menu_.path();
113 expected_path = expected_path.Append(
114 dist_->GetStartMenuShortcutSubfolder(
115 BrowserDistribution::SUBFOLDER_CHROME));
116 break;
117 default:
118 ADD_FAILURE() << "Unknown location";
119 return base::FilePath();
122 base::string16 shortcut_name = properties.has_shortcut_name() ?
123 properties.shortcut_name :
124 dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME);
125 shortcut_name.append(installer::kLnkExt);
126 return expected_path.Append(shortcut_name);
129 // Validates that the shortcut at |location| matches |properties| (and
130 // implicit default properties) for |dist|.
131 // Note: This method doesn't verify the |pin_to_taskbar| property as it
132 // implies real (non-mocked) state which is flaky to test.
133 void ValidateChromeShortcut(
134 ShellUtil::ShortcutLocation location,
135 BrowserDistribution* dist,
136 const ShellUtil::ShortcutProperties& properties) {
137 base::FilePath expected_path(
138 GetExpectedShortcutPath(location, dist, properties));
140 base::win::ShortcutProperties expected_properties;
141 if (properties.has_target()) {
142 expected_properties.set_target(properties.target);
143 expected_properties.set_working_dir(properties.target.DirName());
144 } else {
145 expected_properties.set_target(chrome_exe_);
146 expected_properties.set_working_dir(chrome_exe_.DirName());
149 if (properties.has_arguments())
150 expected_properties.set_arguments(properties.arguments);
151 else
152 expected_properties.set_arguments(base::string16());
154 if (properties.has_description())
155 expected_properties.set_description(properties.description);
156 else
157 expected_properties.set_description(dist->GetAppDescription());
159 if (properties.has_icon()) {
160 expected_properties.set_icon(properties.icon, properties.icon_index);
161 } else {
162 int icon_index = dist->GetIconIndex(BrowserDistribution::SHORTCUT_CHROME);
163 expected_properties.set_icon(chrome_exe_, icon_index);
166 if (properties.has_app_id()) {
167 expected_properties.set_app_id(properties.app_id);
168 } else {
169 // Tests are always seen as user-level installs in ShellUtil.
170 expected_properties.set_app_id(ShellUtil::GetBrowserModelId(dist, true));
173 if (properties.has_dual_mode())
174 expected_properties.set_dual_mode(properties.dual_mode);
175 else
176 expected_properties.set_dual_mode(false);
178 base::win::ValidateShortcut(expected_path, expected_properties);
181 BrowserDistribution* dist_;
182 scoped_ptr<installer::Product> product_;
184 // A ShellUtil::ShortcutProperties object with common properties set already.
185 ShellUtil::ShortcutProperties test_properties_;
187 base::ScopedTempDir temp_dir_;
188 base::ScopedTempDir fake_user_desktop_;
189 base::ScopedTempDir fake_common_desktop_;
190 base::ScopedTempDir fake_user_quick_launch_;
191 base::ScopedTempDir fake_default_user_quick_launch_;
192 base::ScopedTempDir fake_start_menu_;
193 base::ScopedTempDir fake_common_start_menu_;
194 scoped_ptr<base::ScopedPathOverride> user_desktop_override_;
195 scoped_ptr<base::ScopedPathOverride> common_desktop_override_;
196 scoped_ptr<base::ScopedPathOverride> user_quick_launch_override_;
197 scoped_ptr<base::ScopedPathOverride> default_user_quick_launch_override_;
198 scoped_ptr<base::ScopedPathOverride> start_menu_override_;
199 scoped_ptr<base::ScopedPathOverride> common_start_menu_override_;
201 base::FilePath chrome_exe_;
202 base::FilePath manganese_exe_;
203 base::FilePath iron_exe_;
204 base::FilePath other_ico_;
207 } // namespace
209 TEST_F(ShellUtilShortcutTest, GetShortcutPath) {
210 base::FilePath path;
211 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
212 ShellUtil::CURRENT_USER, &path);
213 EXPECT_EQ(fake_user_desktop_.path(), path);
214 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
215 ShellUtil::SYSTEM_LEVEL, &path);
216 EXPECT_EQ(fake_common_desktop_.path(), path);
217 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
218 ShellUtil::CURRENT_USER, &path);
219 EXPECT_EQ(fake_user_quick_launch_.path(), path);
220 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
221 ShellUtil::SYSTEM_LEVEL, &path);
222 EXPECT_EQ(fake_default_user_quick_launch_.path(), path);
223 base::string16 start_menu_subfolder =
224 dist_->GetStartMenuShortcutSubfolder(
225 BrowserDistribution::SUBFOLDER_CHROME);
226 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
227 dist_, ShellUtil::CURRENT_USER, &path);
228 EXPECT_EQ(fake_start_menu_.path().Append(start_menu_subfolder),
229 path);
230 ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
231 dist_, ShellUtil::SYSTEM_LEVEL, &path);
232 EXPECT_EQ(fake_common_start_menu_.path().Append(start_menu_subfolder),
233 path);
236 TEST_F(ShellUtilShortcutTest, CreateChromeExeShortcutWithDefaultProperties) {
237 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
238 product_->AddDefaultShortcutProperties(chrome_exe_, &properties);
239 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
240 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, properties,
241 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
242 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
243 properties);
246 TEST_F(ShellUtilShortcutTest, CreateStartMenuShortcutWithAllProperties) {
247 test_properties_.set_shortcut_name(L"Bobo le shortcut");
248 test_properties_.level = ShellUtil::SYSTEM_LEVEL;
249 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
250 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
251 dist_, test_properties_,
252 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
253 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
254 dist_, test_properties_);
257 TEST_F(ShellUtilShortcutTest, ReplaceSystemLevelQuickLaunchShortcut) {
258 test_properties_.level = ShellUtil::SYSTEM_LEVEL;
259 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
260 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
261 dist_, test_properties_,
262 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
264 ShellUtil::ShortcutProperties new_properties(ShellUtil::SYSTEM_LEVEL);
265 product_->AddDefaultShortcutProperties(chrome_exe_, &new_properties);
266 new_properties.set_description(L"New description");
267 new_properties.set_arguments(L"--new-arguments");
268 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
269 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
270 dist_, new_properties,
271 ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING));
273 // Expect the properties set in |new_properties| to be set as above and
274 // properties that don't have a default value to be set back to their default
275 // (as validated in ValidateChromeShortcut()) or unset if they don't .
276 ShellUtil::ShortcutProperties expected_properties(new_properties);
277 expected_properties.set_dual_mode(false);
279 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
280 expected_properties);
283 TEST_F(ShellUtilShortcutTest, UpdateQuickLaunchShortcutArguments) {
284 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
285 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
286 dist_, test_properties_,
287 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
289 // Only changing one property, don't need all the defaults.
290 ShellUtil::ShortcutProperties updated_properties(ShellUtil::CURRENT_USER);
291 updated_properties.set_arguments(L"--updated --arguments");
292 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
293 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
294 dist_, updated_properties,
295 ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING));
297 // Expect the properties set in |updated_properties| to be set as above and
298 // all other properties to remain unchanged.
299 ShellUtil::ShortcutProperties expected_properties(test_properties_);
300 expected_properties.set_arguments(updated_properties.arguments);
302 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist_,
303 expected_properties);
306 TEST_F(ShellUtilShortcutTest, UpdateAddDualModeToStartMenuShortcut) {
307 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
308 product_->AddDefaultShortcutProperties(chrome_exe_, &properties);
309 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
310 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_,
311 properties, ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
313 ShellUtil::ShortcutProperties added_properties(ShellUtil::CURRENT_USER);
314 added_properties.set_dual_mode(true);
315 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
316 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_,
317 added_properties, ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING));
319 ShellUtil::ShortcutProperties expected_properties(properties);
320 expected_properties.set_dual_mode(true);
322 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
323 dist_, expected_properties);
326 TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevel) {
327 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
328 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
329 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL));
330 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
331 test_properties_);
334 TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelWithSystemLevelPresent) {
335 base::string16 shortcut_name(
336 dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
337 installer::kLnkExt);
339 test_properties_.level = ShellUtil::SYSTEM_LEVEL;
340 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
341 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
342 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
343 ASSERT_TRUE(base::PathExists(
344 fake_common_desktop_.path().Append(shortcut_name)));
346 test_properties_.level = ShellUtil::CURRENT_USER;
347 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
348 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
349 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL));
350 ASSERT_FALSE(base::PathExists(
351 fake_user_desktop_.path().Append(shortcut_name)));
354 TEST_F(ShellUtilShortcutTest, CreateIfNoSystemLevelStartMenu) {
355 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
356 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
357 dist_, test_properties_,
358 ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL));
359 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
360 dist_, test_properties_);
363 TEST_F(ShellUtilShortcutTest, CreateAlwaysUserWithSystemLevelPresent) {
364 base::string16 shortcut_name(
365 dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
366 installer::kLnkExt);
368 test_properties_.level = ShellUtil::SYSTEM_LEVEL;
369 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
370 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
371 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
372 ASSERT_TRUE(base::PathExists(
373 fake_common_desktop_.path().Append(shortcut_name)));
375 test_properties_.level = ShellUtil::CURRENT_USER;
376 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
377 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
378 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
379 ASSERT_TRUE(base::PathExists(
380 fake_user_desktop_.path().Append(shortcut_name)));
383 TEST_F(ShellUtilShortcutTest, RemoveChromeShortcut) {
384 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
385 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
386 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
387 base::FilePath shortcut_path = GetExpectedShortcutPath(
388 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
389 ASSERT_TRUE(base::PathExists(shortcut_path));
391 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
392 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
393 chrome_exe_));
394 ASSERT_FALSE(base::PathExists(shortcut_path));
395 ASSERT_TRUE(base::PathExists(shortcut_path.DirName()));
398 TEST_F(ShellUtilShortcutTest, RemoveSystemLevelChromeShortcut) {
399 test_properties_.level = ShellUtil::SYSTEM_LEVEL;
400 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
401 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
402 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
403 base::FilePath shortcut_path = GetExpectedShortcutPath(
404 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
405 ASSERT_TRUE(base::PathExists(shortcut_path));
407 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
408 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL,
409 chrome_exe_));
410 ASSERT_FALSE(base::PathExists(shortcut_path));
411 ASSERT_TRUE(base::PathExists(shortcut_path.DirName()));
414 TEST_F(ShellUtilShortcutTest, RemoveMultipleChromeShortcuts) {
415 // Shortcut 1: targets "chrome.exe"; no arguments.
416 test_properties_.set_shortcut_name(L"Chrome 1");
417 test_properties_.set_arguments(L"");
418 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
419 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
420 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
421 base::FilePath shortcut1_path = GetExpectedShortcutPath(
422 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
423 ASSERT_TRUE(base::PathExists(shortcut1_path));
425 // Shortcut 2: targets "chrome.exe"; has arguments; icon set to "other.ico".
426 test_properties_.set_shortcut_name(L"Chrome 2");
427 test_properties_.set_arguments(L"--profile-directory=\"Profile 2\"");
428 test_properties_.set_icon(other_ico_, 0);
429 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
430 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
431 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
432 base::FilePath shortcut2_path = GetExpectedShortcutPath(
433 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
434 ASSERT_TRUE(base::PathExists(shortcut2_path));
436 // Shortcut 3: targets "iron.exe"; has arguments; icon set to "chrome.exe".
437 test_properties_.set_shortcut_name(L"Iron 3");
438 test_properties_.set_target(iron_exe_);
439 test_properties_.set_icon(chrome_exe_, 3);
440 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
441 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
442 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
443 base::FilePath shortcut3_path = GetExpectedShortcutPath(
444 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_);
445 ASSERT_TRUE(base::PathExists(shortcut3_path));
447 // Remove shortcuts that target "chrome.exe".
448 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
449 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
450 chrome_exe_));
451 ASSERT_FALSE(base::PathExists(shortcut1_path));
452 ASSERT_FALSE(base::PathExists(shortcut2_path));
453 ASSERT_TRUE(base::PathExists(shortcut3_path));
454 ASSERT_TRUE(base::PathExists(shortcut1_path.DirName()));
457 TEST_F(ShellUtilShortcutTest, RetargetShortcutsWithArgs) {
458 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
459 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
460 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
461 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
462 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
464 base::FilePath new_exe = manganese_exe_;
465 // Relies on the fact that |test_properties_| has non-empty arguments.
466 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
467 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
468 chrome_exe_, new_exe));
470 ShellUtil::ShortcutProperties expected_properties(test_properties_);
471 expected_properties.set_target(new_exe);
472 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
473 expected_properties);
476 TEST_F(ShellUtilShortcutTest, RetargetSystemLevelChromeShortcutsWithArgs) {
477 test_properties_.level = ShellUtil::SYSTEM_LEVEL;
478 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
479 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
480 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
481 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
482 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
484 base::FilePath new_exe = manganese_exe_;
485 // Relies on the fact that |test_properties_| has non-empty arguments.
486 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
487 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::SYSTEM_LEVEL,
488 chrome_exe_, new_exe));
490 ShellUtil::ShortcutProperties expected_properties(test_properties_);
491 expected_properties.set_target(new_exe);
492 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
493 expected_properties);
496 TEST_F(ShellUtilShortcutTest, RetargetChromeShortcutsWithArgsEmpty) {
497 // Shortcut 1: targets "chrome.exe"; no arguments.
498 test_properties_.set_shortcut_name(L"Chrome 1");
499 test_properties_.set_arguments(L"");
500 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
501 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
502 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
503 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
504 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
505 ShellUtil::ShortcutProperties expected_properties1(test_properties_);
507 // Shortcut 2: targets "chrome.exe"; has arguments.
508 test_properties_.set_shortcut_name(L"Chrome 2");
509 test_properties_.set_arguments(L"--profile-directory=\"Profile 2\"");
510 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
511 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
512 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
513 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
514 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
515 ShellUtil::ShortcutProperties expected_properties2(test_properties_);
517 // Retarget shortcuts: replace "chrome.exe" with "manganese.exe". Only
518 // shortcuts with non-empty arguments (i.e., shortcut 2) gets updated.
519 base::FilePath new_exe = manganese_exe_;
520 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
521 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
522 chrome_exe_, new_exe));
524 // Verify shortcut 1: no change.
525 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
526 expected_properties1);
528 // Verify shortcut 2: target => "manganese.exe".
529 expected_properties2.set_target(new_exe);
530 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
531 expected_properties2);
534 TEST_F(ShellUtilShortcutTest, RetargetChromeShortcutsWithArgsIcon) {
535 const int kTestIconIndex1 = 3;
536 const int kTestIconIndex2 = 5;
537 const int kTestIconIndex3 = 8;
539 // Shortcut 1: targets "chrome.exe"; icon same as target.
540 test_properties_.set_shortcut_name(L"Chrome 1");
541 test_properties_.set_icon(test_properties_.target, kTestIconIndex1);
542 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
543 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
544 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
545 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
546 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
547 ShellUtil::ShortcutProperties expected_properties1(test_properties_);
549 // Shortcut 2: targets "chrome.exe"; icon set to "other.ico".
550 test_properties_.set_shortcut_name(L"Chrome 2");
551 test_properties_.set_icon(other_ico_, kTestIconIndex2);
552 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
553 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
554 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
555 ASSERT_TRUE(base::PathExists(GetExpectedShortcutPath(
556 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_)));
557 ShellUtil::ShortcutProperties expected_properties2(test_properties_);
559 // Shortcut 3: targets "iron.exe"; icon set to "chrome.exe".
560 test_properties_.set_target(iron_exe_);
561 test_properties_.set_shortcut_name(L"Iron 3");
562 test_properties_.set_icon(chrome_exe_, kTestIconIndex3);
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_properties3(test_properties_);
570 // Retarget shortcuts: replace "chrome.exe" with "manganese.exe".
571 // Relies on the fact that |test_properties_| has non-empty arguments.
572 base::FilePath new_exe = manganese_exe_;
573 ASSERT_TRUE(ShellUtil::RetargetShortcutsWithArgs(
574 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
575 chrome_exe_, new_exe));
577 // Verify shortcut 1: target & icon => "manganese.exe", kept same icon index.
578 expected_properties1.set_target(new_exe);
579 expected_properties1.set_icon(new_exe, kTestIconIndex1);
580 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
581 expected_properties1);
583 // Verify shortcut 2: target => "manganese.exe", kept icon.
584 expected_properties2.set_target(new_exe);
585 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
586 expected_properties2);
588 // Verify shortcut 3: no change, since target doesn't match.
589 ValidateChromeShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_,
590 expected_properties3);
593 TEST_F(ShellUtilShortcutTest, CreateMultipleStartMenuShortcutsAndRemoveFolder) {
594 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
595 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
596 dist_, test_properties_,
597 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
598 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
599 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR,
600 dist_, test_properties_,
601 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
602 test_properties_.set_shortcut_name(L"A second shortcut");
603 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
604 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR,
605 dist_, test_properties_,
606 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
607 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
608 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR,
609 dist_, test_properties_,
610 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
612 base::FilePath chrome_shortcut_folder(
613 fake_start_menu_.path().Append(
614 dist_->GetStartMenuShortcutSubfolder(
615 BrowserDistribution::SUBFOLDER_CHROME)));
616 base::FilePath chrome_apps_shortcut_folder(
617 fake_start_menu_.path().Append(
618 dist_->GetStartMenuShortcutSubfolder(
619 BrowserDistribution::SUBFOLDER_APPS)));
621 base::FileEnumerator chrome_file_counter(chrome_shortcut_folder, false,
622 base::FileEnumerator::FILES);
623 int count = 0;
624 while (!chrome_file_counter.Next().empty())
625 ++count;
626 EXPECT_EQ(2, count);
628 base::FileEnumerator chrome_apps_file_counter(chrome_apps_shortcut_folder,
629 false,
630 base::FileEnumerator::FILES);
631 count = 0;
632 while (!chrome_apps_file_counter.Next().empty())
633 ++count;
634 EXPECT_EQ(2, count);
636 ASSERT_TRUE(base::PathExists(chrome_shortcut_folder));
637 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
638 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR, dist_,
639 ShellUtil::CURRENT_USER, chrome_exe_));
640 ASSERT_FALSE(base::PathExists(chrome_shortcut_folder));
642 ASSERT_TRUE(base::PathExists(chrome_apps_shortcut_folder));
643 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
644 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR, dist_,
645 ShellUtil::CURRENT_USER, chrome_exe_));
646 ASSERT_FALSE(base::PathExists(chrome_apps_shortcut_folder));
649 TEST_F(ShellUtilShortcutTest,
650 DeleteStartMenuRootShortcutWithoutRemovingFolder) {
651 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
652 ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT,
653 dist_, test_properties_,
654 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
656 base::string16 shortcut_name(
657 dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
658 installer::kLnkExt);
659 base::FilePath shortcut_path(
660 fake_start_menu_.path().Append(shortcut_name));
662 ASSERT_TRUE(base::PathExists(fake_start_menu_.path()));
663 ASSERT_TRUE(base::PathExists(shortcut_path));
664 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
665 ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT, dist_,
666 ShellUtil::CURRENT_USER, chrome_exe_));
667 // The shortcut should be removed but the "Start Menu" root directory should
668 // remain.
669 ASSERT_TRUE(base::PathExists(fake_start_menu_.path()));
670 ASSERT_FALSE(base::PathExists(shortcut_path));
673 TEST_F(ShellUtilShortcutTest, DontRemoveChromeShortcutIfPointsToAnotherChrome) {
674 base::ScopedTempDir other_exe_dir;
675 ASSERT_TRUE(other_exe_dir.CreateUniqueTempDir());
676 base::FilePath other_chrome_exe =
677 other_exe_dir.path().Append(installer::kChromeExe);
678 EXPECT_EQ(0, file_util::WriteFile(other_chrome_exe, "", 0));
680 test_properties_.set_target(other_chrome_exe);
681 ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
682 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, test_properties_,
683 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
685 base::string16 shortcut_name(
686 dist_->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME) +
687 installer::kLnkExt);
688 base::FilePath shortcut_path(fake_user_desktop_.path().Append(shortcut_name));
689 ASSERT_TRUE(base::PathExists(shortcut_path));
691 // The shortcut shouldn't be removed as it was installed pointing to
692 // |other_chrome_exe| and RemoveChromeShortcut() is being told that the
693 // removed shortcut should point to |chrome_exe_|.
694 ASSERT_TRUE(ShellUtil::RemoveShortcuts(
695 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist_, ShellUtil::CURRENT_USER,
696 chrome_exe_));
697 ASSERT_TRUE(base::PathExists(shortcut_path));
698 ASSERT_TRUE(base::PathExists(shortcut_path.DirName()));
701 TEST(ShellUtilTest, BuildAppModelIdBasic) {
702 std::vector<base::string16> components;
703 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
704 const base::string16 base_app_id(dist->GetBaseAppId());
705 components.push_back(base_app_id);
706 ASSERT_EQ(base_app_id, ShellUtil::BuildAppModelId(components));
709 TEST(ShellUtilTest, BuildAppModelIdManySmall) {
710 std::vector<base::string16> components;
711 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
712 const base::string16 suffixed_app_id(dist->GetBaseAppId().append(L".gab"));
713 components.push_back(suffixed_app_id);
714 components.push_back(L"Default");
715 components.push_back(L"Test");
716 ASSERT_EQ(suffixed_app_id + L".Default.Test",
717 ShellUtil::BuildAppModelId(components));
720 TEST(ShellUtilTest, BuildAppModelIdLongUsernameNormalProfile) {
721 std::vector<base::string16> components;
722 const base::string16 long_appname(
723 L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_"
724 L"that_goes_over_64_characters");
725 components.push_back(long_appname);
726 components.push_back(L"Default");
727 ASSERT_EQ(L"Chrome.a_user_wer_64_characters.Default",
728 ShellUtil::BuildAppModelId(components));
731 TEST(ShellUtilTest, BuildAppModelIdLongEverything) {
732 std::vector<base::string16> components;
733 const base::string16 long_appname(L"Chrome.a_user_who_has_a_crazy_long_name_"
734 L"with_some_weird@symbols_in_"
735 L"it_" L"that_goes_over_64_characters");
736 components.push_back(long_appname);
737 components.push_back(
738 L"A_crazy_profile_name_not_even_sure_whether_that_is_possible");
739 const base::string16 constructed_app_id(
740 ShellUtil::BuildAppModelId(components));
741 ASSERT_LE(constructed_app_id.length(), installer::kMaxAppModelIdLength);
742 ASSERT_EQ(L"Chrome.a_user_wer_64_characters.A_crazy_profilethat_is_possible",
743 constructed_app_id);
746 TEST(ShellUtilTest, GetUserSpecificRegistrySuffix) {
747 base::string16 suffix;
748 ASSERT_TRUE(ShellUtil::GetUserSpecificRegistrySuffix(&suffix));
749 ASSERT_TRUE(StartsWith(suffix, L".", true));
750 ASSERT_EQ(27, suffix.length());
751 ASSERT_TRUE(ContainsOnlyChars(suffix.substr(1),
752 L"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"));
755 TEST(ShellUtilTest, GetOldUserSpecificRegistrySuffix) {
756 base::string16 suffix;
757 ASSERT_TRUE(ShellUtil::GetOldUserSpecificRegistrySuffix(&suffix));
758 ASSERT_TRUE(StartsWith(suffix, L".", true));
760 wchar_t user_name[256];
761 DWORD size = arraysize(user_name);
762 ASSERT_NE(0, ::GetUserName(user_name, &size));
763 ASSERT_GE(size, 1U);
764 ASSERT_STREQ(user_name, suffix.substr(1).c_str());
767 TEST(ShellUtilTest, ByteArrayToBase32) {
768 // Tests from http://tools.ietf.org/html/rfc4648#section-10.
769 const unsigned char test_array[] = { 'f', 'o', 'o', 'b', 'a', 'r' };
771 const base::string16 expected[] = { L"", L"MY", L"MZXQ", L"MZXW6", L"MZXW6YQ",
772 L"MZXW6YTB", L"MZXW6YTBOI"};
774 // Run the tests, with one more letter in the input every pass.
775 for (int i = 0; i < arraysize(expected); ++i) {
776 ASSERT_EQ(expected[i],
777 ShellUtil::ByteArrayToBase32(test_array, i));