#include "chrome/browser/ui/tabs/existing_window_sub_menu_model.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/test_browser_window.h"
#include "ui/gfx/text_elider.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/public/cpp/autotest_desks_api.h"
#include "chrome/browser/ui/tabs/existing_window_sub_menu_model_chromeos.h"
#include "chrome/browser/ui/tabs/tab_menu_model_delegate.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#include "ui/views/widget/widget.h"
#endif
namespace {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
class TestBrowserWindowViewsWithDesktopNativeWidgetAura
: public TestBrowserWindow {
public:
explicit TestBrowserWindowViewsWithDesktopNativeWidgetAura(
bool popup = false);
TestBrowserWindowViewsWithDesktopNativeWidgetAura(
const TestBrowserWindowViewsWithDesktopNativeWidgetAura&) = delete;
TestBrowserWindowViewsWithDesktopNativeWidgetAura& operator=(
const TestBrowserWindowViewsWithDesktopNativeWidgetAura&) = delete;
~TestBrowserWindowViewsWithDesktopNativeWidgetAura() override;
private:
std::unique_ptr<views::Widget> CreateDesktopWidget(bool popup);
std::unique_ptr<views::Widget> widget_;
};
TestBrowserWindowViewsWithDesktopNativeWidgetAura::
TestBrowserWindowViewsWithDesktopNativeWidgetAura(bool popup) {
widget_ = CreateDesktopWidget(popup);
SetNativeWindow(widget_->GetNativeWindow());
}
TestBrowserWindowViewsWithDesktopNativeWidgetAura::
~TestBrowserWindowViewsWithDesktopNativeWidgetAura() = default;
std::unique_ptr<views::Widget>
TestBrowserWindowViewsWithDesktopNativeWidgetAura::CreateDesktopWidget(
bool popup) {
auto widget = std::make_unique<views::Widget>();
views::Widget::InitParams params(
views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
popup ? views::Widget::InitParams::TYPE_POPUP
: views::Widget::InitParams::TYPE_WINDOW);
params.native_widget = new views::DesktopNativeWidgetAura(widget.get());
params.bounds = gfx::Rect(0, 0, 20, 20);
widget->Init(std::move(params));
return widget;
}
#endif
class ExistingWindowSubMenuModelTest : public BrowserWithTestWindowTest { … };
std::unique_ptr<Browser> ExistingWindowSubMenuModelTest::CreateTestBrowser(
bool incognito,
bool popup) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
std::unique_ptr<Browser>
ExistingWindowSubMenuModelTest::CreateTestBrowserOnWorkspace(
std::string desk_index) {
auto browser = CreateTestBrowser(false, false);
auto* test_browser_window =
static_cast<TestBrowserWindow*>(browser->window());
test_browser_window->set_workspace(desk_index);
return browser;
}
#endif
void ExistingWindowSubMenuModelTest::AddTabWithTitle(Browser* browser,
std::string title) { … }
void ExistingWindowSubMenuModelTest::CheckBrowserTitle(
const std::u16string& title,
const std::string& expected_title,
const int expected_num_tabs) { … }
TEST_F(ExistingWindowSubMenuModelTest, ShouldShowSubmenu) { … }
TEST_F(ExistingWindowSubMenuModelTest, ShouldShowSubmenuIncognito) { … }
TEST_F(ExistingWindowSubMenuModelTest, ShouldShowSubmenuPopup) { … }
TEST_F(ExistingWindowSubMenuModelTest, BuildSubmenuOrder) { … }
TEST_F(ExistingWindowSubMenuModelTest, BuildSubmenuIncognito) { … }
TEST_F(ExistingWindowSubMenuModelTest, BuildSubmenuPopups) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(ExistingWindowSubMenuModelTest, BuildSubmenuGroupedByDesks) {
const std::string kBrowser2TabTitle("Browser 2 Tab 1");
const std::string kBrowser3TabTitle("Browser 3 Tab 1");
const std::string kBrowser4TabTitle("Browser 4 Tab 1");
const std::string kBrowser5TabTitle("Browser 5 Tab 1");
const std::string kBrowser6TabTitle("Browser 6 Tab 1");
const std::string kBrowser7TabTitle("Browser 7 Tab 1");
ash::AutotestDesksApi().CreateNewDesk();
ash::AutotestDesksApi().CreateNewDesk();
ash::AutotestDesksApi().CreateNewDesk();
ash::AutotestDesksApi().CreateNewDesk();
BrowserList::SetLastActive(browser());
std::unique_ptr<Browser> browser_2(CreateTestBrowserOnWorkspace("0"));
std::unique_ptr<Browser> browser_3(CreateTestBrowserOnWorkspace("1"));
std::unique_ptr<Browser> browser_4(CreateTestBrowserOnWorkspace("1"));
std::unique_ptr<Browser> browser_5(CreateTestBrowserOnWorkspace("2"));
std::unique_ptr<Browser> browser_6(CreateTestBrowserOnWorkspace("2"));
std::unique_ptr<Browser> browser_7(CreateTestBrowserOnWorkspace("3"));
AddTabWithTitle(browser_2.get(), kBrowser2TabTitle);
AddTabWithTitle(browser_3.get(), kBrowser3TabTitle);
AddTabWithTitle(browser_4.get(), kBrowser4TabTitle);
AddTabWithTitle(browser_5.get(), kBrowser5TabTitle);
AddTabWithTitle(browser_6.get(), kBrowser6TabTitle);
AddTabWithTitle(browser_7.get(), kBrowser7TabTitle);
BrowserList::SetLastActive(browser_6.get());
BrowserList::SetLastActive(browser_3.get());
BrowserList::SetLastActive(browser_2.get());
BrowserList::SetLastActive(browser_4.get());
BrowserList::SetLastActive(browser_5.get());
BrowserList::SetLastActive(browser_7.get());
const std::vector<Browser*> kExpectedMRUOrder{
browser_7.get(), browser_5.get(), browser_4.get(),
browser_2.get(), browser_3.get(), browser_6.get()};
const auto& mru_ordered_windows =
browser()->tab_menu_model_delegate()->GetOtherBrowserWindows(
false);
ASSERT_EQ(6u, mru_ordered_windows.size());
ASSERT_EQ(mru_ordered_windows, kExpectedMRUOrder);
auto menu1 = ExistingWindowSubMenuModel::Create(
nullptr, browser()->tab_menu_model_delegate(),
browser()->tab_strip_model(), 0);
ASSERT_EQ(15u, menu1->GetItemCount());
EXPECT_EQ(u"Desk 1 (Current)", menu1->GetLabelAt(2));
CheckBrowserTitle(menu1->GetLabelAt(3), kBrowser2TabTitle, 1);
EXPECT_EQ(ui::SPACING_SEPARATOR, menu1->GetSeparatorTypeAt(4));
EXPECT_EQ(u"Desk 2", menu1->GetLabelAt(5));
CheckBrowserTitle(menu1->GetLabelAt(6), kBrowser4TabTitle, 1);
CheckBrowserTitle(menu1->GetLabelAt(7), kBrowser3TabTitle, 1);
EXPECT_EQ(ui::SPACING_SEPARATOR, menu1->GetSeparatorTypeAt(8));
EXPECT_EQ(u"Desk 3", menu1->GetLabelAt(9));
CheckBrowserTitle(menu1->GetLabelAt(10), kBrowser5TabTitle, 1);
CheckBrowserTitle(menu1->GetLabelAt(11), kBrowser6TabTitle, 1);
EXPECT_EQ(ui::SPACING_SEPARATOR, menu1->GetSeparatorTypeAt(12));
EXPECT_EQ(u"Desk 4", menu1->GetLabelAt(13));
CheckBrowserTitle(menu1->GetLabelAt(14), kBrowser7TabTitle, 1);
chrome::CloseTab(browser_2.get());
chrome::CloseTab(browser_3.get());
chrome::CloseTab(browser_4.get());
chrome::CloseTab(browser_5.get());
chrome::CloseTab(browser_6.get());
chrome::CloseTab(browser_7.get());
}
TEST_F(ExistingWindowSubMenuModelTest, EnsureGroupedByDesksCommands) {
ash::AutotestDesksApi().CreateNewDesk();
ash::AutotestDesksApi().CreateNewDesk();
std::unique_ptr<Browser> browser_2(CreateTestBrowserOnWorkspace("0"));
std::unique_ptr<Browser> browser_3(CreateTestBrowserOnWorkspace("1"));
std::unique_ptr<Browser> browser_4(CreateTestBrowserOnWorkspace("1"));
std::unique_ptr<Browser> browser_5(CreateTestBrowserOnWorkspace("2"));
BrowserList::SetLastActive(browser_5.get());
BrowserList::SetLastActive(browser_3.get());
BrowserList::SetLastActive(browser_2.get());
BrowserList::SetLastActive(browser_4.get());
const std::vector<Browser*> kExpectedMRUOrder{
browser_4.get(), browser_2.get(), browser_3.get(), browser_5.get()};
const auto& mru_ordered_windows =
browser()->tab_menu_model_delegate()->GetOtherBrowserWindows(
false);
ASSERT_EQ(4u, mru_ordered_windows.size());
ASSERT_EQ(mru_ordered_windows, kExpectedMRUOrder);
auto menu1 = ExistingWindowSubMenuModel::Create(
nullptr, browser()->tab_menu_model_delegate(),
browser()->tab_strip_model(), 0);
const auto& command_id_to_target_index =
static_cast<chromeos::ExistingWindowSubMenuModelChromeOS*>(menu1.get())
->command_id_to_target_index_for_testing();
const std::vector<std::pair<int, int>> kExpectedMappings{
{1002, 1}, {1003, 0}, {1004, 2}, {1005, 3}};
for (const auto& pair : kExpectedMappings) {
EXPECT_EQ(pair.second,
static_cast<int>(command_id_to_target_index.at(pair.first)));
}
chrome::CloseTab(browser_2.get());
chrome::CloseTab(browser_3.get());
chrome::CloseTab(browser_4.get());
chrome::CloseTab(browser_5.get());
}
#endif
}