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// Unit tests for master preferences related methods.
6
7#include "base/files/file_util.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/path_service.h"
10#include "base/strings/stringprintf.h"
11#include "base/values.h"
12#include "chrome/common/chrome_paths.h"
13#include "chrome/common/pref_names.h"
14#include "chrome/installer/util/master_preferences.h"
15#include "chrome/installer/util/master_preferences_constants.h"
16#include "chrome/installer/util/util_constants.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19namespace {
20class MasterPreferencesTest : public testing::Test {
21 protected:
22  virtual void SetUp() {
23    ASSERT_TRUE(base::CreateTemporaryFile(&prefs_file_));
24  }
25
26  virtual void TearDown() {
27    EXPECT_TRUE(base::DeleteFile(prefs_file_, false));
28  }
29
30  const base::FilePath& prefs_file() const { return prefs_file_; }
31
32 private:
33  base::FilePath prefs_file_;
34};
35
36// Used to specify an expected value for a set boolean preference variable.
37struct ExpectedBooleans {
38  const char* name;
39  bool expected_value;
40};
41
42}  // namespace
43
44TEST_F(MasterPreferencesTest, NoFileToParse) {
45  EXPECT_TRUE(base::DeleteFile(prefs_file(), false));
46  installer::MasterPreferences prefs(prefs_file());
47  EXPECT_FALSE(prefs.read_from_file());
48}
49
50TEST_F(MasterPreferencesTest, ParseDistroParams) {
51  const char text[] =
52    "{ \n"
53    "  \"distribution\": { \n"
54    "     \"show_welcome_page\": true,\n"
55    "     \"import_search_engine\": true,\n"
56    "     \"import_history\": true,\n"
57    "     \"import_bookmarks\": true,\n"
58    "     \"import_bookmarks_from_file\": \"c:\\\\foo\",\n"
59    "     \"import_home_page\": true,\n"
60    "     \"do_not_create_any_shortcuts\": true,\n"
61    "     \"do_not_create_desktop_shortcut\": true,\n"
62    "     \"do_not_create_quick_launch_shortcut\": true,\n"
63    "     \"do_not_create_taskbar_shortcut\": true,\n"
64    "     \"do_not_launch_chrome\": true,\n"
65    "     \"make_chrome_default\": true,\n"
66    "     \"make_chrome_default_for_user\": true,\n"
67    "     \"system_level\": true,\n"
68    "     \"verbose_logging\": true,\n"
69    "     \"require_eula\": true,\n"
70    "     \"alternate_shortcut_text\": true,\n"
71    "     \"chrome_shortcut_icon_index\": 1,\n"
72    "     \"ping_delay\": 40\n"
73    "  },\n"
74    "  \"blah\": {\n"
75    "     \"import_history\": false\n"
76    "  }\n"
77    "} \n";
78
79  EXPECT_TRUE(base::WriteFile(prefs_file(), text, strlen(text)));
80  installer::MasterPreferences prefs(prefs_file());
81  EXPECT_TRUE(prefs.read_from_file());
82
83  const char* expected_true[] = {
84    installer::master_preferences::kDistroImportSearchPref,
85    installer::master_preferences::kDistroImportHistoryPref,
86    installer::master_preferences::kDistroImportBookmarksPref,
87    installer::master_preferences::kDistroImportHomePagePref,
88    installer::master_preferences::kDoNotCreateAnyShortcuts,
89    installer::master_preferences::kDoNotCreateDesktopShortcut,
90    installer::master_preferences::kDoNotCreateQuickLaunchShortcut,
91    installer::master_preferences::kDoNotCreateTaskbarShortcut,
92    installer::master_preferences::kDoNotLaunchChrome,
93    installer::master_preferences::kMakeChromeDefault,
94    installer::master_preferences::kMakeChromeDefaultForUser,
95    installer::master_preferences::kSystemLevel,
96    installer::master_preferences::kVerboseLogging,
97    installer::master_preferences::kRequireEula,
98    installer::master_preferences::kAltShortcutText,
99  };
100
101  for (int i = 0; i < arraysize(expected_true); ++i) {
102    bool value = false;
103    EXPECT_TRUE(prefs.GetBool(expected_true[i], &value));
104    EXPECT_TRUE(value) << expected_true[i];
105  }
106
107  std::string str_value;
108  EXPECT_TRUE(prefs.GetString(
109      installer::master_preferences::kDistroImportBookmarksFromFilePref,
110      &str_value));
111  EXPECT_STREQ("c:\\foo", str_value.c_str());
112
113  int icon_index = 0;
114  EXPECT_TRUE(prefs.GetInt(
115      installer::master_preferences::kChromeShortcutIconIndex,
116      &icon_index));
117  EXPECT_EQ(icon_index, 1);
118  int ping_delay = 90;
119  EXPECT_TRUE(prefs.GetInt(installer::master_preferences::kDistroPingDelay,
120                           &ping_delay));
121  EXPECT_EQ(ping_delay, 40);
122}
123
124TEST_F(MasterPreferencesTest, ParseMissingDistroParams) {
125  const char text[] =
126    "{ \n"
127    "  \"distribution\": { \n"
128    "     \"import_search_engine\": true,\n"
129    "     \"import_bookmarks\": false,\n"
130    "     \"import_bookmarks_from_file\": \"\",\n"
131    "     \"do_not_create_desktop_shortcut\": true,\n"
132    "     \"do_not_create_quick_launch_shortcut\": true,\n"
133    "     \"do_not_launch_chrome\": true,\n"
134    "     \"chrome_shortcut_icon_index\": \"bac\"\n"
135    "  }\n"
136    "} \n";
137
138  EXPECT_TRUE(base::WriteFile(prefs_file(), text, strlen(text)));
139  installer::MasterPreferences prefs(prefs_file());
140  EXPECT_TRUE(prefs.read_from_file());
141
142  ExpectedBooleans expected_bool[] = {
143    { installer::master_preferences::kDistroImportSearchPref, true },
144    { installer::master_preferences::kDistroImportBookmarksPref, false },
145    { installer::master_preferences::kDoNotCreateDesktopShortcut, true },
146    { installer::master_preferences::kDoNotCreateQuickLaunchShortcut, true },
147    { installer::master_preferences::kDoNotLaunchChrome, true },
148  };
149
150  bool value = false;
151  for (int i = 0; i < arraysize(expected_bool); ++i) {
152    EXPECT_TRUE(prefs.GetBool(expected_bool[i].name, &value));
153    EXPECT_EQ(value, expected_bool[i].expected_value) << expected_bool[i].name;
154  }
155
156  const char* missing_bools[] = {
157    installer::master_preferences::kDistroImportHomePagePref,
158    installer::master_preferences::kDoNotRegisterForUpdateLaunch,
159    installer::master_preferences::kMakeChromeDefault,
160    installer::master_preferences::kMakeChromeDefaultForUser,
161  };
162
163  for (int i = 0; i < arraysize(missing_bools); ++i) {
164    EXPECT_FALSE(prefs.GetBool(missing_bools[i], &value)) << missing_bools[i];
165  }
166
167  std::string str_value;
168  EXPECT_FALSE(prefs.GetString(
169      installer::master_preferences::kDistroImportBookmarksFromFilePref,
170      &str_value));
171
172  int icon_index = 0;
173  EXPECT_FALSE(prefs.GetInt(
174      installer::master_preferences::kChromeShortcutIconIndex,
175      &icon_index));
176  EXPECT_EQ(icon_index, 0);
177
178  int ping_delay = 90;
179  EXPECT_FALSE(prefs.GetInt(
180      installer::master_preferences::kDistroPingDelay, &ping_delay));
181  EXPECT_EQ(ping_delay, 90);
182}
183
184TEST_F(MasterPreferencesTest, FirstRunTabs) {
185  const char text[] =
186    "{ \n"
187    "  \"distribution\": { \n"
188    "     \"something here\": true\n"
189    "  },\n"
190    "  \"first_run_tabs\": [\n"
191    "     \"http://google.com/f1\",\n"
192    "     \"https://google.com/f2\",\n"
193    "     \"new_tab_page\"\n"
194    "  ]\n"
195    "} \n";
196
197  EXPECT_TRUE(base::WriteFile(prefs_file(), text, strlen(text)));
198  installer::MasterPreferences prefs(prefs_file());
199  typedef std::vector<std::string> TabsVector;
200  TabsVector tabs = prefs.GetFirstRunTabs();
201  ASSERT_EQ(3, tabs.size());
202  EXPECT_EQ("http://google.com/f1", tabs[0]);
203  EXPECT_EQ("https://google.com/f2", tabs[1]);
204  EXPECT_EQ("new_tab_page", tabs[2]);
205}
206
207// In this test instead of using our synthetic json file, we use an
208// actual test case from the extensions unittest. The hope here is that if
209// they change something in the manifest this test will break, but in
210// general it is expected the extension format to be backwards compatible.
211TEST(MasterPrefsExtension, ValidateExtensionJSON) {
212  base::FilePath prefs_path;
213  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &prefs_path));
214  prefs_path = prefs_path.AppendASCII("extensions")
215      .AppendASCII("good").AppendASCII("Preferences");
216
217  installer::MasterPreferences prefs(prefs_path);
218  base::DictionaryValue* extensions = NULL;
219  EXPECT_TRUE(prefs.GetExtensionsBlock(&extensions));
220  int location = 0;
221  EXPECT_TRUE(extensions->GetInteger(
222      "behllobkkfkfnphdnhnkndlbkcpglgmj.location", &location));
223  int state = 0;
224  EXPECT_TRUE(extensions->GetInteger(
225      "behllobkkfkfnphdnhnkndlbkcpglgmj.state", &state));
226  std::string path;
227  EXPECT_TRUE(extensions->GetString(
228      "behllobkkfkfnphdnhnkndlbkcpglgmj.path", &path));
229  std::string key;
230  EXPECT_TRUE(extensions->GetString(
231      "behllobkkfkfnphdnhnkndlbkcpglgmj.manifest.key", &key));
232  std::string name;
233  EXPECT_TRUE(extensions->GetString(
234      "behllobkkfkfnphdnhnkndlbkcpglgmj.manifest.name", &name));
235  std::string version;
236  EXPECT_TRUE(extensions->GetString(
237      "behllobkkfkfnphdnhnkndlbkcpglgmj.manifest.version", &version));
238}
239
240// Test that we are parsing master preferences correctly.
241TEST_F(MasterPreferencesTest, GetInstallPreferencesTest) {
242  // Create a temporary prefs file.
243  base::FilePath prefs_file;
244  ASSERT_TRUE(base::CreateTemporaryFile(&prefs_file));
245  const char text[] =
246    "{ \n"
247    "  \"distribution\": { \n"
248    "     \"do_not_create_desktop_shortcut\": false,\n"
249    "     \"do_not_create_quick_launch_shortcut\": false,\n"
250    "     \"do_not_launch_chrome\": true,\n"
251    "     \"system_level\": true,\n"
252    "     \"verbose_logging\": false\n"
253    "  }\n"
254    "} \n";
255  EXPECT_TRUE(base::WriteFile(prefs_file, text, strlen(text)));
256
257  // Make sure command line values override the values in master preferences.
258  std::wstring cmd_str(
259      L"setup.exe --installerdata=\"" + prefs_file.value() + L"\"");
260  cmd_str.append(L" --do-not-launch-chrome");
261  CommandLine cmd_line = CommandLine::FromString(cmd_str);
262  installer::MasterPreferences prefs(cmd_line);
263
264  // Check prefs that do not have any equivalent command line option.
265  ExpectedBooleans expected_bool[] = {
266    { installer::master_preferences::kDoNotLaunchChrome, true },
267    { installer::master_preferences::kSystemLevel, true },
268    { installer::master_preferences::kVerboseLogging, false },
269  };
270
271  // Now check that prefs got merged correctly.
272  bool value = false;
273  for (int i = 0; i < arraysize(expected_bool); ++i) {
274    EXPECT_TRUE(prefs.GetBool(expected_bool[i].name, &value));
275    EXPECT_EQ(value, expected_bool[i].expected_value) << expected_bool[i].name;
276  }
277
278  // Delete temporary prefs file.
279  EXPECT_TRUE(base::DeleteFile(prefs_file, false));
280
281  // Check that if master prefs doesn't exist, we can still parse the common
282  // prefs.
283  cmd_str = L"setup.exe --do-not-launch-chrome";
284  cmd_line.ParseFromString(cmd_str);
285  installer::MasterPreferences prefs2(cmd_line);
286  ExpectedBooleans expected_bool2[] = {
287    { installer::master_preferences::kDoNotLaunchChrome, true },
288  };
289
290  for (int i = 0; i < arraysize(expected_bool2); ++i) {
291    EXPECT_TRUE(prefs2.GetBool(expected_bool2[i].name, &value));
292    EXPECT_EQ(value, expected_bool2[i].expected_value)
293        << expected_bool2[i].name;
294  }
295
296  EXPECT_FALSE(prefs2.GetBool(
297      installer::master_preferences::kSystemLevel, &value));
298  EXPECT_FALSE(prefs2.GetBool(
299      installer::master_preferences::kVerboseLogging, &value));
300}
301
302TEST_F(MasterPreferencesTest, TestDefaultInstallConfig) {
303  std::wstringstream chrome_cmd;
304  chrome_cmd << "setup.exe";
305
306  CommandLine chrome_install(CommandLine::FromString(chrome_cmd.str()));
307
308  installer::MasterPreferences pref_chrome(chrome_install);
309
310  EXPECT_FALSE(pref_chrome.is_multi_install());
311  EXPECT_TRUE(pref_chrome.install_chrome());
312}
313
314TEST_F(MasterPreferencesTest, TestMultiInstallConfig) {
315  using installer::switches::kMultiInstall;
316  using installer::switches::kChrome;
317
318  std::wstringstream chrome_cmd, cf_cmd, chrome_cf_cmd;
319  chrome_cmd << "setup.exe --" << kMultiInstall << " --" << kChrome;
320
321  CommandLine chrome_install(CommandLine::FromString(chrome_cmd.str()));
322
323  installer::MasterPreferences pref_chrome(chrome_install);
324
325  EXPECT_TRUE(pref_chrome.is_multi_install());
326  EXPECT_TRUE(pref_chrome.install_chrome());
327}
328
329TEST_F(MasterPreferencesTest, EnforceLegacyCreateAllShortcutsFalse) {
330  static const char kCreateAllShortcutsFalsePrefs[] =
331      "{"
332      "  \"distribution\": {"
333      "     \"create_all_shortcuts\": false"
334      "  }"
335      "}";
336
337    installer::MasterPreferences prefs(kCreateAllShortcutsFalsePrefs);
338
339    bool do_not_create_desktop_shortcut = false;
340    bool do_not_create_quick_launch_shortcut = false;
341    bool do_not_create_taskbar_shortcut = false;
342    prefs.GetBool(
343        installer::master_preferences::kDoNotCreateDesktopShortcut,
344        &do_not_create_desktop_shortcut);
345    prefs.GetBool(
346        installer::master_preferences::kDoNotCreateQuickLaunchShortcut,
347        &do_not_create_quick_launch_shortcut);
348    prefs.GetBool(
349        installer::master_preferences::kDoNotCreateTaskbarShortcut,
350        &do_not_create_taskbar_shortcut);
351    // create_all_shortcuts is a legacy preference that should only enforce
352    // do_not_create_desktop_shortcut and do_not_create_quick_launch_shortcut
353    // when set to false.
354    EXPECT_TRUE(do_not_create_desktop_shortcut);
355    EXPECT_TRUE(do_not_create_quick_launch_shortcut);
356    EXPECT_FALSE(do_not_create_taskbar_shortcut);
357}
358
359TEST_F(MasterPreferencesTest, DontEnforceLegacyCreateAllShortcutsTrue) {
360  static const char kCreateAllShortcutsFalsePrefs[] =
361      "{"
362      "  \"distribution\": {"
363      "     \"create_all_shortcuts\": true"
364      "  }"
365      "}";
366
367    installer::MasterPreferences prefs(kCreateAllShortcutsFalsePrefs);
368
369    bool do_not_create_desktop_shortcut = false;
370    bool do_not_create_quick_launch_shortcut = false;
371    bool do_not_create_taskbar_shortcut = false;
372    prefs.GetBool(
373        installer::master_preferences::kDoNotCreateDesktopShortcut,
374        &do_not_create_desktop_shortcut);
375    prefs.GetBool(
376        installer::master_preferences::kDoNotCreateQuickLaunchShortcut,
377        &do_not_create_quick_launch_shortcut);
378    prefs.GetBool(
379        installer::master_preferences::kDoNotCreateTaskbarShortcut,
380        &do_not_create_taskbar_shortcut);
381    EXPECT_FALSE(do_not_create_desktop_shortcut);
382    EXPECT_FALSE(do_not_create_quick_launch_shortcut);
383    EXPECT_FALSE(do_not_create_taskbar_shortcut);
384}
385
386TEST_F(MasterPreferencesTest, DontEnforceLegacyCreateAllShortcutsNotSpecified) {
387  static const char kCreateAllShortcutsFalsePrefs[] =
388      "{"
389      "  \"distribution\": {"
390      "     \"some_other_pref\": true"
391      "  }"
392      "}";
393
394    installer::MasterPreferences prefs(kCreateAllShortcutsFalsePrefs);
395
396    bool do_not_create_desktop_shortcut = false;
397    bool do_not_create_quick_launch_shortcut = false;
398    bool do_not_create_taskbar_shortcut = false;
399    prefs.GetBool(
400        installer::master_preferences::kDoNotCreateDesktopShortcut,
401        &do_not_create_desktop_shortcut);
402    prefs.GetBool(
403        installer::master_preferences::kDoNotCreateQuickLaunchShortcut,
404        &do_not_create_quick_launch_shortcut);
405    prefs.GetBool(
406        installer::master_preferences::kDoNotCreateTaskbarShortcut,
407        &do_not_create_taskbar_shortcut);
408    EXPECT_FALSE(do_not_create_desktop_shortcut);
409    EXPECT_FALSE(do_not_create_quick_launch_shortcut);
410    EXPECT_FALSE(do_not_create_taskbar_shortcut);
411}
412
413TEST_F(MasterPreferencesTest, MigrateOldStartupUrlsPref) {
414  static const char kOldMasterPrefs[] =
415      "{ \n"
416      "  \"distribution\": { \n"
417      "     \"show_welcome_page\": true,\n"
418      "     \"import_search_engine\": true,\n"
419      "     \"import_history\": true,\n"
420      "     \"import_bookmarks\": true\n"
421      "  },\n"
422      "  \"session\": {\n"
423      "     \"urls_to_restore_on_startup\": [\"http://www.google.com\"]\n"
424      "  }\n"
425      "} \n";
426
427  const installer::MasterPreferences prefs(kOldMasterPrefs);
428  const base::DictionaryValue& master_dictionary =
429      prefs.master_dictionary();
430
431  const base::ListValue* old_startup_urls_list = NULL;
432  EXPECT_TRUE(master_dictionary.GetList(prefs::kURLsToRestoreOnStartupOld,
433                                        &old_startup_urls_list));
434  EXPECT_TRUE(old_startup_urls_list != NULL);
435
436  // The MasterPreferences dictionary should also conjure up the new setting
437  // as per EnforceLegacyPreferences.
438  const base::ListValue* new_startup_urls_list = NULL;
439  EXPECT_TRUE(master_dictionary.GetList(prefs::kURLsToRestoreOnStartup,
440                                        &new_startup_urls_list));
441  EXPECT_TRUE(new_startup_urls_list != NULL);
442}
443
444TEST_F(MasterPreferencesTest, DontMigrateOldStartupUrlsPrefWhenNewExists) {
445  static const char kOldAndNewMasterPrefs[] =
446      "{ \n"
447      "  \"distribution\": { \n"
448      "     \"show_welcome_page\": true,\n"
449      "     \"import_search_engine\": true,\n"
450      "     \"import_history\": true,\n"
451      "     \"import_bookmarks\": true\n"
452      "  },\n"
453      "  \"session\": {\n"
454      "     \"urls_to_restore_on_startup\": [\"http://www.google.com\"],\n"
455      "     \"startup_urls\": [\"http://www.example.com\"]\n"
456      "  }\n"
457      "} \n";
458
459  const installer::MasterPreferences prefs(kOldAndNewMasterPrefs);
460  const base::DictionaryValue& master_dictionary =
461      prefs.master_dictionary();
462
463  const base::ListValue* old_startup_urls_list = NULL;
464  EXPECT_TRUE(master_dictionary.GetList(prefs::kURLsToRestoreOnStartupOld,
465                                        &old_startup_urls_list));
466  ASSERT_TRUE(old_startup_urls_list != NULL);
467  std::string url_value;
468  EXPECT_TRUE(old_startup_urls_list->GetString(0, &url_value));
469  EXPECT_EQ("http://www.google.com", url_value);
470
471  // The MasterPreferences dictionary should also conjure up the new setting
472  // as per EnforceLegacyPreferences.
473  const base::ListValue* new_startup_urls_list = NULL;
474  EXPECT_TRUE(master_dictionary.GetList(prefs::kURLsToRestoreOnStartup,
475                                        &new_startup_urls_list));
476  ASSERT_TRUE(new_startup_urls_list != NULL);
477  std::string new_url_value;
478  EXPECT_TRUE(new_startup_urls_list->GetString(0, &new_url_value));
479  EXPECT_EQ("http://www.example.com", new_url_value);
480}
481