blob: 4353911711f4e925790c630597498c3c4aa54237 [file] [log] [blame]
[email protected]9bc8cff2010-04-03 01:05:391// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]b96aa932009-08-12 21:34:492// 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/browser/shell_integration.h"
6
[email protected]af71d642010-03-12 10:29:047#include <map>
8
[email protected]b96aa932009-08-12 21:34:499#include "base/file_path.h"
[email protected]af71d642010-03-12 10:29:0410#include "base/file_util.h"
[email protected]af71d642010-03-12 10:29:0411#include "base/message_loop.h"
12#include "base/scoped_temp_dir.h"
13#include "base/stl_util-inl.h"
[email protected]b96aa932009-08-12 21:34:4914#include "base/string_util.h"
[email protected]be1ce6a72010-08-03 14:35:2215#include "base/utf_string_conversions.h"
[email protected]af71d642010-03-12 10:29:0416#include "chrome/browser/chrome_thread.h"
[email protected]42896802009-08-28 23:39:4417#include "chrome/common/chrome_constants.h"
[email protected]12f520c2010-01-06 18:11:1518#include "chrome/common/chrome_paths_internal.h"
[email protected]b96aa932009-08-12 21:34:4919#include "googleurl/src/gurl.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
[email protected]1caa92612010-06-11 00:13:5622#if defined(OS_WIN)
23#include "chrome/installer/util/browser_distribution.h"
24#elif defined(OS_LINUX)
[email protected]76b90d312010-08-03 03:00:5025#include "base/environment.h"
[email protected]3bc60432010-03-12 11:15:1326#endif // defined(OS_LINUX)
27
[email protected]b96aa932009-08-12 21:34:4928#define FPL FILE_PATH_LITERAL
29
30#if defined(OS_LINUX)
[email protected]af71d642010-03-12 10:29:0431namespace {
32
33// Provides mock environment variables values based on a stored map.
[email protected]76b90d312010-08-03 03:00:5034class MockEnvironment : public base::Environment {
[email protected]af71d642010-03-12 10:29:0435 public:
[email protected]76b90d312010-08-03 03:00:5036 MockEnvironment() {}
[email protected]af71d642010-03-12 10:29:0437
38 void Set(const std::string& name, const std::string& value) {
39 variables_[name] = value;
40 }
41
[email protected]9bc8cff2010-04-03 01:05:3942 virtual bool GetEnv(const char* variable_name, std::string* result) {
[email protected]af71d642010-03-12 10:29:0443 if (ContainsKey(variables_, variable_name)) {
44 *result = variables_[variable_name];
45 return true;
46 }
47
48 return false;
49 }
50
[email protected]e9032c62010-07-16 03:34:2551 virtual bool SetEnv(const char* variable_name, const std::string& new_value) {
[email protected]fc586c72010-07-31 16:55:4052 ADD_FAILURE();
53 return false;
54 }
55
[email protected]4fae3162010-08-04 02:13:3456 virtual bool UnSetVar(const char* variable_name) {
[email protected]fc586c72010-07-31 16:55:4057 ADD_FAILURE();
[email protected]e9032c62010-07-16 03:34:2558 return false;
[email protected]ac7264c2010-07-08 13:32:5159 }
60
[email protected]af71d642010-03-12 10:29:0461 private:
62 std::map<std::string, std::string> variables_;
63
[email protected]76b90d312010-08-03 03:00:5064 DISALLOW_COPY_AND_ASSIGN(MockEnvironment);
[email protected]af71d642010-03-12 10:29:0465};
66
67} // namespace
68
69TEST(ShellIntegrationTest, GetDesktopShortcutTemplate) {
70#if defined(GOOGLE_CHROME_BUILD)
71 const char kTemplateFilename[] = "google-chrome.desktop";
72#else // CHROMIUM_BUILD
73 const char kTemplateFilename[] = "chromium-browser.desktop";
74#endif
75
76 const char kTestData1[] = "a magical testing string";
77 const char kTestData2[] = "a different testing string";
78
79 MessageLoop message_loop;
80 ChromeThread file_thread(ChromeThread::FILE, &message_loop);
81
82 {
83 ScopedTempDir temp_dir;
84 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
85
[email protected]76b90d312010-08-03 03:00:5086 MockEnvironment env;
87 env.Set("XDG_DATA_HOME", temp_dir.path().value());
[email protected]af71d642010-03-12 10:29:0488 ASSERT_TRUE(file_util::WriteFile(
89 temp_dir.path().AppendASCII(kTemplateFilename),
90 kTestData1, strlen(kTestData1)));
91 std::string contents;
[email protected]76b90d312010-08-03 03:00:5092 ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env,
[email protected]af71d642010-03-12 10:29:0493 &contents));
94 EXPECT_EQ(kTestData1, contents);
95 }
96
97 {
98 ScopedTempDir temp_dir;
99 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
100
[email protected]76b90d312010-08-03 03:00:50101 MockEnvironment env;
102 env.Set("XDG_DATA_DIRS", temp_dir.path().value());
[email protected]af71d642010-03-12 10:29:04103 ASSERT_TRUE(file_util::CreateDirectory(
104 temp_dir.path().AppendASCII("applications")));
105 ASSERT_TRUE(file_util::WriteFile(
106 temp_dir.path().AppendASCII("applications")
107 .AppendASCII(kTemplateFilename),
108 kTestData2, strlen(kTestData2)));
109 std::string contents;
[email protected]76b90d312010-08-03 03:00:50110 ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env,
[email protected]af71d642010-03-12 10:29:04111 &contents));
112 EXPECT_EQ(kTestData2, contents);
113 }
114
115 {
116 ScopedTempDir temp_dir;
117 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
118
[email protected]76b90d312010-08-03 03:00:50119 MockEnvironment env;
120 env.Set("XDG_DATA_DIRS", temp_dir.path().value() + ":" +
[email protected]af71d642010-03-12 10:29:04121 temp_dir.path().AppendASCII("applications").value());
122 ASSERT_TRUE(file_util::CreateDirectory(
123 temp_dir.path().AppendASCII("applications")));
124 ASSERT_TRUE(file_util::WriteFile(
125 temp_dir.path().AppendASCII(kTemplateFilename),
126 kTestData1, strlen(kTestData1)));
127 ASSERT_TRUE(file_util::WriteFile(
128 temp_dir.path().AppendASCII("applications")
129 .AppendASCII(kTemplateFilename),
130 kTestData2, strlen(kTestData2)));
131 std::string contents;
[email protected]76b90d312010-08-03 03:00:50132 ASSERT_TRUE(ShellIntegration::GetDesktopShortcutTemplate(&env,
[email protected]af71d642010-03-12 10:29:04133 &contents));
134 EXPECT_EQ(kTestData1, contents);
135 }
136}
137
[email protected]b96aa932009-08-12 21:34:49138TEST(ShellIntegrationTest, GetDesktopShortcutFilename) {
139 const struct {
140 const FilePath::CharType* path;
141 const char* url;
142 } test_cases[] = {
143 { FPL("http___foo_.desktop"), "http://foo" },
144 { FPL("http___foo_bar_.desktop"), "http://foo/bar/" },
145 { FPL("http___foo_bar_a=b&c=d.desktop"), "http://foo/bar?a=b&c=d" },
146
147 // Now we're starting to be more evil...
148 { FPL("http___foo_.desktop"), "http://foo/bar/baz/../../../../../" },
149 { FPL("http___foo_.desktop"), "http://foo/bar/././../baz/././../" },
150 { FPL("http___.._.desktop"), "http://../../../../" },
151 };
152 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
[email protected]42896802009-08-28 23:39:44153 EXPECT_EQ(WideToASCII(chrome::kBrowserProcessExecutableName) + "-" +
154 test_cases[i].path,
155 ShellIntegration::GetDesktopShortcutFilename(
156 GURL(test_cases[i].url)).value()) <<
157 " while testing " << test_cases[i].url;
[email protected]b96aa932009-08-12 21:34:49158 }
159}
160
161TEST(ShellIntegrationTest, GetDesktopFileContents) {
162 const struct {
163 const char* url;
164 const char* title;
[email protected]0b303cc2009-09-28 22:35:15165 const char* icon_name;
[email protected]b96aa932009-08-12 21:34:49166 const char* template_contents;
167 const char* expected_output;
168 } test_cases[] = {
169 // Dumb case.
[email protected]0b303cc2009-09-28 22:35:15170 { "ignored", "ignored", "ignored", "", "#!/usr/bin/env xdg-open\n" },
[email protected]b96aa932009-08-12 21:34:49171
172 // Real-world case.
173 { "http://gmail.com",
174 "GMail",
[email protected]0b303cc2009-09-28 22:35:15175 "chrome-http__gmail.com",
[email protected]b96aa932009-08-12 21:34:49176
177 "[Desktop Entry]\n"
178 "Version=1.0\n"
179 "Encoding=UTF-8\n"
180 "Name=Google Chrome\n"
181 "Comment=The web browser from Google\n"
182 "Exec=/opt/google/chrome/google-chrome %U\n"
183 "Terminal=false\n"
184 "Icon=/opt/google/chrome/product_logo_48.png\n"
185 "Type=Application\n"
186 "Categories=Application;Network;WebBrowser;\n"
187 "MimeType=text/html;text/xml;application/xhtml_xml;\n",
188
[email protected]82810fe12009-09-25 16:21:57189 "#!/usr/bin/env xdg-open\n"
[email protected]b96aa932009-08-12 21:34:49190 "[Desktop Entry]\n"
191 "Version=1.0\n"
192 "Encoding=UTF-8\n"
193 "Name=GMail\n"
[email protected]fcc23e842009-10-01 03:19:10194 "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
[email protected]b96aa932009-08-12 21:34:49195 "Terminal=false\n"
[email protected]0b303cc2009-09-28 22:35:15196 "Icon=chrome-http__gmail.com\n"
[email protected]b96aa932009-08-12 21:34:49197 "Type=Application\n"
198 "Categories=Application;Network;WebBrowser;\n"
[email protected]b96aa932009-08-12 21:34:49199 },
200
[email protected]82810fe12009-09-25 16:21:57201 // Make sure we don't insert duplicate shebangs.
202 { "http://gmail.com",
203 "GMail",
[email protected]0b303cc2009-09-28 22:35:15204 "chrome-http__gmail.com",
[email protected]82810fe12009-09-25 16:21:57205
206 "#!/some/shebang\n"
207 "Name=Google Chrome\n"
208 "Exec=/opt/google/chrome/google-chrome %U\n",
209
210 "#!/usr/bin/env xdg-open\n"
211 "Name=GMail\n"
[email protected]fcc23e842009-10-01 03:19:10212 "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
[email protected]82810fe12009-09-25 16:21:57213 },
214
215 // Make sure i18n-ed comments are removed.
216 { "http://gmail.com",
217 "GMail",
[email protected]0b303cc2009-09-28 22:35:15218 "chrome-http__gmail.com",
[email protected]82810fe12009-09-25 16:21:57219
220 "Name=Google Chrome\n"
221 "Exec=/opt/google/chrome/google-chrome %U\n"
222 "Comment[pl]=Jakis komentarz.\n",
223
224 "#!/usr/bin/env xdg-open\n"
225 "Name=GMail\n"
[email protected]fcc23e842009-10-01 03:19:10226 "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
[email protected]82810fe12009-09-25 16:21:57227 },
228
[email protected]0b303cc2009-09-28 22:35:15229 // Make sure that empty icons are replaced by the chrome icon.
230 { "http://gmail.com",
231 "GMail",
232 "",
233
234 "Name=Google Chrome\n"
235 "Exec=/opt/google/chrome/google-chrome %U\n"
236 "Comment[pl]=Jakis komentarz.\n"
237 "Icon=/opt/google/chrome/product_logo_48.png\n",
238
239 "#!/usr/bin/env xdg-open\n"
240 "Name=GMail\n"
[email protected]fcc23e842009-10-01 03:19:10241 "Exec=/opt/google/chrome/google-chrome --app=\"http://gmail.com/\"\n"
[email protected]0b303cc2009-09-28 22:35:15242 "Icon=/opt/google/chrome/product_logo_48.png\n"
243 },
244
[email protected]b96aa932009-08-12 21:34:49245 // Now we're starting to be more evil...
246 { "http://evil.com/evil --join-the-b0tnet",
247 "Ownz0red\nExec=rm -rf /",
[email protected]0b303cc2009-09-28 22:35:15248 "chrome-http__evil.com_evil",
[email protected]b96aa932009-08-12 21:34:49249
250 "Name=Google Chrome\n"
251 "Exec=/opt/google/chrome/google-chrome %U\n",
252
[email protected]82810fe12009-09-25 16:21:57253 "#!/usr/bin/env xdg-open\n"
[email protected]b96aa932009-08-12 21:34:49254 "Name=http://evil.com/evil%20--join-the-b0tnet\n"
255 "Exec=/opt/google/chrome/google-chrome "
[email protected]790613c2009-12-30 14:49:41256 "--app=\"http://evil.com/evil%20--join-the-b0tnet\"\n"
[email protected]b96aa932009-08-12 21:34:49257 },
[email protected]82810fe12009-09-25 16:21:57258 { "http://evil.com/evil; rm -rf /; \"; rm -rf $HOME >ownz0red",
259 "Innocent Title",
[email protected]0b303cc2009-09-28 22:35:15260 "chrome-http__evil.com_evil",
[email protected]82810fe12009-09-25 16:21:57261
262 "Name=Google Chrome\n"
263 "Exec=/opt/google/chrome/google-chrome %U\n",
264
265 "#!/usr/bin/env xdg-open\n"
266 "Name=Innocent Title\n"
267 "Exec=/opt/google/chrome/google-chrome "
[email protected]790613c2009-12-30 14:49:41268 "--app=\"http://evil.com/evil%3B%20rm%20-rf%20/%3B%20%22%3B%20rm%20"
269 "-rf%20%24HOME%20%3Eownz0red\"\n"
[email protected]82810fe12009-09-25 16:21:57270 },
[email protected]790613c2009-12-30 14:49:41271 { "http://evil.com/evil | cat `echo ownz0red` >/dev/null",
[email protected]82810fe12009-09-25 16:21:57272 "Innocent Title",
[email protected]0b303cc2009-09-28 22:35:15273 "chrome-http__evil.com_evil",
[email protected]82810fe12009-09-25 16:21:57274
275 "Name=Google Chrome\n"
276 "Exec=/opt/google/chrome/google-chrome %U\n",
277
278 "#!/usr/bin/env xdg-open\n"
279 "Name=Innocent Title\n"
280 "Exec=/opt/google/chrome/google-chrome "
[email protected]790613c2009-12-30 14:49:41281 "--app=\"http://evil.com/evil%20%7C%20cat%20%60echo%20ownz0red"
282 "%60%20%3E/dev/null\"\n"
[email protected]82810fe12009-09-25 16:21:57283 },
[email protected]b96aa932009-08-12 21:34:49284 };
285 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); i++) {
286 EXPECT_EQ(test_cases[i].expected_output,
287 ShellIntegration::GetDesktopFileContents(
288 test_cases[i].template_contents,
289 GURL(test_cases[i].url),
[email protected]28375ae2010-02-05 04:45:50290 EmptyString16(),
[email protected]0b303cc2009-09-28 22:35:15291 ASCIIToUTF16(test_cases[i].title),
292 test_cases[i].icon_name));
[email protected]b96aa932009-08-12 21:34:49293 }
294}
[email protected]12f520c2010-01-06 18:11:15295#elif defined(OS_WIN)
296TEST(ShellIntegrationTest, GetChromiumAppIdTest) {
297 // Empty profile path should get chrome::kBrowserAppID
298 FilePath empty_path;
[email protected]1caa92612010-06-11 00:13:56299 EXPECT_EQ(BrowserDistribution::GetDistribution()->GetBrowserAppId(),
[email protected]12f520c2010-01-06 18:11:15300 ShellIntegration::GetChromiumAppId(empty_path));
301
302 // Default profile path should get chrome::kBrowserAppID
303 FilePath default_user_data_dir;
304 chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
305 FilePath default_profile_path =
306 default_user_data_dir.Append(chrome::kNotSignedInProfile);
[email protected]1caa92612010-06-11 00:13:56307 EXPECT_EQ(BrowserDistribution::GetDistribution()->GetBrowserAppId(),
[email protected]12f520c2010-01-06 18:11:15308 ShellIntegration::GetChromiumAppId(default_profile_path));
309
310 // Non-default profile path should get chrome::kBrowserAppID joined with
311 // profile info.
312 FilePath profile_path(FILE_PATH_LITERAL("root"));
313 profile_path = profile_path.Append(FILE_PATH_LITERAL("udd"));
314 profile_path = profile_path.Append(FILE_PATH_LITERAL("User Data - Test"));
[email protected]1caa92612010-06-11 00:13:56315 EXPECT_EQ(BrowserDistribution::GetDistribution()->GetBrowserAppId() +
316 L".udd.UserDataTest",
[email protected]12f520c2010-01-06 18:11:15317 ShellIntegration::GetChromiumAppId(profile_path));
318}
319#endif