// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ash/app_list/app_list_bubble_event_filter.h" #include #include "ash/test/ash_test_base.h" #include "ash/test/test_widget_builder.h" #include "base/run_loop.h" #include "base/test/bind.h" #include "testing/gtest/include/gtest/gtest.h" namespace ash { namespace { // Parameterized by mouse events vs. touch events. class AppListBubbleEventFilterTest : public AshTestBase, public testing::WithParamInterface { public: AppListBubbleEventFilterTest() = default; AppListBubbleEventFilterTest(const AppListBubbleEventFilterTest&) = delete; AppListBubbleEventFilterTest& operator=(const AppListBubbleEventFilterTest&) = delete; ~AppListBubbleEventFilterTest() override = default; // testing::Test: void SetUp() override { AshTestBase::SetUp(); widget_ = TestWidgetBuilder() .SetBounds({10, 10, 100, 100}) .SetShow(true) .BuildOwnsNativeWidget(); // Create a separate Widget to host the View. A View must live in a Widget // to have valid screen coordinates. view_holder_widget_ = TestWidgetBuilder() .SetBounds({500, 500, 100, 100}) .SetShow(true) .BuildOwnsNativeWidget(); view_ = view_holder_widget_->client_view()->AddChildView( std::make_unique()); view_->SetBoundsRect({0, 0, 32, 32}); } // Generates a click or a tap based on test parameterization. void ClickOrTapAt(gfx::Point point_in_screen) { auto* generator = GetEventGenerator(); if (GetParam()) { generator->MoveMouseTo(point_in_screen); generator->ClickLeftButton(); } else { generator->GestureTapAt(point_in_screen); } } std::unique_ptr widget_; std::unique_ptr view_holder_widget_; views::View* view_ = nullptr; }; INSTANTIATE_TEST_SUITE_P(MouseOrTouch, AppListBubbleEventFilterTest, testing::Bool()); TEST_P(AppListBubbleEventFilterTest, ClickOutsideWidgetRunsCallback) { int callback_count = 0; auto callback = base::BindLambdaForTesting([&]() { ++callback_count; }); AppListBubbleEventFilter filter(widget_.get(), view_, callback); // Click outside the widget. gfx::Point point_outside_widget = widget_->GetWindowBoundsInScreen().origin(); point_outside_widget.Offset(-1, -1); ClickOrTapAt(point_outside_widget); EXPECT_EQ(callback_count, 1); } TEST_P(AppListBubbleEventFilterTest, ClickInsideWidgetDoesNotRunCallback) { bool callback_ran = false; auto callback = base::BindLambdaForTesting([&]() { callback_ran = true; }); AppListBubbleEventFilter filter(widget_.get(), view_, callback); // Click inside the widget. ClickOrTapAt(widget_->GetWindowBoundsInScreen().CenterPoint()); EXPECT_FALSE(callback_ran); } TEST_P(AppListBubbleEventFilterTest, ClickInsideViewDoesNotRunCallback) { bool callback_ran = false; auto callback = base::BindLambdaForTesting([&]() { callback_ran = true; }); AppListBubbleEventFilter filter(widget_.get(), view_, callback); // Click inside the view. ClickOrTapAt(view_->GetBoundsInScreen().CenterPoint()); EXPECT_FALSE(callback_ran); } } // namespace } // namespace ash