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