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