#include "ash/capture_mode/action_button_container_view.h"
#include <memory>
#include <string>
#include "ash/capture_mode/action_button_view.h"
#include "ash/capture_mode/capture_mode_types.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/style/ash_color_provider.h"
#include "ash/test/view_drawn_waiter.h"
#include "base/test/test_future.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/scoped_animation_duration_scale_mode.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_utils.h"
namespace ash {
namespace {
using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::SizeIs;
bool IsActionButtonCollapsed(const ActionButtonView* action_button) {
return !action_button->label_for_testing()->GetVisible();
}
ActionButtonView* AddCopyTextButton(
ActionButtonContainerView& action_button_container) {
return action_button_container.AddActionButton(
views::Button::PressedCallback(), u"Copy Text", &kCaptureModeImageIcon,
ActionButtonRank(ActionButtonType::kCopyText, 0),
ActionButtonViewID::kCopyTextButton);
}
ActionButtonView* AddSearchButton(
ActionButtonContainerView& action_button_container) {
return action_button_container.AddActionButton(
views::Button::PressedCallback(), u"Search", &kCaptureModeImageIcon,
ActionButtonRank(ActionButtonType::kSunfish, 0),
ActionButtonViewID::kSearchButton);
}
ActionButtonView* AddSmartActionsButton(
ActionButtonContainerView& action_button_container) {
return action_button_container.AddActionButton(
views::Button::PressedCallback(), u"Smart Actions",
&kCaptureModeImageIcon, ActionButtonRank(ActionButtonType::kScanner, 0),
ActionButtonViewID::kSmartActionsButton);
}
class ActionButtonContainerViewTest : public views::ViewsTestBase {
private:
AshColorProvider color_provider_;
};
TEST_F(ActionButtonContainerViewTest, AddsActionButton) {
std::unique_ptr<views::Widget> widget =
CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
widget->SetBounds(gfx::Rect(50, 50, 300, 200));
widget->Show();
auto* action_button_container =
widget->SetContentsView(std::make_unique<ActionButtonContainerView>());
base::test::TestFuture<void> action_future;
ActionButtonView* action_button = action_button_container->AddActionButton(
action_future.GetCallback(), u"Button Text", &kCaptureModeImageIcon,
ActionButtonRank(ActionButtonType::kScanner, 0),
ActionButtonViewID::kScannerButton);
ASSERT_TRUE(action_button);
EXPECT_THAT(action_button_container->GetActionButtons(),
ElementsAre(action_button));
EXPECT_EQ(action_button->label_for_testing()->GetText(), u"Button Text");
ViewDrawnWaiter().Wait(action_button);
ui::test::EventGenerator event_generator(GetRootWindow(widget.get()));
event_generator.MoveMouseTo(action_button->GetBoundsInScreen().CenterPoint());
event_generator.ClickLeftButton();
EXPECT_TRUE(action_future.Wait());
}
TEST_F(ActionButtonContainerViewTest, ActionButtonsOrderedByRank) {
ActionButtonContainerView action_button_container;
ActionButtonView* copy_text_button =
AddCopyTextButton(action_button_container);
ActionButtonView* search_button = AddSearchButton(action_button_container);
ActionButtonView* scanner_button = action_button_container.AddActionButton(
views::Button::PressedCallback(), u"Scanner Button",
&kCaptureModeImageIcon, ActionButtonRank(ActionButtonType::kScanner, 0),
ActionButtonViewID::kScannerButton);
EXPECT_THAT(action_button_container.GetActionButtons(),
ElementsAre(scanner_button, copy_text_button, search_button));
}
TEST_F(ActionButtonContainerViewTest, SmartActionsButtonTransition) {
gfx::ScopedAnimationDurationScaleMode animation_scale(
gfx::ScopedAnimationDurationScaleMode::ZERO_DURATION);
std::unique_ptr<views::Widget> widget =
CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
widget->SetBounds(gfx::Rect(50, 50, 300, 200));
widget->Show();
auto* action_button_container =
widget->SetContentsView(std::make_unique<ActionButtonContainerView>());
ActionButtonView* copy_text_button =
AddCopyTextButton(*action_button_container);
ActionButtonView* search_button = AddSearchButton(*action_button_container);
ActionButtonView* smart_actions_button =
AddSmartActionsButton(*action_button_container);
EXPECT_THAT(
action_button_container->GetActionButtons(),
ElementsAre(smart_actions_button, copy_text_button, search_button));
action_button_container->StartSmartActionsButtonTransition();
EXPECT_THAT(action_button_container->GetActionButtons(),
ElementsAre(copy_text_button, search_button));
EXPECT_TRUE(IsActionButtonCollapsed(copy_text_button));
EXPECT_TRUE(IsActionButtonCollapsed(search_button));
}
TEST_F(ActionButtonContainerViewTest, RemoveSmartActionsButton) {
std::unique_ptr<views::Widget> widget =
CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
widget->SetBounds(gfx::Rect(50, 50, 300, 200));
widget->Show();
auto* action_button_container =
widget->SetContentsView(std::make_unique<ActionButtonContainerView>());
ActionButtonView* copy_text_button =
AddCopyTextButton(*action_button_container);
ActionButtonView* search_button = AddSearchButton(*action_button_container);
ActionButtonView* smart_actions_button =
AddSmartActionsButton(*action_button_container);
EXPECT_THAT(
action_button_container->GetActionButtons(),
ElementsAre(smart_actions_button, copy_text_button, search_button));
action_button_container->RemoveSmartActionsButton();
EXPECT_THAT(action_button_container->GetActionButtons(),
ElementsAre(copy_text_button, search_button));
}
TEST_F(ActionButtonContainerViewTest, ShowsErrorView) {
ActionButtonContainerView action_button_container;
ActionButtonContainerView::ErrorView* error_view =
action_button_container.error_view_for_testing();
EXPECT_FALSE(error_view->GetVisible());
action_button_container.ShowErrorView(u"Error message");
EXPECT_TRUE(error_view->GetVisible());
EXPECT_EQ(error_view->GetErrorMessageForTesting(), u"Error message");
EXPECT_FALSE(error_view->try_again_link()->GetVisible());
action_button_container.HideErrorView();
EXPECT_FALSE(error_view->GetVisible());
}
TEST_F(ActionButtonContainerViewTest, ShowsErrorViewWithTryAgainLink) {
std::unique_ptr<views::Widget> widget =
CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
widget->SetBounds(gfx::Rect(50, 50, 300, 200));
widget->Show();
auto* action_button_container =
widget->SetContentsView(std::make_unique<ActionButtonContainerView>());
base::test::TestFuture<void> try_again_future;
action_button_container->ShowErrorView(
u"Error message", try_again_future.GetRepeatingCallback());
ActionButtonContainerView::ErrorView* error_view =
action_button_container->error_view_for_testing();
EXPECT_TRUE(error_view->GetVisible());
views::Link* try_again_link = error_view->try_again_link();
EXPECT_TRUE(try_again_link->GetVisible());
ViewDrawnWaiter().Wait(try_again_link);
ui::test::EventGenerator event_generator(GetRootWindow(widget.get()));
event_generator.MoveMouseTo(
try_again_link->GetBoundsInScreen().CenterPoint());
event_generator.ClickLeftButton();
EXPECT_TRUE(try_again_future.Wait());
}
TEST_F(ActionButtonContainerViewTest, ClearsContainer) {
ActionButtonContainerView action_button_container;
AddCopyTextButton(action_button_container);
action_button_container.ShowErrorView(u"Error message");
EXPECT_THAT(action_button_container.GetActionButtons(), SizeIs(1));
EXPECT_TRUE(action_button_container.error_view_for_testing()->GetVisible());
action_button_container.ClearContainer();
EXPECT_THAT(action_button_container.GetActionButtons(), IsEmpty());
EXPECT_FALSE(action_button_container.error_view_for_testing()->GetVisible());
}
TEST_F(ActionButtonContainerViewTest, GetsFocusableViews) {
ActionButtonContainerView action_button_container;
ActionButtonView* copy_text_button =
AddCopyTextButton(action_button_container);
EXPECT_THAT(action_button_container.GetFocusableViews(),
ElementsAre(copy_text_button));
action_button_container.ShowErrorView(
u"Error message", base::DoNothing());
EXPECT_THAT(
action_button_container.GetFocusableViews(),
ElementsAre(
action_button_container.error_view_for_testing()->try_again_link(),
copy_text_button));
}
}
}