Home | History | Annotate | Download | only in profiles
      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/host_desktop.h"
     17 #include "chrome/common/pref_names.h"
     18 #include "chrome/test/base/in_process_browser_test.h"
     19 #include "chrome/test/base/test_switches.h"
     20 #include "chrome/test/base/testing_browser_process.h"
     21 #include "chrome/test/base/ui_test_utils.h"
     22 
     23 namespace {
     24 
     25 // An observer that returns back to test code after a new profile is
     26 // initialized.
     27 void OnUnblockOnProfileCreation(Profile* profile,
     28                                 Profile::CreateStatus status) {
     29   if (status == Profile::CREATE_STATUS_INITIALIZED)
     30     base::MessageLoop::current()->Quit();
     31 }
     32 
     33 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) {
     34   ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL);
     35   ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL);
     36   // No browser should have been created for this profile yet.
     37   EXPECT_EQ(chrome::GetTotalBrowserCountForProfile(profile), 0U);
     38   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
     39   if (status == Profile::CREATE_STATUS_INITIALIZED)
     40     base::MessageLoop::current()->Quit();
     41 }
     42 
     43 class ProfileRemovalObserver : public ProfileInfoCacheObserver {
     44  public:
     45   ProfileRemovalObserver() {
     46     g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(
     47         this);
     48   }
     49 
     50   virtual ~ProfileRemovalObserver() {
     51     g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
     52         this);
     53   }
     54 
     55   std::string last_used_profile_name() { return last_used_profile_name_; }
     56 
     57   // ProfileInfoCacheObserver overrides:
     58   virtual void OnProfileWillBeRemoved(
     59       const base::FilePath& profile_path) OVERRIDE {
     60     last_used_profile_name_ = g_browser_process->local_state()->GetString(
     61         prefs::kProfileLastUsed);
     62   }
     63 
     64  private:
     65   std::string last_used_profile_name_;
     66 
     67   DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver);
     68 };
     69 
     70 } // namespace
     71 
     72 // This file contains tests for the ProfileManager that require a heavyweight
     73 // InProcessBrowserTest.  These include tests involving profile deletion.
     74 
     75 // TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
     76 // platforms.
     77 class ProfileManagerBrowserTest : public InProcessBrowserTest {
     78 };
     79 
     80 #if defined(OS_MACOSX)
     81 
     82 // Delete single profile and make sure a new one is created.
     83 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
     84   ProfileManager* profile_manager = g_browser_process->profile_manager();
     85   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
     86   ProfileRemovalObserver observer;
     87 
     88   // We should start out with 1 profile.
     89   ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);
     90 
     91   // Delete singleton profile.
     92   base::FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
     93   EXPECT_FALSE(singleton_profile_path.empty());
     94   profile_manager->ScheduleProfileForDeletion(singleton_profile_path,
     95                                               ProfileManager::CreateCallback());
     96 
     97   // Spin things till profile is actually deleted.
     98   content::RunAllPendingInMessageLoop();
     99 
    100   // Make sure a new profile was created automatically.
    101   EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
    102   base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
    103   EXPECT_NE(new_profile_path, singleton_profile_path);
    104 
    105   // Make sure that last used profile preference is set correctly.
    106   Profile* last_used = ProfileManager::GetLastUsedProfile();
    107   EXPECT_EQ(new_profile_path, last_used->GetPath());
    108 
    109   // Make sure the last used profile was set correctly before the notification
    110   // was sent.
    111   std::string last_used_profile_name =
    112       last_used->GetPath().BaseName().MaybeAsASCII();
    113   EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name());
    114 }
    115 
    116 // Delete all profiles in a multi profile setup and make sure a new one is
    117 // created.
    118 // Crashes/CHECKs. See crbug.com/104851
    119 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) {
    120   ProfileManager* profile_manager = g_browser_process->profile_manager();
    121   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
    122 
    123   // Create an additional profile.
    124   base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
    125   profile_manager->CreateProfileAsync(new_path,
    126                                       base::Bind(&OnUnblockOnProfileCreation),
    127                                       string16(), string16(), std::string());
    128 
    129   // Spin to allow profile creation to take place, loop is terminated
    130   // by OnUnblockOnProfileCreation when the profile is created.
    131   content::RunMessageLoop();
    132 
    133   ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
    134 
    135   // Delete all profiles.
    136   base::FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
    137   base::FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
    138   EXPECT_FALSE(profile_path1.empty());
    139   EXPECT_FALSE(profile_path2.empty());
    140   profile_manager->ScheduleProfileForDeletion(profile_path1,
    141                                               ProfileManager::CreateCallback());
    142   profile_manager->ScheduleProfileForDeletion(profile_path2,
    143                                               ProfileManager::CreateCallback());
    144 
    145   // Spin things so deletion can take place.
    146   content::RunAllPendingInMessageLoop();
    147 
    148   // Make sure a new profile was created automatically.
    149   EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
    150   base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
    151   EXPECT_NE(new_profile_path, profile_path1);
    152   EXPECT_NE(new_profile_path, profile_path2);
    153 
    154   // Make sure that last used profile preference is set correctly.
    155   Profile* last_used = ProfileManager::GetLastUsedProfile();
    156   EXPECT_EQ(new_profile_path, last_used->GetPath());
    157 }
    158 #endif  // OS_MACOSX
    159 
    160 // Times out (http://crbug.com/159002)
    161 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
    162                        DISABLED_CreateProfileWithCallback) {
    163   ProfileManager* profile_manager = g_browser_process->profile_manager();
    164 
    165   ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
    166   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
    167 
    168   // Create a profile, make sure callback is invoked before any callbacks are
    169   // invoked (so they can do things like sign in the profile, etc).
    170   ProfileManager::CreateMultiProfileAsync(
    171       string16(), // name
    172       string16(), // icon url
    173       base::Bind(ProfileCreationComplete),
    174       std::string());
    175   // Wait for profile to finish loading.
    176   content::RunMessageLoop();
    177   EXPECT_EQ(profile_manager->GetNumberOfProfiles(), 2U);
    178   EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
    179 
    180   // Now close all browser windows.
    181   std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
    182   for (std::vector<Profile*>::const_iterator it = profiles.begin();
    183        it != profiles.end(); ++it) {
    184     BrowserList::CloseAllBrowsersWithProfile(*it);
    185   }
    186 }
    187 
    188 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
    189                        SwitchToProfile) {
    190 #if defined(OS_WIN) && defined(USE_ASH)
    191   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    192   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    193     return;
    194 #endif
    195 
    196   // If multiprofile mode is not enabled, you can't switch between profiles.
    197   if (!profiles::IsMultipleProfilesEnabled())
    198     return;
    199 
    200   ProfileManager* profile_manager = g_browser_process->profile_manager();
    201   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
    202   base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
    203 
    204   ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
    205   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
    206 
    207   // Create an additional profile.
    208   base::FilePath path_profile2 =
    209       profile_manager->GenerateNextProfileDirectoryPath();
    210   profile_manager->CreateProfileAsync(path_profile2,
    211                                       base::Bind(&OnUnblockOnProfileCreation),
    212                                       string16(), string16(), std::string());
    213 
    214   // Spin to allow profile creation to take place, loop is terminated
    215   // by OnUnblockOnProfileCreation when the profile is created.
    216   content::RunMessageLoop();
    217 
    218   chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
    219   BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
    220   ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
    221   EXPECT_EQ(1U, browser_list->size());
    222 
    223   // Open a browser window for the first profile.
    224   profiles::SwitchToProfile(path_profile1, desktop_type, false);
    225   EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
    226   EXPECT_EQ(1U, browser_list->size());
    227   EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
    228 
    229   // Open a browser window for the second profile.
    230   profiles::SwitchToProfile(path_profile2, desktop_type, false);
    231   EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
    232   EXPECT_EQ(2U, browser_list->size());
    233   EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
    234 
    235   // Switch to the first profile without opening a new window.
    236   profiles::SwitchToProfile(path_profile1, desktop_type, false);
    237   EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
    238   EXPECT_EQ(2U, browser_list->size());
    239 
    240   EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
    241   EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
    242 }
    243