one_click_signin_bubble_view_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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/sync/one_click_signin_bubble_view.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/memory/scoped_ptr.h"
10#include "chrome/browser/ui/sync/one_click_signin_bubble_delegate.h"
11#include "chrome/test/base/ui_test_utils.h"
12#include "ui/views/controls/button/label_button.h"
13#include "ui/views/test/views_test_base.h"
14#include "ui/views/widget/widget.h"
15
16class OneClickSigninBubbleViewTest : public views::ViewsTestBase {
17 public:
18  OneClickSigninBubbleViewTest()
19      : on_start_sync_called_(false),
20        mode_(OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST),
21        bubble_learn_more_click_count_(0),
22        dialog_learn_more_click_count_(0),
23        advanced_click_count_(0),
24        anchor_widget_(NULL) {
25  }
26
27  virtual void SetUp() OVERRIDE {
28    views::ViewsTestBase::SetUp();
29
30    // Create a widget to host the anchor view.
31    anchor_widget_ = new views::Widget;
32    views::Widget::InitParams widget_params = CreateParams(
33        views::Widget::InitParams::TYPE_WINDOW);
34    anchor_widget_->Init(widget_params);
35    anchor_widget_->Show();
36  }
37
38  virtual void TearDown() OVERRIDE {
39    OneClickSigninBubbleView::Hide();
40    anchor_widget_->Close();
41    anchor_widget_ = NULL;
42    views::ViewsTestBase::TearDown();
43  }
44
45 protected:
46  OneClickSigninBubbleView* ShowOneClickSigninBubble(
47    BrowserWindow::OneClickSigninBubbleType bubble_type) {
48
49    scoped_ptr<OneClickSigninBubbleDelegate> delegate;
50    delegate.reset(new OneClickSigninBubbleTestDelegate(this));
51
52    OneClickSigninBubbleView::ShowBubble(
53        bubble_type,
54        base::string16(),
55        base::string16(),
56        delegate.Pass(),
57        anchor_widget_->GetContentsView(),
58        base::Bind(&OneClickSigninBubbleViewTest::OnStartSync,
59                   base::Unretained(this)));
60
61    OneClickSigninBubbleView* view =
62        OneClickSigninBubbleView::view_for_testing();
63    EXPECT_TRUE(view != NULL);
64    return view;
65  }
66
67  void OnStartSync(OneClickSigninSyncStarter::StartSyncMode mode) {
68    on_start_sync_called_ = true;
69    mode_ = mode;
70  }
71
72  bool on_start_sync_called_;
73  OneClickSigninSyncStarter::StartSyncMode mode_;
74  int bubble_learn_more_click_count_;
75  int dialog_learn_more_click_count_;
76  int advanced_click_count_;
77
78 private:
79  friend class OneClickSigninBubbleTestDelegate;
80
81  class OneClickSigninBubbleTestDelegate
82      : public OneClickSigninBubbleDelegate {
83   public:
84    // |test| is not owned by this object.
85    explicit OneClickSigninBubbleTestDelegate(
86        OneClickSigninBubbleViewTest* test) : test_(test) {}
87
88    // OneClickSigninBubbleDelegate:
89    virtual void OnLearnMoreLinkClicked(bool is_dialog) OVERRIDE {
90      if (is_dialog)
91        ++test_->dialog_learn_more_click_count_;
92      else
93        ++test_->bubble_learn_more_click_count_;
94    }
95    virtual void OnAdvancedLinkClicked() OVERRIDE {
96      ++test_->advanced_click_count_;
97    }
98
99   private:
100    OneClickSigninBubbleViewTest* test_;
101
102    DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleTestDelegate);
103  };
104
105  // Widget to host the anchor view of the bubble. Destroys itself when closed.
106  views::Widget* anchor_widget_;
107
108  DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleViewTest);
109};
110
111TEST_F(OneClickSigninBubbleViewTest, ShowBubble) {
112  ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
113  content::RunAllPendingInMessageLoop();
114  EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
115}
116
117TEST_F(OneClickSigninBubbleViewTest, ShowDialog) {
118  ShowOneClickSigninBubble(
119    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
120  content::RunAllPendingInMessageLoop();
121  EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
122}
123
124TEST_F(OneClickSigninBubbleViewTest, HideBubble) {
125  ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
126
127  OneClickSigninBubbleView::Hide();
128  content::RunAllPendingInMessageLoop();
129  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
130}
131
132TEST_F(OneClickSigninBubbleViewTest, HideDialog) {
133  ShowOneClickSigninBubble(
134    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
135
136  OneClickSigninBubbleView::Hide();
137  content::RunAllPendingInMessageLoop();
138  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
139  EXPECT_TRUE(on_start_sync_called_);
140  EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC, mode_);
141}
142
143TEST_F(OneClickSigninBubbleViewTest, BubbleOkButton) {
144  OneClickSigninBubbleView* view =
145    ShowOneClickSigninBubble(
146      BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
147
148  // Simulate pressing the OK button.  Set the message loop in the bubble
149  // view so that it can be quit once the bubble is hidden.
150  views::ButtonListener* listener = view;
151  const ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
152                             gfx::Point(), gfx::Point(),
153                             0, 0);
154  listener->ButtonPressed(view->ok_button_, event);
155
156  // View should no longer be showing.  The message loop will exit once the
157  // fade animation of the bubble is done.
158  content::RunAllPendingInMessageLoop();
159  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
160}
161
162TEST_F(OneClickSigninBubbleViewTest, DialogOkButton) {
163  OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
164      BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
165
166  // Simulate pressing the OK button.  Set the message loop in the bubble
167  // view so that it can be quit once the bubble is hidden.
168  views::ButtonListener* listener = view;
169  const ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
170                             gfx::Point(), gfx::Point(),
171                             0, 0);
172  listener->ButtonPressed(view->ok_button_, event);
173
174  // View should no longer be showing and sync should start
175  // The message loop will exit once the fade animation of the dialog is done.
176  content::RunAllPendingInMessageLoop();
177  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
178  EXPECT_TRUE(on_start_sync_called_);
179  EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, mode_);
180}
181
182TEST_F(OneClickSigninBubbleViewTest, DialogUndoButton) {
183  OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
184    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
185
186  // Simulate pressing the undo button.  Set the message loop in the bubble
187  // view so that it can be quit once the bubble is hidden.
188  views::ButtonListener* listener = view;
189  const ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
190                             gfx::Point(), gfx::Point(),
191                             0, 0);
192  listener->ButtonPressed(view->undo_button_, event);
193
194  // View should no longer be showing.  The message loop will exit once the
195  // fade animation of the bubble is done.
196  content::RunAllPendingInMessageLoop();
197  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
198  EXPECT_TRUE(on_start_sync_called_);
199  EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC, mode_);
200}
201
202TEST_F(OneClickSigninBubbleViewTest, BubbleAdvancedLink) {
203  OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
204    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
205
206  // Simulate pressing a link in the bubble.
207  views::LinkListener* listener = view;
208  listener->LinkClicked(view->advanced_link_, 0);
209
210  // View should no longer be showing and the OnAdvancedLinkClicked method
211  // of the delegate should have been called.
212  content::RunAllPendingInMessageLoop();
213  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
214  EXPECT_EQ(1, advanced_click_count_);
215}
216
217TEST_F(OneClickSigninBubbleViewTest, DialogAdvancedLink) {
218  OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
219    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
220
221  // Simulate pressing a link in the bubble.
222  views::LinkListener* listener = view;
223  listener->LinkClicked(view->advanced_link_, 0);
224
225  // View should no longer be showing. No delegate method should have been
226  // called: the callback is responsible to open the settings page.
227  content::RunAllPendingInMessageLoop();
228  EXPECT_TRUE(on_start_sync_called_);
229  EXPECT_EQ(OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST, mode_);
230  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
231  EXPECT_EQ(0, advanced_click_count_);
232}
233
234TEST_F(OneClickSigninBubbleViewTest, BubbleLearnMoreLink) {
235  OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
236    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
237
238  views::LinkListener* listener = view;
239  listener->LinkClicked(view->learn_more_link_, 0);
240
241  // View should no longer be showing and the OnLearnMoreLinkClicked method
242  // of the delegate should have been called with |is_dialog| == false.
243  content::RunAllPendingInMessageLoop();
244  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
245  EXPECT_EQ(1, bubble_learn_more_click_count_);
246  EXPECT_EQ(0, dialog_learn_more_click_count_);
247}
248
249TEST_F(OneClickSigninBubbleViewTest, DialogLearnMoreLink) {
250  OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
251      BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
252
253  views::LinkListener* listener = view;
254  listener->LinkClicked(view->learn_more_link_, 0);
255
256  // View should still be showing and the OnLearnMoreLinkClicked method
257  // of the delegate should have been called with |is_dialog| == true.
258  content::RunAllPendingInMessageLoop();
259  EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
260  EXPECT_EQ(0, bubble_learn_more_click_count_);
261  EXPECT_EQ(1, dialog_learn_more_click_count_);
262}
263
264TEST_F(OneClickSigninBubbleViewTest, BubblePressEnterKey) {
265  OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
266    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
267
268  // Simulate pressing the Enter key.
269  views::View* view = one_click_view;
270  const ui::Accelerator accelerator(ui::VKEY_RETURN, 0);
271  view->AcceleratorPressed(accelerator);
272
273  // View should no longer be showing.  The message loop will exit once the
274  // fade animation of the bubble is done.
275  content::RunAllPendingInMessageLoop();
276  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
277}
278
279TEST_F(OneClickSigninBubbleViewTest, DialogPressEnterKey) {
280  OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
281    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
282
283  // Simulate pressing the Enter key.
284  views::View* view = one_click_view;
285  const ui::Accelerator accelerator(ui::VKEY_RETURN, 0);
286  view->AcceleratorPressed(accelerator);
287
288  // View should no longer be showing.  The message loop will exit once the
289  // fade animation of the bubble is done.
290  content::RunAllPendingInMessageLoop();
291  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
292  EXPECT_TRUE(on_start_sync_called_);
293  EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, mode_);
294}
295
296TEST_F(OneClickSigninBubbleViewTest, BubblePressEscapeKey) {
297  OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
298    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
299
300  // Simulate pressing the Escape key.
301  views::View* view = one_click_view;
302  const ui::Accelerator accelerator(ui::VKEY_ESCAPE, 0);
303  view->AcceleratorPressed(accelerator);
304
305  // View should no longer be showing.  The message loop will exit once the
306  // fade animation of the bubble is done.
307  content::RunAllPendingInMessageLoop();
308  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
309}
310
311TEST_F(OneClickSigninBubbleViewTest, DialogPressEscapeKey) {
312  OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
313    BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
314
315  // Simulate pressing the Escape key.
316  views::View* view = one_click_view;
317  const ui::Accelerator accelerator(ui::VKEY_ESCAPE, 0);
318  view->AcceleratorPressed(accelerator);
319
320  // View should no longer be showing.  The message loop will exit once the
321  // fade animation of the bubble is done.
322  content::RunAllPendingInMessageLoop();
323  EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
324  EXPECT_TRUE(on_start_sync_called_);
325  EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC, mode_);
326}
327