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