1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/views/controls/message_box_view.h"
6 
7 #include <algorithm>
8 #include <memory>
9 
10 #include "base/callback_helpers.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/gfx/geometry/insets.h"
15 #include "ui/gfx/geometry/rect.h"
16 #include "ui/views/controls/button/checkbox.h"
17 #include "ui/views/controls/link.h"
18 #include "ui/views/controls/scroll_view.h"
19 #include "ui/views/controls/textfield/textfield.h"
20 #include "ui/views/layout/layout_provider.h"
21 #include "ui/views/test/views_test_base.h"
22 
23 namespace views {
24 
25 namespace {
26 // The default mesage width same as defined in message_box_view.cc.
27 constexpr int kDefaultMessageWidth = 400;
28 const base::string16 kDefaultMessage =
29     base::ASCIIToUTF16("This is a test message for MessageBoxView.");
30 }  // namespace
31 
32 class MessageBoxViewTest : public ViewsTestBase {
33  public:
34   MessageBoxViewTest() = default;
35   MessageBoxViewTest(const MessageBoxViewTest&) = delete;
36   MessageBoxViewTest& operator=(const MessageBoxViewTest&) = delete;
37   ~MessageBoxViewTest() override = default;
38 
39  protected:
SetUp()40   void SetUp() override {
41     ViewsTestBase::SetUp();
42     message_box_ = std::make_unique<MessageBoxView>(kDefaultMessage);
43     provider_ = LayoutProvider::Get();
44   }
45 
46   std::unique_ptr<MessageBoxView> message_box_;
47   const LayoutProvider* provider_;
48 };
49 
TEST_F(MessageBoxViewTest,CheckMessageOnlySize)50 TEST_F(MessageBoxViewTest, CheckMessageOnlySize) {
51   message_box_->SizeToPreferredSize();
52 
53   gfx::Insets box_border =
54       provider_->GetDialogInsetsForContentType(views::TEXT, views::TEXT);
55   gfx::Size scroll_size = message_box_->scroll_view_->size();
56   scroll_size.Enlarge(0, box_border.top() + box_border.bottom());
57   EXPECT_EQ(scroll_size, message_box_->size());
58 }
59 
TEST_F(MessageBoxViewTest,CheckWithOptionalViewsSize)60 TEST_F(MessageBoxViewTest, CheckWithOptionalViewsSize) {
61   message_box_->SetPromptField(base::string16());
62   message_box_->SizeToPreferredSize();
63 
64   gfx::Insets box_border =
65       provider_->GetDialogInsetsForContentType(views::TEXT, views::CONTROL);
66   gfx::Size scroll_size = message_box_->scroll_view_->size();
67   gfx::Size prompt_size = message_box_->prompt_field_->size();
68   gfx::Size content_size(std::max(scroll_size.width(), prompt_size.width()),
69                          scroll_size.height() + prompt_size.height());
70   content_size.Enlarge(0, box_border.top() + box_border.bottom() +
71                               message_box_->inter_row_vertical_spacing_);
72   EXPECT_EQ(content_size, message_box_->size());
73 
74   // Add a checkbox and a link.
75   message_box_->SetCheckBoxLabel(base::ASCIIToUTF16("A checkbox"));
76   message_box_->SetLink(base::ASCIIToUTF16("Link to display"),
77                         base::DoNothing());
78   message_box_->SizeToPreferredSize();
79 
80   box_border =
81       provider_->GetDialogInsetsForContentType(views::TEXT, views::TEXT);
82   gfx::Size checkbox_size = message_box_->checkbox_->size();
83   gfx::Size link_size = message_box_->link_->size();
84   content_size =
85       gfx::Size(std::max(std::max(scroll_size.width(), prompt_size.width()),
86                          std::max(checkbox_size.width(), link_size.width())),
87                 scroll_size.height() + prompt_size.height() +
88                     checkbox_size.height() + link_size.height());
89   content_size.Enlarge(0, box_border.top() + box_border.bottom() +
90                               3 * message_box_->inter_row_vertical_spacing_);
91   EXPECT_EQ(content_size, message_box_->size());
92 }
93 
TEST_F(MessageBoxViewTest,CheckMessageWidthChange)94 TEST_F(MessageBoxViewTest, CheckMessageWidthChange) {
95   message_box_->SizeToPreferredSize();
96   EXPECT_EQ(kDefaultMessageWidth, message_box_->width());
97 
98   static constexpr int kNewWidth = 210;
99   message_box_->SetMessageWidth(kNewWidth);
100   message_box_->SizeToPreferredSize();
101   EXPECT_EQ(kNewWidth, message_box_->width());
102 }
103 
TEST_F(MessageBoxViewTest,CheckInterRowHeightChange)104 TEST_F(MessageBoxViewTest, CheckInterRowHeightChange) {
105   message_box_->SetPromptField(base::string16());
106   message_box_->SizeToPreferredSize();
107 
108   int scroll_height = message_box_->scroll_view_->height();
109   int prompt_height = message_box_->prompt_field_->height();
110   gfx::Insets box_border =
111       provider_->GetDialogInsetsForContentType(views::TEXT, views::CONTROL);
112   int inter_row_spacing = message_box_->inter_row_vertical_spacing_;
113   EXPECT_EQ(
114       scroll_height + inter_row_spacing + prompt_height + box_border.height(),
115       message_box_->height());
116 
117   static constexpr int kNewInterRowSpacing = 50;
118   EXPECT_NE(kNewInterRowSpacing, inter_row_spacing);
119   message_box_->SetInterRowVerticalSpacing(kNewInterRowSpacing);
120   message_box_->SizeToPreferredSize();
121   EXPECT_EQ(kNewInterRowSpacing, message_box_->inter_row_vertical_spacing_);
122   EXPECT_EQ(
123       scroll_height + kNewInterRowSpacing + prompt_height + box_border.height(),
124       message_box_->height());
125 }
126 
TEST_F(MessageBoxViewTest,CheckHasVisibleCheckBox)127 TEST_F(MessageBoxViewTest, CheckHasVisibleCheckBox) {
128   EXPECT_FALSE(message_box_->HasVisibleCheckBox());
129 
130   // Set and show a checkbox.
131   message_box_->SetCheckBoxLabel(base::ASCIIToUTF16("test checkbox"));
132   EXPECT_TRUE(message_box_->HasVisibleCheckBox());
133 }
134 
TEST_F(MessageBoxViewTest,CheckGetVisiblePromptField)135 TEST_F(MessageBoxViewTest, CheckGetVisiblePromptField) {
136   EXPECT_FALSE(message_box_->GetVisiblePromptField());
137 
138   // Set the prompt field.
139   message_box_->SetPromptField(base::string16());
140   EXPECT_TRUE(message_box_->GetVisiblePromptField());
141 }
142 
TEST_F(MessageBoxViewTest,CheckGetInputText)143 TEST_F(MessageBoxViewTest, CheckGetInputText) {
144   EXPECT_TRUE(message_box_->GetInputText().empty());
145 
146   // Set the prompt field with an empty string. The returned text is still
147   // empty.
148   message_box_->SetPromptField(base::string16());
149   EXPECT_TRUE(message_box_->GetInputText().empty());
150 
151   const base::string16 prompt = base::ASCIIToUTF16("prompt");
152   message_box_->SetPromptField(prompt);
153   EXPECT_FALSE(message_box_->GetInputText().empty());
154   EXPECT_EQ(prompt, message_box_->GetInputText());
155 
156   // After user types some text, the returned input text should change to the
157   // user input.
158   views::Textfield* text_field = message_box_->GetVisiblePromptField();
159   const base::string16 input = base::ASCIIToUTF16("new input");
160   text_field->SetText(input);
161   EXPECT_FALSE(message_box_->GetInputText().empty());
162   EXPECT_EQ(input, message_box_->GetInputText());
163 }
164 
TEST_F(MessageBoxViewTest,CheckIsCheckBoxSelected)165 TEST_F(MessageBoxViewTest, CheckIsCheckBoxSelected) {
166   EXPECT_FALSE(message_box_->IsCheckBoxSelected());
167 
168   // Set and show a checkbox.
169   message_box_->SetCheckBoxLabel(base::ASCIIToUTF16("test checkbox"));
170   EXPECT_FALSE(message_box_->IsCheckBoxSelected());
171 
172   // Select the checkbox.
173   message_box_->SetCheckBoxSelected(true);
174   EXPECT_TRUE(message_box_->IsCheckBoxSelected());
175 }
176 
177 }  // namespace views
178