- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / autofill / autofill_popup_controller_unittest.cc
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
26 using ::testing::_;
27 using ::testing::AtLeast;
28 using ::testing::NiceMock;
29 using base::WeakPtr;
30 using WebKit::WebAutofillClient;
31
32 namespace autofill {
33 namespace {
34
35 class 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
53 class 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
67 class 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
122 class 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
174 TEST_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
186 TEST_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
209 TEST_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
231 TEST_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
267 TEST_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
287 TEST_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
307 TEST_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
343 TEST_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
398 TEST_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
428 TEST_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
481 TEST_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)
501 TEST_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
537 TEST_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