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/sync/one_click_signin_bubble_view.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"
17 class OneClickSigninBubbleViewTest
: public views::ViewsTestBase
{
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
) {
28 virtual void SetUp() OVERRIDE
{
29 views::ViewsTestBase::SetUp();
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();
39 virtual void TearDown() OVERRIDE
{
40 OneClickSigninBubbleView::Hide();
41 anchor_widget_
->Close();
42 anchor_widget_
= NULL
;
43 views::ViewsTestBase::TearDown();
47 OneClickSigninBubbleView
* ShowOneClickSigninBubble(
48 BrowserWindow::OneClickSigninBubbleType bubble_type
) {
50 scoped_ptr
<OneClickSigninBubbleDelegate
> delegate
;
51 delegate
.reset(new OneClickSigninBubbleTestDelegate(this));
53 OneClickSigninBubbleView::ShowBubble(
58 anchor_widget_
->GetContentsView(),
59 base::Bind(&OneClickSigninBubbleViewTest::OnStartSync
,
60 base::Unretained(this)));
62 OneClickSigninBubbleView
* view
=
63 OneClickSigninBubbleView::view_for_testing();
64 EXPECT_TRUE(view
!= NULL
);
65 view
->message_loop_for_testing_
= base::MessageLoop::current();
69 void OnStartSync(OneClickSigninSyncStarter::StartSyncMode mode
) {
70 on_start_sync_called_
= true;
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_
;
81 friend class OneClickSigninBubbleTestDelegate
;
83 class OneClickSigninBubbleTestDelegate
84 : public OneClickSigninBubbleDelegate
{
86 // |test| is not owned by this object.
87 explicit OneClickSigninBubbleTestDelegate(
88 OneClickSigninBubbleViewTest
* test
) : test_(test
) {}
90 // OneClickSigninBubbleDelegate:
91 virtual void OnLearnMoreLinkClicked(bool is_dialog
) OVERRIDE
{
93 ++test_
->dialog_learn_more_click_count_
;
95 ++test_
->bubble_learn_more_click_count_
;
97 virtual void OnAdvancedLinkClicked() OVERRIDE
{
98 ++test_
->advanced_click_count_
;
102 OneClickSigninBubbleViewTest
* test_
;
104 DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleTestDelegate
);
107 // Widget to host the anchor view of the bubble. Destroys itself when closed.
108 views::Widget
* anchor_widget_
;
110 DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleViewTest
);
113 TEST_F(OneClickSigninBubbleViewTest
, ShowBubble
) {
114 ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
115 content::RunAllPendingInMessageLoop();
116 EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
119 TEST_F(OneClickSigninBubbleViewTest
, ShowDialog
) {
120 ShowOneClickSigninBubble(
121 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
122 content::RunAllPendingInMessageLoop();
123 EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
126 TEST_F(OneClickSigninBubbleViewTest
, HideBubble
) {
127 ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
129 OneClickSigninBubbleView::Hide();
130 content::RunAllPendingInMessageLoop();
131 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
134 TEST_F(OneClickSigninBubbleViewTest
, HideDialog
) {
135 ShowOneClickSigninBubble(
136 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
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_
);
145 TEST_F(OneClickSigninBubbleViewTest
, BubbleOkButton
) {
146 OneClickSigninBubbleView
* view
=
147 ShowOneClickSigninBubble(
148 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
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(),
156 listener
->ButtonPressed(view
->ok_button_
, event
);
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());
164 TEST_F(OneClickSigninBubbleViewTest
, DialogOkButton
) {
165 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
166 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
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(),
174 listener
->ButtonPressed(view
->ok_button_
, event
);
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_
);
184 TEST_F(OneClickSigninBubbleViewTest
, DialogUndoButton
) {
185 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
186 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
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(),
194 listener
->ButtonPressed(view
->undo_button_
, event
);
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_
);
204 TEST_F(OneClickSigninBubbleViewTest
, BubbleAdvancedLink
) {
205 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
206 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
208 // Simulate pressing a link in the bubble.
209 views::LinkListener
* listener
= view
;
210 listener
->LinkClicked(view
->advanced_link_
, 0);
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_
);
219 TEST_F(OneClickSigninBubbleViewTest
, DialogAdvancedLink
) {
220 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
221 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
223 // Simulate pressing a link in the bubble.
224 views::LinkListener
* listener
= view
;
225 listener
->LinkClicked(view
->advanced_link_
, 0);
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_
);
236 TEST_F(OneClickSigninBubbleViewTest
, BubbleLearnMoreLink
) {
237 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
238 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
240 views::LinkListener
* listener
= view
;
241 listener
->LinkClicked(view
->learn_more_link_
, 0);
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_
);
251 TEST_F(OneClickSigninBubbleViewTest
, DialogLearnMoreLink
) {
252 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
253 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
255 views::LinkListener
* listener
= view
;
256 listener
->LinkClicked(view
->learn_more_link_
, 0);
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_
);
266 TEST_F(OneClickSigninBubbleViewTest
, BubblePressEnterKey
) {
267 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
268 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
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
);
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());
281 TEST_F(OneClickSigninBubbleViewTest
, DialogPressEnterKey
) {
282 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
283 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
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
);
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_
);
298 TEST_F(OneClickSigninBubbleViewTest
, BubblePressEscapeKey
) {
299 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
300 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
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
);
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());
313 TEST_F(OneClickSigninBubbleViewTest
, DialogPressEscapeKey
) {
314 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
315 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
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
);
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_
);