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.
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 "chrome/test/base/ui_test_utils.h"
24 #include "components/autofill/core/common/password_form.h"
25 #include "components/password_manager/core/browser/password_store.h"
26 #include "components/password_manager/core/browser/password_store_consumer.h"
28 #if defined(OS_CHROMEOS)
29 #include "base/path_service.h"
30 #include "chrome/common/chrome_constants.h"
31 #include "chrome/common/chrome_paths.h"
32 #include "chromeos/chromeos_switches.h"
33 #include "testing/gtest/include/gtest/gtest.h"
38 const ProfileManager::CreateCallback kOnProfileSwitchDoNothing
;
40 // An observer that returns back to test code after a new profile is
42 void OnUnblockOnProfileCreation(Profile
* profile
,
43 Profile::CreateStatus status
) {
44 if (status
== Profile::CREATE_STATUS_INITIALIZED
)
45 base::MessageLoop::current()->Quit();
48 void ProfileCreationComplete(Profile
* profile
, Profile::CreateStatus status
) {
49 ASSERT_NE(status
, Profile::CREATE_STATUS_LOCAL_FAIL
);
50 ASSERT_NE(status
, Profile::CREATE_STATUS_REMOTE_FAIL
);
51 // No browser should have been created for this profile yet.
52 EXPECT_EQ(chrome::GetTotalBrowserCountForProfile(profile
), 0U);
53 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
54 if (status
== Profile::CREATE_STATUS_INITIALIZED
)
55 base::MessageLoop::current()->Quit();
58 void EphemeralProfileCreationComplete(Profile
* profile
,
59 Profile::CreateStatus status
) {
60 if (status
== Profile::CREATE_STATUS_INITIALIZED
)
61 profile
->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles
, true);
62 ProfileCreationComplete(profile
, status
);
65 class ProfileRemovalObserver
: public ProfileInfoCacheObserver
{
67 ProfileRemovalObserver() {
68 g_browser_process
->profile_manager()->GetProfileInfoCache().AddObserver(
72 virtual ~ProfileRemovalObserver() {
73 g_browser_process
->profile_manager()->GetProfileInfoCache().RemoveObserver(
77 std::string
last_used_profile_name() { return last_used_profile_name_
; }
79 // ProfileInfoCacheObserver overrides:
80 virtual void OnProfileWillBeRemoved(
81 const base::FilePath
& profile_path
) override
{
82 last_used_profile_name_
= g_browser_process
->local_state()->GetString(
83 prefs::kProfileLastUsed
);
87 std::string last_used_profile_name_
;
89 DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver
);
92 // The class serves to retrieve passwords from PasswordStore asynchronously. It
93 // used by ProfileManagerBrowserTest.DeletePasswords on some platforms.
94 class PasswordStoreConsumerVerifier
:
95 public password_manager::PasswordStoreConsumer
{
97 PasswordStoreConsumerVerifier() : called_(false) {}
99 virtual void OnGetPasswordStoreResults(
100 const std::vector
<autofill::PasswordForm
*>& results
) override
{
101 EXPECT_FALSE(called_
);
103 password_entries_
.clear();
104 password_entries_
.assign(results
.begin(), results
.end());
107 bool IsCalled() const { return called_
; }
109 const std::vector
<autofill::PasswordForm
*>& GetPasswords() const {
110 return password_entries_
.get();
113 ScopedVector
<autofill::PasswordForm
> password_entries_
;
119 // This file contains tests for the ProfileManager that require a heavyweight
120 // InProcessBrowserTest. These include tests involving profile deletion.
122 // TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
124 class ProfileManagerBrowserTest
: public InProcessBrowserTest
{
126 virtual void SetUpCommandLine(CommandLine
* command_line
) override
{
127 #if defined(OS_CHROMEOS)
128 command_line
->AppendSwitch(
129 chromeos::switches::kIgnoreUserProfileMappingForTests
);
134 #if defined(OS_MACOSX)
136 // Delete single profile and make sure a new one is created.
137 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest
, DeleteSingletonProfile
) {
138 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
139 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
140 ProfileRemovalObserver observer
;
142 // We should start out with 1 profile.
143 ASSERT_EQ(cache
.GetNumberOfProfiles(), 1U);
145 // Delete singleton profile.
146 base::FilePath singleton_profile_path
= cache
.GetPathOfProfileAtIndex(0);
147 EXPECT_FALSE(singleton_profile_path
.empty());
148 profile_manager
->ScheduleProfileForDeletion(singleton_profile_path
,
149 ProfileManager::CreateCallback());
151 // Spin things till profile is actually deleted.
152 content::RunAllPendingInMessageLoop();
154 // Make sure a new profile was created automatically.
155 EXPECT_EQ(cache
.GetNumberOfProfiles(), 1U);
156 base::FilePath new_profile_path
= cache
.GetPathOfProfileAtIndex(0);
157 EXPECT_NE(new_profile_path
, singleton_profile_path
);
159 // Make sure that last used profile preference is set correctly.
160 Profile
* last_used
= ProfileManager::GetLastUsedProfile();
161 EXPECT_EQ(new_profile_path
, last_used
->GetPath());
163 // Make sure the last used profile was set correctly before the notification
165 std::string last_used_profile_name
=
166 last_used
->GetPath().BaseName().MaybeAsASCII();
167 EXPECT_EQ(last_used_profile_name
, observer
.last_used_profile_name());
170 // Delete all profiles in a multi profile setup and make sure a new one is
172 // Crashes/CHECKs. See crbug.com/104851
173 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest
, DISABLED_DeleteAllProfiles
) {
174 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
175 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
177 // Create an additional profile.
178 base::FilePath new_path
= profile_manager
->GenerateNextProfileDirectoryPath();
179 profile_manager
->CreateProfileAsync(new_path
,
180 base::Bind(&OnUnblockOnProfileCreation
),
181 base::string16(), base::string16(),
184 // Spin to allow profile creation to take place, loop is terminated
185 // by OnUnblockOnProfileCreation when the profile is created.
186 content::RunMessageLoop();
188 ASSERT_EQ(cache
.GetNumberOfProfiles(), 2U);
190 // Delete all profiles.
191 base::FilePath profile_path1
= cache
.GetPathOfProfileAtIndex(0);
192 base::FilePath profile_path2
= cache
.GetPathOfProfileAtIndex(1);
193 EXPECT_FALSE(profile_path1
.empty());
194 EXPECT_FALSE(profile_path2
.empty());
195 profile_manager
->ScheduleProfileForDeletion(profile_path1
,
196 ProfileManager::CreateCallback());
197 profile_manager
->ScheduleProfileForDeletion(profile_path2
,
198 ProfileManager::CreateCallback());
200 // Spin things so deletion can take place.
201 content::RunAllPendingInMessageLoop();
203 // Make sure a new profile was created automatically.
204 EXPECT_EQ(cache
.GetNumberOfProfiles(), 1U);
205 base::FilePath new_profile_path
= cache
.GetPathOfProfileAtIndex(0);
206 EXPECT_NE(new_profile_path
, profile_path1
);
207 EXPECT_NE(new_profile_path
, profile_path2
);
209 // Make sure that last used profile preference is set correctly.
210 Profile
* last_used
= ProfileManager::GetLastUsedProfile();
211 EXPECT_EQ(new_profile_path
, last_used
->GetPath());
215 #if defined(OS_CHROMEOS)
217 class ProfileManagerCrOSBrowserTest
: public ProfileManagerBrowserTest
{
219 virtual void SetUpCommandLine(CommandLine
* command_line
) override
{
220 // Use a user hash other than the default chrome::kTestUserProfileDir
221 // so that the prefix case is tested.
222 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
,
227 IN_PROC_BROWSER_TEST_F(ProfileManagerCrOSBrowserTest
, GetLastUsedProfile
) {
228 // Make sure that last used profile is correct.
229 Profile
* last_used_profile
= ProfileManager::GetLastUsedProfile();
230 EXPECT_TRUE(last_used_profile
!= NULL
);
232 base::FilePath profile_path
;
233 PathService::Get(chrome::DIR_USER_DATA
, &profile_path
);
235 profile_path
= profile_path
.AppendASCII(
236 std::string(chrome::kProfileDirPrefix
) + "test-user-hash");
237 EXPECT_EQ(profile_path
.value(), last_used_profile
->GetPath().value());
240 #endif // OS_CHROMEOS
242 // Times out (http://crbug.com/159002)
243 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest
,
244 DISABLED_CreateProfileWithCallback
) {
245 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
247 ASSERT_EQ(profile_manager
->GetNumberOfProfiles(), 1U);
248 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
250 // Create a profile, make sure callback is invoked before any callbacks are
251 // invoked (so they can do things like sign in the profile, etc).
252 ProfileManager::CreateMultiProfileAsync(
253 base::string16(), // name
254 base::string16(), // icon url
255 base::Bind(ProfileCreationComplete
),
257 // Wait for profile to finish loading.
258 content::RunMessageLoop();
259 EXPECT_EQ(profile_manager
->GetNumberOfProfiles(), 2U);
260 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
262 // Now close all browser windows.
263 std::vector
<Profile
*> profiles
= profile_manager
->GetLoadedProfiles();
264 for (std::vector
<Profile
*>::const_iterator it
= profiles
.begin();
265 it
!= profiles
.end(); ++it
) {
266 BrowserList::CloseAllBrowsersWithProfile(*it
);
270 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest
,
272 #if defined(OS_WIN) && defined(USE_ASH)
273 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
274 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests
))
278 // If multiprofile mode is not enabled, you can't switch between profiles.
279 if (!profiles::IsMultipleProfilesEnabled())
282 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
283 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
284 base::FilePath path_profile1
= cache
.GetPathOfProfileAtIndex(0);
286 ASSERT_EQ(profile_manager
->GetNumberOfProfiles(), 1U);
287 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
289 // Create an additional profile.
290 base::FilePath path_profile2
=
291 profile_manager
->GenerateNextProfileDirectoryPath();
292 profile_manager
->CreateProfileAsync(path_profile2
,
293 base::Bind(&OnUnblockOnProfileCreation
),
294 base::string16(), base::string16(),
297 // Spin to allow profile creation to take place, loop is terminated
298 // by OnUnblockOnProfileCreation when the profile is created.
299 content::RunMessageLoop();
301 chrome::HostDesktopType desktop_type
= chrome::GetActiveDesktop();
302 BrowserList
* browser_list
= BrowserList::GetInstance(desktop_type
);
303 ASSERT_EQ(cache
.GetNumberOfProfiles(), 2U);
304 EXPECT_EQ(1U, browser_list
->size());
306 // Open a browser window for the first profile.
307 profiles::SwitchToProfile(path_profile1
, desktop_type
, false,
308 kOnProfileSwitchDoNothing
,
309 ProfileMetrics::SWITCH_PROFILE_ICON
);
310 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
311 EXPECT_EQ(1U, browser_list
->size());
312 EXPECT_EQ(path_profile1
, browser_list
->get(0)->profile()->GetPath());
314 // Open a browser window for the second profile.
315 profiles::SwitchToProfile(path_profile2
, desktop_type
, false,
316 kOnProfileSwitchDoNothing
,
317 ProfileMetrics::SWITCH_PROFILE_ICON
);
318 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
319 EXPECT_EQ(2U, browser_list
->size());
320 EXPECT_EQ(path_profile2
, browser_list
->get(1)->profile()->GetPath());
322 // Switch to the first profile without opening a new window.
323 profiles::SwitchToProfile(path_profile1
, desktop_type
, false,
324 kOnProfileSwitchDoNothing
,
325 ProfileMetrics::SWITCH_PROFILE_ICON
);
326 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
327 EXPECT_EQ(2U, browser_list
->size());
329 EXPECT_EQ(path_profile1
, browser_list
->get(0)->profile()->GetPath());
330 EXPECT_EQ(path_profile2
, browser_list
->get(1)->profile()->GetPath());
333 // Flakes on Windows: http://crbug.com/314905
335 #define MAYBE_EphemeralProfile DISABLED_EphemeralProfile
337 #define MAYBE_EphemeralProfile EphemeralProfile
339 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest
, MAYBE_EphemeralProfile
) {
340 #if defined(OS_WIN) && defined(USE_ASH)
341 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
342 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests
))
346 // If multiprofile mode is not enabled, you can't switch between profiles.
347 if (!profiles::IsMultipleProfilesEnabled())
350 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
351 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
352 base::FilePath path_profile1
= cache
.GetPathOfProfileAtIndex(0);
354 ASSERT_EQ(1U, profile_manager
->GetNumberOfProfiles());
355 EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
357 // Create an ephemeral profile.
358 base::FilePath path_profile2
=
359 profile_manager
->GenerateNextProfileDirectoryPath();
360 profile_manager
->CreateProfileAsync(
362 base::Bind(&EphemeralProfileCreationComplete
),
363 base::string16(), base::string16(), std::string());
365 // Spin to allow profile creation to take place.
366 content::RunMessageLoop();
368 chrome::HostDesktopType desktop_type
= chrome::GetActiveDesktop();
369 BrowserList
* browser_list
= BrowserList::GetInstance(desktop_type
);
370 ASSERT_EQ(2U, cache
.GetNumberOfProfiles());
371 EXPECT_EQ(1U, browser_list
->size());
373 // Open a browser window for the second profile.
374 profiles::SwitchToProfile(path_profile2
, desktop_type
, false,
375 kOnProfileSwitchDoNothing
,
376 ProfileMetrics::SWITCH_PROFILE_ICON
);
377 EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
378 EXPECT_EQ(2U, browser_list
->size());
379 EXPECT_EQ(path_profile2
, browser_list
->get(1)->profile()->GetPath());
381 // Create a second window for the ephemeral profile.
382 profiles::SwitchToProfile(path_profile2
, desktop_type
, true,
383 kOnProfileSwitchDoNothing
,
384 ProfileMetrics::SWITCH_PROFILE_ICON
);
385 EXPECT_EQ(3U, chrome::GetTotalBrowserCount());
386 EXPECT_EQ(3U, browser_list
->size());
388 EXPECT_EQ(path_profile1
, browser_list
->get(0)->profile()->GetPath());
389 EXPECT_EQ(path_profile2
, browser_list
->get(1)->profile()->GetPath());
390 EXPECT_EQ(path_profile2
, browser_list
->get(2)->profile()->GetPath());
392 // Closing the first window of the ephemeral profile should not delete it.
393 browser_list
->get(2)->window()->Close();
394 content::RunAllPendingInMessageLoop();
395 EXPECT_EQ(2U, browser_list
->size());
396 ASSERT_EQ(2U, cache
.GetNumberOfProfiles());
398 // The second should though.
399 browser_list
->get(1)->window()->Close();
400 content::RunAllPendingInMessageLoop();
401 EXPECT_EQ(1U, browser_list
->size());
402 ASSERT_EQ(1U, cache
.GetNumberOfProfiles());
405 // The test makes sense on those platforms where the keychain exists.
406 #if !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
407 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest
, DeletePasswords
) {
408 Profile
* profile
= ProfileManager::GetActiveUserProfile();
409 ASSERT_TRUE(profile
);
411 autofill::PasswordForm form
;
412 form
.scheme
= autofill::PasswordForm::SCHEME_HTML
;
413 form
.origin
= GURL("http://accounts.google.com/LoginAuth");
414 form
.signon_realm
= "http://accounts.google.com/";
415 form
.username_value
= base::ASCIIToUTF16("my_username");
416 form
.password_value
= base::ASCIIToUTF16("my_password");
417 form
.ssl_valid
= false;
418 form
.preferred
= true;
419 form
.blacklisted_by_user
= false;
421 scoped_refptr
<password_manager::PasswordStore
> password_store
=
422 PasswordStoreFactory::GetForProfile(profile
, Profile::EXPLICIT_ACCESS
)
424 ASSERT_TRUE(password_store
.get());
426 password_store
->AddLogin(form
);
427 PasswordStoreConsumerVerifier verify_add
;
428 password_store
->GetAutofillableLogins(&verify_add
);
430 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
431 profile_manager
->ScheduleProfileForDeletion(profile
->GetPath(),
432 ProfileManager::CreateCallback());
433 content::RunAllPendingInMessageLoop();
434 PasswordStoreConsumerVerifier verify_delete
;
435 password_store
->GetAutofillableLogins(&verify_delete
);
437 // Run the password background thread.
438 base::RunLoop run_loop
;
439 base::Closure task
= base::Bind(
440 base::IgnoreResult(&content::BrowserThread::PostTask
),
441 content::BrowserThread::UI
,
443 run_loop
.QuitClosure());
444 EXPECT_TRUE(password_store
->ScheduleTask(task
));
447 EXPECT_TRUE(verify_add
.IsCalled());
448 EXPECT_EQ(1u, verify_add
.GetPasswords().size());
449 EXPECT_TRUE(verify_delete
.IsCalled());
450 EXPECT_EQ(0u, verify_delete
.GetPasswords().size());
452 #endif // !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)