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
);
68 void OnStartSync(OneClickSigninSyncStarter::StartSyncMode mode
) {
69 on_start_sync_called_
= true;
73 bool on_start_sync_called_
;
74 OneClickSigninSyncStarter::StartSyncMode mode_
;
75 int bubble_learn_more_click_count_
;
76 int dialog_learn_more_click_count_
;
77 int advanced_click_count_
;
80 friend class OneClickSigninBubbleTestDelegate
;
82 class OneClickSigninBubbleTestDelegate
83 : public OneClickSigninBubbleDelegate
{
85 // |test| is not owned by this object.
86 explicit OneClickSigninBubbleTestDelegate(
87 OneClickSigninBubbleViewTest
* test
) : test_(test
) {}
89 // OneClickSigninBubbleDelegate:
90 virtual void OnLearnMoreLinkClicked(bool is_dialog
) OVERRIDE
{
92 ++test_
->dialog_learn_more_click_count_
;
94 ++test_
->bubble_learn_more_click_count_
;
96 virtual void OnAdvancedLinkClicked() OVERRIDE
{
97 ++test_
->advanced_click_count_
;
101 OneClickSigninBubbleViewTest
* test_
;
103 DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleTestDelegate
);
106 // Widget to host the anchor view of the bubble. Destroys itself when closed.
107 views::Widget
* anchor_widget_
;
109 DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleViewTest
);
112 TEST_F(OneClickSigninBubbleViewTest
, ShowBubble
) {
113 ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
114 content::RunAllPendingInMessageLoop();
115 EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
118 TEST_F(OneClickSigninBubbleViewTest
, ShowDialog
) {
119 ShowOneClickSigninBubble(
120 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
121 content::RunAllPendingInMessageLoop();
122 EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
125 TEST_F(OneClickSigninBubbleViewTest
, HideBubble
) {
126 ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
128 OneClickSigninBubbleView::Hide();
129 content::RunAllPendingInMessageLoop();
130 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
133 TEST_F(OneClickSigninBubbleViewTest
, HideDialog
) {
134 ShowOneClickSigninBubble(
135 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
137 OneClickSigninBubbleView::Hide();
138 content::RunAllPendingInMessageLoop();
139 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
140 EXPECT_TRUE(on_start_sync_called_
);
141 EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC
, mode_
);
144 TEST_F(OneClickSigninBubbleViewTest
, BubbleOkButton
) {
145 OneClickSigninBubbleView
* view
=
146 ShowOneClickSigninBubble(
147 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
149 // Simulate pressing the OK button. Set the message loop in the bubble
150 // view so that it can be quit once the bubble is hidden.
151 views::ButtonListener
* listener
= view
;
152 const ui::MouseEvent
event(ui::ET_MOUSE_PRESSED
,
153 gfx::Point(), gfx::Point(),
155 listener
->ButtonPressed(view
->ok_button_
, event
);
157 // View should no longer be showing. The message loop will exit once the
158 // fade animation of the bubble is done.
159 content::RunAllPendingInMessageLoop();
160 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
163 TEST_F(OneClickSigninBubbleViewTest
, DialogOkButton
) {
164 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
165 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
167 // Simulate pressing the OK button. Set the message loop in the bubble
168 // view so that it can be quit once the bubble is hidden.
169 views::ButtonListener
* listener
= view
;
170 const ui::MouseEvent
event(ui::ET_MOUSE_PRESSED
,
171 gfx::Point(), gfx::Point(),
173 listener
->ButtonPressed(view
->ok_button_
, event
);
175 // View should no longer be showing and sync should start
176 // The message loop will exit once the fade animation of the dialog is done.
177 content::RunAllPendingInMessageLoop();
178 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
179 EXPECT_TRUE(on_start_sync_called_
);
180 EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS
, mode_
);
183 TEST_F(OneClickSigninBubbleViewTest
, DialogUndoButton
) {
184 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
185 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
187 // Simulate pressing the undo button. Set the message loop in the bubble
188 // view so that it can be quit once the bubble is hidden.
189 views::ButtonListener
* listener
= view
;
190 const ui::MouseEvent
event(ui::ET_MOUSE_PRESSED
,
191 gfx::Point(), gfx::Point(),
193 listener
->ButtonPressed(view
->undo_button_
, event
);
195 // View should no longer be showing. The message loop will exit once the
196 // fade animation of the bubble is done.
197 content::RunAllPendingInMessageLoop();
198 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
199 EXPECT_TRUE(on_start_sync_called_
);
200 EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC
, mode_
);
203 TEST_F(OneClickSigninBubbleViewTest
, BubbleAdvancedLink
) {
204 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
205 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
207 // Simulate pressing a link in the bubble.
208 views::LinkListener
* listener
= view
;
209 listener
->LinkClicked(view
->advanced_link_
, 0);
211 // View should no longer be showing and the OnAdvancedLinkClicked method
212 // of the delegate should have been called.
213 content::RunAllPendingInMessageLoop();
214 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
215 EXPECT_EQ(1, advanced_click_count_
);
218 TEST_F(OneClickSigninBubbleViewTest
, DialogAdvancedLink
) {
219 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
220 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
222 // Simulate pressing a link in the bubble.
223 views::LinkListener
* listener
= view
;
224 listener
->LinkClicked(view
->advanced_link_
, 0);
226 // View should no longer be showing. No delegate method should have been
227 // called: the callback is responsible to open the settings page.
228 content::RunAllPendingInMessageLoop();
229 EXPECT_TRUE(on_start_sync_called_
);
230 EXPECT_EQ(OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST
, mode_
);
231 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
232 EXPECT_EQ(0, advanced_click_count_
);
235 TEST_F(OneClickSigninBubbleViewTest
, BubbleLearnMoreLink
) {
236 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
237 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
239 views::LinkListener
* listener
= view
;
240 listener
->LinkClicked(view
->learn_more_link_
, 0);
242 // View should no longer be showing and the OnLearnMoreLinkClicked method
243 // of the delegate should have been called with |is_dialog| == false.
244 content::RunAllPendingInMessageLoop();
245 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
246 EXPECT_EQ(1, bubble_learn_more_click_count_
);
247 EXPECT_EQ(0, dialog_learn_more_click_count_
);
250 TEST_F(OneClickSigninBubbleViewTest
, DialogLearnMoreLink
) {
251 OneClickSigninBubbleView
* view
= ShowOneClickSigninBubble(
252 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
254 views::LinkListener
* listener
= view
;
255 listener
->LinkClicked(view
->learn_more_link_
, 0);
257 // View should still be showing and the OnLearnMoreLinkClicked method
258 // of the delegate should have been called with |is_dialog| == true.
259 content::RunAllPendingInMessageLoop();
260 EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
261 EXPECT_EQ(0, bubble_learn_more_click_count_
);
262 EXPECT_EQ(1, dialog_learn_more_click_count_
);
265 TEST_F(OneClickSigninBubbleViewTest
, BubblePressEnterKey
) {
266 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
267 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
269 // Simulate pressing the Enter key.
270 views::View
* view
= one_click_view
;
271 const ui::Accelerator
accelerator(ui::VKEY_RETURN
, 0);
272 view
->AcceleratorPressed(accelerator
);
274 // View should no longer be showing. The message loop will exit once the
275 // fade animation of the bubble is done.
276 content::RunAllPendingInMessageLoop();
277 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
280 TEST_F(OneClickSigninBubbleViewTest
, DialogPressEnterKey
) {
281 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
282 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
284 // Simulate pressing the Enter key.
285 views::View
* view
= one_click_view
;
286 const ui::Accelerator
accelerator(ui::VKEY_RETURN
, 0);
287 view
->AcceleratorPressed(accelerator
);
289 // View should no longer be showing. The message loop will exit once the
290 // fade animation of the bubble is done.
291 content::RunAllPendingInMessageLoop();
292 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
293 EXPECT_TRUE(on_start_sync_called_
);
294 EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS
, mode_
);
297 TEST_F(OneClickSigninBubbleViewTest
, BubblePressEscapeKey
) {
298 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
299 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE
);
301 // Simulate pressing the Escape key.
302 views::View
* view
= one_click_view
;
303 const ui::Accelerator
accelerator(ui::VKEY_ESCAPE
, 0);
304 view
->AcceleratorPressed(accelerator
);
306 // View should no longer be showing. The message loop will exit once the
307 // fade animation of the bubble is done.
308 content::RunAllPendingInMessageLoop();
309 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
312 TEST_F(OneClickSigninBubbleViewTest
, DialogPressEscapeKey
) {
313 OneClickSigninBubbleView
* one_click_view
= ShowOneClickSigninBubble(
314 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG
);
316 // Simulate pressing the Escape key.
317 views::View
* view
= one_click_view
;
318 const ui::Accelerator
accelerator(ui::VKEY_ESCAPE
, 0);
319 view
->AcceleratorPressed(accelerator
);
321 // View should no longer be showing. The message loop will exit once the
322 // fade animation of the bubble is done.
323 content::RunAllPendingInMessageLoop();
324 EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
325 EXPECT_TRUE(on_start_sync_called_
);
326 EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC
, mode_
);