1 // Copyright (c) 2012 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 "base/memory/scoped_ptr.h" 6 #include "base/memory/weak_ptr.h" 7 #include "base/prefs/testing_pref_service.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" 10 #include "chrome/browser/ui/autofill/autofill_popup_view.h" 11 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 12 #include "chrome/test/base/testing_profile.h" 13 #include "components/autofill/content/browser/autofill_driver_impl.h" 14 #include "components/autofill/core/browser/autofill_external_delegate.h" 15 #include "components/autofill/core/browser/autofill_manager.h" 16 #include "components/autofill/core/browser/test_autofill_external_delegate.h" 17 #include "components/autofill/core/browser/test_autofill_manager_delegate.h" 18 #include "testing/gmock/include/gmock/gmock.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 #include "third_party/WebKit/public/web/WebAutofillClient.h" 21 #include "ui/gfx/display.h" 22 #include "ui/gfx/rect.h" 23 24 using ::testing::_; 25 using ::testing::AtLeast; 26 using ::testing::NiceMock; 27 using base::WeakPtr; 28 using WebKit::WebAutofillClient; 29 30 namespace autofill { 31 namespace { 32 33 class MockAutofillExternalDelegate : public AutofillExternalDelegate { 34 public: 35 MockAutofillExternalDelegate(content::WebContents* web_contents, 36 AutofillManager* autofill_manager, 37 AutofillDriver* autofill_driver) 38 : AutofillExternalDelegate(web_contents, autofill_manager, 39 autofill_driver) {} 40 virtual ~MockAutofillExternalDelegate() {} 41 42 virtual void DidSelectSuggestion(int identifier) OVERRIDE {} 43 virtual void RemoveSuggestion(const string16& value, int identifier) OVERRIDE 44 {} 45 virtual void ClearPreviewedForm() OVERRIDE {} 46 base::WeakPtr<AutofillExternalDelegate> GetWeakPtr() { 47 return AutofillExternalDelegate::GetWeakPtr(); 48 } 49 }; 50 51 class MockAutofillManagerDelegate 52 : public autofill::TestAutofillManagerDelegate { 53 public: 54 MockAutofillManagerDelegate() {} 55 virtual ~MockAutofillManagerDelegate() {} 56 57 virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; } 58 59 private: 60 TestingPrefServiceSimple prefs_; 61 62 DISALLOW_COPY_AND_ASSIGN(MockAutofillManagerDelegate); 63 }; 64 65 class TestAutofillPopupController : public AutofillPopupControllerImpl { 66 public: 67 explicit TestAutofillPopupController( 68 base::WeakPtr<AutofillExternalDelegate> external_delegate, 69 const gfx::RectF& element_bounds) 70 : AutofillPopupControllerImpl( 71 external_delegate, NULL, element_bounds, 72 base::i18n::UNKNOWN_DIRECTION) {} 73 virtual ~TestAutofillPopupController() {} 74 75 void set_display(const gfx::Display display) { 76 display_ = display; 77 } 78 virtual gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const 79 OVERRIDE { 80 return display_; 81 } 82 83 // Making protected functions public for testing 84 void SetPopupBounds(const gfx::Rect& bounds) { 85 AutofillPopupControllerImpl::SetPopupBounds(bounds); 86 } 87 const std::vector<string16>& names() const { 88 return AutofillPopupControllerImpl::names(); 89 } 90 const std::vector<string16>& subtexts() const { 91 return AutofillPopupControllerImpl::subtexts(); 92 } 93 const std::vector<int>& identifiers() const { 94 return AutofillPopupControllerImpl::identifiers(); 95 } 96 int selected_line() const { 97 return AutofillPopupControllerImpl::selected_line(); 98 } 99 void SetSelectedLine(size_t selected_line) { 100 AutofillPopupControllerImpl::SetSelectedLine(selected_line); 101 } 102 void SelectNextLine() { 103 AutofillPopupControllerImpl::SelectNextLine(); 104 } 105 void SelectPreviousLine() { 106 AutofillPopupControllerImpl::SelectPreviousLine(); 107 } 108 bool RemoveSelectedLine() { 109 return AutofillPopupControllerImpl::RemoveSelectedLine(); 110 } 111 void DoHide() { 112 AutofillPopupControllerImpl::Hide(); 113 } 114 const gfx::Rect& popup_bounds() const { 115 return AutofillPopupControllerImpl::popup_bounds(); 116 } 117 const gfx::RectF& element_bounds() const { 118 return AutofillPopupControllerImpl::element_bounds(); 119 } 120 #if !defined(OS_ANDROID) 121 const gfx::Font& GetNameFontForRow(size_t index) const { 122 return AutofillPopupControllerImpl::GetNameFontForRow(index); 123 } 124 const gfx::Font& subtext_font() const { 125 return AutofillPopupControllerImpl::subtext_font(); 126 } 127 int RowWidthWithoutText(int row) const { 128 return AutofillPopupControllerImpl::RowWidthWithoutText(row); 129 } 130 #endif 131 using AutofillPopupControllerImpl::SetValues; 132 int GetDesiredPopupWidth() const { 133 return AutofillPopupControllerImpl::GetDesiredPopupWidth(); 134 } 135 int GetDesiredPopupHeight() const { 136 return AutofillPopupControllerImpl::GetDesiredPopupHeight(); 137 } 138 139 WeakPtr<AutofillPopupControllerImpl> GetWeakPtr() { 140 return AutofillPopupControllerImpl::GetWeakPtr(); 141 } 142 143 MOCK_METHOD1(InvalidateRow, void(size_t)); 144 MOCK_METHOD0(UpdateBoundsAndRedrawPopup, void()); 145 MOCK_METHOD0(Hide, void()); 146 147 private: 148 virtual void ShowView() OVERRIDE {} 149 150 gfx::Display display_; 151 }; 152 153 } // namespace 154 155 class AutofillPopupControllerUnitTest : public ChromeRenderViewHostTestHarness { 156 public: 157 AutofillPopupControllerUnitTest() 158 : manager_delegate_(new MockAutofillManagerDelegate()), 159 autofill_popup_controller_(NULL) {} 160 virtual ~AutofillPopupControllerUnitTest() {} 161 162 virtual void SetUp() OVERRIDE { 163 ChromeRenderViewHostTestHarness::SetUp(); 164 165 AutofillDriverImpl::CreateForWebContentsAndDelegate( 166 web_contents(), 167 manager_delegate_.get(), 168 "en-US", 169 AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER); 170 AutofillDriverImpl* driver = 171 AutofillDriverImpl::FromWebContents(web_contents()); 172 external_delegate_.reset( 173 new NiceMock<MockAutofillExternalDelegate>( 174 web_contents(), 175 driver->autofill_manager(), 176 driver)); 177 178 autofill_popup_controller_ = 179 new testing::NiceMock<TestAutofillPopupController>( 180 external_delegate_->GetWeakPtr(), gfx::Rect()); 181 } 182 183 virtual void TearDown() OVERRIDE { 184 // This will make sure the controller and the view (if any) are both 185 // cleaned up. 186 if (autofill_popup_controller_) 187 autofill_popup_controller_->DoHide(); 188 189 external_delegate_.reset(); 190 ChromeRenderViewHostTestHarness::TearDown(); 191 } 192 193 TestAutofillPopupController* popup_controller() { 194 return autofill_popup_controller_; 195 } 196 197 MockAutofillExternalDelegate* delegate() { 198 return external_delegate_.get(); 199 } 200 201 protected: 202 scoped_ptr<MockAutofillManagerDelegate> manager_delegate_; 203 scoped_ptr<NiceMock<MockAutofillExternalDelegate> > external_delegate_; 204 testing::NiceMock<TestAutofillPopupController>* autofill_popup_controller_; 205 }; 206 207 TEST_F(AutofillPopupControllerUnitTest, SetBounds) { 208 // Ensure the popup size can be set and causes a redraw. 209 gfx::Rect popup_bounds(10, 10, 100, 100); 210 211 EXPECT_CALL(*autofill_popup_controller_, 212 UpdateBoundsAndRedrawPopup()); 213 214 popup_controller()->SetPopupBounds(popup_bounds); 215 216 EXPECT_EQ(popup_bounds, popup_controller()->popup_bounds()); 217 } 218 219 TEST_F(AutofillPopupControllerUnitTest, ChangeSelectedLine) { 220 // Set up the popup. 221 std::vector<string16> names(2, string16()); 222 std::vector<int> autofill_ids(2, 0); 223 autofill_popup_controller_->Show(names, names, names, autofill_ids); 224 225 EXPECT_LT(autofill_popup_controller_->selected_line(), 0); 226 // Check that there are at least 2 values so that the first and last selection 227 // are different. 228 EXPECT_GE(2, 229 static_cast<int>(autofill_popup_controller_->subtexts().size())); 230 231 // Test wrapping before the front. 232 autofill_popup_controller_->SelectPreviousLine(); 233 EXPECT_EQ(static_cast<int>( 234 autofill_popup_controller_->subtexts().size() - 1), 235 autofill_popup_controller_->selected_line()); 236 237 // Test wrapping after the end. 238 autofill_popup_controller_->SelectNextLine(); 239 EXPECT_EQ(0, autofill_popup_controller_->selected_line()); 240 } 241 242 TEST_F(AutofillPopupControllerUnitTest, RedrawSelectedLine) { 243 // Set up the popup. 244 std::vector<string16> names(2, string16()); 245 std::vector<int> autofill_ids(2, 0); 246 autofill_popup_controller_->Show(names, names, names, autofill_ids); 247 248 // Make sure that when a new line is selected, it is invalidated so it can 249 // be updated to show it is selected. 250 int selected_line = 0; 251 EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(selected_line)); 252 autofill_popup_controller_->SetSelectedLine(selected_line); 253 254 // Ensure that the row isn't invalidated if it didn't change. 255 EXPECT_CALL(*autofill_popup_controller_, 256 InvalidateRow(selected_line)).Times(0); 257 autofill_popup_controller_->SetSelectedLine(selected_line); 258 259 // Change back to no selection. 260 EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(selected_line)); 261 autofill_popup_controller_->SetSelectedLine(-1); 262 } 263 264 TEST_F(AutofillPopupControllerUnitTest, RemoveLine) { 265 // Set up the popup. 266 std::vector<string16> names(3, string16()); 267 std::vector<int> autofill_ids; 268 autofill_ids.push_back(1); 269 autofill_ids.push_back(1); 270 autofill_ids.push_back(WebAutofillClient::MenuItemIDAutofillOptions); 271 autofill_popup_controller_->Show(names, names, names, autofill_ids); 272 273 // Generate a popup, so it can be hidden later. It doesn't matter what the 274 // external_delegate thinks is being shown in the process, since we are just 275 // testing the popup here. 276 autofill::GenerateTestAutofillPopup(external_delegate_.get()); 277 278 // No line is selected so the removal should fail. 279 EXPECT_FALSE(autofill_popup_controller_->RemoveSelectedLine()); 280 281 // Try to remove the last entry and ensure it fails (it is an option). 282 autofill_popup_controller_->SetSelectedLine( 283 autofill_popup_controller_->subtexts().size() - 1); 284 EXPECT_FALSE(autofill_popup_controller_->RemoveSelectedLine()); 285 EXPECT_LE(0, autofill_popup_controller_->selected_line()); 286 287 // Remove the first entry. The popup should be redrawn since its size has 288 // changed. 289 EXPECT_CALL(*autofill_popup_controller_, UpdateBoundsAndRedrawPopup()); 290 autofill_popup_controller_->SetSelectedLine(0); 291 EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); 292 293 // Remove the last entry. The popup should then be hidden since there are 294 // no Autofill entries left. 295 EXPECT_CALL(*autofill_popup_controller_, Hide()); 296 autofill_popup_controller_->SetSelectedLine(0); 297 EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); 298 } 299 300 TEST_F(AutofillPopupControllerUnitTest, RemoveOnlyLine) { 301 // Set up the popup. 302 std::vector<string16> names(1, string16()); 303 std::vector<int> autofill_ids; 304 autofill_ids.push_back(1); 305 autofill_popup_controller_->Show(names, names, names, autofill_ids); 306 307 // Generate a popup. 308 autofill::GenerateTestAutofillPopup(external_delegate_.get()); 309 310 // Select the only line. 311 autofill_popup_controller_->SetSelectedLine(0); 312 313 // Remove the only line. There should be no row invalidation and the popup 314 // should then be hidden since there are no Autofill entries left. 315 EXPECT_CALL(*autofill_popup_controller_, Hide()); 316 EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(_)).Times(0); 317 EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); 318 } 319 320 TEST_F(AutofillPopupControllerUnitTest, SkipSeparator) { 321 // Set up the popup. 322 std::vector<string16> names(3, string16()); 323 std::vector<int> autofill_ids; 324 autofill_ids.push_back(1); 325 autofill_ids.push_back(WebAutofillClient::MenuItemIDSeparator); 326 autofill_ids.push_back(WebAutofillClient::MenuItemIDAutofillOptions); 327 autofill_popup_controller_->Show(names, names, names, autofill_ids); 328 329 autofill_popup_controller_->SetSelectedLine(0); 330 331 // Make sure next skips the unselectable separator. 332 autofill_popup_controller_->SelectNextLine(); 333 EXPECT_EQ(2, autofill_popup_controller_->selected_line()); 334 335 // Make sure previous skips the unselectable separator. 336 autofill_popup_controller_->SelectPreviousLine(); 337 EXPECT_EQ(0, autofill_popup_controller_->selected_line()); 338 } 339 340 TEST_F(AutofillPopupControllerUnitTest, RowWidthWithoutText) { 341 std::vector<string16> names(4); 342 std::vector<string16> subtexts(4); 343 std::vector<string16> icons(4); 344 std::vector<int> ids(4); 345 346 // Set up some visible display so the text values are kept. 347 gfx::Display display(0, gfx::Rect(0, 0, 100, 100)); 348 autofill_popup_controller_->set_display(display); 349 350 // Give elements 1 and 3 subtexts and elements 2 and 3 icons, to ensure 351 // all combinations of subtexts and icons. 352 subtexts[1] = ASCIIToUTF16("x"); 353 subtexts[3] = ASCIIToUTF16("x"); 354 icons[2] = ASCIIToUTF16("x"); 355 icons[3] = ASCIIToUTF16("x"); 356 autofill_popup_controller_->Show(names, subtexts, icons, ids); 357 358 int base_size = AutofillPopupView::kEndPadding * 2; 359 int subtext_increase = AutofillPopupView::kNamePadding; 360 int icon_increase = AutofillPopupView::kIconPadding + 361 AutofillPopupView::kAutofillIconWidth; 362 363 EXPECT_EQ(base_size, autofill_popup_controller_->RowWidthWithoutText(0)); 364 EXPECT_EQ(base_size + subtext_increase, 365 autofill_popup_controller_->RowWidthWithoutText(1)); 366 EXPECT_EQ(base_size + icon_increase, 367 autofill_popup_controller_->RowWidthWithoutText(2)); 368 EXPECT_EQ(base_size + subtext_increase + icon_increase, 369 autofill_popup_controller_->RowWidthWithoutText(3)); 370 } 371 372 TEST_F(AutofillPopupControllerUnitTest, UpdateDataListValues) { 373 std::vector<string16> items; 374 items.push_back(string16()); 375 std::vector<int> ids; 376 ids.push_back(1); 377 378 autofill_popup_controller_->Show(items, items, items, ids); 379 380 EXPECT_EQ(items, autofill_popup_controller_->names()); 381 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 382 383 // Add one data list entry. 384 std::vector<string16> data_list_values; 385 data_list_values.push_back(ASCIIToUTF16("data list value 1")); 386 387 autofill_popup_controller_->UpdateDataListValues(data_list_values, 388 data_list_values); 389 390 // Update the expected values. 391 items.insert(items.begin(), data_list_values[0]); 392 items.insert(items.begin() + 1, string16()); 393 ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry); 394 ids.insert(ids.begin() + 1, WebAutofillClient::MenuItemIDSeparator); 395 396 EXPECT_EQ(items, autofill_popup_controller_->names()); 397 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 398 399 // Add two data list entries (which should replace the current one). 400 data_list_values.push_back(ASCIIToUTF16("data list value 2")); 401 402 autofill_popup_controller_->UpdateDataListValues(data_list_values, 403 data_list_values); 404 405 // Update the expected values. 406 items.insert(items.begin() + 1, data_list_values[1]); 407 ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry); 408 409 EXPECT_EQ(items, autofill_popup_controller_->names()); 410 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 411 412 // Clear all data list values. 413 data_list_values.clear(); 414 415 autofill_popup_controller_->UpdateDataListValues(data_list_values, 416 data_list_values); 417 418 items.clear(); 419 items.push_back(string16()); 420 ids.clear(); 421 ids.push_back(1); 422 423 EXPECT_EQ(items, autofill_popup_controller_->names()); 424 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 425 } 426 427 TEST_F(AutofillPopupControllerUnitTest, PopupsWithOnlyDataLists) { 428 // Create the popup with a single datalist element. 429 std::vector<string16> items; 430 items.push_back(string16()); 431 std::vector<int> ids; 432 ids.push_back(WebAutofillClient::MenuItemIDDataListEntry); 433 434 autofill_popup_controller_->Show(items, items, items, ids); 435 436 EXPECT_EQ(items, autofill_popup_controller_->names()); 437 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 438 439 // Replace the datalist element with a new one. 440 std::vector<string16> data_list_values; 441 data_list_values.push_back(ASCIIToUTF16("data list value 1")); 442 443 autofill_popup_controller_->UpdateDataListValues(data_list_values, 444 data_list_values); 445 446 EXPECT_EQ(data_list_values, autofill_popup_controller_->names()); 447 // The id value should stay the same. 448 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 449 450 // Clear datalist values and check that the popup becomes hidden. 451 EXPECT_CALL(*autofill_popup_controller_, Hide()); 452 data_list_values.clear(); 453 autofill_popup_controller_->UpdateDataListValues(data_list_values, 454 data_list_values); 455 } 456 457 TEST_F(AutofillPopupControllerUnitTest, GetOrCreate) { 458 AutofillDriverImpl* driver = 459 AutofillDriverImpl::FromWebContents(web_contents()); 460 MockAutofillExternalDelegate delegate( 461 web_contents(), driver->autofill_manager(), driver); 462 463 WeakPtr<AutofillPopupControllerImpl> controller = 464 AutofillPopupControllerImpl::GetOrCreate( 465 WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), NULL, 466 gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); 467 EXPECT_TRUE(controller.get()); 468 469 controller->Hide(); 470 471 controller = AutofillPopupControllerImpl::GetOrCreate( 472 WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), NULL, 473 gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); 474 EXPECT_TRUE(controller.get()); 475 476 WeakPtr<AutofillPopupControllerImpl> controller2 = 477 AutofillPopupControllerImpl::GetOrCreate(controller, 478 delegate.GetWeakPtr(), 479 NULL, 480 gfx::Rect(), 481 base::i18n::UNKNOWN_DIRECTION); 482 EXPECT_EQ(controller.get(), controller2.get()); 483 controller->Hide(); 484 485 testing::NiceMock<TestAutofillPopupController>* test_controller = 486 new testing::NiceMock<TestAutofillPopupController>(delegate.GetWeakPtr(), 487 gfx::Rect()); 488 EXPECT_CALL(*test_controller, Hide()); 489 490 gfx::RectF bounds(0.f, 0.f, 1.f, 2.f); 491 base::WeakPtr<AutofillPopupControllerImpl> controller3 = 492 AutofillPopupControllerImpl::GetOrCreate( 493 test_controller->GetWeakPtr(), 494 delegate.GetWeakPtr(), 495 NULL, 496 bounds, 497 base::i18n::UNKNOWN_DIRECTION); 498 EXPECT_EQ( 499 bounds, 500 static_cast<AutofillPopupController*>(controller3.get())-> 501 element_bounds()); 502 controller3->Hide(); 503 504 // Hide the test_controller to delete it. 505 test_controller->DoHide(); 506 } 507 508 TEST_F(AutofillPopupControllerUnitTest, ProperlyResetController) { 509 std::vector<string16> names(2); 510 std::vector<int> ids(2); 511 popup_controller()->SetValues(names, names, names, ids); 512 popup_controller()->SetSelectedLine(0); 513 514 // Now show a new popup with the same controller, but with fewer items. 515 WeakPtr<AutofillPopupControllerImpl> controller = 516 AutofillPopupControllerImpl::GetOrCreate( 517 popup_controller()->GetWeakPtr(), 518 delegate()->GetWeakPtr(), 519 NULL, 520 gfx::Rect(), 521 base::i18n::UNKNOWN_DIRECTION); 522 EXPECT_NE(0, controller->selected_line()); 523 EXPECT_TRUE(controller->names().empty()); 524 } 525 526 #if !defined(OS_ANDROID) 527 TEST_F(AutofillPopupControllerUnitTest, ElideText) { 528 std::vector<string16> names; 529 names.push_back(ASCIIToUTF16("Text that will need to be trimmed")); 530 names.push_back(ASCIIToUTF16("Untrimmed")); 531 532 std::vector<string16> subtexts; 533 subtexts.push_back(ASCIIToUTF16("Label that will be trimmed")); 534 subtexts.push_back(ASCIIToUTF16("Untrimmed")); 535 536 std::vector<string16> icons(2, string16()); 537 std::vector<int> autofill_ids(2, 0); 538 539 // Show the popup once so we can easily generate the size it needs. 540 autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); 541 542 // Ensure the popup will be too small to display all of the first row. 543 int popup_max_width = 544 autofill_popup_controller_->GetNameFontForRow(0).GetStringWidth( 545 names[0]) + 546 autofill_popup_controller_->subtext_font().GetStringWidth(subtexts[0]) - 547 25; 548 gfx::Rect popup_bounds = gfx::Rect(0, 0, popup_max_width, 0); 549 autofill_popup_controller_->set_display(gfx::Display(0, popup_bounds)); 550 551 autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); 552 553 // The first element was long so it should have been trimmed. 554 EXPECT_NE(names[0], autofill_popup_controller_->names()[0]); 555 EXPECT_NE(subtexts[0], autofill_popup_controller_->subtexts()[0]); 556 557 // The second element was shorter so it should be unchanged. 558 EXPECT_EQ(names[1], autofill_popup_controller_->names()[1]); 559 EXPECT_EQ(subtexts[1], autofill_popup_controller_->subtexts()[1]); 560 } 561 #endif 562 563 TEST_F(AutofillPopupControllerUnitTest, GrowPopupInSpace) { 564 std::vector<string16> names(1); 565 std::vector<int> autofill_ids(1, 1); 566 567 // Call Show so that GetDesired...() will be able to provide valid values. 568 autofill_popup_controller_->Show(names, names, names, autofill_ids); 569 int desired_width = autofill_popup_controller_->GetDesiredPopupWidth(); 570 int desired_height = autofill_popup_controller_->GetDesiredPopupHeight(); 571 572 // Set up the visible screen space. 573 gfx::Display display(0, 574 gfx::Rect(0, 0, desired_width * 2, desired_height * 2)); 575 576 // Store the possible element bounds and the popup bounds they should result 577 // in. 578 std::vector<gfx::RectF> element_bounds; 579 std::vector<gfx::Rect> expected_popup_bounds; 580 581 // The popup grows down and to the right. 582 element_bounds.push_back(gfx::RectF(0, 0, 0, 0)); 583 expected_popup_bounds.push_back( 584 gfx::Rect(0, 0, desired_width, desired_height)); 585 586 // The popup grows down and to the left. 587 element_bounds.push_back(gfx::RectF(2 * desired_width, 0, 0, 0)); 588 expected_popup_bounds.push_back( 589 gfx::Rect(desired_width, 0, desired_width, desired_height)); 590 591 // The popup grows up and to the right. 592 element_bounds.push_back(gfx::RectF(0, 2 * desired_height, 0, 0)); 593 expected_popup_bounds.push_back( 594 gfx::Rect(0, desired_height, desired_width, desired_height)); 595 596 // The popup grows up and to the left. 597 element_bounds.push_back( 598 gfx::RectF(2 * desired_width, 2 * desired_height, 0, 0)); 599 expected_popup_bounds.push_back( 600 gfx::Rect(desired_width, desired_height, desired_width, desired_height)); 601 602 // The popup would be partial off the top and left side of the screen. 603 element_bounds.push_back( 604 gfx::RectF(-desired_width / 2, -desired_height / 2, 0, 0)); 605 expected_popup_bounds.push_back( 606 gfx::Rect(0, 0, desired_width, desired_height)); 607 608 // The popup would be partially off the bottom and the right side of 609 // the screen. 610 element_bounds.push_back( 611 gfx::RectF(desired_width * 1.5, desired_height * 1.5, 0, 0)); 612 expected_popup_bounds.push_back( 613 gfx::Rect((desired_width + 1) / 2, (desired_height + 1) / 2, 614 desired_width, desired_height)); 615 616 for (size_t i = 0; i < element_bounds.size(); ++i) { 617 AutofillDriverImpl* driver = 618 AutofillDriverImpl::FromWebContents(web_contents()); 619 NiceMock<MockAutofillExternalDelegate> external_delegate( 620 web_contents(), driver->autofill_manager(), driver); 621 TestAutofillPopupController* autofill_popup_controller = 622 new TestAutofillPopupController(external_delegate.GetWeakPtr(), 623 element_bounds[i]); 624 625 autofill_popup_controller->set_display(display); 626 autofill_popup_controller->Show(names, names, names, autofill_ids); 627 628 EXPECT_EQ(expected_popup_bounds[i].ToString(), 629 autofill_popup_controller->popup_bounds().ToString()) << 630 "Popup bounds failed to match for test " << i; 631 632 // Hide the controller to delete it. 633 autofill_popup_controller->DoHide(); 634 } 635 } 636 637 } // namespace autofill 638