Cleanup: new common GetProfileSwitcherTextForItem for use on both Win and Mac
[chromium-blink-merge.git] / chrome / browser / profiles / profile_manager_browsertest.cc
blob43df0d4b63a5b991c7590ceebb84d7e508e193be
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.
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/password_manager/password_store_factory.h"
10 #include "chrome/browser/profiles/profile_info_cache.h"
11 #include "chrome/browser/profiles/profile_info_cache_observer.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/profiles/profile_window.h"
14 #include "chrome/browser/profiles/profiles_state.h"
15 #include "chrome/browser/ui/browser_finder.h"
16 #include "chrome/browser/ui/browser_list.h"
17 #include "chrome/browser/ui/browser_window.h"
18 #include "chrome/browser/ui/host_desktop.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/test_switches.h"
22 #include "chrome/test/base/testing_browser_process.h"
23 #include "components/autofill/core/common/password_form.h"
24 #include "components/password_manager/core/browser/password_store.h"
25 #include "components/password_manager/core/browser/password_store_consumer.h"
26 #include "content/public/test/test_utils.h"
28 #if defined(OS_CHROMEOS)
29 #include "base/path_service.h"
30 #include "chrome/browser/chromeos/profiles/profile_helper.h"
31 #include "chrome/common/chrome_constants.h"
32 #include "chrome/common/chrome_paths.h"
33 #include "chromeos/chromeos_switches.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #endif
37 namespace {
39 const ProfileManager::CreateCallback kOnProfileSwitchDoNothing;
41 // An observer that returns back to test code after a new profile is
42 // initialized.
43 void OnUnblockOnProfileCreation(base::RunLoop* run_loop,
44 Profile* profile,
45 Profile::CreateStatus status) {
46 if (status == Profile::CREATE_STATUS_INITIALIZED)
47 run_loop->Quit();
50 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) {
51 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL);
52 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL);
53 // No browser should have been created for this profile yet.
54 EXPECT_EQ(chrome::GetTotalBrowserCountForProfile(profile), 0U);
55 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
56 if (status == Profile::CREATE_STATUS_INITIALIZED)
57 base::MessageLoop::current()->Quit();
60 void EphemeralProfileCreationComplete(Profile* profile,
61 Profile::CreateStatus status) {
62 if (status == Profile::CREATE_STATUS_INITIALIZED)
63 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true);
64 ProfileCreationComplete(profile, status);
67 class ProfileRemovalObserver : public ProfileInfoCacheObserver {
68 public:
69 ProfileRemovalObserver() {
70 g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(
71 this);
74 ~ProfileRemovalObserver() override {
75 g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
76 this);
79 std::string last_used_profile_name() { return last_used_profile_name_; }
81 // ProfileInfoCacheObserver overrides:
82 void OnProfileWillBeRemoved(const base::FilePath& profile_path) override {
83 last_used_profile_name_ = g_browser_process->local_state()->GetString(
84 prefs::kProfileLastUsed);
87 private:
88 std::string last_used_profile_name_;
90 DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver);
93 // The class serves to retrieve passwords from PasswordStore asynchronously. It
94 // used by ProfileManagerBrowserTest.DeletePasswords on some platforms.
95 class PasswordStoreConsumerVerifier
96 : public password_manager::PasswordStoreConsumer {
97 public:
98 void OnGetPasswordStoreResults(
99 ScopedVector<autofill::PasswordForm> results) override {
100 password_entries_.swap(results);
101 run_loop_.Quit();
104 void Wait() {
105 run_loop_.Run();
108 const std::vector<autofill::PasswordForm*>& GetPasswords() const {
109 return password_entries_.get();
112 private:
113 base::RunLoop run_loop_;
114 ScopedVector<autofill::PasswordForm> password_entries_;
117 static base::FilePath GetFirstNonSigninProfile(const ProfileInfoCache& cache) {
118 #if defined(OS_CHROMEOS)
119 const base::FilePath signin_path =
120 chromeos::ProfileHelper::GetSigninProfileDir();
121 size_t i, profile_num = cache.GetNumberOfProfiles();
122 for (i = 0; i != profile_num; ++i) {
123 base::FilePath profile_path = cache.GetPathOfProfileAtIndex(i);
124 if (profile_path != signin_path)
125 return profile_path;
127 return base::FilePath();
128 #else
129 return cache.GetPathOfProfileAtIndex(0);
130 #endif
133 } // namespace
135 // This file contains tests for the ProfileManager that require a heavyweight
136 // InProcessBrowserTest. These include tests involving profile deletion.
138 // TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
139 // platforms.
140 class ProfileManagerBrowserTest : public InProcessBrowserTest {
141 protected:
142 void SetUpCommandLine(base::CommandLine* command_line) override {
143 #if defined(OS_CHROMEOS)
144 command_line->AppendSwitch(
145 chromeos::switches::kIgnoreUserProfileMappingForTests);
146 #endif
150 #if defined(OS_MACOSX)
152 // Delete single profile and make sure a new one is created.
153 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
154 ProfileManager* profile_manager = g_browser_process->profile_manager();
155 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
156 ProfileRemovalObserver observer;
158 // We should start out with 1 profile.
159 ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);
161 // Delete singleton profile.
162 base::FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
163 EXPECT_FALSE(singleton_profile_path.empty());
164 base::RunLoop run_loop;
165 profile_manager->ScheduleProfileForDeletion(
166 singleton_profile_path,
167 base::Bind(&OnUnblockOnProfileCreation, &run_loop));
169 // Run the message loop until the profile is actually deleted (as indicated
170 // by the callback above being called).
171 run_loop.Run();
173 // Make sure a new profile was created automatically.
174 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
175 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
176 EXPECT_NE(new_profile_path.value(), singleton_profile_path.value());
178 // Make sure that last used profile preference is set correctly.
179 Profile* last_used = ProfileManager::GetLastUsedProfile();
180 EXPECT_EQ(new_profile_path.value(), last_used->GetPath().value());
182 // Make sure the last used profile was set correctly before the notification
183 // was sent.
184 std::string last_used_profile_name =
185 last_used->GetPath().BaseName().MaybeAsASCII();
186 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name());
189 // Delete all profiles in a multi profile setup and make sure a new one is
190 // created.
191 // Crashes/CHECKs. See crbug.com/104851
192 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) {
193 ProfileManager* profile_manager = g_browser_process->profile_manager();
194 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
196 // Create an additional profile.
197 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
198 base::RunLoop run_loop;
199 profile_manager->CreateProfileAsync(
200 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop),
201 base::string16(), base::string16(), std::string());
203 // Run the message loop to allow profile creation to take place; the loop is
204 // terminated by OnUnblockOnProfileCreation when the profile is created.
205 run_loop.Run();
207 ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
209 // Delete all profiles.
210 base::FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
211 base::FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
212 EXPECT_FALSE(profile_path1.empty());
213 EXPECT_FALSE(profile_path2.empty());
214 profile_manager->ScheduleProfileForDeletion(profile_path1,
215 ProfileManager::CreateCallback());
216 profile_manager->ScheduleProfileForDeletion(profile_path2,
217 ProfileManager::CreateCallback());
219 // Spin things so deletion can take place.
220 content::RunAllPendingInMessageLoop();
222 // Make sure a new profile was created automatically.
223 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
224 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
225 EXPECT_NE(new_profile_path, profile_path1);
226 EXPECT_NE(new_profile_path, profile_path2);
228 // Make sure that last used profile preference is set correctly.
229 Profile* last_used = ProfileManager::GetLastUsedProfile();
230 EXPECT_EQ(new_profile_path, last_used->GetPath());
232 #endif // OS_MACOSX
234 #if defined(OS_CHROMEOS)
236 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest {
237 protected:
238 void SetUpCommandLine(base::CommandLine* command_line) override {
239 // Use a user hash other than the default chrome::kTestUserProfileDir
240 // so that the prefix case is tested.
241 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
242 "test-user-hash");
246 IN_PROC_BROWSER_TEST_F(ProfileManagerCrOSBrowserTest, GetLastUsedProfile) {
247 // Make sure that last used profile is correct.
248 Profile* last_used_profile = ProfileManager::GetLastUsedProfile();
249 EXPECT_TRUE(last_used_profile != NULL);
251 base::FilePath profile_path;
252 PathService::Get(chrome::DIR_USER_DATA, &profile_path);
254 profile_path = profile_path.AppendASCII(
255 std::string(chrome::kProfileDirPrefix) + "test-user-hash");
256 EXPECT_EQ(profile_path.value(), last_used_profile->GetPath().value());
259 #endif // OS_CHROMEOS
261 // Times out (http://crbug.com/159002)
262 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
263 DISABLED_CreateProfileWithCallback) {
264 ProfileManager* profile_manager = g_browser_process->profile_manager();
266 ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
267 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
269 // Create a profile, make sure callback is invoked before any callbacks are
270 // invoked (so they can do things like sign in the profile, etc).
271 ProfileManager::CreateMultiProfileAsync(
272 base::string16(), // name
273 base::string16(), // icon url
274 base::Bind(ProfileCreationComplete),
275 std::string());
276 // Wait for profile to finish loading.
277 content::RunMessageLoop();
278 EXPECT_EQ(profile_manager->GetNumberOfProfiles(), 2U);
279 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
281 // Now close all browser windows.
282 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
283 for (std::vector<Profile*>::const_iterator it = profiles.begin();
284 it != profiles.end(); ++it) {
285 BrowserList::CloseAllBrowsersWithProfile(*it);
289 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
290 SwitchToProfile) {
291 #if defined(OS_WIN) && defined(USE_ASH)
292 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
293 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
294 switches::kAshBrowserTests))
295 return;
296 #endif
298 // If multiprofile mode is not enabled, you can't switch between profiles.
299 if (!profiles::IsMultipleProfilesEnabled())
300 return;
302 ProfileManager* profile_manager = g_browser_process->profile_manager();
303 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
304 size_t initial_profile_count = profile_manager->GetNumberOfProfiles();
305 base::FilePath path_profile1 = GetFirstNonSigninProfile(cache);
307 ASSERT_NE(0U, initial_profile_count);
308 EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
310 // Create an additional profile.
311 base::FilePath path_profile2 =
312 profile_manager->GenerateNextProfileDirectoryPath();
313 base::RunLoop run_loop;
314 profile_manager->CreateProfileAsync(
315 path_profile2, base::Bind(&OnUnblockOnProfileCreation, &run_loop),
316 base::string16(), base::string16(), std::string());
318 // Run the message loop to allow profile creation to take place; the loop is
319 // terminated by OnUnblockOnProfileCreation when the profile is created.
320 run_loop.Run();
322 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
323 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
324 ASSERT_EQ(initial_profile_count + 1, cache.GetNumberOfProfiles());
325 EXPECT_EQ(1U, browser_list->size());
327 // Open a browser window for the first profile.
328 profiles::SwitchToProfile(path_profile1, desktop_type, false,
329 kOnProfileSwitchDoNothing,
330 ProfileMetrics::SWITCH_PROFILE_ICON);
331 EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
332 EXPECT_EQ(1U, browser_list->size());
333 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
335 // Open a browser window for the second profile.
336 profiles::SwitchToProfile(path_profile2, desktop_type, false,
337 kOnProfileSwitchDoNothing,
338 ProfileMetrics::SWITCH_PROFILE_ICON);
339 EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
340 EXPECT_EQ(2U, browser_list->size());
341 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
343 // Switch to the first profile without opening a new window.
344 profiles::SwitchToProfile(path_profile1, desktop_type, false,
345 kOnProfileSwitchDoNothing,
346 ProfileMetrics::SWITCH_PROFILE_ICON);
347 EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
348 EXPECT_EQ(2U, browser_list->size());
350 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
351 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
354 // Flakes on Windows: http://crbug.com/314905
355 #if defined(OS_WIN)
356 #define MAYBE_EphemeralProfile DISABLED_EphemeralProfile
357 #else
358 #define MAYBE_EphemeralProfile EphemeralProfile
359 #endif
360 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, MAYBE_EphemeralProfile) {
361 #if defined(OS_WIN) && defined(USE_ASH)
362 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
363 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
364 switches::kAshBrowserTests))
365 return;
366 #endif
368 // If multiprofile mode is not enabled, you can't switch between profiles.
369 if (!profiles::IsMultipleProfilesEnabled())
370 return;
372 ProfileManager* profile_manager = g_browser_process->profile_manager();
373 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
374 size_t initial_profile_count = profile_manager->GetNumberOfProfiles();
375 base::FilePath path_profile1 = GetFirstNonSigninProfile(cache);
377 ASSERT_NE(0U, initial_profile_count);
378 EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
380 // Create an ephemeral profile.
381 base::FilePath path_profile2 =
382 profile_manager->GenerateNextProfileDirectoryPath();
383 profile_manager->CreateProfileAsync(
384 path_profile2,
385 base::Bind(&EphemeralProfileCreationComplete),
386 base::string16(), base::string16(), std::string());
388 // Spin to allow profile creation to take place.
389 content::RunMessageLoop();
391 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
392 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
393 ASSERT_EQ(initial_profile_count + 1, cache.GetNumberOfProfiles());
394 EXPECT_EQ(1U, browser_list->size());
396 // Open a browser window for the second profile.
397 profiles::SwitchToProfile(path_profile2, desktop_type, false,
398 kOnProfileSwitchDoNothing,
399 ProfileMetrics::SWITCH_PROFILE_ICON);
400 EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
401 EXPECT_EQ(2U, browser_list->size());
402 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
404 // Create a second window for the ephemeral profile.
405 profiles::SwitchToProfile(path_profile2, desktop_type, true,
406 kOnProfileSwitchDoNothing,
407 ProfileMetrics::SWITCH_PROFILE_ICON);
408 EXPECT_EQ(3U, chrome::GetTotalBrowserCount());
409 EXPECT_EQ(3U, browser_list->size());
411 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
412 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
413 EXPECT_EQ(path_profile2, browser_list->get(2)->profile()->GetPath());
415 // Closing the first window of the ephemeral profile should not delete it.
416 browser_list->get(2)->window()->Close();
417 content::RunAllPendingInMessageLoop();
418 EXPECT_EQ(2U, browser_list->size());
419 EXPECT_EQ(initial_profile_count + 1, cache.GetNumberOfProfiles());
421 // The second should though.
422 browser_list->get(1)->window()->Close();
423 content::RunAllPendingInMessageLoop();
424 EXPECT_EQ(1U, browser_list->size());
425 EXPECT_EQ(initial_profile_count, cache.GetNumberOfProfiles());
428 // The test makes sense on those platforms where the keychain exists.
429 #if !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
430 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeletePasswords) {
431 Profile* profile = ProfileManager::GetActiveUserProfile();
432 ASSERT_TRUE(profile);
434 autofill::PasswordForm form;
435 form.scheme = autofill::PasswordForm::SCHEME_HTML;
436 form.origin = GURL("http://accounts.google.com/LoginAuth");
437 form.signon_realm = "http://accounts.google.com/";
438 form.username_value = base::ASCIIToUTF16("my_username");
439 form.password_value = base::ASCIIToUTF16("my_password");
440 form.ssl_valid = false;
441 form.preferred = true;
442 form.blacklisted_by_user = false;
444 scoped_refptr<password_manager::PasswordStore> password_store =
445 PasswordStoreFactory::GetForProfile(
446 profile, ServiceAccessType::EXPLICIT_ACCESS).get();
447 ASSERT_TRUE(password_store.get());
449 password_store->AddLogin(form);
450 PasswordStoreConsumerVerifier verify_add;
451 password_store->GetAutofillableLogins(&verify_add);
452 verify_add.Wait();
453 EXPECT_EQ(1u, verify_add.GetPasswords().size());
455 ProfileManager* profile_manager = g_browser_process->profile_manager();
456 base::RunLoop run_loop;
457 profile_manager->ScheduleProfileForDeletion(
458 profile->GetPath(), base::Bind(&OnUnblockOnProfileCreation, &run_loop));
459 run_loop.Run();
461 PasswordStoreConsumerVerifier verify_delete;
462 password_store->GetAutofillableLogins(&verify_delete);
463 verify_delete.Wait();
464 EXPECT_EQ(0u, verify_delete.GetPasswords().size());
466 #endif // !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)