e67cae02feb4c4fc9e764906337b1a6631290c80
[platform/framework/web/crosswalk.git] / src / chrome / browser / profiles / profile_manager_browsertest.cc
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/bind.h"
6 #include "base/command_line.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/profiles/profile_info_cache.h"
10 #include "chrome/browser/profiles/profile_info_cache_observer.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/profiles/profile_window.h"
13 #include "chrome/browser/profiles/profiles_state.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/host_desktop.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/test_switches.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "chrome/test/base/ui_test_utils.h"
23
24 #if defined(OS_CHROMEOS)
25 #include "base/path_service.h"
26 #include "chrome/common/chrome_constants.h"
27 #include "chrome/common/chrome_paths.h"
28 #include "chromeos/chromeos_switches.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #endif
31
32 namespace {
33
34 const profiles::ProfileSwitchingDoneCallback kOnProfileSwitchDoNothing;
35
36 // An observer that returns back to test code after a new profile is
37 // initialized.
38 void OnUnblockOnProfileCreation(Profile* profile,
39                                 Profile::CreateStatus status) {
40   if (status == Profile::CREATE_STATUS_INITIALIZED)
41     base::MessageLoop::current()->Quit();
42 }
43
44 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) {
45   ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL);
46   ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL);
47   // No browser should have been created for this profile yet.
48   EXPECT_EQ(chrome::GetTotalBrowserCountForProfile(profile), 0U);
49   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
50   if (status == Profile::CREATE_STATUS_INITIALIZED)
51     base::MessageLoop::current()->Quit();
52 }
53
54 void EphemeralProfileCreationComplete(Profile* profile,
55                                       Profile::CreateStatus status) {
56   if (status == Profile::CREATE_STATUS_INITIALIZED)
57     profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true);
58   ProfileCreationComplete(profile, status);
59 }
60
61 class ProfileRemovalObserver : public ProfileInfoCacheObserver {
62  public:
63   ProfileRemovalObserver() {
64     g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(
65         this);
66   }
67
68   virtual ~ProfileRemovalObserver() {
69     g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
70         this);
71   }
72
73   std::string last_used_profile_name() { return last_used_profile_name_; }
74
75   // ProfileInfoCacheObserver overrides:
76   virtual void OnProfileWillBeRemoved(
77       const base::FilePath& profile_path) OVERRIDE {
78     last_used_profile_name_ = g_browser_process->local_state()->GetString(
79         prefs::kProfileLastUsed);
80   }
81
82  private:
83   std::string last_used_profile_name_;
84
85   DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver);
86 };
87
88 } // namespace
89
90 // This file contains tests for the ProfileManager that require a heavyweight
91 // InProcessBrowserTest.  These include tests involving profile deletion.
92
93 // TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
94 // platforms.
95 class ProfileManagerBrowserTest : public InProcessBrowserTest {
96  protected:
97   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
98 #if defined(OS_CHROMEOS)
99     command_line->AppendSwitch(
100         chromeos::switches::kIgnoreUserProfileMappingForTests);
101 #endif
102   }
103 };
104
105 #if defined(OS_MACOSX)
106
107 // Delete single profile and make sure a new one is created.
108 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
109   ProfileManager* profile_manager = g_browser_process->profile_manager();
110   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
111   ProfileRemovalObserver observer;
112
113   // We should start out with 1 profile.
114   ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);
115
116   // Delete singleton profile.
117   base::FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
118   EXPECT_FALSE(singleton_profile_path.empty());
119   profile_manager->ScheduleProfileForDeletion(singleton_profile_path,
120                                               ProfileManager::CreateCallback());
121
122   // Spin things till profile is actually deleted.
123   content::RunAllPendingInMessageLoop();
124
125   // Make sure a new profile was created automatically.
126   EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
127   base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
128   EXPECT_NE(new_profile_path, singleton_profile_path);
129
130   // Make sure that last used profile preference is set correctly.
131   Profile* last_used = ProfileManager::GetLastUsedProfile();
132   EXPECT_EQ(new_profile_path, last_used->GetPath());
133
134   // Make sure the last used profile was set correctly before the notification
135   // was sent.
136   std::string last_used_profile_name =
137       last_used->GetPath().BaseName().MaybeAsASCII();
138   EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name());
139 }
140
141 // Delete all profiles in a multi profile setup and make sure a new one is
142 // created.
143 // Crashes/CHECKs. See crbug.com/104851
144 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) {
145   ProfileManager* profile_manager = g_browser_process->profile_manager();
146   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
147
148   // Create an additional profile.
149   base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
150   profile_manager->CreateProfileAsync(new_path,
151                                       base::Bind(&OnUnblockOnProfileCreation),
152                                       base::string16(), base::string16(),
153                                       std::string());
154
155   // Spin to allow profile creation to take place, loop is terminated
156   // by OnUnblockOnProfileCreation when the profile is created.
157   content::RunMessageLoop();
158
159   ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
160
161   // Delete all profiles.
162   base::FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
163   base::FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
164   EXPECT_FALSE(profile_path1.empty());
165   EXPECT_FALSE(profile_path2.empty());
166   profile_manager->ScheduleProfileForDeletion(profile_path1,
167                                               ProfileManager::CreateCallback());
168   profile_manager->ScheduleProfileForDeletion(profile_path2,
169                                               ProfileManager::CreateCallback());
170
171   // Spin things so deletion can take place.
172   content::RunAllPendingInMessageLoop();
173
174   // Make sure a new profile was created automatically.
175   EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
176   base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
177   EXPECT_NE(new_profile_path, profile_path1);
178   EXPECT_NE(new_profile_path, profile_path2);
179
180   // Make sure that last used profile preference is set correctly.
181   Profile* last_used = ProfileManager::GetLastUsedProfile();
182   EXPECT_EQ(new_profile_path, last_used->GetPath());
183 }
184 #endif  // OS_MACOSX
185
186 #if defined(OS_CHROMEOS)
187
188 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest {
189  protected:
190   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
191     // Use a user hash other than the default chrome::kTestUserProfileDir
192     // so that the prefix case is tested.
193     command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
194                                     "test-user-hash");
195   }
196 };
197
198 IN_PROC_BROWSER_TEST_F(ProfileManagerCrOSBrowserTest, GetLastUsedProfile) {
199   // Make sure that last used profile is correct.
200   Profile* last_used_profile = ProfileManager::GetLastUsedProfile();
201   EXPECT_TRUE(last_used_profile != NULL);
202
203   base::FilePath profile_path;
204   PathService::Get(chrome::DIR_USER_DATA, &profile_path);
205
206   profile_path = profile_path.AppendASCII(
207       std::string(chrome::kProfileDirPrefix) + "test-user-hash");
208   EXPECT_EQ(profile_path.value(), last_used_profile->GetPath().value());
209 }
210
211 #endif  // OS_CHROMEOS
212
213 // Times out (http://crbug.com/159002)
214 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
215                        DISABLED_CreateProfileWithCallback) {
216   ProfileManager* profile_manager = g_browser_process->profile_manager();
217
218   ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
219   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
220
221   // Create a profile, make sure callback is invoked before any callbacks are
222   // invoked (so they can do things like sign in the profile, etc).
223   ProfileManager::CreateMultiProfileAsync(
224       base::string16(), // name
225       base::string16(), // icon url
226       base::Bind(ProfileCreationComplete),
227       std::string());
228   // Wait for profile to finish loading.
229   content::RunMessageLoop();
230   EXPECT_EQ(profile_manager->GetNumberOfProfiles(), 2U);
231   EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
232
233   // Now close all browser windows.
234   std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
235   for (std::vector<Profile*>::const_iterator it = profiles.begin();
236        it != profiles.end(); ++it) {
237     BrowserList::CloseAllBrowsersWithProfile(*it);
238   }
239 }
240
241 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
242                        SwitchToProfile) {
243 #if defined(OS_WIN) && defined(USE_ASH)
244   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
245   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
246     return;
247 #endif
248
249   // If multiprofile mode is not enabled, you can't switch between profiles.
250   if (!profiles::IsMultipleProfilesEnabled())
251     return;
252
253   ProfileManager* profile_manager = g_browser_process->profile_manager();
254   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
255   base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
256
257   ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
258   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
259
260   // Create an additional profile.
261   base::FilePath path_profile2 =
262       profile_manager->GenerateNextProfileDirectoryPath();
263   profile_manager->CreateProfileAsync(path_profile2,
264                                       base::Bind(&OnUnblockOnProfileCreation),
265                                       base::string16(), base::string16(),
266                                       std::string());
267
268   // Spin to allow profile creation to take place, loop is terminated
269   // by OnUnblockOnProfileCreation when the profile is created.
270   content::RunMessageLoop();
271
272   chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
273   BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
274   ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
275   EXPECT_EQ(1U, browser_list->size());
276
277   // Open a browser window for the first profile.
278   profiles::SwitchToProfile(path_profile1, desktop_type, false,
279                             kOnProfileSwitchDoNothing,
280                             ProfileMetrics::SWITCH_PROFILE_ICON);
281   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
282   EXPECT_EQ(1U, browser_list->size());
283   EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
284
285   // Open a browser window for the second profile.
286   profiles::SwitchToProfile(path_profile2, desktop_type, false,
287                             kOnProfileSwitchDoNothing,
288                             ProfileMetrics::SWITCH_PROFILE_ICON);
289   EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
290   EXPECT_EQ(2U, browser_list->size());
291   EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
292
293   // Switch to the first profile without opening a new window.
294   profiles::SwitchToProfile(path_profile1, desktop_type, false,
295                             kOnProfileSwitchDoNothing,
296                             ProfileMetrics::SWITCH_PROFILE_ICON);
297   EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
298   EXPECT_EQ(2U, browser_list->size());
299
300   EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
301   EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
302 }
303
304 // This test used to be flakily timing out on Windows: http://crbug.com/314905.
305 // If this happens again please make it a MAYBE_ test and reopen that bug.
306 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, EphemeralProfile) {
307 #if defined(OS_WIN) && defined(USE_ASH)
308   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
309   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
310     return;
311 #endif
312
313   // If multiprofile mode is not enabled, you can't switch between profiles.
314   if (!profiles::IsMultipleProfilesEnabled())
315     return;
316
317   ProfileManager* profile_manager = g_browser_process->profile_manager();
318   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
319   base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
320
321   ASSERT_EQ(1U, profile_manager->GetNumberOfProfiles());
322   EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
323
324   // Create an ephemeral profile.
325   base::FilePath path_profile2 =
326       profile_manager->GenerateNextProfileDirectoryPath();
327   profile_manager->CreateProfileAsync(
328       path_profile2,
329       base::Bind(&EphemeralProfileCreationComplete),
330       base::string16(), base::string16(), std::string());
331
332   // Spin to allow profile creation to take place.
333   content::RunMessageLoop();
334
335   chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
336   BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
337   ASSERT_EQ(2U, cache.GetNumberOfProfiles());
338   EXPECT_EQ(1U, browser_list->size());
339
340   // Open a browser window for the second profile.
341   profiles::SwitchToProfile(path_profile2, desktop_type, false,
342                             kOnProfileSwitchDoNothing,
343                             ProfileMetrics::SWITCH_PROFILE_ICON);
344   EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
345   EXPECT_EQ(2U, browser_list->size());
346   EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
347
348   // Create a second window for the ephemeral profile.
349   profiles::SwitchToProfile(path_profile2, desktop_type, true,
350                             kOnProfileSwitchDoNothing,
351                             ProfileMetrics::SWITCH_PROFILE_ICON);
352   EXPECT_EQ(3U, chrome::GetTotalBrowserCount());
353   EXPECT_EQ(3U, browser_list->size());
354
355   EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
356   EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
357   EXPECT_EQ(path_profile2, browser_list->get(2)->profile()->GetPath());
358
359   // Closing the first window of the ephemeral profile should not delete it.
360   browser_list->get(2)->window()->Close();
361   content::RunAllPendingInMessageLoop();
362   EXPECT_EQ(2U, browser_list->size());
363   ASSERT_EQ(2U, cache.GetNumberOfProfiles());
364
365   // The second should though.
366   browser_list->get(1)->window()->Close();
367   content::RunAllPendingInMessageLoop();
368   EXPECT_EQ(1U, browser_list->size());
369   ASSERT_EQ(1U, cache.GetNumberOfProfiles());
370 }
371