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