autofill_popup_controller_unittest.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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 "grit/webkit_resources.h" 19#include "testing/gmock/include/gmock/gmock.h" 20#include "testing/gtest/include/gtest/gtest.h" 21#include "third_party/WebKit/public/web/WebAutofillClient.h" 22#include "ui/base/resource/resource_bundle.h" 23#include "ui/gfx/display.h" 24#include "ui/gfx/rect.h" 25 26using ::testing::_; 27using ::testing::AtLeast; 28using ::testing::NiceMock; 29using base::WeakPtr; 30using WebKit::WebAutofillClient; 31 32namespace autofill { 33namespace { 34 35class MockAutofillExternalDelegate : public AutofillExternalDelegate { 36 public: 37 MockAutofillExternalDelegate(content::WebContents* web_contents, 38 AutofillManager* autofill_manager, 39 AutofillDriver* autofill_driver) 40 : AutofillExternalDelegate(web_contents, autofill_manager, 41 autofill_driver) {} 42 virtual ~MockAutofillExternalDelegate() {} 43 44 virtual void DidSelectSuggestion(int identifier) OVERRIDE {} 45 virtual void RemoveSuggestion(const string16& value, int identifier) OVERRIDE 46 {} 47 virtual void ClearPreviewedForm() OVERRIDE {} 48 base::WeakPtr<AutofillExternalDelegate> GetWeakPtr() { 49 return AutofillExternalDelegate::GetWeakPtr(); 50 } 51}; 52 53class MockAutofillManagerDelegate 54 : public autofill::TestAutofillManagerDelegate { 55 public: 56 MockAutofillManagerDelegate() {} 57 virtual ~MockAutofillManagerDelegate() {} 58 59 virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; } 60 61 private: 62 TestingPrefServiceSimple prefs_; 63 64 DISALLOW_COPY_AND_ASSIGN(MockAutofillManagerDelegate); 65}; 66 67class TestAutofillPopupController : public AutofillPopupControllerImpl { 68 public: 69 explicit TestAutofillPopupController( 70 base::WeakPtr<AutofillExternalDelegate> external_delegate, 71 const gfx::RectF& element_bounds) 72 : AutofillPopupControllerImpl( 73 external_delegate, NULL, NULL, element_bounds, 74 base::i18n::UNKNOWN_DIRECTION) {} 75 virtual ~TestAutofillPopupController() {} 76 77 void set_display(const gfx::Display display) { 78 display_ = display; 79 } 80 virtual gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const 81 OVERRIDE { 82 return display_; 83 } 84 85 // Making protected functions public for testing 86 using AutofillPopupControllerImpl::SetPopupBounds; 87 using AutofillPopupControllerImpl::names; 88 using AutofillPopupControllerImpl::subtexts; 89 using AutofillPopupControllerImpl::identifiers; 90 using AutofillPopupControllerImpl::selected_line; 91 using AutofillPopupControllerImpl::SetSelectedLine; 92 using AutofillPopupControllerImpl::SelectNextLine; 93 using AutofillPopupControllerImpl::SelectPreviousLine; 94 using AutofillPopupControllerImpl::RemoveSelectedLine; 95 using AutofillPopupControllerImpl::popup_bounds; 96 using AutofillPopupControllerImpl::element_bounds; 97#if !defined(OS_ANDROID) 98 using AutofillPopupControllerImpl::GetNameFontForRow; 99 using AutofillPopupControllerImpl::subtext_font; 100 using AutofillPopupControllerImpl::RowWidthWithoutText; 101#endif 102 using AutofillPopupControllerImpl::SetValues; 103 using AutofillPopupControllerImpl::GetDesiredPopupWidth; 104 using AutofillPopupControllerImpl::GetDesiredPopupHeight; 105 using AutofillPopupControllerImpl::GetWeakPtr; 106 MOCK_METHOD1(InvalidateRow, void(size_t)); 107 MOCK_METHOD0(UpdateBoundsAndRedrawPopup, void()); 108 MOCK_METHOD0(Hide, void()); 109 110 void DoHide() { 111 AutofillPopupControllerImpl::Hide(); 112 } 113 114 private: 115 virtual void ShowView() OVERRIDE {} 116 117 gfx::Display display_; 118}; 119 120} // namespace 121 122class AutofillPopupControllerUnitTest : public ChromeRenderViewHostTestHarness { 123 public: 124 AutofillPopupControllerUnitTest() 125 : manager_delegate_(new MockAutofillManagerDelegate()), 126 autofill_popup_controller_(NULL) {} 127 virtual ~AutofillPopupControllerUnitTest() {} 128 129 virtual void SetUp() OVERRIDE { 130 ChromeRenderViewHostTestHarness::SetUp(); 131 132 AutofillDriverImpl::CreateForWebContentsAndDelegate( 133 web_contents(), 134 manager_delegate_.get(), 135 "en-US", 136 AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER); 137 AutofillDriverImpl* driver = 138 AutofillDriverImpl::FromWebContents(web_contents()); 139 external_delegate_.reset( 140 new NiceMock<MockAutofillExternalDelegate>( 141 web_contents(), 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<string16> names(2, 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<string16> names(2, 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<string16> names(3, 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<string16> names(1, 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<string16> names(3, 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<string16> names(4); 309 std::vector<string16> subtexts(4); 310 std::vector<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<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<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, 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<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<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( 432 web_contents(), driver->autofill_manager(), driver); 433 434 WeakPtr<AutofillPopupControllerImpl> controller = 435 AutofillPopupControllerImpl::GetOrCreate( 436 WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), 437 NULL, NULL, gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); 438 EXPECT_TRUE(controller.get()); 439 440 controller->Hide(); 441 442 controller = AutofillPopupControllerImpl::GetOrCreate( 443 WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), 444 NULL, NULL, gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); 445 EXPECT_TRUE(controller.get()); 446 447 WeakPtr<AutofillPopupControllerImpl> controller2 = 448 AutofillPopupControllerImpl::GetOrCreate(controller, 449 delegate.GetWeakPtr(), 450 NULL, 451 NULL, 452 gfx::Rect(), 453 base::i18n::UNKNOWN_DIRECTION); 454 EXPECT_EQ(controller.get(), controller2.get()); 455 controller->Hide(); 456 457 testing::NiceMock<TestAutofillPopupController>* test_controller = 458 new testing::NiceMock<TestAutofillPopupController>(delegate.GetWeakPtr(), 459 gfx::Rect()); 460 EXPECT_CALL(*test_controller, Hide()); 461 462 gfx::RectF bounds(0.f, 0.f, 1.f, 2.f); 463 base::WeakPtr<AutofillPopupControllerImpl> controller3 = 464 AutofillPopupControllerImpl::GetOrCreate( 465 test_controller->GetWeakPtr(), 466 delegate.GetWeakPtr(), 467 NULL, 468 NULL, 469 bounds, 470 base::i18n::UNKNOWN_DIRECTION); 471 EXPECT_EQ( 472 bounds, 473 static_cast<AutofillPopupController*>(controller3.get())-> 474 element_bounds()); 475 controller3->Hide(); 476 477 // Hide the test_controller to delete it. 478 test_controller->DoHide(); 479} 480 481TEST_F(AutofillPopupControllerUnitTest, ProperlyResetController) { 482 std::vector<string16> names(2); 483 std::vector<int> ids(2); 484 popup_controller()->SetValues(names, names, names, ids); 485 popup_controller()->SetSelectedLine(0); 486 487 // Now show a new popup with the same controller, but with fewer items. 488 WeakPtr<AutofillPopupControllerImpl> controller = 489 AutofillPopupControllerImpl::GetOrCreate( 490 popup_controller()->GetWeakPtr(), 491 delegate()->GetWeakPtr(), 492 NULL, 493 NULL, 494 gfx::Rect(), 495 base::i18n::UNKNOWN_DIRECTION); 496 EXPECT_NE(0, controller->selected_line()); 497 EXPECT_TRUE(controller->names().empty()); 498} 499 500#if !defined(OS_ANDROID) 501TEST_F(AutofillPopupControllerUnitTest, ElideText) { 502 std::vector<string16> names; 503 names.push_back(ASCIIToUTF16("Text that will need to be trimmed")); 504 names.push_back(ASCIIToUTF16("Untrimmed")); 505 506 std::vector<string16> subtexts; 507 subtexts.push_back(ASCIIToUTF16("Label that will be trimmed")); 508 subtexts.push_back(ASCIIToUTF16("Untrimmed")); 509 510 std::vector<string16> icons(2, ASCIIToUTF16("genericCC")); 511 std::vector<int> autofill_ids(2, 0); 512 513 // Show the popup once so we can easily generate the size it needs. 514 autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); 515 516 // Ensure the popup will be too small to display all of the first row. 517 int popup_max_width = 518 autofill_popup_controller_->GetNameFontForRow(0).GetStringWidth( 519 names[0]) + 520 autofill_popup_controller_->subtext_font().GetStringWidth(subtexts[0]) - 521 25; 522 gfx::Rect popup_bounds = gfx::Rect(0, 0, popup_max_width, 0); 523 autofill_popup_controller_->set_display(gfx::Display(0, popup_bounds)); 524 525 autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); 526 527 // The first element was long so it should have been trimmed. 528 EXPECT_NE(names[0], autofill_popup_controller_->names()[0]); 529 EXPECT_NE(subtexts[0], autofill_popup_controller_->subtexts()[0]); 530 531 // The second element was shorter so it should be unchanged. 532 EXPECT_EQ(names[1], autofill_popup_controller_->names()[1]); 533 EXPECT_EQ(subtexts[1], autofill_popup_controller_->subtexts()[1]); 534} 535#endif 536 537TEST_F(AutofillPopupControllerUnitTest, GrowPopupInSpace) { 538 std::vector<string16> names(1); 539 std::vector<int> autofill_ids(1, 1); 540 541 // Call Show so that GetDesired...() will be able to provide valid values. 542 autofill_popup_controller_->Show(names, names, names, autofill_ids); 543 int desired_width = autofill_popup_controller_->GetDesiredPopupWidth(); 544 int desired_height = autofill_popup_controller_->GetDesiredPopupHeight(); 545 546 // Set up the visible screen space. 547 gfx::Display display(0, 548 gfx::Rect(0, 0, desired_width * 2, desired_height * 2)); 549 550 // Store the possible element bounds and the popup bounds they should result 551 // in. 552 std::vector<gfx::RectF> element_bounds; 553 std::vector<gfx::Rect> expected_popup_bounds; 554 555 // The popup grows down and to the right. 556 element_bounds.push_back(gfx::RectF(0, 0, 0, 0)); 557 expected_popup_bounds.push_back( 558 gfx::Rect(0, 0, desired_width, desired_height)); 559 560 // The popup grows down and to the left. 561 element_bounds.push_back(gfx::RectF(2 * desired_width, 0, 0, 0)); 562 expected_popup_bounds.push_back( 563 gfx::Rect(desired_width, 0, desired_width, desired_height)); 564 565 // The popup grows up and to the right. 566 element_bounds.push_back(gfx::RectF(0, 2 * desired_height, 0, 0)); 567 expected_popup_bounds.push_back( 568 gfx::Rect(0, desired_height, desired_width, desired_height)); 569 570 // The popup grows up and to the left. 571 element_bounds.push_back( 572 gfx::RectF(2 * desired_width, 2 * desired_height, 0, 0)); 573 expected_popup_bounds.push_back( 574 gfx::Rect(desired_width, desired_height, desired_width, desired_height)); 575 576 // The popup would be partial off the top and left side of the screen. 577 element_bounds.push_back( 578 gfx::RectF(-desired_width / 2, -desired_height / 2, 0, 0)); 579 expected_popup_bounds.push_back( 580 gfx::Rect(0, 0, desired_width, desired_height)); 581 582 // The popup would be partially off the bottom and the right side of 583 // the screen. 584 element_bounds.push_back( 585 gfx::RectF(desired_width * 1.5, desired_height * 1.5, 0, 0)); 586 expected_popup_bounds.push_back( 587 gfx::Rect((desired_width + 1) / 2, (desired_height + 1) / 2, 588 desired_width, desired_height)); 589 590 for (size_t i = 0; i < element_bounds.size(); ++i) { 591 AutofillDriverImpl* driver = 592 AutofillDriverImpl::FromWebContents(web_contents()); 593 NiceMock<MockAutofillExternalDelegate> external_delegate( 594 web_contents(), driver->autofill_manager(), driver); 595 TestAutofillPopupController* autofill_popup_controller = 596 new TestAutofillPopupController(external_delegate.GetWeakPtr(), 597 element_bounds[i]); 598 599 autofill_popup_controller->set_display(display); 600 autofill_popup_controller->Show(names, names, names, autofill_ids); 601 602 EXPECT_EQ(expected_popup_bounds[i].ToString(), 603 autofill_popup_controller->popup_bounds().ToString()) << 604 "Popup bounds failed to match for test " << i; 605 606 // Hide the controller to delete it. 607 autofill_popup_controller->DoHide(); 608 } 609} 610 611} // namespace autofill 612