[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / shell_integration_win_unittest.cc
1 // Copyright 2012 The Chromium Authors
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/browser/shell_integration_win.h"
6
7 #include <stddef.h>
8
9 #include <string>
10 #include <vector>
11
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/test/test_shortcut_win.h"
19 #include "base/win/scoped_com_initializer.h"
20 #include "chrome/browser/shell_integration.h"
21 #include "chrome/browser/web_applications/os_integration/web_app_shortcut_win.h"
22 #include "chrome/browser/web_applications/web_app_helpers.h"
23 #include "chrome/common/chrome_constants.h"
24 #include "chrome/common/chrome_paths_internal.h"
25 #include "chrome/install_static/install_util.h"
26 #include "chrome/installer/util/install_util.h"
27 #include "chrome/installer/util/shell_util.h"
28 #include "chrome/installer/util/util_constants.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 namespace shell_integration {
32 namespace win {
33
34 namespace {
35
36 struct ShortcutTestObject {
37   base::FilePath path;
38   base::win::ShortcutProperties properties;
39 };
40
41 class ShellIntegrationWinMigrateShortcutTest : public testing::Test {
42  public:
43   ShellIntegrationWinMigrateShortcutTest(
44       const ShellIntegrationWinMigrateShortcutTest&) = delete;
45   ShellIntegrationWinMigrateShortcutTest& operator=(
46       const ShellIntegrationWinMigrateShortcutTest&) = delete;
47
48  protected:
49   ShellIntegrationWinMigrateShortcutTest() {}
50
51   void SetUp() override {
52     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
53     ASSERT_TRUE(
54         temp_dir_sub_dir_.CreateUniqueTempDirUnderPath(temp_dir_.GetPath()));
55     // A path to a random target.
56     base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &other_target_);
57
58     // This doesn't need to actually have a base name of "chrome.exe".
59     base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &chrome_exe_);
60
61     chrome_app_id_ = ShellUtil::GetBrowserModelId(true);
62
63     base::FilePath default_user_data_dir;
64     chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
65     base::FilePath default_profile_path =
66         default_user_data_dir.AppendASCII(chrome::kInitialProfile);
67     non_default_user_data_dir_ = base::FilePath(FILE_PATH_LITERAL("root"))
68         .Append(FILE_PATH_LITERAL("Non Default Data Dir"));
69     non_default_profile_ = L"NonDefault";
70     non_default_profile_chrome_app_id_ = GetAppUserModelIdForBrowser(
71         default_user_data_dir.Append(non_default_profile_));
72     non_default_user_data_dir_chrome_app_id_ = GetAppUserModelIdForBrowser(
73         non_default_user_data_dir_.AppendASCII(chrome::kInitialProfile));
74     non_default_user_data_dir_and_profile_chrome_app_id_ =
75         GetAppUserModelIdForBrowser(
76             non_default_user_data_dir_.Append(non_default_profile_));
77
78     extension_id_ = L"chromiumexampleappidforunittests";
79     std::wstring app_name =
80         base::UTF8ToWide(web_app::GenerateApplicationNameFromAppId(
81             base::WideToUTF8(extension_id_)));
82     extension_app_id_ = GetAppUserModelIdForApp(app_name, default_profile_path);
83     non_default_profile_extension_app_id_ = GetAppUserModelIdForApp(
84         app_name, default_user_data_dir.Append(non_default_profile_));
85   }
86
87   // Creates a test shortcut corresponding to |shortcut_properties| and resets
88   // |shortcut_properties| after copying it to an internal structure for later
89   // verification.
90   void AddTestShortcutAndResetProperties(
91       const base::FilePath& shortcut_dir,
92       base::win::ShortcutProperties* shortcut_properties) {
93     ShortcutTestObject shortcut_test_object;
94     base::FilePath shortcut_path = shortcut_dir.Append(
95         L"Shortcut " + base::NumberToWString(shortcuts_.size()) +
96         installer::kLnkExt);
97     shortcut_test_object.path = shortcut_path;
98     shortcut_test_object.properties = *shortcut_properties;
99     shortcuts_.push_back(shortcut_test_object);
100     ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
101         shortcut_path, *shortcut_properties,
102         base::win::ShortcutOperation::kCreateAlways));
103     shortcut_properties->options = 0U;
104   }
105
106   void CreateShortcuts() {
107     // A temporary object to pass properties to
108     // AddTestShortcutAndResetProperties().
109     base::win::ShortcutProperties temp_properties;
110
111     // Shortcut 0 doesn't point to chrome.exe and thus should never be migrated.
112     temp_properties.set_target(other_target_);
113     temp_properties.set_app_id(L"Dumbo");
114     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
115         temp_dir_.GetPath(), &temp_properties));
116
117     // Shortcut 1 points to chrome.exe and thus should be migrated.
118     temp_properties.set_target(chrome_exe_);
119     temp_properties.set_app_id(L"Dumbo");
120     temp_properties.set_dual_mode(false);
121     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
122         temp_dir_.GetPath(), &temp_properties));
123
124     // Shortcut 2 points to chrome.exe, but already has the right appid and thus
125     // should only be migrated if dual_mode is desired.
126     temp_properties.set_target(chrome_exe_);
127     temp_properties.set_app_id(chrome_app_id_);
128     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
129         temp_dir_.GetPath(), &temp_properties));
130
131     // Shortcut 3 is like shortcut 1, but it's appid is a prefix of the expected
132     // appid instead of being totally different.
133     std::wstring chrome_app_id_is_prefix(chrome_app_id_);
134     chrome_app_id_is_prefix.push_back(L'1');
135     temp_properties.set_target(chrome_exe_);
136     temp_properties.set_app_id(chrome_app_id_is_prefix);
137     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
138         temp_dir_.GetPath(), &temp_properties));
139
140     // Shortcut 4 is like shortcut 1, but it's appid is of the same size as the
141     // expected appid.
142     std::wstring same_size_as_chrome_app_id(chrome_app_id_.size(), L'1');
143     temp_properties.set_target(chrome_exe_);
144     temp_properties.set_app_id(same_size_as_chrome_app_id);
145     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
146         temp_dir_.GetPath(), &temp_properties));
147
148     // Shortcut 5 doesn't have an app_id, nor is dual_mode even set; they should
149     // be set as expected upon migration.
150     temp_properties.set_target(chrome_exe_);
151     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
152         temp_dir_.GetPath(), &temp_properties));
153
154     // Shortcut 6 has a non-default profile directory and so should get a non-
155     // default app id.
156     temp_properties.set_target(chrome_exe_);
157     temp_properties.set_app_id(L"Dumbo");
158     temp_properties.set_arguments(
159         L"--profile-directory=" + non_default_profile_);
160     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
161         temp_dir_.GetPath(), &temp_properties));
162
163     // Shortcut 7 has a non-default user data directory and so should get a non-
164     // default app id.
165     temp_properties.set_target(chrome_exe_);
166     temp_properties.set_app_id(L"Dumbo");
167     temp_properties.set_arguments(
168         L"--user-data-dir=\"" + non_default_user_data_dir_.value() + L"\"");
169     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
170         temp_dir_.GetPath(), &temp_properties));
171
172     // Shortcut 8 has a non-default user data directory as well as a non-default
173     // profile directory and so should get a non-default app id.
174     temp_properties.set_target(chrome_exe_);
175     temp_properties.set_app_id(L"Dumbo");
176     temp_properties.set_arguments(
177         L"--user-data-dir=\"" + non_default_user_data_dir_.value() + L"\" " +
178         L"--profile-directory=" + non_default_profile_);
179     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
180         temp_dir_.GetPath(), &temp_properties));
181
182     // Shortcut 9 is a shortcut to an app and should get an app id for that app
183     // rather than the chrome app id.
184     temp_properties.set_target(chrome_exe_);
185     temp_properties.set_app_id(L"Dumbo");
186     temp_properties.set_arguments(
187         L"--app-id=" + extension_id_);
188     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
189         temp_dir_.GetPath(), &temp_properties));
190
191     // Shortcut 10 is a shortcut to an app with a non-default profile and should
192     // get an app id for that app with a non-default app id rather than the
193     // chrome app id.
194     temp_properties.set_target(chrome_exe_);
195     temp_properties.set_app_id(L"Dumbo");
196     temp_properties.set_arguments(
197         L"--app-id=" + extension_id_ +
198         L" --profile-directory=" + non_default_profile_);
199     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
200         temp_dir_.GetPath(), &temp_properties));
201
202     // Shortcut 11 points to chrome.exe, already has the right appid, and has
203     // dual_mode set and thus should only be migrated if dual_mode is being
204     // cleared.
205     temp_properties.set_target(chrome_exe_);
206     temp_properties.set_app_id(chrome_app_id_);
207     temp_properties.set_dual_mode(true);
208     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
209         temp_dir_.GetPath(), &temp_properties));
210
211     // Shortcut 12 is similar to 11 but with dual_mode explicitly set to false.
212     temp_properties.set_target(chrome_exe_);
213     temp_properties.set_app_id(chrome_app_id_);
214     temp_properties.set_dual_mode(false);
215     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
216         temp_dir_.GetPath(), &temp_properties));
217
218     // Shortcut 13 is like shortcut 1, but it's appid explicitly includes the
219     // default profile.
220     std::wstring chrome_app_id_with_default_profile =
221         chrome_app_id_ + L".Default";
222     temp_properties.set_target(chrome_exe_);
223     temp_properties.set_app_id(chrome_app_id_with_default_profile);
224     ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
225         temp_dir_.GetPath(), &temp_properties));
226   }
227
228   base::win::ScopedCOMInitializer com_initializer_;
229
230   base::ScopedTempDir temp_dir_;
231
232   // Used to test migration of shortcuts in ImplicitApps sub-directories.
233   base::ScopedTempDir temp_dir_sub_dir_;
234
235   // Test shortcuts.
236   std::vector<ShortcutTestObject> shortcuts_;
237
238   // The path to a fake chrome.exe.
239   base::FilePath chrome_exe_;
240
241   // The path to a random target.
242   base::FilePath other_target_;
243
244   // Chrome's AppUserModelId.
245   std::wstring chrome_app_id_;
246
247   // A profile that isn't the Default profile.
248   std::wstring non_default_profile_;
249
250   // A user data dir that isn't the default.
251   base::FilePath non_default_user_data_dir_;
252
253   // Chrome's AppUserModelId for the non-default profile.
254   std::wstring non_default_profile_chrome_app_id_;
255
256   // Chrome's AppUserModelId for the non-default user data dir.
257   std::wstring non_default_user_data_dir_chrome_app_id_;
258
259   // Chrome's AppUserModelId for the non-default user data dir and non-default
260   // profile.
261   std::wstring non_default_user_data_dir_and_profile_chrome_app_id_;
262
263   // An example extension id of an example app.
264   std::wstring extension_id_;
265
266   // The app id of the example app for the default profile and user data dir.
267   std::wstring extension_app_id_;
268
269   // The app id of the example app for the non-default profile.
270   std::wstring non_default_profile_extension_app_id_;
271 };
272
273 }  // namespace
274
275 TEST_F(ShellIntegrationWinMigrateShortcutTest, ClearDualModeAndAdjustAppIds) {
276   CreateShortcuts();
277   // 10 shortcuts should have their app id updated below and shortcut 11 should
278   // be migrated away from dual_mode for a total of 11 shortcuts migrated.
279   EXPECT_EQ(11,
280             MigrateShortcutsInPathInternal(chrome_exe_, temp_dir_.GetPath()));
281
282   // Shortcut 1, 3, 4, 5, 6, 7, 8, 9, 10, and 13 should have had their app_id
283   //  fixed.
284   shortcuts_[1].properties.set_app_id(chrome_app_id_);
285   shortcuts_[3].properties.set_app_id(chrome_app_id_);
286   shortcuts_[4].properties.set_app_id(chrome_app_id_);
287   shortcuts_[5].properties.set_app_id(chrome_app_id_);
288   shortcuts_[6].properties.set_app_id(non_default_profile_chrome_app_id_);
289   shortcuts_[7].properties.set_app_id(non_default_user_data_dir_chrome_app_id_);
290   shortcuts_[8].properties.set_app_id(
291       non_default_user_data_dir_and_profile_chrome_app_id_);
292   shortcuts_[9].properties.set_app_id(extension_app_id_);
293   shortcuts_[10].properties.set_app_id(non_default_profile_extension_app_id_);
294   shortcuts_[13].properties.set_app_id(chrome_app_id_);
295
296   // No shortcut should still have the dual_mode property.
297   for (size_t i = 0; i < shortcuts_.size(); ++i)
298     shortcuts_[i].properties.set_dual_mode(false);
299
300   for (size_t i = 0; i < shortcuts_.size(); ++i) {
301     SCOPED_TRACE(i);
302     base::win::ValidateShortcut(shortcuts_[i].path, shortcuts_[i].properties);
303   }
304
305   // Make sure shortcuts are not re-migrated.
306   EXPECT_EQ(0,
307             MigrateShortcutsInPathInternal(chrome_exe_, temp_dir_.GetPath()));
308 }
309
310 // Test that chrome_proxy.exe shortcuts (PWA) have their app_id migrated
311 // to not include the default profile name. This tests both shortcuts in the
312 // DIR_TASKBAR_PINS and sub-directories of DIR_IMPLICIT_APP_SHORTCUTS.
313 TEST_F(ShellIntegrationWinMigrateShortcutTest, MigrateChromeProxyTest) {
314   // Create shortcut to chrome_proxy_exe in executable directory,
315   // using the default profile, with the AppModelId not containing the
316   // profile name.
317   base::win::ShortcutProperties temp_properties;
318   temp_properties.set_target(web_app::GetChromeProxyPath());
319   temp_properties.set_app_id(L"Dumbo.Default");
320   ASSERT_NO_FATAL_FAILURE(
321       AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));
322   temp_properties.set_target(web_app::GetChromeProxyPath());
323   temp_properties.set_app_id(L"Dumbo2.Default");
324   ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
325       temp_dir_sub_dir_.GetPath(), &temp_properties));
326
327   // Check that a chrome proxy shortcut whose app_id is just the extension app
328   // id has its AUMI migrated to start with the browser's app_id.
329   // It technically doesn't matter what ShortcutProperties's app_id is,
330   // since the migration is based on ShortcutProperties.arguments.
331   temp_properties.set_target(web_app::GetChromeProxyPath());
332   temp_properties.set_app_id(L"Dumbo3.Default");
333   base::CommandLine cmd_line = shell_integration::CommandLineArgsForLauncher(
334       GURL(), base::WideToUTF8(extension_id_), base::FilePath(), "");
335   ASSERT_EQ(cmd_line.GetCommandLineString(), L" --app-id=" + extension_id_);
336   temp_properties.set_arguments(cmd_line.GetCommandLineString());
337   ASSERT_NO_FATAL_FAILURE(
338       AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));
339
340   // Check that a chrome proxy shortcut with a kApp url in its command line
341   // has its AUMI migrated to start with the browser's app_id.
342   temp_properties.set_target(web_app::GetChromeProxyPath());
343   temp_properties.set_app_id(L"Dumbo4.Default");
344   GURL url("http://www.example.com");
345   cmd_line = shell_integration::CommandLineArgsForLauncher(
346       url, std::string(), base::FilePath(), "");
347   ASSERT_EQ(cmd_line.GetCommandLineString(), L" --app=http://www.example.com/");
348   temp_properties.set_arguments(cmd_line.GetCommandLineString());
349   ASSERT_NO_FATAL_FAILURE(
350       AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));
351
352   MigrateTaskbarPinsCallback(temp_dir_.GetPath(), temp_dir_.GetPath());
353   // Verify that the migrated shortcut in temp_dir_ does not contain the default
354   // profile name.
355   shortcuts_[0].properties.set_app_id(chrome_app_id_);
356   base::win::ValidateShortcut(shortcuts_[0].path, shortcuts_[0].properties);
357   // Verify that the migrated shortcut in temp_dir_sub does not contain the
358   // default profile name.
359   shortcuts_[1].properties.set_app_id(chrome_app_id_);
360   base::win::ValidateShortcut(shortcuts_[1].path, shortcuts_[1].properties);
361
362   shortcuts_[2].properties.set_app_id(extension_app_id_);
363   base::win::ValidateShortcut(shortcuts_[2].path, shortcuts_[2].properties);
364
365   shortcuts_[3].properties.set_app_id(GetAppUserModelIdForApp(
366       base::UTF8ToWide(web_app::GenerateApplicationNameFromURL(url)),
367       base::FilePath()));
368   base::win::ValidateShortcut(shortcuts_[3].path, shortcuts_[3].properties);
369 }
370
371 // This test verifies that MigrateTaskbarPins does a case-insensitive
372 // comparison when comparing the shortcut target with the chrome exe path.
373 TEST_F(ShellIntegrationWinMigrateShortcutTest, MigrateMixedCaseDirTest) {
374   base::win::ShortcutProperties temp_properties;
375   base::FilePath chrome_proxy_path(web_app::GetChromeProxyPath());
376   ASSERT_EQ(chrome_proxy_path.Extension(), FILE_PATH_LITERAL(".exe"));
377   temp_properties.set_target(
378       chrome_proxy_path.ReplaceExtension(FILE_PATH_LITERAL("EXE")));
379   temp_properties.set_app_id(L"Dumbo.Default");
380   ASSERT_NO_FATAL_FAILURE(
381       AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));
382   MigrateTaskbarPinsCallback(temp_dir_.GetPath(), temp_dir_.GetPath());
383   // Verify that the shortcut was migrated, i.e., its app_id does not contain
384   // the default profile name.
385   shortcuts_[0].properties.set_app_id(chrome_app_id_);
386   base::win::ValidateShortcut(shortcuts_[0].path, shortcuts_[0].properties);
387 }
388
389 TEST(ShellIntegrationWinTest, GetAppModelIdForProfileTest) {
390   const std::wstring base_app_id(install_static::GetBaseAppId());
391
392   // Empty profile path should get chrome::kBrowserAppID
393   std::wstring app_name = L"app";
394   std::wstring expected_model_id_without_profile =
395       base_app_id + L"." + app_name;
396   base::FilePath empty_path;
397   EXPECT_EQ(expected_model_id_without_profile,
398             GetAppUserModelIdForApp(app_name, empty_path));
399
400   // Default profile path should get chrome::kBrowserAppID
401   base::FilePath default_user_data_dir;
402   chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
403   base::FilePath default_profile_path =
404       default_user_data_dir.AppendASCII(chrome::kInitialProfile);
405   EXPECT_EQ(expected_model_id_without_profile,
406             GetAppUserModelIdForApp(app_name, default_profile_path));
407
408   // Non-default profile path should get chrome::kBrowserAppID joined with
409   // profile info.
410   base::FilePath profile_path(FILE_PATH_LITERAL("root"));
411   profile_path = profile_path.Append(FILE_PATH_LITERAL("udd"));
412   profile_path = profile_path.Append(FILE_PATH_LITERAL("User Data - Test"));
413   EXPECT_EQ(expected_model_id_without_profile + L".udd.UserDataTest",
414             GetAppUserModelIdForApp(app_name, profile_path));
415 }
416
417 }  // namespace win
418 }  // namespace shell_integration