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.
5 #include "chrome/browser/ui/views/autofill/autofill_dialog_views.h"
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/autofill/content/browser/wallet/wallet_service_url.h"
16 #include "components/web_modal/test_web_contents_modal_dialog_host.h"
17 #include "components/web_modal/test_web_contents_modal_dialog_manager_delegate.h"
18 #include "components/web_modal/web_contents_modal_dialog_manager.h"
19 #include "content/public/common/url_constants.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "ui/views/controls/webview/webview.h"
23 #include "ui/views/widget/widget.h"
29 using testing::Return
;
30 using web_modal::WebContentsModalDialogManager
;
32 // A views implementation of the Autofill dialog with slightly more testability.
33 class TestAutofillDialogViews
: public AutofillDialogViews
{
35 explicit TestAutofillDialogViews(AutofillDialogViewDelegate
* delegate
)
36 : AutofillDialogViews(delegate
) {}
37 ~TestAutofillDialogViews() override
{}
39 using AutofillDialogViews::GetLoadingShieldForTesting
;
40 using AutofillDialogViews::GetSignInWebViewForTesting
;
41 using AutofillDialogViews::GetNotificationAreaForTesting
;
42 using AutofillDialogViews::GetScrollableAreaForTesting
;
45 DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogViews
);
50 class AutofillDialogViewsTest
: public TestWithBrowserView
{
52 AutofillDialogViewsTest() {}
53 virtual ~AutofillDialogViewsTest() {}
55 // TestWithBrowserView:
56 virtual void SetUp() override
{
57 TestWithBrowserView::SetUp();
59 view_delegate_
.SetProfile(profile());
61 AddTab(browser(), GURL(url::kAboutBlankURL
));
62 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
63 content::WebContents
* contents
= tab_strip_model
->GetWebContentsAt(0);
64 ASSERT_TRUE(contents
);
65 view_delegate_
.SetWebContents(contents
);
67 BrowserView
* browser_view
=
68 BrowserView::GetBrowserViewForBrowser(browser());
69 dialog_host_
.reset(new web_modal::TestWebContentsModalDialogHost(
70 browser_view
->GetWidget()->GetNativeView()));
71 dialog_delegate_
.set_web_contents_modal_dialog_host(dialog_host_
.get());
73 WebContentsModalDialogManager
* dialog_manager
=
74 WebContentsModalDialogManager::FromWebContents(contents
);
75 ASSERT_TRUE(dialog_manager
);
76 dialog_manager
->SetDelegate(&dialog_delegate_
);
78 dialog_
.reset(new TestAutofillDialogViews(&view_delegate_
));
82 virtual void TearDown() override
{
83 dialog_
->GetWidget()->CloseNow();
86 TestWithBrowserView::TearDown();
89 MockAutofillDialogViewDelegate
* delegate() { return &view_delegate_
; }
91 TestAutofillDialogViews
* dialog() { return dialog_
.get(); }
94 void SetSectionsFocusable() {
95 dialog()->GetLoadingShieldForTesting()->SetFocusable(true);
96 // The sign in web view is not focusable until a web contents is created.
97 // TODO(dbeam): figure out how to create a web contents on the right thread.
98 dialog()->GetNotificationAreaForTesting()->SetFocusable(true);
99 dialog()->GetScrollableAreaForTesting()->SetFocusable(true);
103 // Fake dialog delegate and host to isolate test behavior.
104 web_modal::TestWebContentsModalDialogManagerDelegate dialog_delegate_
;
105 scoped_ptr
<web_modal::TestWebContentsModalDialogHost
> dialog_host_
;
107 // Mock view delegate as this file only tests the view.
108 testing::NiceMock
<MockAutofillDialogViewDelegate
> view_delegate_
;
110 scoped_ptr
<TestAutofillDialogViews
> dialog_
;
113 TEST_F(AutofillDialogViewsTest
, InitialFocus
) {
114 views::FocusManager
* focus_manager
= dialog()->GetWidget()->GetFocusManager();
115 views::View
* focused_view
= focus_manager
->GetFocusedView();
116 EXPECT_STREQ(DecoratedTextfield::kViewClassName
,
117 focused_view
->GetClassName());
120 TEST_F(AutofillDialogViewsTest
, SignInFocus
) {
121 SetSectionsFocusable();
123 views::View
* loading_shield
= dialog()->GetLoadingShieldForTesting();
124 views::View
* sign_in_web_view
= dialog()->GetSignInWebViewForTesting();
125 views::View
* notification_area
= dialog()->GetNotificationAreaForTesting();
126 views::View
* scrollable_area
= dialog()->GetScrollableAreaForTesting();
128 dialog()->ShowSignIn(wallet::GetAddAccountUrl());
130 // The sign in view should be the only showing and focusable view.
131 EXPECT_TRUE(sign_in_web_view
->IsFocusable());
132 EXPECT_FALSE(loading_shield
->IsFocusable());
133 EXPECT_FALSE(notification_area
->IsFocusable());
134 EXPECT_FALSE(scrollable_area
->IsFocusable());
136 EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(false));
137 dialog()->HideSignIn();
139 // Hide sign in while not loading Wallet items as if the user clicked "Back".
140 EXPECT_TRUE(notification_area
->IsFocusable());
141 EXPECT_TRUE(scrollable_area
->IsFocusable());
142 EXPECT_FALSE(loading_shield
->IsFocusable());
143 EXPECT_FALSE(sign_in_web_view
->IsFocusable());
145 dialog()->ShowSignIn(wallet::GetAddAccountUrl());
147 EXPECT_TRUE(sign_in_web_view
->IsFocusable());
148 EXPECT_FALSE(loading_shield
->IsFocusable());
149 EXPECT_FALSE(notification_area
->IsFocusable());
150 EXPECT_FALSE(scrollable_area
->IsFocusable());
152 EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(true));
153 dialog()->HideSignIn();
155 // Hide sign in while pretending to load Wallet data.
156 EXPECT_TRUE(loading_shield
->IsFocusable());
157 EXPECT_FALSE(notification_area
->IsFocusable());
158 EXPECT_FALSE(scrollable_area
->IsFocusable());
159 EXPECT_FALSE(sign_in_web_view
->IsFocusable());
162 TEST_F(AutofillDialogViewsTest
, LoadingFocus
) {
163 SetSectionsFocusable();
165 views::View
* loading_shield
= dialog()->GetLoadingShieldForTesting();
166 views::View
* sign_in_web_view
= dialog()->GetSignInWebViewForTesting();
167 views::View
* notification_area
= dialog()->GetNotificationAreaForTesting();
168 views::View
* scrollable_area
= dialog()->GetScrollableAreaForTesting();
170 // Pretend as if loading Wallet data.
171 EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(true));
172 dialog()->UpdateAccountChooser();
174 EXPECT_TRUE(loading_shield
->IsFocusable());
175 EXPECT_FALSE(notification_area
->IsFocusable());
176 EXPECT_FALSE(scrollable_area
->IsFocusable());
177 EXPECT_FALSE(sign_in_web_view
->IsFocusable());
179 // Pretend as if Wallet data has finished loading.
180 EXPECT_CALL(*delegate(), ShouldShowSpinner()).WillRepeatedly(Return(false));
181 dialog()->UpdateAccountChooser();
183 EXPECT_TRUE(notification_area
->IsFocusable());
184 EXPECT_TRUE(scrollable_area
->IsFocusable());
185 EXPECT_FALSE(loading_shield
->IsFocusable());
186 EXPECT_FALSE(sign_in_web_view
->IsFocusable());
189 TEST_F(AutofillDialogViewsTest
, ImeEventDoesntCrash
) {
190 // IMEs create synthetic events with no backing native event.
191 views::FocusManager
* focus_manager
= dialog()->GetWidget()->GetFocusManager();
192 views::View
* focused_view
= focus_manager
->GetFocusedView();
193 ASSERT_STREQ(DecoratedTextfield::kViewClassName
,
194 focused_view
->GetClassName());
195 EXPECT_FALSE(dialog()->HandleKeyEvent(
196 static_cast<views::Textfield
*>(focused_view
),
197 ui::KeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_A
, ui::EF_NONE
)));
200 } // namespace autofill