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 "base/command_line.h"
6#include "base/files/file_path.h"
7#include "base/memory/ref_counted.h"
8#include "base/prefs/pref_service.h"
9#include "base/strings/string_util.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/extensions/component_loader.h"
13#include "chrome/browser/first_run/first_run.h"
14#include "chrome/browser/importer/importer_list.h"
15#include "chrome/browser/profiles/profile_manager.h"
16#include "chrome/browser/ui/browser.h"
17#include "chrome/browser/ui/tabs/tab_strip_model.h"
18#include "chrome/common/chrome_switches.h"
19#include "chrome/common/pref_names.h"
20#include "chrome/common/url_constants.h"
21#include "chrome/test/base/in_process_browser_test.h"
22#include "chrome/test/base/ui_test_utils.h"
23#include "content/public/browser/web_contents.h"
24#include "content/public/test/test_launcher.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27typedef InProcessBrowserTest FirstRunBrowserTest;
28
29IN_PROC_BROWSER_TEST_F(FirstRunBrowserTest, SetShowFirstRunBubblePref) {
30  EXPECT_TRUE(g_browser_process->local_state()->FindPreference(
31      prefs::kShowFirstRunBubbleOption));
32  EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_DONT_SHOW,
33            g_browser_process->local_state()->GetInteger(
34                prefs::kShowFirstRunBubbleOption));
35  EXPECT_TRUE(first_run::SetShowFirstRunBubblePref(
36      first_run::FIRST_RUN_BUBBLE_SHOW));
37  ASSERT_TRUE(g_browser_process->local_state()->FindPreference(
38      prefs::kShowFirstRunBubbleOption));
39  EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_SHOW,
40            g_browser_process->local_state()->GetInteger(
41                prefs::kShowFirstRunBubbleOption));
42  // Test that toggling the value works in either direction after it's been set.
43  EXPECT_TRUE(first_run::SetShowFirstRunBubblePref(
44      first_run::FIRST_RUN_BUBBLE_DONT_SHOW));
45  EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_DONT_SHOW,
46            g_browser_process->local_state()->GetInteger(
47                prefs::kShowFirstRunBubbleOption));
48  // Test that the value can't be set to FIRST_RUN_BUBBLE_SHOW after it has been
49  // set to FIRST_RUN_BUBBLE_SUPPRESS.
50  EXPECT_TRUE(first_run::SetShowFirstRunBubblePref(
51      first_run::FIRST_RUN_BUBBLE_SUPPRESS));
52  EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_SUPPRESS,
53            g_browser_process->local_state()->GetInteger(
54                prefs::kShowFirstRunBubbleOption));
55  EXPECT_TRUE(first_run::SetShowFirstRunBubblePref(
56      first_run::FIRST_RUN_BUBBLE_SHOW));
57  EXPECT_EQ(first_run::FIRST_RUN_BUBBLE_SUPPRESS,
58            g_browser_process->local_state()->GetInteger(
59                prefs::kShowFirstRunBubbleOption));
60}
61
62IN_PROC_BROWSER_TEST_F(FirstRunBrowserTest, SetShouldShowWelcomePage) {
63  EXPECT_FALSE(first_run::ShouldShowWelcomePage());
64  first_run::SetShouldShowWelcomePage();
65  EXPECT_TRUE(first_run::ShouldShowWelcomePage());
66  EXPECT_FALSE(first_run::ShouldShowWelcomePage());
67}
68
69#if !defined(OS_CHROMEOS)
70namespace {
71
72// A generic test class to be subclassed by test classes testing specific
73// master_preferences. All subclasses must call SetMasterPreferencesForTest()
74// from their SetUp() method before deferring the remainder of Setup() to this
75// class.
76class FirstRunMasterPrefsBrowserTestBase : public InProcessBrowserTest {
77 public:
78  FirstRunMasterPrefsBrowserTestBase() {}
79
80 protected:
81  virtual void SetUp() OVERRIDE {
82    // All users of this test class need to call SetMasterPreferencesForTest()
83    // before this class' SetUp() is invoked.
84    ASSERT_TRUE(text_.get());
85
86    ASSERT_TRUE(base::CreateTemporaryFile(&prefs_file_));
87    EXPECT_TRUE(file_util::WriteFile(prefs_file_, text_->c_str(),
88                                     text_->size()));
89    first_run::SetMasterPrefsPathForTesting(prefs_file_);
90
91    // This invokes BrowserMain, and does the import, so must be done last.
92    InProcessBrowserTest::SetUp();
93  }
94
95  virtual void TearDown() OVERRIDE {
96    EXPECT_TRUE(base::DeleteFile(prefs_file_, false));
97    InProcessBrowserTest::TearDown();
98  }
99
100  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
101    InProcessBrowserTest::SetUpCommandLine(command_line);
102    command_line->AppendSwitch(switches::kForceFirstRun);
103    EXPECT_EQ(first_run::AUTO_IMPORT_NONE, first_run::auto_import_state());
104
105    extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
106  }
107
108  void SetMasterPreferencesForTest(const char text[]) {
109    text_.reset(new std::string(text));
110  }
111
112 private:
113  base::FilePath prefs_file_;
114  scoped_ptr<std::string> text_;
115
116  DISALLOW_COPY_AND_ASSIGN(FirstRunMasterPrefsBrowserTestBase);
117};
118
119template<const char Text[]>
120class FirstRunMasterPrefsBrowserTestT
121    : public FirstRunMasterPrefsBrowserTestBase {
122 public:
123  FirstRunMasterPrefsBrowserTestT() {}
124
125 protected:
126  virtual void SetUp() OVERRIDE {
127    SetMasterPreferencesForTest(Text);
128    FirstRunMasterPrefsBrowserTestBase::SetUp();
129  }
130
131 private:
132  DISALLOW_COPY_AND_ASSIGN(FirstRunMasterPrefsBrowserTestT);
133};
134
135// Returns the true expected import state, derived from the original
136// |expected_import_state|, for the current test machine's configuration. Some
137// bot configurations do not have another profile (browser) to import from and
138// thus the import must not be expected to have occurred.
139int MaskExpectedImportState(int expected_import_state) {
140  scoped_refptr<ImporterList> importer_list(new ImporterList());
141  importer_list->DetectSourceProfilesHack(
142      g_browser_process->GetApplicationLocale(), false);
143  int source_profile_count = importer_list->count();
144#if defined(OS_WIN)
145  // On Windows, the importer's DetectIEProfiles() will always add to the count.
146  // Internet Explorer always exists and always has something to import.
147  EXPECT_GT(source_profile_count, 0);
148#endif
149  if (source_profile_count == 0)
150    return expected_import_state & ~first_run::AUTO_IMPORT_PROFILE_IMPORTED;
151
152  return expected_import_state;
153}
154
155}  // namespace
156
157extern const char kImportDefault[] =
158    "{\n"
159    "}\n";
160typedef FirstRunMasterPrefsBrowserTestT<kImportDefault>
161    FirstRunMasterPrefsImportDefault;
162// http://crbug.com/314221
163#if defined(GOOGLE_CHROME_BUILD) && defined(OS_MACOSX)
164#define MAYBE_ImportDefault DISABLED_ImportDefault
165#else
166#define MAYBE_ImportDefault ImportDefault
167#endif
168IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportDefault, MAYBE_ImportDefault) {
169  int auto_import_state = first_run::auto_import_state();
170  EXPECT_EQ(MaskExpectedImportState(first_run::AUTO_IMPORT_CALLED |
171                                    first_run::AUTO_IMPORT_PROFILE_IMPORTED),
172            auto_import_state);
173}
174
175// The bookmarks file doesn't actually need to exist for this integration test
176// to trigger the interaction being tested.
177extern const char kImportBookmarksFile[] =
178    "{\n"
179    "  \"distribution\": {\n"
180    "     \"import_bookmarks_from_file\": \"/foo/doesntexists.wtv\"\n"
181    "  }\n"
182    "}\n";
183typedef FirstRunMasterPrefsBrowserTestT<kImportBookmarksFile>
184    FirstRunMasterPrefsImportBookmarksFile;
185// http://crbug.com/314221
186#if defined(GOOGLE_CHROME_BUILD) && defined(OS_MACOSX)
187#define MAYBE_ImportBookmarksFile DISABLED_ImportBookmarksFile
188#else
189#define MAYBE_ImportBookmarksFile ImportBookmarksFile
190#endif
191IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportBookmarksFile,
192                       MAYBE_ImportBookmarksFile) {
193  int auto_import_state = first_run::auto_import_state();
194  EXPECT_EQ(
195      MaskExpectedImportState(first_run::AUTO_IMPORT_CALLED |
196                              first_run::AUTO_IMPORT_PROFILE_IMPORTED |
197                              first_run::AUTO_IMPORT_BOOKMARKS_FILE_IMPORTED),
198      auto_import_state);
199}
200
201// Test an import with all import options disabled. This is a regression test
202// for http://crbug.com/169984 where this would cause the import process to
203// stay running, and the NTP to be loaded with no apps.
204extern const char kImportNothing[] =
205    "{\n"
206    "  \"distribution\": {\n"
207    "    \"import_bookmarks\": false,\n"
208    "    \"import_history\": false,\n"
209    "    \"import_home_page\": false,\n"
210    "    \"import_search_engine\": false\n"
211    "  }\n"
212    "}\n";
213typedef FirstRunMasterPrefsBrowserTestT<kImportNothing>
214    FirstRunMasterPrefsImportNothing;
215// http://crbug.com/314221
216#if defined(GOOGLE_CHROME_BUILD) && defined(OS_MACOSX)
217#define MAYBE_ImportNothingAndShowNewTabPage \
218    DISABLED_ImportNothingAndShowNewTabPage
219#else
220#define MAYBE_ImportNothingAndShowNewTabPage ImportNothingAndShowNewTabPage
221#endif
222IN_PROC_BROWSER_TEST_F(FirstRunMasterPrefsImportNothing,
223                       MAYBE_ImportNothingAndShowNewTabPage) {
224  EXPECT_EQ(first_run::AUTO_IMPORT_CALLED, first_run::auto_import_state());
225  ui_test_utils::NavigateToURLWithDisposition(
226      browser(), GURL(chrome::kChromeUINewTabURL), CURRENT_TAB,
227      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
228  content::WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(0);
229  EXPECT_EQ(1, tab->GetMaxPageID());
230}
231
232#endif  // !defined(OS_CHROMEOS)
233