blob: 83b8a0e9ff0fd3f093f4ac3bfd6373899881cf57 [file] [log] [blame]
// Copyright 2020 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 "ui/base/models/dialog_model.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/test/test_dialog_model_host.h"
#include "ui/events/event.h"
namespace ui {
class DialogModelButtonTest : public testing::Test {};
TEST_F(DialogModelButtonTest, UsesParamsUniqueId) {
constexpr int kUniqueId = 42;
// TODO(pbos): Replace AddOkButton() with AddButton() once buttons in dialogs
// are supported.
std::unique_ptr<DialogModel> model =
DialogModel::Builder()
.AddOkButton(base::OnceClosure(), base::string16(),
DialogModelButton::Params().SetUniqueId(kUniqueId))
.Build();
EXPECT_EQ(kUniqueId,
model->ok_button(TestDialogModelHost::GetPassKey())->unique_id_);
}
TEST_F(DialogModelButtonTest, UsesParamsAccelerators) {
const Accelerator accelerator_1;
const Accelerator accelerator_2(VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN);
// TODO(pbos): Replace AddOkButton() with AddButton() once buttons in dialogs
// are supported.
std::unique_ptr<DialogModel> model =
DialogModel::Builder()
.AddOkButton(base::OnceClosure(), base::string16(),
DialogModelButton::Params()
.AddAccelerator(accelerator_1)
.AddAccelerator(accelerator_2))
.Build();
EXPECT_THAT(model->ok_button(TestDialogModelHost::GetPassKey())
->accelerators(TestDialogModelHost::GetPassKey()),
testing::UnorderedElementsAre(accelerator_1, accelerator_2));
}
TEST_F(DialogModelButtonTest, UsesCallback) {
int callback_count = 0;
std::unique_ptr<KeyEvent> last_event;
// TODO(pbos): Replace AddExtraButton() with AddButton() once buttons in
// dialogs are supported.
std::unique_ptr<DialogModel> model =
DialogModel::Builder()
.AddDialogExtraButton(
base::BindLambdaForTesting([&](const Event& event) {
++callback_count;
last_event = std::make_unique<KeyEvent>(*event.AsKeyEvent());
}),
base::string16())
.Build();
DialogModelButton* const button =
model->extra_button(TestDialogModelHost::GetPassKey());
KeyEvent first_event(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
button->OnPressed(TestDialogModelHost::GetPassKey(), first_event);
EXPECT_EQ(1, callback_count);
EXPECT_EQ(first_event.key_code(), last_event->key_code());
KeyEvent second_event(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
button->OnPressed(TestDialogModelHost::GetPassKey(), second_event);
EXPECT_EQ(2, callback_count);
EXPECT_EQ(second_event.key_code(), last_event->key_code());
}
class DialogModelDialogButtonTest : public testing::Test {
public:
enum DialogButtonId {
kCancelButton,
kExtraButton,
kOkButton,
};
void DialogButtonUsesArguments(DialogButtonId button_id) {
DialogModel::Builder builder;
// Callback to verify that the first parameter is used.
bool callback_called = false;
base::OnceClosure callback = base::BindRepeating(
[](bool* callback_called) { *callback_called = true; },
&callback_called);
// Label to verify the second parameter.
base::string16 label = base::ASCIIToUTF16("my cool button");
// The presence of an accelerator in |params| will be used to verify that
// |params| are forwarded correctly to the DialogModelButton constructor.
DialogModelButton::Params params;
Accelerator accelerator(VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN);
params.AddAccelerator(accelerator);
switch (button_id) {
case kCancelButton:
builder.AddCancelButton(std::move(callback), label, params);
break;
case kExtraButton:
// Wrap the callback into a repeating callback that'll only be called
// once so the same verification can be used for the extra button.
builder.AddDialogExtraButton(
base::BindRepeating(
[](base::OnceClosure* callback, const Event& event) {
std::move(*callback).Run();
},
&callback),
label, params);
break;
case kOkButton:
builder.AddOkButton(std::move(callback), label, params);
break;
}
std::unique_ptr<DialogModel> model = builder.Build();
// Get the DialogModelButton and trigger the corresponding callback.
DialogModelButton* button = nullptr;
switch (button_id) {
case kCancelButton:
button = model->cancel_button(TestDialogModelHost::GetPassKey());
model->OnDialogCancelled(TestDialogModelHost::GetPassKey());
break;
case kExtraButton:
button = model->extra_button(TestDialogModelHost::GetPassKey());
button->OnPressed(TestDialogModelHost::GetPassKey(),
KeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE));
break;
case kOkButton:
button = model->ok_button(TestDialogModelHost::GetPassKey());
model->OnDialogAccepted(TestDialogModelHost::GetPassKey());
break;
}
ASSERT_TRUE(button);
EXPECT_TRUE(callback_called) << "The callback parameter wasn't used.";
EXPECT_EQ(label, button->label(TestDialogModelHost::GetPassKey()))
<< "The label parameter wasn't used.";
EXPECT_THAT(button->accelerators(TestDialogModelHost::GetPassKey()),
testing::UnorderedElementsAre(accelerator))
<< "The params parameter wasn't used.";
}
};
TEST_F(DialogModelDialogButtonTest, OkButtonUsesArguments) {
DialogButtonUsesArguments(kOkButton);
}
TEST_F(DialogModelDialogButtonTest, ExtraButtonUsesArguments) {
DialogButtonUsesArguments(kExtraButton);
}
TEST_F(DialogModelDialogButtonTest, CancelButtonUsesArguments) {
DialogButtonUsesArguments(kCancelButton);
}
} // namespace ui