autofill_dialog_views_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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
24namespace autofill {
25
26namespace {
27
28using testing::Return;
29using web_modal::WebContentsModalDialogManager;
30
31// A views implementation of the Autofill dialog with slightly more testability.
32class 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
49class 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(content::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
112TEST_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
119TEST_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
161TEST_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
188TEST_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