Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / shell_integration_linux_unittest.cc
blob39ecd625169b8bf4cd8ef2a34f60c0d49ba45e64
1 // Copyright 2013 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/browser/shell_integration_linux.h"
7 #include <algorithm>
8 #include <cstdlib>
9 #include <map>
11 #include "base/base_paths.h"
12 #include "base/environment.h"
13 #include "base/file_util.h"
14 #include "base/files/file_path.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/stl_util.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/test/scoped_path_override.h"
21 #include "chrome/browser/web_applications/web_app.h"
22 #include "chrome/common/chrome_constants.h"
23 #include "content/public/test/test_browser_thread.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "url/gurl.h"
28 #define FPL FILE_PATH_LITERAL
30 using content::BrowserThread;
31 using ::testing::ElementsAre;
33 namespace {
35 // Provides mock environment variables values based on a stored map.
36 class MockEnvironment : public base::Environment {
37 public:
38 MockEnvironment() {}
40 void Set(const std::string& name, const std::string& value) {
41 variables_[name] = value;
44 virtual bool GetVar(const char* variable_name, std::string* result) OVERRIDE {
45 if (ContainsKey(variables_, variable_name)) {
46 *result = variables_[variable_name];
47 return true;
50 return false;
53 virtual bool SetVar(const char* variable_name,
54 const std::string& new_value) OVERRIDE {
55 ADD_FAILURE();
56 return false;
59 virtual bool UnSetVar(const char* variable_name) OVERRIDE {
60 ADD_FAILURE();
61 return false;
64 private:
65 std::map<std::string, std::string> variables_;
67 DISALLOW_COPY_AND_ASSIGN(MockEnvironment);
70 } // namespace
72 TEST(ShellIntegrationTest, GetDataWriteLocation) {
73 base::MessageLoop message_loop;
74 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
76 // Test that it returns $XDG_DATA_HOME.
78 MockEnvironment env;
79 env.Set("HOME", "/home/user");
80 env.Set("XDG_DATA_HOME", "/user/path");
81 base::FilePath path;
82 ASSERT_TRUE(ShellIntegrationLinux::GetDataWriteLocation(&env, &path));
83 EXPECT_EQ(base::FilePath("/user/path"), path);
86 // Test that $XDG_DATA_HOME falls back to $HOME/.local/share.
88 MockEnvironment env;
89 env.Set("HOME", "/home/user");
90 base::FilePath path;
91 ASSERT_TRUE(ShellIntegrationLinux::GetDataWriteLocation(&env, &path));
92 EXPECT_EQ(base::FilePath("/home/user/.local/share"), path);
95 // Test that if neither $XDG_DATA_HOME nor $HOME are specified, it fails.
97 MockEnvironment env;
98 base::FilePath path;
99 ASSERT_FALSE(ShellIntegrationLinux::GetDataWriteLocation(&env, &path));
103 TEST(ShellIntegrationTest, GetDataSearchLocations) {
104 base::MessageLoop message_loop;
105 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
107 // Test that it returns $XDG_DATA_HOME + $XDG_DATA_DIRS.
109 MockEnvironment env;
110 env.Set("HOME", "/home/user");
111 env.Set("XDG_DATA_HOME", "/user/path");
112 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2");
113 EXPECT_THAT(
114 ShellIntegrationLinux::GetDataSearchLocations(&env),
115 ElementsAre(base::FilePath("/user/path"),
116 base::FilePath("/system/path/1"),
117 base::FilePath("/system/path/2")));
120 // Test that $XDG_DATA_HOME falls back to $HOME/.local/share.
122 MockEnvironment env;
123 env.Set("HOME", "/home/user");
124 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2");
125 EXPECT_THAT(
126 ShellIntegrationLinux::GetDataSearchLocations(&env),
127 ElementsAre(base::FilePath("/home/user/.local/share"),
128 base::FilePath("/system/path/1"),
129 base::FilePath("/system/path/2")));
132 // Test that if neither $XDG_DATA_HOME nor $HOME are specified, it still
133 // succeeds.
135 MockEnvironment env;
136 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2");
137 EXPECT_THAT(
138 ShellIntegrationLinux::GetDataSearchLocations(&env),
139 ElementsAre(base::FilePath("/system/path/1"),
140 base::FilePath("/system/path/2")));
143 // Test that $XDG_DATA_DIRS falls back to the two default paths.
145 MockEnvironment env;
146 env.Set("HOME", "/home/user");
147 env.Set("XDG_DATA_HOME", "/user/path");
148 EXPECT_THAT(
149 ShellIntegrationLinux::GetDataSearchLocations(&env),
150 ElementsAre(base::FilePath("/user/path"),
151 base::FilePath("/usr/local/share"),
152 base::FilePath("/usr/share")));
156 TEST(ShellIntegrationTest, GetExistingShortcutLocations) {
157 base::FilePath kProfilePath("Profile 1");
158 const char kExtensionId[] = "test_extension";
159 const char kTemplateFilename[] = "chrome-test_extension-Profile_1.desktop";
160 base::FilePath kTemplateFilepath(kTemplateFilename);
161 const char kNoDisplayDesktopFile[] = "[Desktop Entry]\nNoDisplay=true";
163 base::MessageLoop message_loop;
164 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
166 // No existing shortcuts.
168 MockEnvironment env;
169 ShellIntegration::ShortcutLocations result =
170 ShellIntegrationLinux::GetExistingShortcutLocations(
171 &env, kProfilePath, kExtensionId);
172 EXPECT_FALSE(result.on_desktop);
173 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_NONE,
174 result.applications_menu_location);
176 EXPECT_FALSE(result.in_quick_launch_bar);
177 EXPECT_FALSE(result.hidden);
180 // Shortcut on desktop.
182 base::ScopedTempDir temp_dir;
183 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
184 base::FilePath desktop_path = temp_dir.path();
186 MockEnvironment env;
187 ASSERT_TRUE(base::CreateDirectory(desktop_path));
188 ASSERT_FALSE(file_util::WriteFile(
189 desktop_path.AppendASCII(kTemplateFilename),
190 "", 0));
191 ShellIntegration::ShortcutLocations result =
192 ShellIntegrationLinux::GetExistingShortcutLocations(
193 &env, kProfilePath, kExtensionId, desktop_path);
194 EXPECT_TRUE(result.on_desktop);
195 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_NONE,
196 result.applications_menu_location);
198 EXPECT_FALSE(result.in_quick_launch_bar);
199 EXPECT_FALSE(result.hidden);
202 // Shortcut in applications directory.
204 base::ScopedTempDir temp_dir;
205 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
206 base::FilePath apps_path = temp_dir.path().AppendASCII("applications");
208 MockEnvironment env;
209 env.Set("XDG_DATA_HOME", temp_dir.path().value());
210 ASSERT_TRUE(base::CreateDirectory(apps_path));
211 ASSERT_FALSE(file_util::WriteFile(
212 apps_path.AppendASCII(kTemplateFilename),
213 "", 0));
214 ShellIntegration::ShortcutLocations result =
215 ShellIntegrationLinux::GetExistingShortcutLocations(
216 &env, kProfilePath, kExtensionId);
217 EXPECT_FALSE(result.on_desktop);
218 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
219 result.applications_menu_location);
221 EXPECT_FALSE(result.in_quick_launch_bar);
222 EXPECT_FALSE(result.hidden);
225 // Shortcut in applications directory with NoDisplay=true.
227 base::ScopedTempDir temp_dir;
228 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
229 base::FilePath apps_path = temp_dir.path().AppendASCII("applications");
231 MockEnvironment env;
232 env.Set("XDG_DATA_HOME", temp_dir.path().value());
233 ASSERT_TRUE(base::CreateDirectory(apps_path));
234 ASSERT_TRUE(file_util::WriteFile(
235 apps_path.AppendASCII(kTemplateFilename),
236 kNoDisplayDesktopFile, strlen(kNoDisplayDesktopFile)));
237 ShellIntegration::ShortcutLocations result =
238 ShellIntegrationLinux::GetExistingShortcutLocations(
239 &env, kProfilePath, kExtensionId);
240 // Doesn't count as being in applications menu.
241 EXPECT_FALSE(result.on_desktop);
242 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_NONE,
243 result.applications_menu_location);
244 EXPECT_FALSE(result.in_quick_launch_bar);
245 EXPECT_TRUE(result.hidden);
248 // Shortcut on desktop and in applications directory.
250 base::ScopedTempDir temp_dir1;
251 ASSERT_TRUE(temp_dir1.CreateUniqueTempDir());
252 base::FilePath desktop_path = temp_dir1.path();
254 base::ScopedTempDir temp_dir2;
255 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
256 base::FilePath apps_path = temp_dir2.path().AppendASCII("applications");
258 MockEnvironment env;
259 ASSERT_TRUE(base::CreateDirectory(desktop_path));
260 ASSERT_FALSE(file_util::WriteFile(
261 desktop_path.AppendASCII(kTemplateFilename),
262 "", 0));
263 env.Set("XDG_DATA_HOME", temp_dir2.path().value());
264 ASSERT_TRUE(base::CreateDirectory(apps_path));
265 ASSERT_FALSE(file_util::WriteFile(
266 apps_path.AppendASCII(kTemplateFilename),
267 "", 0));
268 ShellIntegration::ShortcutLocations result =
269 ShellIntegrationLinux::GetExistingShortcutLocations(
270 &env, kProfilePath, kExtensionId, desktop_path);
271 EXPECT_TRUE(result.on_desktop);
272 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
273 result.applications_menu_location);
274 EXPECT_FALSE(result.in_quick_launch_bar);
275 EXPECT_FALSE(result.hidden);
279 TEST(ShellIntegrationTest, GetExistingShortcutContents) {
280 const char kTemplateFilename[] = "shortcut-test.desktop";
281 base::FilePath kTemplateFilepath(kTemplateFilename);
282 const char kTestData1[] = "a magical testing string";
283 const char kTestData2[] = "a different testing string";
285 base::MessageLoop message_loop;
286 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
288 // Test that it searches $XDG_DATA_HOME/applications.
290 base::ScopedTempDir temp_dir;
291 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
293 MockEnvironment env;
294 env.Set("XDG_DATA_HOME", temp_dir.path().value());
295 // Create a file in a non-applications directory. This should be ignored.
296 ASSERT_TRUE(file_util::WriteFile(
297 temp_dir.path().AppendASCII(kTemplateFilename),
298 kTestData2, strlen(kTestData2)));
299 ASSERT_TRUE(base::CreateDirectory(
300 temp_dir.path().AppendASCII("applications")));
301 ASSERT_TRUE(file_util::WriteFile(
302 temp_dir.path().AppendASCII("applications")
303 .AppendASCII(kTemplateFilename),
304 kTestData1, strlen(kTestData1)));
305 std::string contents;
306 ASSERT_TRUE(
307 ShellIntegrationLinux::GetExistingShortcutContents(
308 &env, kTemplateFilepath, &contents));
309 EXPECT_EQ(kTestData1, contents);
312 // Test that it falls back to $HOME/.local/share/applications.
314 base::ScopedTempDir temp_dir;
315 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
317 MockEnvironment env;
318 env.Set("HOME", temp_dir.path().value());
319 ASSERT_TRUE(base::CreateDirectory(
320 temp_dir.path().AppendASCII(".local/share/applications")));
321 ASSERT_TRUE(file_util::WriteFile(
322 temp_dir.path().AppendASCII(".local/share/applications")
323 .AppendASCII(kTemplateFilename),
324 kTestData1, strlen(kTestData1)));
325 std::string contents;
326 ASSERT_TRUE(
327 ShellIntegrationLinux::GetExistingShortcutContents(
328 &env, kTemplateFilepath, &contents));
329 EXPECT_EQ(kTestData1, contents);
332 // Test that it searches $XDG_DATA_DIRS/applications.
334 base::ScopedTempDir temp_dir;
335 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
337 MockEnvironment env;
338 env.Set("XDG_DATA_DIRS", temp_dir.path().value());
339 ASSERT_TRUE(base::CreateDirectory(
340 temp_dir.path().AppendASCII("applications")));
341 ASSERT_TRUE(file_util::WriteFile(
342 temp_dir.path().AppendASCII("applications")
343 .AppendASCII(kTemplateFilename),
344 kTestData2, strlen(kTestData2)));
345 std::string contents;
346 ASSERT_TRUE(
347 ShellIntegrationLinux::GetExistingShortcutContents(
348 &env, kTemplateFilepath, &contents));
349 EXPECT_EQ(kTestData2, contents);
352 // Test that it searches $X/applications for each X in $XDG_DATA_DIRS.
354 base::ScopedTempDir temp_dir1;
355 ASSERT_TRUE(temp_dir1.CreateUniqueTempDir());
356 base::ScopedTempDir temp_dir2;
357 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
359 MockEnvironment env;
360 env.Set("XDG_DATA_DIRS", temp_dir1.path().value() + ":" +
361 temp_dir2.path().value());
362 // Create a file in a non-applications directory. This should be ignored.
363 ASSERT_TRUE(file_util::WriteFile(
364 temp_dir1.path().AppendASCII(kTemplateFilename),
365 kTestData1, strlen(kTestData1)));
366 // Only create a findable desktop file in the second path.
367 ASSERT_TRUE(base::CreateDirectory(
368 temp_dir2.path().AppendASCII("applications")));
369 ASSERT_TRUE(file_util::WriteFile(
370 temp_dir2.path().AppendASCII("applications")
371 .AppendASCII(kTemplateFilename),
372 kTestData2, strlen(kTestData2)));
373 std::string contents;
374 ASSERT_TRUE(
375 ShellIntegrationLinux::GetExistingShortcutContents(
376 &env, kTemplateFilepath, &contents));
377 EXPECT_EQ(kTestData2, contents);
381 TEST(ShellIntegrationTest, GetExtensionShortcutFilename) {
382 base::FilePath kProfilePath("a/b/c/Profile Name?");
383 const char kExtensionId[] = "extensionid";
384 EXPECT_EQ(base::FilePath("chrome-extensionid-Profile_Name_.desktop"),
385 ShellIntegrationLinux::GetExtensionShortcutFilename(
386 kProfilePath, kExtensionId));
389 TEST(ShellIntegrationTest, GetExistingProfileShortcutFilenames) {
390 base::FilePath kProfilePath("a/b/c/Profile Name?");
391 const char kApp1Filename[] = "chrome-extension1-Profile_Name_.desktop";
392 const char kApp2Filename[] = "chrome-extension2-Profile_Name_.desktop";
393 const char kUnrelatedAppFilename[] = "chrome-extension-Other_Profile.desktop";
395 base::MessageLoop message_loop;
396 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
398 base::ScopedTempDir temp_dir;
399 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
400 ASSERT_EQ(0,
401 file_util::WriteFile(
402 temp_dir.path().AppendASCII(kApp1Filename), "", 0));
403 ASSERT_EQ(0,
404 file_util::WriteFile(
405 temp_dir.path().AppendASCII(kApp2Filename), "", 0));
406 // This file should not be returned in the results.
407 ASSERT_EQ(0,
408 file_util::WriteFile(
409 temp_dir.path().AppendASCII(kUnrelatedAppFilename), "", 0));
410 std::vector<base::FilePath> paths =
411 ShellIntegrationLinux::GetExistingProfileShortcutFilenames(
412 kProfilePath, temp_dir.path());
413 // Path order is arbitrary. Sort the output for consistency.
414 std::sort(paths.begin(), paths.end());
415 EXPECT_THAT(paths,
416 ElementsAre(base::FilePath(kApp1Filename),
417 base::FilePath(kApp2Filename)));
420 TEST(ShellIntegrationTest, GetWebShortcutFilename) {
421 const struct {
422 const base::FilePath::CharType* path;
423 const char* url;
424 } test_cases[] = {
425 { FPL("http___foo_.desktop"), "http://foo" },
426 { FPL("http___foo_bar_.desktop"), "http://foo/bar/" },
427 { FPL("http___foo_bar_a=b&c=d.desktop"), "http://foo/bar?a=b&c=d" },
429 // Now we're starting to be more evil...
430 { FPL("http___foo_.desktop"), "http://foo/bar/baz/../../../../../" },
431 { FPL("http___foo_.desktop"), "http://foo/bar/././../baz/././../" },
432 { FPL("http___.._.desktop"), "http://../../../../" },
434 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
435 EXPECT_EQ(std::string(chrome::kBrowserProcessExecutableName) + "-" +
436 test_cases[i].path,
437 ShellIntegrationLinux::GetWebShortcutFilename(
438 GURL(test_cases[i].url)).value()) <<
439 " while testing " << test_cases[i].url;
443 TEST(ShellIntegrationTest, GetDesktopFileContents) {
444 const base::FilePath kChromeExePath("/opt/google/chrome/google-chrome");
445 const struct {
446 const char* url;
447 const char* title;
448 const char* icon_name;
449 bool nodisplay;
450 const char* expected_output;
451 } test_cases[] = {
452 // Real-world case.
453 { "http://gmail.com",
454 "GMail",
455 "chrome-http__gmail.com",
456 false,
458 "#!/usr/bin/env xdg-open\n"
459 "[Desktop Entry]\n"
460 "Version=1.0\n"
461 "Terminal=false\n"
462 "Type=Application\n"
463 "Name=GMail\n"
464 "Exec=/opt/google/chrome/google-chrome --app=http://gmail.com/\n"
465 "Icon=chrome-http__gmail.com\n"
466 "StartupWMClass=gmail.com\n"
469 // Make sure that empty icons are replaced by the chrome icon.
470 { "http://gmail.com",
471 "GMail",
473 false,
475 "#!/usr/bin/env xdg-open\n"
476 "[Desktop Entry]\n"
477 "Version=1.0\n"
478 "Terminal=false\n"
479 "Type=Application\n"
480 "Name=GMail\n"
481 "Exec=/opt/google/chrome/google-chrome --app=http://gmail.com/\n"
482 #if defined(GOOGLE_CHROME_BUILD)
483 "Icon=google-chrome\n"
484 #else
485 "Icon=chromium-browser\n"
486 #endif
487 "StartupWMClass=gmail.com\n"
490 // Test adding NoDisplay=true.
491 { "http://gmail.com",
492 "GMail",
493 "chrome-http__gmail.com",
494 true,
496 "#!/usr/bin/env xdg-open\n"
497 "[Desktop Entry]\n"
498 "Version=1.0\n"
499 "Terminal=false\n"
500 "Type=Application\n"
501 "Name=GMail\n"
502 "Exec=/opt/google/chrome/google-chrome --app=http://gmail.com/\n"
503 "Icon=chrome-http__gmail.com\n"
504 "NoDisplay=true\n"
505 "StartupWMClass=gmail.com\n"
508 // Now we're starting to be more evil...
509 { "http://evil.com/evil --join-the-b0tnet",
510 "Ownz0red\nExec=rm -rf /",
511 "chrome-http__evil.com_evil",
512 false,
514 "#!/usr/bin/env xdg-open\n"
515 "[Desktop Entry]\n"
516 "Version=1.0\n"
517 "Terminal=false\n"
518 "Type=Application\n"
519 "Name=http://evil.com/evil%20--join-the-b0tnet\n"
520 "Exec=/opt/google/chrome/google-chrome "
521 "--app=http://evil.com/evil%20--join-the-b0tnet\n"
522 "Icon=chrome-http__evil.com_evil\n"
523 "StartupWMClass=evil.com__evil%20--join-the-b0tnet\n"
525 { "http://evil.com/evil; rm -rf /; \"; rm -rf $HOME >ownz0red",
526 "Innocent Title",
527 "chrome-http__evil.com_evil",
528 false,
530 "#!/usr/bin/env xdg-open\n"
531 "[Desktop Entry]\n"
532 "Version=1.0\n"
533 "Terminal=false\n"
534 "Type=Application\n"
535 "Name=Innocent Title\n"
536 "Exec=/opt/google/chrome/google-chrome "
537 "\"--app=http://evil.com/evil;%20rm%20-rf%20/;%20%22;%20rm%20"
538 // Note: $ is escaped as \$ within an arg to Exec, and then
539 // the \ is escaped as \\ as all strings in a Desktop file should
540 // be; finally, \\ becomes \\\\ when represented in a C++ string!
541 "-rf%20\\\\$HOME%20%3Eownz0red\"\n"
542 "Icon=chrome-http__evil.com_evil\n"
543 "StartupWMClass=evil.com__evil;%20rm%20-rf%20_;%20%22;%20"
544 "rm%20-rf%20$HOME%20%3Eownz0red\n"
546 { "http://evil.com/evil | cat `echo ownz0red` >/dev/null",
547 "Innocent Title",
548 "chrome-http__evil.com_evil",
549 false,
551 "#!/usr/bin/env xdg-open\n"
552 "[Desktop Entry]\n"
553 "Version=1.0\n"
554 "Terminal=false\n"
555 "Type=Application\n"
556 "Name=Innocent Title\n"
557 "Exec=/opt/google/chrome/google-chrome "
558 "--app=http://evil.com/evil%20%7C%20cat%20%60echo%20ownz0red"
559 "%60%20%3E/dev/null\n"
560 "Icon=chrome-http__evil.com_evil\n"
561 "StartupWMClass=evil.com__evil%20%7C%20cat%20%60echo%20ownz0red"
562 "%60%20%3E_dev_null\n"
566 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
567 SCOPED_TRACE(i);
568 EXPECT_EQ(
569 test_cases[i].expected_output,
570 ShellIntegrationLinux::GetDesktopFileContents(
571 kChromeExePath,
572 web_app::GenerateApplicationNameFromURL(GURL(test_cases[i].url)),
573 GURL(test_cases[i].url),
574 std::string(),
575 base::FilePath(),
576 base::ASCIIToUTF16(test_cases[i].title),
577 test_cases[i].icon_name,
578 base::FilePath(),
579 test_cases[i].nodisplay,
580 false));
584 TEST(ShellIntegrationTest, GetDesktopFileContentsAppList) {
585 const base::FilePath kChromeExePath("/opt/google/chrome/google-chrome");
586 EXPECT_EQ(
587 "#!/usr/bin/env xdg-open\n"
588 "[Desktop Entry]\n"
589 "Version=1.0\n"
590 "Terminal=false\n"
591 "Type=Application\n"
592 "Name=Chrome App Launcher\n"
593 "Exec=/opt/google/chrome/google-chrome --show-app-list\n"
594 "Icon=chrome_app_list\n"
595 "StartupWMClass=chrome-app-list\n",
596 ShellIntegrationLinux::GetDesktopFileContents(
597 kChromeExePath,
598 "chrome-app-list",
599 GURL(),
600 std::string(),
601 base::FilePath(),
602 base::ASCIIToUTF16("Chrome App Launcher"),
603 "chrome_app_list",
604 base::FilePath(),
605 false,
606 true));
609 TEST(ShellIntegrationTest, GetDirectoryFileContents) {
610 const struct {
611 const char* title;
612 const char* icon_name;
613 const char* expected_output;
614 } test_cases[] = {
615 // Real-world case.
616 { "Chrome Apps",
617 "chrome-apps",
619 "[Desktop Entry]\n"
620 "Version=1.0\n"
621 "Type=Directory\n"
622 "Name=Chrome Apps\n"
623 "Icon=chrome-apps\n"
626 // Make sure that empty icons are replaced by the chrome icon.
627 { "Chrome Apps",
630 "[Desktop Entry]\n"
631 "Version=1.0\n"
632 "Type=Directory\n"
633 "Name=Chrome Apps\n"
634 #if defined(GOOGLE_CHROME_BUILD)
635 "Icon=google-chrome\n"
636 #else
637 "Icon=chromium-browser\n"
638 #endif
642 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
643 SCOPED_TRACE(i);
644 EXPECT_EQ(
645 test_cases[i].expected_output,
646 ShellIntegrationLinux::GetDirectoryFileContents(
647 base::ASCIIToUTF16(test_cases[i].title),
648 test_cases[i].icon_name));