chromium/ui/views/controls/button/menu_button_unittest.cc

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

#include "ui/views/controls/button/menu_button.h"

#include <memory>
#include <utility>

#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/animation/ink_drop.h"
#include "ui/views/animation/test/ink_drop_host_test_api.h"
#include "ui/views/animation/test/test_ink_drop.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/menu_button_controller.h"
#include "ui/views/drag_controller.h"
#include "ui/views/style/platform_style.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget_utils.h"

#if defined(USE_AURA)
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/client/drag_drop_client_observer.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
#endif

namespace views {

ASCIIToUTF16;
DragOperation;

class TestMenuButton : public MenuButton {};

class MenuButtonTest : public ViewsTestBase {};

// A Button that will acquire a PressedLock in the pressed callback and
// optionally release it as well.
class PressStateButton : public TestMenuButton {};

// Basic implementation of a DragController, to test input behaviour for
// MenuButtons that can be dragged.
class TestDragController : public DragController {};

#if defined(USE_AURA)
// Basic implementation of a DragDropClient, tracking the state of the drag
// operation. While dragging addition mouse events are consumed, preventing the
// target view from receiving them.
class TestDragDropClient : public aura::client::DragDropClient,
                           public ui::EventHandler {};

TestDragDropClient::TestDragDropClient() = default;

TestDragDropClient::~TestDragDropClient() = default;

DragOperation TestDragDropClient::StartDragAndDrop(
    std::unique_ptr<ui::OSExchangeData> data,
    aura::Window* root_window,
    aura::Window* source_window,
    const gfx::Point& screen_location,
    int allowed_operations,
    ui::mojom::DragEventSource source) {}

void TestDragDropClient::DragCancel() {}

bool TestDragDropClient::IsDragDropInProgress() {}

void TestDragDropClient::OnMouseEvent(ui::MouseEvent* event) {}
#endif  // defined(USE_AURA)

// Tests if the callback is called correctly when a mouse click happens on a
// MenuButton.
TEST_F(MenuButtonTest, ActivateDropDownOnMouseClick) {}

TEST_F(MenuButtonTest, ActivateOnKeyPress) {}

// Tests that the ink drop center point is set from the mouse click point.
TEST_F(MenuButtonTest, InkDropCenterSetFromClick) {}

// Tests that the ink drop center point is set from the PressedLock constructor.
// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_InkDropCenterSetFromClickWithPressedLock
#else
#define MAYBE_InkDropCenterSetFromClickWithPressedLock
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest, MAYBE_InkDropCenterSetFromClickWithPressedLock) {}

// Test that the MenuButton stays pressed while there are any PressedLocks.
// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_ButtonStateForMenuButtonsWithPressedLocks
#else
#define MAYBE_ButtonStateForMenuButtonsWithPressedLocks
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest, MAYBE_ButtonStateForMenuButtonsWithPressedLocks) {}

// Test that the MenuButton does not become pressed if it can be dragged, until
// a release occurs.
// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_DraggableMenuButtonActivatesOnRelease
#else
#define MAYBE_DraggableMenuButtonActivatesOnRelease
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest, MAYBE_DraggableMenuButtonActivatesOnRelease) {}

// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_InkDropStateForMenuButtonActivationsWithoutCallback
#else
#define MAYBE_InkDropStateForMenuButtonActivationsWithoutCallback
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest,
       MAYBE_InkDropStateForMenuButtonActivationsWithoutCallback) {}

// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_InkDropStateForMenuButtonActivationsWithCallbackThatDoesntAcquireALock
#else
#define MAYBE_InkDropStateForMenuButtonActivationsWithCallbackThatDoesntAcquireALock
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(
    MenuButtonTest,
    MAYBE_InkDropStateForMenuButtonActivationsWithCallbackThatDoesntAcquireALock) {}

TEST_F(
    MenuButtonTest,
    InkDropStateForMenuButtonActivationsWithCallbackThatDoesntReleaseAllLocks) {}

TEST_F(MenuButtonTest,
       InkDropStateForMenuButtonActivationsWithCallbackThatReleasesAllLocks) {}

// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_InkDropStateForMenuButtonsWithPressedLocks
#else
#define MAYBE_InkDropStateForMenuButtonsWithPressedLocks
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest, MAYBE_InkDropStateForMenuButtonsWithPressedLocks) {}

// Verifies only one ink drop animation is triggered when multiple PressedLocks
// are attached to a MenuButton.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_OneInkDropAnimationForReentrantPressedLocks
#else
#define MAYBE_OneInkDropAnimationForReentrantPressedLocks
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest, MAYBE_OneInkDropAnimationForReentrantPressedLocks) {}

// Verifies the InkDropState is left as ACTIVATED if a PressedLock is active
// before another Activation occurs.
// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_InkDropStateForMenuButtonWithPressedLockBeforeActivation
#else
#define MAYBE_InkDropStateForMenuButtonWithPressedLockBeforeActivation
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest,
       MAYBE_InkDropStateForMenuButtonWithPressedLockBeforeActivation) {}

#if defined(USE_AURA)

// Tests that the MenuButton does not become pressed if it can be dragged, and a
// DragDropClient is processing the events.
// TODO(crbug.com/40903656): Test flaky on MSAN ChromeOS builders.
#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER)
#define MAYBE_DraggableMenuButtonDoesNotActivateOnDrag
#else
#define MAYBE_DraggableMenuButtonDoesNotActivateOnDrag
#endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(MEMORY_SANITIZER)
TEST_F(MenuButtonTest, MAYBE_DraggableMenuButtonDoesNotActivateOnDrag) {}

#endif  // USE_AURA

// No touch on desktop Mac. Tracked in http://crbug.com/445520.
#if !BUILDFLAG(IS_MAC) || defined(USE_AURA)

// Tests if the callback is notified correctly when a gesture tap happens on a
// MenuButton that has a callback.
TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) {}

// Tests that the button enters a hovered state upon a tap down, before becoming
// pressed at activation.
TEST_F(MenuButtonTest, TouchFeedbackDuringTap) {}

// Tests that a move event that exits the button returns it to the normal state,
// and that the button did not activate the callback.
TEST_F(MenuButtonTest, TouchFeedbackDuringTapCancel) {}

#endif  // !BUILDFLAG(IS_MAC) || defined(USE_AURA)

TEST_F(MenuButtonTest, InkDropHoverWhenShowingMenu) {}

TEST_F(MenuButtonTest, InkDropIsHoveredAfterDismissingMenuWhenMouseOverButton) {}

TEST_F(MenuButtonTest,
       InkDropIsntHoveredAfterDismissingMenuWhenMouseOutsideButton) {}

// This test ensures there isn't a UAF in MenuButton::OnGestureEvent() if the
// button callback deletes the MenuButton.
TEST_F(MenuButtonTest, DestroyButtonInGesture) {}

TEST_F(MenuButtonTest, AccessibleDefaultActionVerb) {}

}  // namespace views