| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 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 "chrome/browser/ui/views/chooser_content_view.h" |
| 6 |
| 7 #include "base/macros.h" |
| 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/grit/generated_resources.h" |
| 10 #include "components/chooser_controller/mock_chooser_controller.h" |
| 11 #include "testing/gmock/include/gmock/gmock.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "ui/base/l10n/l10n_util.h" |
| 14 #include "ui/views/controls/styled_label.h" |
| 15 #include "ui/views/controls/styled_label_listener.h" |
| 16 #include "ui/views/controls/table/table_view.h" |
| 17 #include "ui/views/controls/table/table_view_observer.h" |
| 18 |
| 19 namespace { |
| 20 |
| 21 class MockTableViewObserver : public views::TableViewObserver { |
| 22 public: |
| 23 // views::TableViewObserver: |
| 24 MOCK_METHOD0(OnSelectionChanged, void()); |
| 25 }; |
| 26 |
| 27 class MockStyledLabelListener : public views::StyledLabelListener { |
| 28 public: |
| 29 // views::StyledLabelListener: |
| 30 MOCK_METHOD3(StyledLabelLinkClicked, |
| 31 void(views::StyledLabel* label, |
| 32 const gfx::Range& range, |
| 33 int event_flags)); |
| 34 }; |
| 35 |
| 36 } // namespace |
| 37 |
| 38 class ChooserContentViewTest : public testing::Test { |
| 39 public: |
| 40 ChooserContentViewTest() {} |
| 41 |
| 42 // testing::Test: |
| 43 void SetUp() override { |
| 44 mock_chooser_controller_.reset(new MockChooserController(nullptr)); |
| 45 mock_table_view_observer_.reset(new MockTableViewObserver()); |
| 46 chooser_content_view_.reset(new ChooserContentView( |
| 47 mock_table_view_observer_.get(), mock_chooser_controller_.get())); |
| 48 table_view_ = chooser_content_view_->table_view_for_test(); |
| 49 ASSERT_TRUE(table_view_); |
| 50 table_model_ = table_view_->model(); |
| 51 ASSERT_TRUE(table_model_); |
| 52 mock_styled_label_listener_.reset(new MockStyledLabelListener()); |
| 53 styled_label_.reset(chooser_content_view_->CreateFootnoteView( |
| 54 mock_styled_label_listener_.get())); |
| 55 ASSERT_TRUE(styled_label_); |
| 56 } |
| 57 |
| 58 protected: |
| 59 std::unique_ptr<MockChooserController> mock_chooser_controller_; |
| 60 std::unique_ptr<MockTableViewObserver> mock_table_view_observer_; |
| 61 std::unique_ptr<ChooserContentView> chooser_content_view_; |
| 62 views::TableView* table_view_; |
| 63 ui::TableModel* table_model_; |
| 64 std::unique_ptr<MockStyledLabelListener> mock_styled_label_listener_; |
| 65 std::unique_ptr<views::StyledLabel> styled_label_; |
| 66 |
| 67 private: |
| 68 DISALLOW_COPY_AND_ASSIGN(ChooserContentViewTest); |
| 69 }; |
| 70 |
| 71 TEST_F(ChooserContentViewTest, InitialState) { |
| 72 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(0); |
| 73 |
| 74 // Since "No devices found." needs to be displayed on the |table_view_|, |
| 75 // the number of rows is 1. |
| 76 EXPECT_EQ(1, table_view_->RowCount()); |
| 77 EXPECT_EQ( |
| 78 l10n_util::GetStringUTF16(IDS_CHOOSER_BUBBLE_NO_DEVICES_FOUND_PROMPT), |
| 79 table_model_->GetText(0, 0)); |
| 80 // |table_view_| should be disabled since there is no option shown. |
| 81 EXPECT_FALSE(table_view_->enabled()); |
| 82 // No option selected. |
| 83 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 84 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 85 } |
| 86 |
| 87 TEST_F(ChooserContentViewTest, AddOption) { |
| 88 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(0); |
| 89 |
| 90 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 91 EXPECT_EQ(1, table_view_->RowCount()); |
| 92 EXPECT_EQ(base::ASCIIToUTF16("a"), table_model_->GetText(0, 0)); |
| 93 // |table_view_| should be enabled since there is an option. |
| 94 EXPECT_TRUE(table_view_->enabled()); |
| 95 // No option selected. |
| 96 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 97 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 98 |
| 99 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("b")); |
| 100 EXPECT_EQ(2, table_view_->RowCount()); |
| 101 EXPECT_EQ(base::ASCIIToUTF16("b"), table_model_->GetText(1, 0)); |
| 102 EXPECT_TRUE(table_view_->enabled()); |
| 103 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 104 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 105 |
| 106 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("c")); |
| 107 EXPECT_EQ(3, table_view_->RowCount()); |
| 108 EXPECT_EQ(base::ASCIIToUTF16("c"), table_model_->GetText(2, 0)); |
| 109 EXPECT_TRUE(table_view_->enabled()); |
| 110 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 111 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 112 } |
| 113 |
| 114 TEST_F(ChooserContentViewTest, RemoveOption) { |
| 115 // Called from TableView::OnItemsRemoved(). |
| 116 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); |
| 117 |
| 118 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 119 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("b")); |
| 120 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("c")); |
| 121 |
| 122 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("b")); |
| 123 EXPECT_EQ(2, table_view_->RowCount()); |
| 124 EXPECT_EQ(base::ASCIIToUTF16("a"), table_model_->GetText(0, 0)); |
| 125 EXPECT_EQ(base::ASCIIToUTF16("c"), table_model_->GetText(1, 0)); |
| 126 EXPECT_TRUE(table_view_->enabled()); |
| 127 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 128 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 129 |
| 130 // Remove a non-existent option, the number of rows should not change. |
| 131 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("non-existent")); |
| 132 EXPECT_EQ(2, table_view_->RowCount()); |
| 133 EXPECT_EQ(base::ASCIIToUTF16("a"), table_model_->GetText(0, 0)); |
| 134 EXPECT_EQ(base::ASCIIToUTF16("c"), table_model_->GetText(1, 0)); |
| 135 EXPECT_TRUE(table_view_->enabled()); |
| 136 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 137 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 138 |
| 139 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("c")); |
| 140 EXPECT_EQ(1, table_view_->RowCount()); |
| 141 EXPECT_EQ(base::ASCIIToUTF16("a"), table_model_->GetText(0, 0)); |
| 142 EXPECT_TRUE(table_view_->enabled()); |
| 143 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 144 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 145 |
| 146 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("a")); |
| 147 // There is no option shown now. But since "No devices found." |
| 148 // needs to be displayed on the |table_view_|, the number of rows is 1. |
| 149 EXPECT_EQ(1, table_view_->RowCount()); |
| 150 EXPECT_EQ( |
| 151 l10n_util::GetStringUTF16(IDS_CHOOSER_BUBBLE_NO_DEVICES_FOUND_PROMPT), |
| 152 table_model_->GetText(0, 0)); |
| 153 // |table_view_| should be disabled since all options are removed. |
| 154 EXPECT_FALSE(table_view_->enabled()); |
| 155 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 156 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 157 } |
| 158 |
| 159 TEST_F(ChooserContentViewTest, AddAndRemoveOption) { |
| 160 // Called from TableView::OnItemsRemoved(). |
| 161 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); |
| 162 |
| 163 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 164 EXPECT_EQ(1, table_view_->RowCount()); |
| 165 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("b")); |
| 166 EXPECT_EQ(2, table_view_->RowCount()); |
| 167 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("b")); |
| 168 EXPECT_EQ(1, table_view_->RowCount()); |
| 169 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("c")); |
| 170 EXPECT_EQ(2, table_view_->RowCount()); |
| 171 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("d")); |
| 172 EXPECT_EQ(3, table_view_->RowCount()); |
| 173 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("d")); |
| 174 EXPECT_EQ(2, table_view_->RowCount()); |
| 175 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("c")); |
| 176 EXPECT_EQ(1, table_view_->RowCount()); |
| 177 } |
| 178 |
| 179 TEST_F(ChooserContentViewTest, SelectAndDeselectAnOption) { |
| 180 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(4); |
| 181 |
| 182 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 183 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("b")); |
| 184 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("c")); |
| 185 |
| 186 // Select option 0. |
| 187 table_view_->Select(0); |
| 188 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 189 EXPECT_EQ(0, table_view_->FirstSelectedRow()); |
| 190 |
| 191 // Unselect option 0. |
| 192 table_view_->Select(-1); |
| 193 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 194 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 195 |
| 196 // Select option 1. |
| 197 table_view_->Select(1); |
| 198 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 199 EXPECT_EQ(1, table_view_->FirstSelectedRow()); |
| 200 |
| 201 // Unselect option 1. |
| 202 table_view_->Select(-1); |
| 203 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 204 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 205 } |
| 206 |
| 207 TEST_F(ChooserContentViewTest, SelectAnOptionAndThenSelectAnotherOption) { |
| 208 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); |
| 209 |
| 210 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 211 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("b")); |
| 212 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("c")); |
| 213 |
| 214 // Select option 0. |
| 215 table_view_->Select(0); |
| 216 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 217 EXPECT_EQ(0, table_view_->FirstSelectedRow()); |
| 218 |
| 219 // Select option 1. |
| 220 table_view_->Select(1); |
| 221 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 222 EXPECT_EQ(1, table_view_->FirstSelectedRow()); |
| 223 |
| 224 // Select option 2. |
| 225 table_view_->Select(2); |
| 226 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 227 EXPECT_EQ(2, table_view_->FirstSelectedRow()); |
| 228 } |
| 229 |
| 230 TEST_F(ChooserContentViewTest, SelectAnOptionAndRemoveAnotherOption) { |
| 231 // Called one time from TableView::Select() and two times from |
| 232 // TableView::OnItemsRemoved(). |
| 233 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); |
| 234 |
| 235 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 236 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("b")); |
| 237 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("c")); |
| 238 |
| 239 // Select option 1. |
| 240 table_view_->Select(1); |
| 241 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 242 EXPECT_EQ(1, table_view_->FirstSelectedRow()); |
| 243 |
| 244 // Remove option 0, the list becomes: b c. |
| 245 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("a")); |
| 246 EXPECT_EQ(2, table_view_->RowCount()); |
| 247 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 248 // Since option 0 is removed, the original selected option 1 becomes |
| 249 // the first option in the list. |
| 250 EXPECT_EQ(0, table_view_->FirstSelectedRow()); |
| 251 |
| 252 // Remove option 1. |
| 253 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("c")); |
| 254 EXPECT_EQ(1, table_view_->RowCount()); |
| 255 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 256 EXPECT_EQ(0, table_view_->FirstSelectedRow()); |
| 257 } |
| 258 |
| 259 TEST_F(ChooserContentViewTest, SelectAnOptionAndRemoveTheSelectedOption) { |
| 260 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(2); |
| 261 |
| 262 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 263 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("b")); |
| 264 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("c")); |
| 265 |
| 266 // Select option 1. |
| 267 table_view_->Select(1); |
| 268 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 269 EXPECT_EQ(1, table_view_->FirstSelectedRow()); |
| 270 |
| 271 // Remove option 1. |
| 272 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("b")); |
| 273 EXPECT_EQ(2, table_view_->RowCount()); |
| 274 // No option selected. |
| 275 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 276 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 277 } |
| 278 |
| 279 TEST_F(ChooserContentViewTest, |
| 280 AddAnOptionAndSelectItAndRemoveTheSelectedOption) { |
| 281 EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(2); |
| 282 |
| 283 mock_chooser_controller_->OptionAdded(base::ASCIIToUTF16("a")); |
| 284 |
| 285 // Select option 0. |
| 286 table_view_->Select(0); |
| 287 EXPECT_EQ(1, table_view_->SelectedRowCount()); |
| 288 EXPECT_EQ(0, table_view_->FirstSelectedRow()); |
| 289 |
| 290 // Remove option 0. |
| 291 mock_chooser_controller_->OptionRemoved(base::ASCIIToUTF16("a")); |
| 292 // There is no option shown now. But since "No devices found." |
| 293 // needs to be displayed on the |table_view_|, the number of rows is 1. |
| 294 EXPECT_EQ(1, table_view_->RowCount()); |
| 295 EXPECT_EQ( |
| 296 l10n_util::GetStringUTF16(IDS_CHOOSER_BUBBLE_NO_DEVICES_FOUND_PROMPT), |
| 297 table_model_->GetText(0, 0)); |
| 298 // |table_view_| should be disabled since all options are removed. |
| 299 EXPECT_FALSE(table_view_->enabled()); |
| 300 // No option selected. |
| 301 EXPECT_EQ(0, table_view_->SelectedRowCount()); |
| 302 EXPECT_EQ(-1, table_view_->FirstSelectedRow()); |
| 303 } |
| 304 |
| 305 TEST_F(ChooserContentViewTest, ClickStyledLabelLink) { |
| 306 EXPECT_CALL(*mock_styled_label_listener_, |
| 307 StyledLabelLinkClicked(styled_label_.get(), testing::_, 0)) |
| 308 .Times(1); |
| 309 styled_label_->LinkClicked(nullptr, 0); |
| 310 } |
| OLD | NEW |