| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/profiles/avatar_menu.h" |
| |
| #include <memory> |
| |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/profiles/profile_test_util.h" |
| #include "chrome/browser/profiles/profile_window.h" |
| #include "chrome/browser/signin/signin_util.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_commands.h" |
| #include "chrome/browser/ui/browser_finder.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/chrome_pages.h" |
| #include "chrome/browser/ui/profile_picker.h" |
| #include "chrome/browser/ui/profile_ui_test_utils.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/webui_url_constants.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/keep_alive_registry/keep_alive_types.h" |
| #include "components/keep_alive_registry/scoped_keep_alive.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| class AvatarMenuBrowserTest : public InProcessBrowserTest { |
| public: |
| AvatarMenuBrowserTest() { |
| // Needed to avoid showing the browser window in a multi-profile use-case. |
| set_open_about_blank_on_browser_launch(false); |
| } |
| ~AvatarMenuBrowserTest() override = default; |
| |
| // InProcessBrowserTest: |
| void SetUpOnMainThread() override { |
| InProcessBrowserTest::SetUpOnMainThread(); |
| |
| menu_ = std::make_unique<AvatarMenu>( |
| &g_browser_process->profile_manager()->GetProfileAttributesStorage(), |
| nullptr, nullptr); |
| menu_->RebuildMenu(); |
| } |
| |
| AvatarMenu* menu() { return menu_.get(); } |
| |
| private: |
| std::unique_ptr<AvatarMenu> menu_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(AvatarMenuBrowserTest, AddNewProfile) { |
| EXPECT_TRUE(menu()->ShouldShowAddNewProfileLink()); |
| menu()->AddNewProfile(); |
| profiles::testing::WaitForPickerLoadStop( |
| GURL("chrome://profile-picker/new-profile")); |
| EXPECT_TRUE(ProfilePicker::IsOpen()); |
| ProfilePicker::Hide(); |
| profiles::testing::WaitForPickerClosed(); |
| |
| g_browser_process->local_state()->SetBoolean(prefs::kBrowserAddPersonEnabled, |
| false); |
| EXPECT_FALSE(menu()->ShouldShowAddNewProfileLink()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AvatarMenuBrowserTest, EditProfile) { |
| absl::optional<size_t> active_profile_index = menu()->GetActiveProfileIndex(); |
| ASSERT_TRUE(active_profile_index.has_value()); |
| ASSERT_EQ(menu()->GetItemAt(*active_profile_index).profile_path, |
| browser()->profile()->GetPath()); |
| EXPECT_TRUE(menu()->ShouldShowEditProfileLink()); |
| menu()->EditProfile(*active_profile_index); |
| |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| EXPECT_EQ(web_contents->GetVisibleURL(), |
| chrome::GetSettingsUrl(chrome::kManageProfileSubPage)); |
| } |
| |
| // Click on "Edit" will open a new browser if none exists for a profile. |
| IN_PROC_BROWSER_TEST_F(AvatarMenuBrowserTest, EditProfile_NoBrowser) { |
| // Keep the browser process running while browsers are closed. |
| ScopedKeepAlive keep_alive(KeepAliveOrigin::BROWSER, |
| KeepAliveRestartOption::DISABLED); |
| Profile* profile = browser()->profile(); |
| BrowserList::CloseAllBrowsersWithProfile(profile); |
| ui_test_utils::WaitForBrowserToClose(browser()); |
| EXPECT_EQ(chrome::GetBrowserCount(profile), 0U); |
| |
| absl::optional<size_t> active_profile_index = menu()->GetActiveProfileIndex(); |
| ASSERT_TRUE(active_profile_index.has_value()); |
| ASSERT_EQ(menu()->GetItemAt(*active_profile_index).profile_path, |
| profile->GetPath()); |
| EXPECT_TRUE(menu()->ShouldShowEditProfileLink()); |
| menu()->EditProfile(*active_profile_index); |
| |
| // A new browser is opened. |
| EXPECT_EQ(chrome::GetBrowserCount(profile), 1U); |
| Browser* new_browser = chrome::FindBrowserWithProfile(profile); |
| ASSERT_TRUE(new_browser); |
| content::WebContents* web_contents = |
| new_browser->tab_strip_model()->GetActiveWebContents(); |
| EXPECT_EQ(web_contents->GetVisibleURL(), |
| chrome::GetSettingsUrl(chrome::kManageProfileSubPage)); |
| } |
| |
| // "Edit" does not unlock the profile (regression test for |
| // https://crbug.com/1324958). |
| IN_PROC_BROWSER_TEST_F(AvatarMenuBrowserTest, EditProfile_SigninRequired) { |
| signin_util::ScopedForceSigninSetterForTesting force_signin_setter(true); |
| Profile* profile = browser()->profile(); |
| ProfileAttributesEntry* entry = |
| g_browser_process->profile_manager() |
| ->GetProfileAttributesStorage() |
| .GetProfileAttributesWithPath(profile->GetPath()); |
| ASSERT_NE(entry, nullptr); |
| entry->LockForceSigninProfile(true); |
| // Keep the browser process running while browsers are closed. |
| ScopedKeepAlive keep_alive(KeepAliveOrigin::BROWSER, |
| KeepAliveRestartOption::DISABLED); |
| BrowserList::CloseAllBrowsersWithProfile(profile); |
| ui_test_utils::WaitForBrowserToClose(browser()); |
| EXPECT_EQ(chrome::GetBrowserCount(profile), 0U); |
| |
| absl::optional<size_t> active_profile_index = menu()->GetActiveProfileIndex(); |
| ASSERT_TRUE(active_profile_index.has_value()); |
| ASSERT_EQ(menu()->GetItemAt(*active_profile_index).profile_path, |
| profile->GetPath()); |
| EXPECT_FALSE(menu()->ShouldShowEditProfileLink()); |
| menu()->EditProfile(*active_profile_index); |
| |
| // Browser shouldn't be opened since `profile` is locked. |
| EXPECT_EQ(chrome::GetBrowserCount(profile), 0U); |
| |
| // The browser test doesn't shut down correctly if `keep_alive` is released |
| // while there are no browser windows. Create browser to work around this |
| // problem. |
| entry->LockForceSigninProfile(false); |
| CreateBrowser(profile); |
| } |
| |
| // Sets up multiple profiles so that the profile picker is shown on next |
| // startup. |
| IN_PROC_BROWSER_TEST_F(AvatarMenuBrowserTest, PRE_EditProfile_NotLoaded) { |
| ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| Profile& secondary_profile = profiles::testing::CreateProfileSync( |
| profile_manager, profile_manager->GenerateNextProfileDirectoryPath()); |
| chrome::NewEmptyWindow(&secondary_profile); |
| // Let the browser window fully open before closing it. |
| if (chrome::GetBrowserCount(&secondary_profile) == 0) { |
| ui_test_utils::WaitForBrowserToOpen(); |
| } |
| // Close all browsers to avoid restoring profiles on the next startup. |
| CloseAllBrowsers(); |
| } |
| |
| // "Edit" isn't enabled if no profiles are loaded. |
| IN_PROC_BROWSER_TEST_F(AvatarMenuBrowserTest, EditProfile_NotLoaded) { |
| EXPECT_EQ(chrome::GetTotalBrowserCount(), 0U); |
| EXPECT_FALSE(menu()->ShouldShowEditProfileLink()); |
| EXPECT_FALSE(menu()->GetActiveProfileIndex().has_value()); |
| } |
| |
| // Regression test for https://crbug.com/1382509 |
| IN_PROC_BROWSER_TEST_F(AvatarMenuBrowserTest, Guest) { |
| // Keep the browser process running while browsers are closed. |
| ScopedKeepAlive keep_alive(KeepAliveOrigin::BROWSER, |
| KeepAliveRestartOption::DISABLED); |
| CloseAllBrowsers(); |
| ui_test_utils::WaitForBrowserToClose(browser()); |
| EXPECT_EQ(chrome::GetTotalBrowserCount(), 0U); |
| |
| profiles::SwitchToGuestProfile(); |
| Browser* guest_browser = ui_test_utils::WaitForBrowserToOpen(); |
| ASSERT_TRUE(guest_browser); |
| ASSERT_TRUE(guest_browser->profile()->IsGuestSession()); |
| // This should not crash. |
| EXPECT_FALSE(menu()->ShouldShowEditProfileLink()); |
| } |