| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/prefs/pref_service.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" |
| #include "chrome/browser/ui/autofill/autofill_popup_view.h" |
| #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/autofill/content/browser/autofill_driver_impl.h" |
| #include "components/autofill/core/browser/autofill_external_delegate.h" |
| #include "components/autofill/core/browser/autofill_manager.h" |
| #include "components/autofill/core/browser/autofill_test_utils.h" |
| #include "components/autofill/core/browser/test_autofill_external_delegate.h" |
| #include "components/autofill/core/browser/test_autofill_manager_delegate.h" |
| #include "grit/webkit_resources.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/WebKit/public/web/WebAutofillClient.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/gfx/display.h" |
| #include "ui/gfx/rect.h" |
| |
| using ::testing::_; |
| using ::testing::AtLeast; |
| using ::testing::NiceMock; |
| using base::WeakPtr; |
| using blink::WebAutofillClient; |
| |
| namespace autofill { |
| namespace { |
| |
| class MockAutofillExternalDelegate : public AutofillExternalDelegate { |
| public: |
| MockAutofillExternalDelegate(AutofillManager* autofill_manager, |
| AutofillDriver* autofill_driver) |
| : AutofillExternalDelegate(autofill_manager, autofill_driver) {} |
| virtual ~MockAutofillExternalDelegate() {} |
| |
| virtual void DidSelectSuggestion(int identifier) OVERRIDE {} |
| virtual void RemoveSuggestion(const base::string16& value, |
| int identifier) OVERRIDE {} |
| virtual void ClearPreviewedForm() OVERRIDE {} |
| base::WeakPtr<AutofillExternalDelegate> GetWeakPtr() { |
| return AutofillExternalDelegate::GetWeakPtr(); |
| } |
| }; |
| |
| class MockAutofillManagerDelegate |
| : public autofill::TestAutofillManagerDelegate { |
| public: |
| MockAutofillManagerDelegate() |
| : prefs_(autofill::test::PrefServiceForTesting()) { |
| } |
| virtual ~MockAutofillManagerDelegate() {} |
| |
| virtual PrefService* GetPrefs() OVERRIDE { return prefs_.get(); } |
| |
| private: |
| scoped_ptr<PrefService> prefs_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockAutofillManagerDelegate); |
| }; |
| |
| class TestAutofillPopupController : public AutofillPopupControllerImpl { |
| public: |
| explicit TestAutofillPopupController( |
| base::WeakPtr<AutofillExternalDelegate> external_delegate, |
| const gfx::RectF& element_bounds) |
| : AutofillPopupControllerImpl( |
| external_delegate, NULL, NULL, element_bounds, |
| base::i18n::UNKNOWN_DIRECTION) {} |
| virtual ~TestAutofillPopupController() {} |
| |
| void set_display(const gfx::Display display) { |
| display_ = display; |
| } |
| virtual gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const |
| OVERRIDE { |
| return display_; |
| } |
| |
| // Making protected functions public for testing |
| using AutofillPopupControllerImpl::SetPopupBounds; |
| using AutofillPopupControllerImpl::names; |
| using AutofillPopupControllerImpl::subtexts; |
| using AutofillPopupControllerImpl::identifiers; |
| using AutofillPopupControllerImpl::selected_line; |
| using AutofillPopupControllerImpl::SetSelectedLine; |
| using AutofillPopupControllerImpl::SelectNextLine; |
| using AutofillPopupControllerImpl::SelectPreviousLine; |
| using AutofillPopupControllerImpl::RemoveSelectedLine; |
| using AutofillPopupControllerImpl::popup_bounds; |
| using AutofillPopupControllerImpl::element_bounds; |
| #if !defined(OS_ANDROID) |
| using AutofillPopupControllerImpl::GetNameFontForRow; |
| using AutofillPopupControllerImpl::subtext_font; |
| using AutofillPopupControllerImpl::RowWidthWithoutText; |
| #endif |
| using AutofillPopupControllerImpl::SetValues; |
| using AutofillPopupControllerImpl::GetDesiredPopupWidth; |
| using AutofillPopupControllerImpl::GetDesiredPopupHeight; |
| using AutofillPopupControllerImpl::GetWeakPtr; |
| MOCK_METHOD1(InvalidateRow, void(size_t)); |
| MOCK_METHOD0(UpdateBoundsAndRedrawPopup, void()); |
| MOCK_METHOD0(Hide, void()); |
| |
| void DoHide() { |
| AutofillPopupControllerImpl::Hide(); |
| } |
| |
| private: |
| virtual void ShowView() OVERRIDE {} |
| |
| gfx::Display display_; |
| }; |
| |
| } // namespace |
| |
| class AutofillPopupControllerUnitTest : public ChromeRenderViewHostTestHarness { |
| public: |
| AutofillPopupControllerUnitTest() |
| : manager_delegate_(new MockAutofillManagerDelegate()), |
| autofill_popup_controller_(NULL) {} |
| virtual ~AutofillPopupControllerUnitTest() {} |
| |
| virtual void SetUp() OVERRIDE { |
| ChromeRenderViewHostTestHarness::SetUp(); |
| |
| AutofillDriverImpl::CreateForWebContentsAndDelegate( |
| web_contents(), |
| manager_delegate_.get(), |
| "en-US", |
| AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER); |
| AutofillDriverImpl* driver = |
| AutofillDriverImpl::FromWebContents(web_contents()); |
| external_delegate_.reset( |
| new NiceMock<MockAutofillExternalDelegate>( |
| driver->autofill_manager(), |
| driver)); |
| |
| autofill_popup_controller_ = |
| new testing::NiceMock<TestAutofillPopupController>( |
| external_delegate_->GetWeakPtr(),gfx::Rect()); |
| } |
| |
| virtual void TearDown() OVERRIDE { |
| // This will make sure the controller and the view (if any) are both |
| // cleaned up. |
| if (autofill_popup_controller_) |
| autofill_popup_controller_->DoHide(); |
| |
| external_delegate_.reset(); |
| ChromeRenderViewHostTestHarness::TearDown(); |
| } |
| |
| TestAutofillPopupController* popup_controller() { |
| return autofill_popup_controller_; |
| } |
| |
| MockAutofillExternalDelegate* delegate() { |
| return external_delegate_.get(); |
| } |
| |
| protected: |
| scoped_ptr<MockAutofillManagerDelegate> manager_delegate_; |
| scoped_ptr<NiceMock<MockAutofillExternalDelegate> > external_delegate_; |
| testing::NiceMock<TestAutofillPopupController>* autofill_popup_controller_; |
| }; |
| |
| TEST_F(AutofillPopupControllerUnitTest, SetBounds) { |
| // Ensure the popup size can be set and causes a redraw. |
| gfx::Rect popup_bounds(10, 10, 100, 100); |
| |
| EXPECT_CALL(*autofill_popup_controller_, |
| UpdateBoundsAndRedrawPopup()); |
| |
| popup_controller()->SetPopupBounds(popup_bounds); |
| |
| EXPECT_EQ(popup_bounds, popup_controller()->popup_bounds()); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, ChangeSelectedLine) { |
| // Set up the popup. |
| std::vector<base::string16> names(2, base::string16()); |
| std::vector<int> autofill_ids(2, 0); |
| autofill_popup_controller_->Show(names, names, names, autofill_ids); |
| |
| EXPECT_LT(autofill_popup_controller_->selected_line(), 0); |
| // Check that there are at least 2 values so that the first and last selection |
| // are different. |
| EXPECT_GE(2, |
| static_cast<int>(autofill_popup_controller_->subtexts().size())); |
| |
| // Test wrapping before the front. |
| autofill_popup_controller_->SelectPreviousLine(); |
| EXPECT_EQ(static_cast<int>( |
| autofill_popup_controller_->subtexts().size() - 1), |
| autofill_popup_controller_->selected_line()); |
| |
| // Test wrapping after the end. |
| autofill_popup_controller_->SelectNextLine(); |
| EXPECT_EQ(0, autofill_popup_controller_->selected_line()); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, RedrawSelectedLine) { |
| // Set up the popup. |
| std::vector<base::string16> names(2, base::string16()); |
| std::vector<int> autofill_ids(2, 0); |
| autofill_popup_controller_->Show(names, names, names, autofill_ids); |
| |
| // Make sure that when a new line is selected, it is invalidated so it can |
| // be updated to show it is selected. |
| int selected_line = 0; |
| EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(selected_line)); |
| autofill_popup_controller_->SetSelectedLine(selected_line); |
| |
| // Ensure that the row isn't invalidated if it didn't change. |
| EXPECT_CALL(*autofill_popup_controller_, |
| InvalidateRow(selected_line)).Times(0); |
| autofill_popup_controller_->SetSelectedLine(selected_line); |
| |
| // Change back to no selection. |
| EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(selected_line)); |
| autofill_popup_controller_->SetSelectedLine(-1); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, RemoveLine) { |
| // Set up the popup. |
| std::vector<base::string16> names(3, base::string16()); |
| std::vector<int> autofill_ids; |
| autofill_ids.push_back(1); |
| autofill_ids.push_back(1); |
| autofill_ids.push_back(WebAutofillClient::MenuItemIDAutofillOptions); |
| autofill_popup_controller_->Show(names, names, names, autofill_ids); |
| |
| // Generate a popup, so it can be hidden later. It doesn't matter what the |
| // external_delegate thinks is being shown in the process, since we are just |
| // testing the popup here. |
| autofill::GenerateTestAutofillPopup(external_delegate_.get()); |
| |
| // No line is selected so the removal should fail. |
| EXPECT_FALSE(autofill_popup_controller_->RemoveSelectedLine()); |
| |
| // Try to remove the last entry and ensure it fails (it is an option). |
| autofill_popup_controller_->SetSelectedLine( |
| autofill_popup_controller_->subtexts().size() - 1); |
| EXPECT_FALSE(autofill_popup_controller_->RemoveSelectedLine()); |
| EXPECT_LE(0, autofill_popup_controller_->selected_line()); |
| |
| // Remove the first entry. The popup should be redrawn since its size has |
| // changed. |
| EXPECT_CALL(*autofill_popup_controller_, UpdateBoundsAndRedrawPopup()); |
| autofill_popup_controller_->SetSelectedLine(0); |
| EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); |
| |
| // Remove the last entry. The popup should then be hidden since there are |
| // no Autofill entries left. |
| EXPECT_CALL(*autofill_popup_controller_, Hide()); |
| autofill_popup_controller_->SetSelectedLine(0); |
| EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, RemoveOnlyLine) { |
| // Set up the popup. |
| std::vector<base::string16> names(1, base::string16()); |
| std::vector<int> autofill_ids; |
| autofill_ids.push_back(1); |
| autofill_popup_controller_->Show(names, names, names, autofill_ids); |
| |
| // Generate a popup. |
| autofill::GenerateTestAutofillPopup(external_delegate_.get()); |
| |
| // Select the only line. |
| autofill_popup_controller_->SetSelectedLine(0); |
| |
| // Remove the only line. There should be no row invalidation and the popup |
| // should then be hidden since there are no Autofill entries left. |
| EXPECT_CALL(*autofill_popup_controller_, Hide()); |
| EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(_)).Times(0); |
| EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, SkipSeparator) { |
| // Set up the popup. |
| std::vector<base::string16> names(3, base::string16()); |
| std::vector<int> autofill_ids; |
| autofill_ids.push_back(1); |
| autofill_ids.push_back(WebAutofillClient::MenuItemIDSeparator); |
| autofill_ids.push_back(WebAutofillClient::MenuItemIDAutofillOptions); |
| autofill_popup_controller_->Show(names, names, names, autofill_ids); |
| |
| autofill_popup_controller_->SetSelectedLine(0); |
| |
| // Make sure next skips the unselectable separator. |
| autofill_popup_controller_->SelectNextLine(); |
| EXPECT_EQ(2, autofill_popup_controller_->selected_line()); |
| |
| // Make sure previous skips the unselectable separator. |
| autofill_popup_controller_->SelectPreviousLine(); |
| EXPECT_EQ(0, autofill_popup_controller_->selected_line()); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, RowWidthWithoutText) { |
| std::vector<base::string16> names(4); |
| std::vector<base::string16> subtexts(4); |
| std::vector<base::string16> icons(4); |
| std::vector<int> ids(4); |
| |
| // Set up some visible display so the text values are kept. |
| gfx::Display display(0, gfx::Rect(0, 0, 100, 100)); |
| autofill_popup_controller_->set_display(display); |
| |
| // Give elements 1 and 3 subtexts and elements 2 and 3 icons, to ensure |
| // all combinations of subtexts and icons. |
| subtexts[1] = ASCIIToUTF16("x"); |
| subtexts[3] = ASCIIToUTF16("x"); |
| icons[2] = ASCIIToUTF16("americanExpressCC"); |
| icons[3] = ASCIIToUTF16("genericCC"); |
| autofill_popup_controller_->Show(names, subtexts, icons, ids); |
| |
| int base_size = |
| AutofillPopupView::kEndPadding * 2 + |
| AutofillPopupView::kBorderThickness * 2; |
| int subtext_increase = AutofillPopupView::kNamePadding; |
| |
| EXPECT_EQ(base_size, autofill_popup_controller_->RowWidthWithoutText(0)); |
| EXPECT_EQ(base_size + subtext_increase, |
| autofill_popup_controller_->RowWidthWithoutText(1)); |
| EXPECT_EQ(base_size + AutofillPopupView::kIconPadding + |
| ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| IDR_AUTOFILL_CC_AMEX).Width(), |
| autofill_popup_controller_->RowWidthWithoutText(2)); |
| EXPECT_EQ(base_size + subtext_increase + AutofillPopupView::kIconPadding + |
| ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| IDR_AUTOFILL_CC_GENERIC).Width(), |
| autofill_popup_controller_->RowWidthWithoutText(3)); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, UpdateDataListValues) { |
| std::vector<base::string16> items; |
| items.push_back(base::string16()); |
| std::vector<int> ids; |
| ids.push_back(1); |
| |
| autofill_popup_controller_->Show(items, items, items, ids); |
| |
| EXPECT_EQ(items, autofill_popup_controller_->names()); |
| EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); |
| |
| // Add one data list entry. |
| std::vector<base::string16> data_list_values; |
| data_list_values.push_back(ASCIIToUTF16("data list value 1")); |
| |
| autofill_popup_controller_->UpdateDataListValues(data_list_values, |
| data_list_values); |
| |
| // Update the expected values. |
| items.insert(items.begin(), data_list_values[0]); |
| items.insert(items.begin() + 1, base::string16()); |
| ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry); |
| ids.insert(ids.begin() + 1, WebAutofillClient::MenuItemIDSeparator); |
| |
| EXPECT_EQ(items, autofill_popup_controller_->names()); |
| EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); |
| |
| // Add two data list entries (which should replace the current one). |
| data_list_values.push_back(ASCIIToUTF16("data list value 2")); |
| |
| autofill_popup_controller_->UpdateDataListValues(data_list_values, |
| data_list_values); |
| |
| // Update the expected values. |
| items.insert(items.begin() + 1, data_list_values[1]); |
| ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry); |
| |
| EXPECT_EQ(items, autofill_popup_controller_->names()); |
| EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); |
| |
| // Clear all data list values. |
| data_list_values.clear(); |
| |
| autofill_popup_controller_->UpdateDataListValues(data_list_values, |
| data_list_values); |
| |
| items.clear(); |
| items.push_back(base::string16()); |
| ids.clear(); |
| ids.push_back(1); |
| |
| EXPECT_EQ(items, autofill_popup_controller_->names()); |
| EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, PopupsWithOnlyDataLists) { |
| // Create the popup with a single datalist element. |
| std::vector<base::string16> items; |
| items.push_back(base::string16()); |
| std::vector<int> ids; |
| ids.push_back(WebAutofillClient::MenuItemIDDataListEntry); |
| |
| autofill_popup_controller_->Show(items, items, items, ids); |
| |
| EXPECT_EQ(items, autofill_popup_controller_->names()); |
| EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); |
| |
| // Replace the datalist element with a new one. |
| std::vector<base::string16> data_list_values; |
| data_list_values.push_back(ASCIIToUTF16("data list value 1")); |
| |
| autofill_popup_controller_->UpdateDataListValues(data_list_values, |
| data_list_values); |
| |
| EXPECT_EQ(data_list_values, autofill_popup_controller_->names()); |
| // The id value should stay the same. |
| EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); |
| |
| // Clear datalist values and check that the popup becomes hidden. |
| EXPECT_CALL(*autofill_popup_controller_, Hide()); |
| data_list_values.clear(); |
| autofill_popup_controller_->UpdateDataListValues(data_list_values, |
| data_list_values); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, GetOrCreate) { |
| AutofillDriverImpl* driver = |
| AutofillDriverImpl::FromWebContents(web_contents()); |
| MockAutofillExternalDelegate delegate(driver->autofill_manager(), driver); |
| |
| WeakPtr<AutofillPopupControllerImpl> controller = |
| AutofillPopupControllerImpl::GetOrCreate( |
| WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), |
| NULL, NULL, gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); |
| EXPECT_TRUE(controller.get()); |
| |
| controller->Hide(); |
| |
| controller = AutofillPopupControllerImpl::GetOrCreate( |
| WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), |
| NULL, NULL, gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); |
| EXPECT_TRUE(controller.get()); |
| |
| WeakPtr<AutofillPopupControllerImpl> controller2 = |
| AutofillPopupControllerImpl::GetOrCreate(controller, |
| delegate.GetWeakPtr(), |
| NULL, |
| NULL, |
| gfx::Rect(), |
| base::i18n::UNKNOWN_DIRECTION); |
| EXPECT_EQ(controller.get(), controller2.get()); |
| controller->Hide(); |
| |
| testing::NiceMock<TestAutofillPopupController>* test_controller = |
| new testing::NiceMock<TestAutofillPopupController>(delegate.GetWeakPtr(), |
| gfx::Rect()); |
| EXPECT_CALL(*test_controller, Hide()); |
| |
| gfx::RectF bounds(0.f, 0.f, 1.f, 2.f); |
| base::WeakPtr<AutofillPopupControllerImpl> controller3 = |
| AutofillPopupControllerImpl::GetOrCreate( |
| test_controller->GetWeakPtr(), |
| delegate.GetWeakPtr(), |
| NULL, |
| NULL, |
| bounds, |
| base::i18n::UNKNOWN_DIRECTION); |
| EXPECT_EQ( |
| bounds, |
| static_cast<AutofillPopupController*>(controller3.get())-> |
| element_bounds()); |
| controller3->Hide(); |
| |
| // Hide the test_controller to delete it. |
| test_controller->DoHide(); |
| } |
| |
| TEST_F(AutofillPopupControllerUnitTest, ProperlyResetController) { |
| std::vector<base::string16> names(2); |
| std::vector<int> ids(2); |
| popup_controller()->SetValues(names, names, names, ids); |
| popup_controller()->SetSelectedLine(0); |
| |
| // Now show a new popup with the same controller, but with fewer items. |
| WeakPtr<AutofillPopupControllerImpl> controller = |
| AutofillPopupControllerImpl::GetOrCreate( |
| popup_controller()->GetWeakPtr(), |
| delegate()->GetWeakPtr(), |
| NULL, |
| NULL, |
| gfx::Rect(), |
| base::i18n::UNKNOWN_DIRECTION); |
| EXPECT_NE(0, controller->selected_line()); |
| EXPECT_TRUE(controller->names().empty()); |
| } |
| |
| #if !defined(OS_ANDROID) |
| TEST_F(AutofillPopupControllerUnitTest, ElideText) { |
| std::vector<base::string16> names; |
| names.push_back(ASCIIToUTF16("Text that will need to be trimmed")); |
| names.push_back(ASCIIToUTF16("Untrimmed")); |
| |
| std::vector<base::string16> subtexts; |
| subtexts.push_back(ASCIIToUTF16("Label that will be trimmed")); |
| subtexts.push_back(ASCIIToUTF16("Untrimmed")); |
| |
| std::vector<base::string16> icons(2, ASCIIToUTF16("genericCC")); |
| std::vector<int> autofill_ids(2, 0); |
| |
| // Show the popup once so we can easily generate the size it needs. |
| autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); |
| |
| // Ensure the popup will be too small to display all of the first row. |
| int popup_max_width = |
| autofill_popup_controller_->GetNameFontForRow(0).GetStringWidth( |
| names[0]) + |
| autofill_popup_controller_->subtext_font().GetStringWidth(subtexts[0]) - |
| 25; |
| gfx::Rect popup_bounds = gfx::Rect(0, 0, popup_max_width, 0); |
| autofill_popup_controller_->set_display(gfx::Display(0, popup_bounds)); |
| |
| autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); |
| |
| // The first element was long so it should have been trimmed. |
| EXPECT_NE(names[0], autofill_popup_controller_->names()[0]); |
| EXPECT_NE(subtexts[0], autofill_popup_controller_->subtexts()[0]); |
| |
| // The second element was shorter so it should be unchanged. |
| EXPECT_EQ(names[1], autofill_popup_controller_->names()[1]); |
| EXPECT_EQ(subtexts[1], autofill_popup_controller_->subtexts()[1]); |
| } |
| #endif |
| |
| TEST_F(AutofillPopupControllerUnitTest, GrowPopupInSpace) { |
| std::vector<base::string16> names(1); |
| std::vector<int> autofill_ids(1, 1); |
| |
| // Call Show so that GetDesired...() will be able to provide valid values. |
| autofill_popup_controller_->Show(names, names, names, autofill_ids); |
| int desired_width = autofill_popup_controller_->GetDesiredPopupWidth(); |
| int desired_height = autofill_popup_controller_->GetDesiredPopupHeight(); |
| |
| // Set up the visible screen space. |
| gfx::Display display(0, |
| gfx::Rect(0, 0, desired_width * 2, desired_height * 2)); |
| |
| // Store the possible element bounds and the popup bounds they should result |
| // in. |
| std::vector<gfx::RectF> element_bounds; |
| std::vector<gfx::Rect> expected_popup_bounds; |
| |
| // The popup grows down and to the right. |
| element_bounds.push_back(gfx::RectF(0, 0, 0, 0)); |
| expected_popup_bounds.push_back( |
| gfx::Rect(0, 0, desired_width, desired_height)); |
| |
| // The popup grows down and to the left. |
| element_bounds.push_back(gfx::RectF(2 * desired_width, 0, 0, 0)); |
| expected_popup_bounds.push_back( |
| gfx::Rect(desired_width, 0, desired_width, desired_height)); |
| |
| // The popup grows up and to the right. |
| element_bounds.push_back(gfx::RectF(0, 2 * desired_height, 0, 0)); |
| expected_popup_bounds.push_back( |
| gfx::Rect(0, desired_height, desired_width, desired_height)); |
| |
| // The popup grows up and to the left. |
| element_bounds.push_back( |
| gfx::RectF(2 * desired_width, 2 * desired_height, 0, 0)); |
| expected_popup_bounds.push_back( |
| gfx::Rect(desired_width, desired_height, desired_width, desired_height)); |
| |
| // The popup would be partial off the top and left side of the screen. |
| element_bounds.push_back( |
| gfx::RectF(-desired_width / 2, -desired_height / 2, 0, 0)); |
| expected_popup_bounds.push_back( |
| gfx::Rect(0, 0, desired_width, desired_height)); |
| |
| // The popup would be partially off the bottom and the right side of |
| // the screen. |
| element_bounds.push_back( |
| gfx::RectF(desired_width * 1.5, desired_height * 1.5, 0, 0)); |
| expected_popup_bounds.push_back( |
| gfx::Rect((desired_width + 1) / 2, (desired_height + 1) / 2, |
| desired_width, desired_height)); |
| |
| for (size_t i = 0; i < element_bounds.size(); ++i) { |
| AutofillDriverImpl* driver = |
| AutofillDriverImpl::FromWebContents(web_contents()); |
| NiceMock<MockAutofillExternalDelegate> external_delegate( |
| driver->autofill_manager(), driver); |
| TestAutofillPopupController* autofill_popup_controller = |
| new TestAutofillPopupController(external_delegate.GetWeakPtr(), |
| element_bounds[i]); |
| |
| autofill_popup_controller->set_display(display); |
| autofill_popup_controller->Show(names, names, names, autofill_ids); |
| |
| EXPECT_EQ(expected_popup_bounds[i].ToString(), |
| autofill_popup_controller->popup_bounds().ToString()) << |
| "Popup bounds failed to match for test " << i; |
| |
| // Hide the controller to delete it. |
| autofill_popup_controller->DoHide(); |
| } |
| } |
| |
| } // namespace autofill |