Componentize AccountReconcilor.
[chromium-blink-merge.git] / chrome / browser / shell_integration_linux_unittest.cc
blobadf43781d8059a2e31001a512d4e525aca87f17b
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/command_line.h"
13 #include "base/environment.h"
14 #include "base/file_util.h"
15 #include "base/files/file_path.h"
16 #include "base/files/scoped_temp_dir.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/stl_util.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/test/scoped_path_override.h"
22 #include "chrome/browser/web_applications/web_app.h"
23 #include "chrome/common/chrome_constants.h"
24 #include "content/public/test/test_browser_thread.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "url/gurl.h"
29 #define FPL FILE_PATH_LITERAL
31 using content::BrowserThread;
32 using ::testing::ElementsAre;
34 namespace {
36 // Provides mock environment variables values based on a stored map.
37 class MockEnvironment : public base::Environment {
38 public:
39 MockEnvironment() {}
41 void Set(const std::string& name, const std::string& value) {
42 variables_[name] = value;
45 virtual bool GetVar(const char* variable_name, std::string* result) OVERRIDE {
46 if (ContainsKey(variables_, variable_name)) {
47 *result = variables_[variable_name];
48 return true;
51 return false;
54 virtual bool SetVar(const char* variable_name,
55 const std::string& new_value) OVERRIDE {
56 ADD_FAILURE();
57 return false;
60 virtual bool UnSetVar(const char* variable_name) OVERRIDE {
61 ADD_FAILURE();
62 return false;
65 private:
66 std::map<std::string, std::string> variables_;
68 DISALLOW_COPY_AND_ASSIGN(MockEnvironment);
71 } // namespace
73 TEST(ShellIntegrationTest, GetDataWriteLocation) {
74 base::MessageLoop message_loop;
75 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
77 // Test that it returns $XDG_DATA_HOME.
79 MockEnvironment env;
80 env.Set("HOME", "/home/user");
81 env.Set("XDG_DATA_HOME", "/user/path");
82 base::FilePath path;
83 ASSERT_TRUE(ShellIntegrationLinux::GetDataWriteLocation(&env, &path));
84 EXPECT_EQ(base::FilePath("/user/path"), path);
87 // Test that $XDG_DATA_HOME falls back to $HOME/.local/share.
89 MockEnvironment env;
90 env.Set("HOME", "/home/user");
91 base::FilePath path;
92 ASSERT_TRUE(ShellIntegrationLinux::GetDataWriteLocation(&env, &path));
93 EXPECT_EQ(base::FilePath("/home/user/.local/share"), path);
96 // Test that if neither $XDG_DATA_HOME nor $HOME are specified, it fails.
98 MockEnvironment env;
99 base::FilePath path;
100 ASSERT_FALSE(ShellIntegrationLinux::GetDataWriteLocation(&env, &path));
104 TEST(ShellIntegrationTest, GetDataSearchLocations) {
105 base::MessageLoop message_loop;
106 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
108 // Test that it returns $XDG_DATA_HOME + $XDG_DATA_DIRS.
110 MockEnvironment env;
111 env.Set("HOME", "/home/user");
112 env.Set("XDG_DATA_HOME", "/user/path");
113 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2");
114 EXPECT_THAT(
115 ShellIntegrationLinux::GetDataSearchLocations(&env),
116 ElementsAre(base::FilePath("/user/path"),
117 base::FilePath("/system/path/1"),
118 base::FilePath("/system/path/2")));
121 // Test that $XDG_DATA_HOME falls back to $HOME/.local/share.
123 MockEnvironment env;
124 env.Set("HOME", "/home/user");
125 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2");
126 EXPECT_THAT(
127 ShellIntegrationLinux::GetDataSearchLocations(&env),
128 ElementsAre(base::FilePath("/home/user/.local/share"),
129 base::FilePath("/system/path/1"),
130 base::FilePath("/system/path/2")));
133 // Test that if neither $XDG_DATA_HOME nor $HOME are specified, it still
134 // succeeds.
136 MockEnvironment env;
137 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2");
138 EXPECT_THAT(
139 ShellIntegrationLinux::GetDataSearchLocations(&env),
140 ElementsAre(base::FilePath("/system/path/1"),
141 base::FilePath("/system/path/2")));
144 // Test that $XDG_DATA_DIRS falls back to the two default paths.
146 MockEnvironment env;
147 env.Set("HOME", "/home/user");
148 env.Set("XDG_DATA_HOME", "/user/path");
149 EXPECT_THAT(
150 ShellIntegrationLinux::GetDataSearchLocations(&env),
151 ElementsAre(base::FilePath("/user/path"),
152 base::FilePath("/usr/local/share"),
153 base::FilePath("/usr/share")));
157 TEST(ShellIntegrationTest, GetExistingShortcutLocations) {
158 base::FilePath kProfilePath("Profile 1");
159 const char kExtensionId[] = "test_extension";
160 const char kTemplateFilename[] = "chrome-test_extension-Profile_1.desktop";
161 base::FilePath kTemplateFilepath(kTemplateFilename);
162 const char kNoDisplayDesktopFile[] = "[Desktop Entry]\nNoDisplay=true";
164 base::MessageLoop message_loop;
165 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
167 // No existing shortcuts.
169 MockEnvironment env;
170 ShellIntegration::ShortcutLocations result =
171 ShellIntegrationLinux::GetExistingShortcutLocations(
172 &env, kProfilePath, kExtensionId);
173 EXPECT_FALSE(result.on_desktop);
174 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_NONE,
175 result.applications_menu_location);
177 EXPECT_FALSE(result.in_quick_launch_bar);
178 EXPECT_FALSE(result.hidden);
181 // Shortcut on desktop.
183 base::ScopedTempDir temp_dir;
184 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
185 base::FilePath desktop_path = temp_dir.path();
187 MockEnvironment env;
188 ASSERT_TRUE(base::CreateDirectory(desktop_path));
189 ASSERT_FALSE(base::WriteFile(
190 desktop_path.AppendASCII(kTemplateFilename),
191 "", 0));
192 ShellIntegration::ShortcutLocations result =
193 ShellIntegrationLinux::GetExistingShortcutLocations(
194 &env, kProfilePath, kExtensionId, desktop_path);
195 EXPECT_TRUE(result.on_desktop);
196 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_NONE,
197 result.applications_menu_location);
199 EXPECT_FALSE(result.in_quick_launch_bar);
200 EXPECT_FALSE(result.hidden);
203 // Shortcut in applications directory.
205 base::ScopedTempDir temp_dir;
206 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
207 base::FilePath apps_path = temp_dir.path().AppendASCII("applications");
209 MockEnvironment env;
210 env.Set("XDG_DATA_HOME", temp_dir.path().value());
211 ASSERT_TRUE(base::CreateDirectory(apps_path));
212 ASSERT_FALSE(base::WriteFile(
213 apps_path.AppendASCII(kTemplateFilename),
214 "", 0));
215 ShellIntegration::ShortcutLocations result =
216 ShellIntegrationLinux::GetExistingShortcutLocations(
217 &env, kProfilePath, kExtensionId);
218 EXPECT_FALSE(result.on_desktop);
219 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
220 result.applications_menu_location);
222 EXPECT_FALSE(result.in_quick_launch_bar);
223 EXPECT_FALSE(result.hidden);
226 // Shortcut in applications directory with NoDisplay=true.
228 base::ScopedTempDir temp_dir;
229 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
230 base::FilePath apps_path = temp_dir.path().AppendASCII("applications");
232 MockEnvironment env;
233 env.Set("XDG_DATA_HOME", temp_dir.path().value());
234 ASSERT_TRUE(base::CreateDirectory(apps_path));
235 ASSERT_TRUE(base::WriteFile(
236 apps_path.AppendASCII(kTemplateFilename),
237 kNoDisplayDesktopFile, strlen(kNoDisplayDesktopFile)));
238 ShellIntegration::ShortcutLocations result =
239 ShellIntegrationLinux::GetExistingShortcutLocations(
240 &env, kProfilePath, kExtensionId);
241 // Doesn't count as being in applications menu.
242 EXPECT_FALSE(result.on_desktop);
243 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_NONE,
244 result.applications_menu_location);
245 EXPECT_FALSE(result.in_quick_launch_bar);
246 EXPECT_TRUE(result.hidden);
249 // Shortcut on desktop and in applications directory.
251 base::ScopedTempDir temp_dir1;
252 ASSERT_TRUE(temp_dir1.CreateUniqueTempDir());
253 base::FilePath desktop_path = temp_dir1.path();
255 base::ScopedTempDir temp_dir2;
256 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
257 base::FilePath apps_path = temp_dir2.path().AppendASCII("applications");
259 MockEnvironment env;
260 ASSERT_TRUE(base::CreateDirectory(desktop_path));
261 ASSERT_FALSE(base::WriteFile(
262 desktop_path.AppendASCII(kTemplateFilename),
263 "", 0));
264 env.Set("XDG_DATA_HOME", temp_dir2.path().value());
265 ASSERT_TRUE(base::CreateDirectory(apps_path));
266 ASSERT_FALSE(base::WriteFile(
267 apps_path.AppendASCII(kTemplateFilename),
268 "", 0));
269 ShellIntegration::ShortcutLocations result =
270 ShellIntegrationLinux::GetExistingShortcutLocations(
271 &env, kProfilePath, kExtensionId, desktop_path);
272 EXPECT_TRUE(result.on_desktop);
273 EXPECT_EQ(ShellIntegration::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
274 result.applications_menu_location);
275 EXPECT_FALSE(result.in_quick_launch_bar);
276 EXPECT_FALSE(result.hidden);
280 TEST(ShellIntegrationTest, GetExistingShortcutContents) {
281 const char kTemplateFilename[] = "shortcut-test.desktop";
282 base::FilePath kTemplateFilepath(kTemplateFilename);
283 const char kTestData1[] = "a magical testing string";
284 const char kTestData2[] = "a different testing string";
286 base::MessageLoop message_loop;
287 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
289 // Test that it searches $XDG_DATA_HOME/applications.
291 base::ScopedTempDir temp_dir;
292 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
294 MockEnvironment env;
295 env.Set("XDG_DATA_HOME", temp_dir.path().value());
296 // Create a file in a non-applications directory. This should be ignored.
297 ASSERT_TRUE(base::WriteFile(
298 temp_dir.path().AppendASCII(kTemplateFilename),
299 kTestData2, strlen(kTestData2)));
300 ASSERT_TRUE(base::CreateDirectory(
301 temp_dir.path().AppendASCII("applications")));
302 ASSERT_TRUE(base::WriteFile(
303 temp_dir.path().AppendASCII("applications")
304 .AppendASCII(kTemplateFilename),
305 kTestData1, strlen(kTestData1)));
306 std::string contents;
307 ASSERT_TRUE(
308 ShellIntegrationLinux::GetExistingShortcutContents(
309 &env, kTemplateFilepath, &contents));
310 EXPECT_EQ(kTestData1, contents);
313 // Test that it falls back to $HOME/.local/share/applications.
315 base::ScopedTempDir temp_dir;
316 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
318 MockEnvironment env;
319 env.Set("HOME", temp_dir.path().value());
320 ASSERT_TRUE(base::CreateDirectory(
321 temp_dir.path().AppendASCII(".local/share/applications")));
322 ASSERT_TRUE(base::WriteFile(
323 temp_dir.path().AppendASCII(".local/share/applications")
324 .AppendASCII(kTemplateFilename),
325 kTestData1, strlen(kTestData1)));
326 std::string contents;
327 ASSERT_TRUE(
328 ShellIntegrationLinux::GetExistingShortcutContents(
329 &env, kTemplateFilepath, &contents));
330 EXPECT_EQ(kTestData1, contents);
333 // Test that it searches $XDG_DATA_DIRS/applications.
335 base::ScopedTempDir temp_dir;
336 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
338 MockEnvironment env;
339 env.Set("XDG_DATA_DIRS", temp_dir.path().value());
340 ASSERT_TRUE(base::CreateDirectory(
341 temp_dir.path().AppendASCII("applications")));
342 ASSERT_TRUE(base::WriteFile(
343 temp_dir.path().AppendASCII("applications")
344 .AppendASCII(kTemplateFilename),
345 kTestData2, strlen(kTestData2)));
346 std::string contents;
347 ASSERT_TRUE(
348 ShellIntegrationLinux::GetExistingShortcutContents(
349 &env, kTemplateFilepath, &contents));
350 EXPECT_EQ(kTestData2, contents);
353 // Test that it searches $X/applications for each X in $XDG_DATA_DIRS.
355 base::ScopedTempDir temp_dir1;
356 ASSERT_TRUE(temp_dir1.CreateUniqueTempDir());
357 base::ScopedTempDir temp_dir2;
358 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
360 MockEnvironment env;
361 env.Set("XDG_DATA_DIRS", temp_dir1.path().value() + ":" +
362 temp_dir2.path().value());
363 // Create a file in a non-applications directory. This should be ignored.
364 ASSERT_TRUE(base::WriteFile(
365 temp_dir1.path().AppendASCII(kTemplateFilename),
366 kTestData1, strlen(kTestData1)));
367 // Only create a findable desktop file in the second path.
368 ASSERT_TRUE(base::CreateDirectory(
369 temp_dir2.path().AppendASCII("applications")));
370 ASSERT_TRUE(base::WriteFile(
371 temp_dir2.path().AppendASCII("applications")
372 .AppendASCII(kTemplateFilename),
373 kTestData2, strlen(kTestData2)));
374 std::string contents;
375 ASSERT_TRUE(
376 ShellIntegrationLinux::GetExistingShortcutContents(
377 &env, kTemplateFilepath, &contents));
378 EXPECT_EQ(kTestData2, contents);
382 TEST(ShellIntegrationTest, GetExtensionShortcutFilename) {
383 base::FilePath kProfilePath("a/b/c/Profile Name?");
384 const char kExtensionId[] = "extensionid";
385 EXPECT_EQ(base::FilePath("chrome-extensionid-Profile_Name_.desktop"),
386 ShellIntegrationLinux::GetExtensionShortcutFilename(
387 kProfilePath, kExtensionId));
390 TEST(ShellIntegrationTest, GetExistingProfileShortcutFilenames) {
391 base::FilePath kProfilePath("a/b/c/Profile Name?");
392 const char kApp1Filename[] = "chrome-extension1-Profile_Name_.desktop";
393 const char kApp2Filename[] = "chrome-extension2-Profile_Name_.desktop";
394 const char kUnrelatedAppFilename[] = "chrome-extension-Other_Profile.desktop";
396 base::MessageLoop message_loop;
397 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop);
399 base::ScopedTempDir temp_dir;
400 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
401 ASSERT_EQ(0,
402 base::WriteFile(
403 temp_dir.path().AppendASCII(kApp1Filename), "", 0));
404 ASSERT_EQ(0,
405 base::WriteFile(
406 temp_dir.path().AppendASCII(kApp2Filename), "", 0));
407 // This file should not be returned in the results.
408 ASSERT_EQ(0,
409 base::WriteFile(
410 temp_dir.path().AppendASCII(kUnrelatedAppFilename), "", 0));
411 std::vector<base::FilePath> paths =
412 ShellIntegrationLinux::GetExistingProfileShortcutFilenames(
413 kProfilePath, temp_dir.path());
414 // Path order is arbitrary. Sort the output for consistency.
415 std::sort(paths.begin(), paths.end());
416 EXPECT_THAT(paths,
417 ElementsAre(base::FilePath(kApp1Filename),
418 base::FilePath(kApp2Filename)));
421 TEST(ShellIntegrationTest, GetWebShortcutFilename) {
422 const struct {
423 const base::FilePath::CharType* path;
424 const char* url;
425 } test_cases[] = {
426 { FPL("http___foo_.desktop"), "http://foo" },
427 { FPL("http___foo_bar_.desktop"), "http://foo/bar/" },
428 { FPL("http___foo_bar_a=b&c=d.desktop"), "http://foo/bar?a=b&c=d" },
430 // Now we're starting to be more evil...
431 { FPL("http___foo_.desktop"), "http://foo/bar/baz/../../../../../" },
432 { FPL("http___foo_.desktop"), "http://foo/bar/././../baz/././../" },
433 { FPL("http___.._.desktop"), "http://../../../../" },
435 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
436 EXPECT_EQ(std::string(chrome::kBrowserProcessExecutableName) + "-" +
437 test_cases[i].path,
438 ShellIntegrationLinux::GetWebShortcutFilename(
439 GURL(test_cases[i].url)).value()) <<
440 " while testing " << test_cases[i].url;
444 TEST(ShellIntegrationTest, GetDesktopFileContents) {
445 const base::FilePath kChromeExePath("/opt/google/chrome/google-chrome");
446 const struct {
447 const char* url;
448 const char* title;
449 const char* icon_name;
450 bool nodisplay;
451 const char* expected_output;
452 } test_cases[] = {
453 // Real-world case.
454 { "http://gmail.com",
455 "GMail",
456 "chrome-http__gmail.com",
457 false,
459 "#!/usr/bin/env xdg-open\n"
460 "[Desktop Entry]\n"
461 "Version=1.0\n"
462 "Terminal=false\n"
463 "Type=Application\n"
464 "Name=GMail\n"
465 "Exec=/opt/google/chrome/google-chrome --app=http://gmail.com/\n"
466 "Icon=chrome-http__gmail.com\n"
467 "StartupWMClass=gmail.com\n"
470 // Make sure that empty icons are replaced by the chrome icon.
471 { "http://gmail.com",
472 "GMail",
474 false,
476 "#!/usr/bin/env xdg-open\n"
477 "[Desktop Entry]\n"
478 "Version=1.0\n"
479 "Terminal=false\n"
480 "Type=Application\n"
481 "Name=GMail\n"
482 "Exec=/opt/google/chrome/google-chrome --app=http://gmail.com/\n"
483 #if defined(GOOGLE_CHROME_BUILD)
484 "Icon=google-chrome\n"
485 #else
486 "Icon=chromium-browser\n"
487 #endif
488 "StartupWMClass=gmail.com\n"
491 // Test adding NoDisplay=true.
492 { "http://gmail.com",
493 "GMail",
494 "chrome-http__gmail.com",
495 true,
497 "#!/usr/bin/env xdg-open\n"
498 "[Desktop Entry]\n"
499 "Version=1.0\n"
500 "Terminal=false\n"
501 "Type=Application\n"
502 "Name=GMail\n"
503 "Exec=/opt/google/chrome/google-chrome --app=http://gmail.com/\n"
504 "Icon=chrome-http__gmail.com\n"
505 "NoDisplay=true\n"
506 "StartupWMClass=gmail.com\n"
509 // Now we're starting to be more evil...
510 { "http://evil.com/evil --join-the-b0tnet",
511 "Ownz0red\nExec=rm -rf /",
512 "chrome-http__evil.com_evil",
513 false,
515 "#!/usr/bin/env xdg-open\n"
516 "[Desktop Entry]\n"
517 "Version=1.0\n"
518 "Terminal=false\n"
519 "Type=Application\n"
520 "Name=http://evil.com/evil%20--join-the-b0tnet\n"
521 "Exec=/opt/google/chrome/google-chrome "
522 "--app=http://evil.com/evil%20--join-the-b0tnet\n"
523 "Icon=chrome-http__evil.com_evil\n"
524 "StartupWMClass=evil.com__evil%20--join-the-b0tnet\n"
526 { "http://evil.com/evil; rm -rf /; \"; rm -rf $HOME >ownz0red",
527 "Innocent Title",
528 "chrome-http__evil.com_evil",
529 false,
531 "#!/usr/bin/env xdg-open\n"
532 "[Desktop Entry]\n"
533 "Version=1.0\n"
534 "Terminal=false\n"
535 "Type=Application\n"
536 "Name=Innocent Title\n"
537 "Exec=/opt/google/chrome/google-chrome "
538 "\"--app=http://evil.com/evil;%20rm%20-rf%20/;%20%22;%20rm%20"
539 // Note: $ is escaped as \$ within an arg to Exec, and then
540 // the \ is escaped as \\ as all strings in a Desktop file should
541 // be; finally, \\ becomes \\\\ when represented in a C++ string!
542 "-rf%20\\\\$HOME%20%3Eownz0red\"\n"
543 "Icon=chrome-http__evil.com_evil\n"
544 "StartupWMClass=evil.com__evil;%20rm%20-rf%20_;%20%22;%20"
545 "rm%20-rf%20$HOME%20%3Eownz0red\n"
547 { "http://evil.com/evil | cat `echo ownz0red` >/dev/null",
548 "Innocent Title",
549 "chrome-http__evil.com_evil",
550 false,
552 "#!/usr/bin/env xdg-open\n"
553 "[Desktop Entry]\n"
554 "Version=1.0\n"
555 "Terminal=false\n"
556 "Type=Application\n"
557 "Name=Innocent Title\n"
558 "Exec=/opt/google/chrome/google-chrome "
559 "--app=http://evil.com/evil%20%7C%20cat%20%60echo%20ownz0red"
560 "%60%20%3E/dev/null\n"
561 "Icon=chrome-http__evil.com_evil\n"
562 "StartupWMClass=evil.com__evil%20%7C%20cat%20%60echo%20ownz0red"
563 "%60%20%3E_dev_null\n"
567 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
568 SCOPED_TRACE(i);
569 EXPECT_EQ(
570 test_cases[i].expected_output,
571 ShellIntegrationLinux::GetDesktopFileContents(
572 kChromeExePath,
573 web_app::GenerateApplicationNameFromURL(GURL(test_cases[i].url)),
574 GURL(test_cases[i].url),
575 std::string(),
576 base::ASCIIToUTF16(test_cases[i].title),
577 test_cases[i].icon_name,
578 base::FilePath(),
579 test_cases[i].nodisplay));
583 TEST(ShellIntegrationTest, GetDesktopFileContentsAppList) {
584 const base::FilePath kChromeExePath("/opt/google/chrome/google-chrome");
585 CommandLine command_line(kChromeExePath);
586 command_line.AppendSwitch("--show-app-list");
587 EXPECT_EQ(
588 "#!/usr/bin/env xdg-open\n"
589 "[Desktop Entry]\n"
590 "Version=1.0\n"
591 "Terminal=false\n"
592 "Type=Application\n"
593 "Name=Chrome App Launcher\n"
594 "Exec=/opt/google/chrome/google-chrome --show-app-list\n"
595 "Icon=chrome_app_list\n"
596 "StartupWMClass=chrome-app-list\n",
597 ShellIntegrationLinux::GetDesktopFileContentsForCommand(
598 command_line,
599 "chrome-app-list",
600 GURL(),
601 base::ASCIIToUTF16("Chrome App Launcher"),
602 "chrome_app_list",
603 false));
606 TEST(ShellIntegrationTest, GetDirectoryFileContents) {
607 const struct {
608 const char* title;
609 const char* icon_name;
610 const char* expected_output;
611 } test_cases[] = {
612 // Real-world case.
613 { "Chrome Apps",
614 "chrome-apps",
616 "[Desktop Entry]\n"
617 "Version=1.0\n"
618 "Type=Directory\n"
619 "Name=Chrome Apps\n"
620 "Icon=chrome-apps\n"
623 // Make sure that empty icons are replaced by the chrome icon.
624 { "Chrome Apps",
627 "[Desktop Entry]\n"
628 "Version=1.0\n"
629 "Type=Directory\n"
630 "Name=Chrome Apps\n"
631 #if defined(GOOGLE_CHROME_BUILD)
632 "Icon=google-chrome\n"
633 #else
634 "Icon=chromium-browser\n"
635 #endif
639 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
640 SCOPED_TRACE(i);
641 EXPECT_EQ(
642 test_cases[i].expected_output,
643 ShellIntegrationLinux::GetDirectoryFileContents(
644 base::ASCIIToUTF16(test_cases[i].title),
645 test_cases[i].icon_name));