Home | History | Annotate | Download | only in autofill
      1 // Copyright 2013 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 "chrome/browser/ui/views/autofill/autofill_dialog_views.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/compiler_specific.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h"
     11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     12 #include "chrome/browser/ui/views/autofill/decorated_textfield.h"
     13 #include "chrome/browser/ui/views/frame/browser_view.h"
     14 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
     15 #include "components/web_modal/test_web_contents_modal_dialog_host.h"
     16 #include "components/web_modal/test_web_contents_modal_dialog_manager_delegate.h"
     17 #include "components/web_modal/web_contents_modal_dialog_manager.h"
     18 #include "content/public/common/url_constants.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "ui/views/controls/webview/webview.h"
     22 #include "ui/views/widget/widget.h"
     23 
     24 namespace autofill {
     25 
     26 namespace {
     27 
     28 using testing::Return;
     29 using web_modal::WebContentsModalDialogManager;
     30 
     31 // A views implementation of the Autofill dialog with slightly more testability.
     32 class TestAutofillDialogViews : public AutofillDialogViews {
     33  public:
     34   explicit TestAutofillDialogViews(AutofillDialogViewDelegate* delegate)
     35       : AutofillDialogViews(delegate) {}
     36   virtual ~TestAutofillDialogViews() {}
     37 
     38   using AutofillDialogViews::GetLoadingShieldForTesting;
     39   using AutofillDialogViews::GetSignInWebViewForTesting;
     40   using AutofillDialogViews::GetNotificationAreaForTesting;
     41   using AutofillDialogViews::GetScrollableAreaForTesting;
     42 
     43  private:
     44   DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogViews);
     45 };
     46 
     47 }  // namespace
     48 
     49 class AutofillDialogViewsTest : public TestWithBrowserView {
     50  public:
     51   AutofillDialogViewsTest() {}
     52   virtual ~AutofillDialogViewsTest() {}
     53 
     54   // TestWithBrowserView:
     55   virtual void SetUp() OVERRIDE {
     56     TestWithBrowserView::SetUp();
     57 
     58     view_delegate_.SetProfile(profile());
     59 
     60     AddTab(browser(), GURL(url::kAboutBlankURL));
     61     TabStripModel* tab_strip_model = browser()->tab_strip_model();
     62     content::WebContents* contents = tab_strip_model->GetWebContentsAt(0);
     63     ASSERT_TRUE(contents);
     64     view_delegate_.SetWebContents(contents);
     65 
     66     BrowserView* browser_view =
     67         BrowserView::GetBrowserViewForBrowser(browser());
     68     dialog_host_.reset(new web_modal::TestWebContentsModalDialogHost(
     69         browser_view->GetWidget()->GetNativeView()));
     70     dialog_delegate_.set_web_contents_modal_dialog_host(dialog_host_.get());
     71 
     72     WebContentsModalDialogManager* dialog_manager =
     73         WebContentsModalDialogManager::FromWebContents(contents);
     74     ASSERT_TRUE(dialog_manager);
     75     dialog_manager->SetDelegate(&dialog_delegate_);
     76 
     77     dialog_.reset(new TestAutofillDialogViews(&view_delegate_));
     78     dialog_->Show();
     79   }
     80 
     81   virtual void TearDown() OVERRIDE {
     82     dialog_->GetWidget()->CloseNow();
     83     dialog_.reset();
     84 
     85     TestWithBrowserView::TearDown();
     86   }
     87 
     88   MockAutofillDialogViewDelegate* delegate() { return &view_delegate_; }
     89 
     90   TestAutofillDialogViews* dialog() { return dialog_.get(); }
     91 
     92  protected:
     93   void SetSectionsFocusable() {
     94     dialog()->GetLoadingShieldForTesting()->SetFocusable(true);
     95     // The sign in web view is not focusable until a web contents is created.
     96     // TODO(dbeam): figure out how to create a web contents on the right thread.
     97     dialog()->GetNotificationAreaForTesting()->SetFocusable(true);
     98     dialog()->GetScrollableAreaForTesting()->SetFocusable(true);
     99   }
    100 
    101  private:
    102   // Fake dialog delegate and host to isolate test behavior.
    103   web_modal::TestWebContentsModalDialogManagerDelegate dialog_delegate_;
    104   scoped_ptr<web_modal::TestWebContentsModalDialogHost> dialog_host_;
    105 
    106   // Mock view delegate as this file only tests the view.
    107   testing::NiceMock<MockAutofillDialogViewDelegate> view_delegate_;
    108 
    109   scoped_ptr<TestAutofillDialogViews> dialog_;
    110 };
    111 
    112 TEST_F(AutofillDialogViewsTest, InitialFocus) {
    113   views::FocusManager* focus_manager = dialog()->GetWidget()->GetFocusManager();
    114   views::View* focused_view = focus_manager->GetFocusedView();
    115   EXPECT_STREQ(DecoratedTextfield::kViewClassName,
    116                focused_view->GetClassName());
    117 }
    118 
    119 TEST_F(AutofillDialogViewsTest, SignInFocus) {
    120   SetSectionsFocusable();
    121 
    122   views::View* loading_shield = dialog()->GetLoadingShieldForTesting();
    123   views::View* sign_in_web_view = dialog()->GetSignInWebViewForTesting();
    124   views::View* notification_area = dialog()->GetNotificationAreaForTesting();
    125   views::View* scrollable_area = dialog()->GetScrollableAreaForTesting();
    126 
    127   dialog()->ShowSignIn();
    128 
    129   // The sign in view should be the only showing and focusable view.
    130   EXPECT_TRUE(sign_in_web_view->IsFocusable());
    131   EXPECT_FALSE(loading_shield->IsFocusable());
    132   EXPECT_FALSE(notification_area->IsFocusable());
    133   EXPECT_FALSE(scrollable_area->IsFocusable());
    134 
    135   EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(false));
    136   dialog()->HideSignIn();
    137 
    138   // Hide sign in while not loading Wallet items as if the user clicked "Back".
    139   EXPECT_TRUE(notification_area->IsFocusable());
    140   EXPECT_TRUE(scrollable_area->IsFocusable());
    141   EXPECT_FALSE(loading_shield->IsFocusable());
    142   EXPECT_FALSE(sign_in_web_view->IsFocusable());
    143 
    144   dialog()->ShowSignIn();
    145 
    146   EXPECT_TRUE(sign_in_web_view->IsFocusable());
    147   EXPECT_FALSE(loading_shield->IsFocusable());
    148   EXPECT_FALSE(notification_area->IsFocusable());
    149   EXPECT_FALSE(scrollable_area->IsFocusable());
    150 
    151   EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(true));
    152   dialog()->HideSignIn();
    153 
    154   // Hide sign in while pretending to load Wallet data.
    155   EXPECT_TRUE(loading_shield->IsFocusable());
    156   EXPECT_FALSE(notification_area->IsFocusable());
    157   EXPECT_FALSE(scrollable_area->IsFocusable());
    158   EXPECT_FALSE(sign_in_web_view->IsFocusable());
    159 }
    160 
    161 TEST_F(AutofillDialogViewsTest, LoadingFocus) {
    162   SetSectionsFocusable();
    163 
    164   views::View* loading_shield = dialog()->GetLoadingShieldForTesting();
    165   views::View* sign_in_web_view = dialog()->GetSignInWebViewForTesting();
    166   views::View* notification_area = dialog()->GetNotificationAreaForTesting();
    167   views::View* scrollable_area = dialog()->GetScrollableAreaForTesting();
    168 
    169   // Pretend as if loading Wallet data.
    170   EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(true));
    171   dialog()->UpdateAccountChooser();
    172 
    173   EXPECT_TRUE(loading_shield->IsFocusable());
    174   EXPECT_FALSE(notification_area->IsFocusable());
    175   EXPECT_FALSE(scrollable_area->IsFocusable());
    176   EXPECT_FALSE(sign_in_web_view->IsFocusable());
    177 
    178   // Pretend as if Wallet data has finished loading.
    179   EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(false));
    180   dialog()->UpdateAccountChooser();
    181 
    182   EXPECT_TRUE(notification_area->IsFocusable());
    183   EXPECT_TRUE(scrollable_area->IsFocusable());
    184   EXPECT_FALSE(loading_shield->IsFocusable());
    185   EXPECT_FALSE(sign_in_web_view->IsFocusable());
    186 }
    187 
    188 TEST_F(AutofillDialogViewsTest, ImeEventDoesntCrash) {
    189   // IMEs create synthetic events with no backing native event.
    190   views::FocusManager* focus_manager = dialog()->GetWidget()->GetFocusManager();
    191   views::View* focused_view = focus_manager->GetFocusedView();
    192   ASSERT_STREQ(DecoratedTextfield::kViewClassName,
    193                focused_view->GetClassName());
    194   EXPECT_FALSE(dialog()->HandleKeyEvent(
    195       static_cast<views::Textfield*>(focused_view),
    196       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0, false)));
    197 }
    198 
    199 }  // namespace autofill
    200