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