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 #include <string> 6 7 #include "base/command_line.h" 8 #include "base/files/file_path.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/prefs/pref_service.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/extensions/component_loader.h" 15 #include "chrome/browser/first_run/first_run.h" 16 #include "chrome/browser/importer/importer_list.h" 17 #include "chrome/browser/prefs/chrome_pref_service_factory.h" 18 #include "chrome/browser/profiles/profile_manager.h" 19 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" 21 #include "chrome/common/chrome_switches.h" 22 #include "chrome/common/pref_names.h" 23 #include "chrome/common/url_constants.h" 24 #include "chrome/test/base/in_process_browser_test.h" 25 #include "chrome/test/base/ui_test_utils.h" 26 #include "components/user_prefs/user_prefs.h" 27 #include "content/public/browser/web_contents.h" 28 #include "content/public/common/content_switches.h" 29 #include "content/public/test/test_launcher.h" 30 #include "testing/gtest/include/gtest/gtest.h" 31 32 typedef InProcessBrowserTest FirstRunBrowserTest; 33 34 IN_PROC_BROWSER_TEST_F(FirstRunBrowserTest, SetShowFirstRunBubblePref) { 35 EXPECT_TRUE(g_browser_process->local_state()->FindPreference( 36 prefs::kShowFirstRunBubbleOption)); 37 EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_DONT_SHOW, 38 g_browser_process->local_state()->GetInteger( 39 prefs::kShowFirstRunBubbleOption)); 40 EXPECT_TRUE(first_run::SetShowFirstRunBubblePref( 41 first_run::FIRST_RUN_BUBBLE_SHOW)); 42 ASSERT_TRUE(g_browser_process->local_state()->FindPreference( 43 prefs::kShowFirstRunBubbleOption)); 44 EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_SHOW, 45 g_browser_process->local_state()->GetInteger( 46 prefs::kShowFirstRunBubbleOption)); 47 // Test that toggling the value works in either direction after it's been set. 48 EXPECT_TRUE(first_run::SetShowFirstRunBubblePref( 49 first_run::FIRST_RUN_BUBBLE_DONT_SHOW)); 50 EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_DONT_SHOW, 51 g_browser_process->local_state()->GetInteger( 52 prefs::kShowFirstRunBubbleOption)); 53 // Test that the value can't be set to FIRST_RUN_BUBBLE_SHOW after it has been 54 // set to FIRST_RUN_BUBBLE_SUPPRESS. 55 EXPECT_TRUE(first_run::SetShowFirstRunBubblePref( 56 first_run::FIRST_RUN_BUBBLE_SUPPRESS)); 57 EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_SUPPRESS, 58 g_browser_process->local_state()->GetInteger( 59 prefs::kShowFirstRunBubbleOption)); 60 EXPECT_TRUE(first_run::SetShowFirstRunBubblePref( 61 first_run::FIRST_RUN_BUBBLE_SHOW)); 62 EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_SUPPRESS, 63 g_browser_process->local_state()->GetInteger( 64 prefs::kShowFirstRunBubbleOption)); 65 } 66 67 IN_PROC_BROWSER_TEST_F(FirstRunBrowserTest, SetShouldShowWelcomePage) { 68 EXPECT_FALSE(first_run::ShouldShowWelcomePage()); 69 first_run::SetShouldShowWelcomePage(); 70 EXPECT_TRUE(first_run::ShouldShowWelcomePage()); 71 EXPECT_FALSE(first_run::ShouldShowWelcomePage()); 72 } 73 74 #if !defined(OS_CHROMEOS) 75 namespace { 76 77 // A generic test class to be subclassed by test classes testing specific 78 // master_preferences. All subclasses must call SetMasterPreferencesForTest() 79 // from their SetUp() method before deferring the remainder of Setup() to this 80 // class. 81 class FirstRunMasterPrefsBrowserTestBase : public InProcessBrowserTest { 82 public: 83 FirstRunMasterPrefsBrowserTestBase() {} 84 85 protected: 86 virtual void SetUp() OVERRIDE { 87 // All users of this test class need to call SetMasterPreferencesForTest() 88 // before this class' SetUp() is invoked. 89 ASSERT_TRUE(text_.get()); 90 91 ASSERT_TRUE(base::CreateTemporaryFile(&prefs_file_)); 92 EXPECT_TRUE(base::WriteFile(prefs_file_, text_->c_str(), text_->size())); 93 first_run::SetMasterPrefsPathForTesting(prefs_file_); 94 95 // This invokes BrowserMain, and does the import, so must be done last. 96 InProcessBrowserTest::SetUp(); 97 } 98 99 virtual void TearDown() OVERRIDE { 100 EXPECT_TRUE(base::DeleteFile(prefs_file_, false)); 101 InProcessBrowserTest::TearDown(); 102 } 103 104 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 105 InProcessBrowserTest::SetUpCommandLine(command_line); 106 command_line->AppendSwitch(switches::kForceFirstRun); 107 EXPECT_EQ(first_run::AUTO_IMPORT_NONE, first_run::auto_import_state()); 108 109 extensions::ComponentLoader::EnableBackgroundExtensionsForTesting(); 110 } 111 112 void SetMasterPreferencesForTest(const char text[]) { 113 text_.reset(new std::string(text)); 114 } 115 116 private: 117 base::FilePath prefs_file_; 118 scoped_ptr<std::string> text_; 119 120 DISALLOW_COPY_AND_ASSIGN(FirstRunMasterPrefsBrowserTestBase); 121 }; 122 123 template<const char Text[]> 124 class FirstRunMasterPrefsBrowserTestT 125 : public FirstRunMasterPrefsBrowserTestBase { 126 public: 127 FirstRunMasterPrefsBrowserTestT() {} 128 129 protected: 130 virtual void SetUp() OVERRIDE { 131 SetMasterPreferencesForTest(Text); 132 FirstRunMasterPrefsBrowserTestBase::SetUp(); 133 } 134 135 private: 136 DISALLOW_COPY_AND_ASSIGN(FirstRunMasterPrefsBrowserTestT); 137 }; 138 139 // Returns the true expected import state, derived from the original 140 // |expected_import_state|, for the current test machine's configuration. Some 141 // bot configurations do not have another profile (browser) to import from and 142 // thus the import must not be expected to have occurred. 143 int MaskExpectedImportState(int expected_import_state) { 144 scoped_ptr<ImporterList> importer_list(new ImporterList()); 145 base::RunLoop run_loop; 146 importer_list->DetectSourceProfiles( 147 g_browser_process->GetApplicationLocale(), 148 false, // include_interactive_profiles? 149 run_loop.QuitClosure()); 150 run_loop.Run(); 151 int source_profile_count = importer_list->count(); 152 #if defined(OS_WIN) 153 // On Windows, the importer's DetectIEProfiles() will always add to the count. 154 // Internet Explorer always exists and always has something to import. 155 EXPECT_GT(source_profile_count, 0); 156 #endif 157 if (source_profile_count == 0) 158 return expected_import_state & ~first_run::AUTO_IMPORT_PROFILE_IMPORTED; 159 return expected_import_state; 160 } 161 162 } // namespace 163 164 extern const char kImportDefault[] = 165 "{\n" 166 "}\n"; 167 typedef FirstRunMasterPrefsBrowserTestT<kImportDefault> 168 FirstRunMasterPrefsImportDefault; 169 // http://crbug.com/314221 170 #if defined(GOOGLE_CHROME_BUILD) && (defined(OS_MACOSX) || defined(OS_LINUX)) 171 #define MAYBE_ImportDefault DISABLED_ImportDefault 172 #else 173 #define MAYBE_ImportDefault ImportDefault 174 #endif 175 IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportDefault, MAYBE_ImportDefault) { 176 int auto_import_state = first_run::auto_import_state(); 177 EXPECT_EQ(MaskExpectedImportState(first_run::AUTO_IMPORT_CALLED | 178 first_run::AUTO_IMPORT_PROFILE_IMPORTED), 179 auto_import_state); 180 } 181 182 // The bookmarks file doesn't actually need to exist for this integration test 183 // to trigger the interaction being tested. 184 extern const char kImportBookmarksFile[] = 185 "{\n" 186 " \"distribution\": {\n" 187 " \"import_bookmarks_from_file\": \"/foo/doesntexists.wtv\"\n" 188 " }\n" 189 "}\n"; 190 typedef FirstRunMasterPrefsBrowserTestT<kImportBookmarksFile> 191 FirstRunMasterPrefsImportBookmarksFile; 192 // http://crbug.com/314221 193 #if defined(GOOGLE_CHROME_BUILD) && (defined(OS_MACOSX) || defined(OS_LINUX)) 194 #define MAYBE_ImportBookmarksFile DISABLED_ImportBookmarksFile 195 #else 196 #define MAYBE_ImportBookmarksFile ImportBookmarksFile 197 #endif 198 IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportBookmarksFile, 199 MAYBE_ImportBookmarksFile) { 200 int auto_import_state = first_run::auto_import_state(); 201 EXPECT_EQ( 202 MaskExpectedImportState(first_run::AUTO_IMPORT_CALLED | 203 first_run::AUTO_IMPORT_PROFILE_IMPORTED | 204 first_run::AUTO_IMPORT_BOOKMARKS_FILE_IMPORTED), 205 auto_import_state); 206 } 207 208 // Test an import with all import options disabled. This is a regression test 209 // for http://crbug.com/169984 where this would cause the import process to 210 // stay running, and the NTP to be loaded with no apps. 211 extern const char kImportNothing[] = 212 "{\n" 213 " \"distribution\": {\n" 214 " \"import_bookmarks\": false,\n" 215 " \"import_history\": false,\n" 216 " \"import_home_page\": false,\n" 217 " \"import_search_engine\": false\n" 218 " }\n" 219 "}\n"; 220 typedef FirstRunMasterPrefsBrowserTestT<kImportNothing> 221 FirstRunMasterPrefsImportNothing; 222 // http://crbug.com/314221 223 #if defined(GOOGLE_CHROME_BUILD) && (defined(OS_MACOSX) || defined(OS_LINUX)) 224 #define MAYBE_ImportNothingAndShowNewTabPage \ 225 DISABLED_ImportNothingAndShowNewTabPage 226 #else 227 #define MAYBE_ImportNothingAndShowNewTabPage ImportNothingAndShowNewTabPage 228 #endif 229 IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportNothing, 230 MAYBE_ImportNothingAndShowNewTabPage) { 231 EXPECT_EQ(first_run::AUTO_IMPORT_CALLED, first_run::auto_import_state()); 232 ui_test_utils::NavigateToURLWithDisposition( 233 browser(), GURL(chrome::kChromeUINewTabURL), CURRENT_TAB, 234 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 235 content::WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(0); 236 EXPECT_EQ(1, tab->GetMaxPageID()); 237 } 238 239 // Test first run with some tracked preferences. 240 extern const char kWithTrackedPrefs[] = 241 "{\n" 242 " \"homepage\": \"example.com\",\n" 243 " \"homepage_is_newtabpage\": false\n" 244 "}\n"; 245 // A test fixture that will run in a first run scenario with master_preferences 246 // set to kWithTrackedPrefs. Parameterizable on the SettingsEnforcement 247 // experiment to be forced. 248 class FirstRunMasterPrefsWithTrackedPreferences 249 : public FirstRunMasterPrefsBrowserTestT<kWithTrackedPrefs>, 250 public testing::WithParamInterface<std::string> { 251 public: 252 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 253 FirstRunMasterPrefsBrowserTestT::SetUpCommandLine(command_line); 254 command_line->AppendSwitchASCII( 255 switches::kForceFieldTrials, 256 std::string(chrome_prefs::internals::kSettingsEnforcementTrialName) + 257 "/" + GetParam() + "/"); 258 } 259 }; 260 261 // http://crbug.com/314221 262 #if defined(GOOGLE_CHROME_BUILD) && (defined(OS_MACOSX) || defined(OS_LINUX)) 263 #define MAYBE_TrackedPreferencesSurviveFirstRun \ 264 DISABLED_TrackedPreferencesSurviveFirstRun 265 #else 266 #define MAYBE_TrackedPreferencesSurviveFirstRun \ 267 TrackedPreferencesSurviveFirstRun 268 #endif 269 IN_PROC_BROWSER_TEST_P(FirstRunMasterPrefsWithTrackedPreferences, 270 MAYBE_TrackedPreferencesSurviveFirstRun) { 271 const PrefService* user_prefs = browser()->profile()->GetPrefs(); 272 EXPECT_EQ("example.com", user_prefs->GetString(prefs::kHomePage)); 273 EXPECT_FALSE(user_prefs->GetBoolean(prefs::kHomePageIsNewTabPage)); 274 275 // The test for kHomePageIsNewTabPage above relies on the fact that true is 276 // the default (hence false must be the user's pref); ensure this fact remains 277 // true. 278 const base::Value* default_homepage_is_ntp_value = 279 user_prefs->GetDefaultPrefValue(prefs::kHomePageIsNewTabPage); 280 ASSERT_TRUE(default_homepage_is_ntp_value != NULL); 281 bool default_homepage_is_ntp = false; 282 EXPECT_TRUE( 283 default_homepage_is_ntp_value->GetAsBoolean(&default_homepage_is_ntp)); 284 EXPECT_TRUE(default_homepage_is_ntp); 285 } 286 287 INSTANTIATE_TEST_CASE_P( 288 FirstRunMasterPrefsWithTrackedPreferencesInstance, 289 FirstRunMasterPrefsWithTrackedPreferences, 290 testing::Values( 291 chrome_prefs::internals::kSettingsEnforcementGroupNoEnforcement, 292 chrome_prefs::internals::kSettingsEnforcementGroupEnforceAlways, 293 chrome_prefs::internals:: 294 kSettingsEnforcementGroupEnforceAlwaysWithDSE, 295 chrome_prefs::internals:: 296 kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE)); 297 298 #endif // !defined(OS_CHROMEOS) 299