Index: chrome/browser/profiles/profile_manager_unittest.cc |
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc |
index c7cde5637b3f1ef299baa30b4a784332b860079c..dd4666083b688dd51d4ed76ccaa2535d514eb361 100644 |
--- a/chrome/browser/profiles/profile_manager_unittest.cc |
+++ b/chrome/browser/profiles/profile_manager_unittest.cc |
@@ -15,7 +15,6 @@ |
#include "chrome/browser/bookmarks/bookmark_model_factory.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/chromeos/settings/cros_settings.h" |
-#include "chrome/browser/extensions/event_router_forwarder.h" |
#include "chrome/browser/history/history_service.h" |
#include "chrome/browser/history/history_service_factory.h" |
#include "chrome/browser/io_thread.h" |
@@ -97,7 +96,6 @@ class ProfileManagerTest : public testing::Test { |
ProfileManagerTest() |
: local_state_(TestingBrowserProcess::GetGlobal()), |
- extension_event_router_forwarder_(new extensions::EventRouterForwarder), |
ui_thread_(BrowserThread::UI, &message_loop_), |
db_thread_(BrowserThread::DB, &message_loop_), |
file_thread_(BrowserThread::FILE, &message_loop_) { |
@@ -120,6 +118,19 @@ class ProfileManagerTest : public testing::Test { |
message_loop_.RunUntilIdle(); |
} |
+ // Helper function to create a profile with |name| for a profile |manager|. |
+ void CreateProfileAsync(ProfileManager* manager, |
+ const std::string& name, |
+ MockObserver* mock_observer) { |
+ manager->CreateProfileAsync( |
+ temp_dir_.path().AppendASCII(name), |
+ base::Bind(&MockObserver::OnProfileCreated, |
+ base::Unretained(mock_observer)), |
+ UTF8ToUTF16(name), |
+ string16(), |
+ false); |
+ } |
+ |
#if defined(OS_CHROMEOS) |
chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; |
chromeos::ScopedTestCrosSettings test_cros_settings_; |
@@ -128,9 +139,6 @@ class ProfileManagerTest : public testing::Test { |
// The path to temporary directory used to contain the test operations. |
base::ScopedTempDir temp_dir_; |
ScopedTestingLocalState local_state_; |
- scoped_refptr<extensions::EventRouterForwarder> |
- extension_event_router_forwarder_; |
- |
base::MessageLoopForUI message_loop_; |
content::TestBrowserThread ui_thread_; |
content::TestBrowserThread db_thread_; |
@@ -240,17 +248,12 @@ MATCHER(NotFail, "Profile creation failure status is not reported.") { |
// Tests asynchronous profile creation mechanism. |
// Crashes: http://crbug.com/89421 |
TEST_F(ProfileManagerTest, DISABLED_CreateProfileAsync) { |
- base::FilePath dest_path = |
- temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile")); |
- |
MockObserver mock_observer; |
EXPECT_CALL(mock_observer, OnProfileCreated( |
testing::NotNull(), NotFail())).Times(testing::AtLeast(1)); |
- g_browser_process->profile_manager()->CreateProfileAsync(dest_path, |
- base::Bind(&MockObserver::OnProfileCreated, |
- base::Unretained(&mock_observer)), |
- string16(), string16(), false); |
+ CreateProfileAsync(g_browser_process->profile_manager(), |
+ "New Profile", &mock_observer); |
message_loop_.RunUntilIdle(); |
} |
@@ -262,9 +265,6 @@ MATCHER(SameNotNull, "The same non-NULL value for all calls.") { |
} |
TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) { |
- base::FilePath dest_path = |
- temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile")); |
- |
g_created_profile = NULL; |
MockObserver mock_observer1; |
@@ -278,28 +278,17 @@ TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) { |
SameNotNull(), NotFail())).Times(testing::AtLeast(1)); |
ProfileManager* profile_manager = g_browser_process->profile_manager(); |
- |
- profile_manager->CreateProfileAsync(dest_path, |
- base::Bind(&MockObserver::OnProfileCreated, |
- base::Unretained(&mock_observer1)), |
- string16(), string16(), false); |
- profile_manager->CreateProfileAsync(dest_path, |
- base::Bind(&MockObserver::OnProfileCreated, |
- base::Unretained(&mock_observer2)), |
- string16(), string16(), false); |
- profile_manager->CreateProfileAsync(dest_path, |
- base::Bind(&MockObserver::OnProfileCreated, |
- base::Unretained(&mock_observer3)), |
- string16(), string16(), false); |
+ const std::string profile_name = "New Profile"; |
+ CreateProfileAsync(profile_manager, profile_name, &mock_observer1); |
+ CreateProfileAsync(profile_manager, profile_name, &mock_observer2); |
+ CreateProfileAsync(profile_manager, profile_name, &mock_observer3); |
message_loop_.RunUntilIdle(); |
} |
TEST_F(ProfileManagerTest, CreateProfilesAsync) { |
- base::FilePath dest_path1 = |
- temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 1")); |
- base::FilePath dest_path2 = |
- temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 2")); |
+ const std::string profile_name1 = "New Profile 1"; |
+ const std::string profile_name2 = "New Profile 2"; |
MockObserver mock_observer; |
EXPECT_CALL(mock_observer, OnProfileCreated( |
@@ -307,14 +296,8 @@ TEST_F(ProfileManagerTest, CreateProfilesAsync) { |
ProfileManager* profile_manager = g_browser_process->profile_manager(); |
- profile_manager->CreateProfileAsync(dest_path1, |
- base::Bind(&MockObserver::OnProfileCreated, |
- base::Unretained(&mock_observer)), |
- string16(), string16(), false); |
- profile_manager->CreateProfileAsync(dest_path2, |
- base::Bind(&MockObserver::OnProfileCreated, |
- base::Unretained(&mock_observer)), |
- string16(), string16(), false); |
+ CreateProfileAsync(profile_manager, profile_name1, &mock_observer); |
+ CreateProfileAsync(profile_manager, profile_name2, &mock_observer); |
message_loop_.RunUntilIdle(); |
} |
@@ -634,3 +617,155 @@ TEST_F(ProfileManagerTest, LastOpenedProfilesDoesNotContainIncognito) { |
ASSERT_EQ(0U, last_opened_profiles.size()); |
} |
#endif // !defined(OS_ANDROID) |
+ |
+#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
+// There's no Browser object on Android and there's no multi-profiles on Chrome. |
+TEST_F(ProfileManagerTest, ActiveProfileDeleted) { |
+ ProfileManager* profile_manager = g_browser_process->profile_manager(); |
+ ASSERT_TRUE(profile_manager); |
+ |
+ // Create and load two profiles. |
+ const std::string profile_name1 = "New Profile 1"; |
+ const std::string profile_name2 = "New Profile 2"; |
+ base::FilePath dest_path1 = |
+ temp_dir_.path().AppendASCII(profile_name1); |
+ base::FilePath dest_path2 = |
+ temp_dir_.path().AppendASCII(profile_name2); |
+ |
+ MockObserver mock_observer; |
+ EXPECT_CALL(mock_observer, OnProfileCreated( |
+ testing::NotNull(), NotFail())).Times(testing::AtLeast(3)); |
+ |
+ CreateProfileAsync(profile_manager, profile_name1, &mock_observer); |
+ CreateProfileAsync(profile_manager, profile_name2, &mock_observer); |
+ message_loop_.RunUntilIdle(); |
+ |
+ EXPECT_EQ(2u, profile_manager->GetLoadedProfiles().size()); |
+ EXPECT_EQ(2u, profile_manager->GetProfileInfoCache().GetNumberOfProfiles()); |
+ |
+ // Set the active profile. |
+ PrefService* local_state = g_browser_process->local_state(); |
+ local_state->SetString(prefs::kProfileLastUsed, profile_name1); |
+ |
+ // Delete the active profile. |
+ profile_manager->ScheduleProfileForDeletion(dest_path1, |
+ ProfileManager::CreateCallback()); |
+ // Spin the message loop so that all the callbacks can finish running. |
+ message_loop_.RunUntilIdle(); |
+ |
+ EXPECT_EQ(dest_path2, profile_manager->GetLastUsedProfile()->GetPath()); |
+ EXPECT_EQ(profile_name2, local_state->GetString(prefs::kProfileLastUsed)); |
+} |
+#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
+ |
+#if defined(OS_MACOSX) |
+// These tests are for a Mac-only code path that assumes the browser |
+// process isn't killed when all browser windows are closed. |
+TEST_F(ProfileManagerTest, ActiveProfileDeletedNeedsToLoadNextProfile) { |
+ ProfileManager* profile_manager = g_browser_process->profile_manager(); |
+ ASSERT_TRUE(profile_manager); |
+ |
+ // Create and load one profile, and just create a second profile. |
+ const std::string profile_name1 = "New Profile 1"; |
+ const std::string profile_name2 = "New Profile 2"; |
+ base::FilePath dest_path1 = |
+ temp_dir_.path().AppendASCII(profile_name1); |
+ base::FilePath dest_path2 = |
+ temp_dir_.path().AppendASCII(profile_name2); |
+ |
+ MockObserver mock_observer; |
+ EXPECT_CALL(mock_observer, OnProfileCreated( |
+ testing::NotNull(), NotFail())).Times(testing::AtLeast(2)); |
+ CreateProfileAsync(profile_manager, profile_name1, &mock_observer); |
+ message_loop_.RunUntilIdle(); |
+ |
+ // Track the profile, but don't load it. |
+ ProfileInfoCache& cache = profile_manager->GetProfileInfoCache(); |
+ cache.AddProfileToCache(dest_path2, ASCIIToUTF16(profile_name2), |
+ string16(), 0, false); |
+ message_loop_.RunUntilIdle(); |
+ |
+ EXPECT_EQ(1u, profile_manager->GetLoadedProfiles().size()); |
+ EXPECT_EQ(2u, cache.GetNumberOfProfiles()); |
+ |
+ // Set the active profile. |
+ PrefService* local_state = g_browser_process->local_state(); |
+ local_state->SetString(prefs::kProfileLastUsed, |
+ dest_path1.BaseName().MaybeAsASCII()); |
+ |
+ // Delete the active profile. This should switch and load the unloaded |
+ // profile. |
+ profile_manager->ScheduleProfileForDeletion(dest_path1, |
+ ProfileManager::CreateCallback()); |
+ |
+ // Spin the message loop so that all the callbacks can finish running. |
+ message_loop_.RunUntilIdle(); |
+ |
+ EXPECT_EQ(dest_path2, profile_manager->GetLastUsedProfile()->GetPath()); |
+ EXPECT_EQ(profile_name2, local_state->GetString(prefs::kProfileLastUsed)); |
+} |
+ |
+// This tests the recursive call in ProfileManager::OnNewActiveProfileLoaded |
+// by simulating a scenario in which the profile that is being loaded as |
+// the next active profile has also been marked for deletion, so the |
+// ProfileManager needs to recursively select a different next profile. |
+TEST_F(ProfileManagerTest, ActiveProfileDeletedNextProfileDeletedToo) { |
+ ProfileManager* profile_manager = g_browser_process->profile_manager(); |
+ ASSERT_TRUE(profile_manager); |
+ |
+ // Create and load one profile, and create two more profiles. |
+ const std::string profile_name1 = "New Profile 1"; |
+ const std::string profile_name2 = "New Profile 2"; |
+ const std::string profile_name3 = "New Profile 3"; |
+ base::FilePath dest_path1 = |
+ temp_dir_.path().AppendASCII(profile_name1); |
+ base::FilePath dest_path2 = |
+ temp_dir_.path().AppendASCII(profile_name2); |
+ base::FilePath dest_path3 = |
+ temp_dir_.path().AppendASCII(profile_name3); |
+ |
+ MockObserver mock_observer; |
+ EXPECT_CALL(mock_observer, OnProfileCreated( |
+ testing::NotNull(), NotFail())).Times(testing::AtLeast(2)); |
+ CreateProfileAsync(profile_manager, profile_name1, &mock_observer); |
+ message_loop_.RunUntilIdle(); |
+ |
+ // Create the other profiles, but don't load them. Assign a fake avatar icon |
+ // to ensure that profiles in the info cache are sorted by the profile name, |
+ // and not randomly by the avatar name. |
+ ProfileInfoCache& cache = profile_manager->GetProfileInfoCache(); |
+ cache.AddProfileToCache(dest_path2, ASCIIToUTF16(profile_name2), |
+ ASCIIToUTF16(profile_name2), 1, false); |
+ cache.AddProfileToCache(dest_path3, ASCIIToUTF16(profile_name3), |
+ ASCIIToUTF16(profile_name3), 2, false); |
+ |
+ message_loop_.RunUntilIdle(); |
+ |
+ EXPECT_EQ(1u, profile_manager->GetLoadedProfiles().size()); |
+ EXPECT_EQ(3u, cache.GetNumberOfProfiles()); |
+ |
+ // Set the active profile. |
+ PrefService* local_state = g_browser_process->local_state(); |
+ local_state->SetString(prefs::kProfileLastUsed, |
+ dest_path1.BaseName().MaybeAsASCII()); |
+ |
+ // Delete the active profile, Profile1. |
+ // This will post a CreateProfileAsync message, that tries to load Profile2, |
+ // which checks that the profile is not being deleted, and then calls back |
+ // FinishDeletingProfile for Profile1. |
+ // Try to break this flow by setting the active profile to Profile2 in the |
+ // middle (so after the first posted message), and trying to delete Profile2, |
+ // so that the ProfileManager has to look for a different profile to load. |
+ profile_manager->ScheduleProfileForDeletion(dest_path1, |
+ ProfileManager::CreateCallback()); |
+ local_state->SetString(prefs::kProfileLastUsed, |
+ dest_path2.BaseName().MaybeAsASCII()); |
+ profile_manager->ScheduleProfileForDeletion(dest_path2, |
+ ProfileManager::CreateCallback()); |
+ // Spin the message loop so that all the callbacks can finish running. |
+ message_loop_.RunUntilIdle(); |
+ |
+ EXPECT_EQ(dest_path3, profile_manager->GetLastUsedProfile()->GetPath()); |
+ EXPECT_EQ(profile_name3, local_state->GetString(prefs::kProfileLastUsed)); |
+} |
+#endif // !defined(OS_MACOSX) |