chromium/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest_chromeos.cc

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/containers/contains.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/ash/login/login_manager_test.h"
#include "chrome/browser/ash/login/test/login_manager_mixin.h"
#include "chrome/browser/ash/login/ui/user_adding_screen.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h"
#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
#include "chrome/browser/ui/settings_window_manager_chromeos.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/user_manager.h"
#include "components/webapps/common/web_app_id.h"
#include "content/public/test/browser_test.h"
#include "ui/base/models/menu_model.h"
#include "url/gurl.h"

using ::ash::ProfileHelper;
using chrome::SettingsWindowManager;
using user_manager::UserManager;

namespace {

// Returns true if there exists a command with specified id in the given menu.
// False otherwise.
bool ContainsCommandIdInMenu(int command_id, const ui::MenuModel* menu) {
  CHECK(menu);
  for (size_t index = 0; index < menu->GetItemCount(); index++) {
    if (menu->GetCommandIdAt(index) == command_id) {
      return true;
    }
  }
  return false;
}

// Browser tests for verifying `SystemMenuModelBuilder` behavior for apps when
// locked (and not locked) for OnTask. Only relevant for non-web browser
// scenarios.
class SystemMenuModelBuilderWithOnTaskTest : public InProcessBrowserTest {
 protected:
  webapps::AppId InstallMockApp() {
    return web_app::test::InstallDummyWebApp(
        browser()->profile(), /*app_name=*/"Mock app",
        /*app_url=*/GURL("https://www.example.com/"));
  }
};

IN_PROC_BROWSER_TEST_F(SystemMenuModelBuilderWithOnTaskTest,
                       SystemMenuWhenNotLockedForOnTask) {
  // Install and launch app.
  webapps::AppId app_id = InstallMockApp();
  Browser* const app_browser =
      web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
  app_browser->SetLockedForOnTask(false);

  // Retrieve system menu.
  const BrowserView* const browser_view =
      BrowserView::GetBrowserViewForBrowser(app_browser);
  const ui::MenuModel* const menu = browser_view->frame()->GetSystemMenuModel();

  // Verify system menu command availability.
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_BACK, menu));
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_FORWARD, menu));
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_RELOAD, menu));
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_TASK_MANAGER, menu));
}

IN_PROC_BROWSER_TEST_F(SystemMenuModelBuilderWithOnTaskTest,
                       SystemMenuWhenLockedForOnTask) {
  // Install and launch app.
  webapps::AppId app_id = InstallMockApp();
  Browser* const app_browser =
      web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
  app_browser->SetLockedForOnTask(true);

  // Retrieve system menu.
  const BrowserView* const browser_view =
      BrowserView::GetBrowserViewForBrowser(app_browser);
  const ui::MenuModel* const menu = browser_view->frame()->GetSystemMenuModel();

  // Verify system menu command availability.
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_BACK, menu));
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_FORWARD, menu));
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_RELOAD, menu));
  EXPECT_FALSE(ContainsCommandIdInMenu(IDC_TASK_MANAGER, menu));
}

class SystemMenuModelBuilderMultiUserTest : public ash::LoginManagerTest {
 public:
  SystemMenuModelBuilderMultiUserTest() : LoginManagerTest() {
    login_mixin_.AppendRegularUsers(2);
    account_id1_ = login_mixin_.users()[0].account_id;
    account_id2_ = login_mixin_.users()[1].account_id;
  }
  ~SystemMenuModelBuilderMultiUserTest() override = default;

 protected:
  AccountId account_id1_;
  AccountId account_id2_;
  ash::LoginManagerMixin login_mixin_{&mixin_host_};
};

// Regression test for https://crbug.com/1023043
IN_PROC_BROWSER_TEST_F(SystemMenuModelBuilderMultiUserTest,
                       MultiUserSettingsWindowFrameMenu) {
  // Log in 2 users.
  LoginUser(account_id1_);
  base::RunLoop().RunUntilIdle();
  ash::UserAddingScreen::Get()->Start();
  AddUser(account_id2_);
  base::RunLoop().RunUntilIdle();

  // Install the Settings App.
  Profile* profile = ProfileHelper::Get()->GetProfileByUser(
      UserManager::Get()->FindUser(account_id1_));
  ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting();

  // Open the settings window and record the |settings_browser|.
  auto* manager = SettingsWindowManager::GetInstance();
  ui_test_utils::BrowserChangeObserver browser_opened(
      nullptr, ui_test_utils::BrowserChangeObserver::ChangeType::kAdded);
  manager->ShowOSSettings(profile);
  browser_opened.Wait();

  auto* settings_browser = manager->FindBrowserForProfile(profile);
  ASSERT_TRUE(settings_browser);

  // Retrieve the system menu so we can verify command availability.
  const BrowserView* const browser_view =
      BrowserView::GetBrowserViewForBrowser(settings_browser);
  const ui::MenuModel* const menu = browser_view->frame()->GetSystemMenuModel();

  // Standard WebUI commands are available.
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_BACK, menu));
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_FORWARD, menu));
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_RELOAD, menu));

  // Task manager should also be available.
  EXPECT_TRUE(ContainsCommandIdInMenu(IDC_TASK_MANAGER, menu));

  // Settings window cannot be teleported.
  EXPECT_FALSE(ContainsCommandIdInMenu(IDC_VISIT_DESKTOP_OF_LRU_USER_2, menu));
  EXPECT_FALSE(ContainsCommandIdInMenu(IDC_VISIT_DESKTOP_OF_LRU_USER_3, menu));
  EXPECT_FALSE(ContainsCommandIdInMenu(IDC_VISIT_DESKTOP_OF_LRU_USER_4, menu));
  EXPECT_FALSE(ContainsCommandIdInMenu(IDC_VISIT_DESKTOP_OF_LRU_USER_5, menu));
}

}  // namespace