Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: ash/system/logout_button/logout_button_tray_unittest.cc

Issue 40053002: Implements the dialog view for logout button tray in public sessions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more fixes; make delegate pure; add ShowDialog() to delegate(); add TODO in tests Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 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 "ash/system/logout_button/logout_button_tray.h"
6
7 #include <queue>
8 #include <utility>
9 #include <vector>
10
11 #include "ash/system/status_area_widget.h"
12 #include "base/callback.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/events/event.h"
19 #include "ui/events/keycodes/keyboard_codes.h"
20 #include "ui/views/controls/button/label_button.h"
21
22 namespace ash {
23 namespace internal {
24
25 class LogoutConfirmationDialogTest;
26
27 namespace {
28
29 // A SingleThreadTaskRunner that mocks the current time and allows it to be
30 // fast-forwarded.
31 // TODO: crbug.com/329911
32 // Move shared copies of this class to one place.
33 class MockTimeSingleThreadTaskRunner : public base::SingleThreadTaskRunner {
34 public:
35 MockTimeSingleThreadTaskRunner();
36
37 // base::SingleThreadTaskRunner:
38 virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
39 virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
40 const base::Closure& task,
41 base::TimeDelta delay) OVERRIDE;
42 virtual bool PostNonNestableDelayedTask(
43 const tracked_objects::Location& from_here,
44 const base::Closure& task,
45 base::TimeDelta delay) OVERRIDE;
46
47 const base::TimeTicks& GetCurrentTime() const;
48
49 void FastForwardBy(base::TimeDelta delta);
50 void FastForwardUntilNoTasksRemain();
51
52 private:
53 // Strict weak temporal ordering of tasks.
54 class TemporalOrder {
55 public:
56 bool operator()(
57 const std::pair<base::TimeTicks, base::Closure>& first_task,
58 const std::pair<base::TimeTicks, base::Closure>& second_task) const;
59 };
60
61 virtual ~MockTimeSingleThreadTaskRunner();
62
63 base::TimeTicks now_;
64 std::priority_queue<std::pair<base::TimeTicks, base::Closure>,
65 std::vector<std::pair<base::TimeTicks, base::Closure> >,
66 TemporalOrder> tasks_;
67 };
68
69 MockTimeSingleThreadTaskRunner::MockTimeSingleThreadTaskRunner() {
70 }
71
72 bool MockTimeSingleThreadTaskRunner::RunsTasksOnCurrentThread() const {
73 return true;
74 }
75
76 bool MockTimeSingleThreadTaskRunner::PostDelayedTask(
77 const tracked_objects::Location& from_here,
78 const base::Closure& task,
79 base::TimeDelta delay) {
80 tasks_.push(std::pair<base::TimeTicks, base::Closure>(now_ + delay, task));
81 return true;
82 }
83
84 bool MockTimeSingleThreadTaskRunner::PostNonNestableDelayedTask(
85 const tracked_objects::Location& from_here,
86 const base::Closure& task,
87 base::TimeDelta delay) {
88 NOTREACHED();
89 return false;
90 }
91
92 const base::TimeTicks& MockTimeSingleThreadTaskRunner::GetCurrentTime() const {
93 return now_;
94 }
95
96 void MockTimeSingleThreadTaskRunner::FastForwardBy(base::TimeDelta delta) {
97 const base::TimeTicks latest = now_ + delta;
98 while (!tasks_.empty() && tasks_.top().first <= latest) {
99 now_ = tasks_.top().first;
100 base::Closure task = tasks_.top().second;
101 tasks_.pop();
102 task.Run();
103 }
104 now_ = latest;
105 }
106
107 void MockTimeSingleThreadTaskRunner::FastForwardUntilNoTasksRemain() {
108 while (!tasks_.empty()) {
109 now_ = tasks_.top().first;
110 base::Closure task = tasks_.top().second;
111 tasks_.pop();
112 task.Run();
113 }
114 }
115
116 bool MockTimeSingleThreadTaskRunner::TemporalOrder::operator()(
117 const std::pair<base::TimeTicks, base::Closure>& first_task,
118 const std::pair<base::TimeTicks, base::Closure>& second_task) const {
119 return first_task.first > second_task.first;
120 }
121
122 MockTimeSingleThreadTaskRunner::~MockTimeSingleThreadTaskRunner() {
123 }
124
125 } // namespace
126
127 class MockLogoutConfirmationDelegate
128 : public LogoutConfirmationDialogView::Delegate {
129 public:
130 MockLogoutConfirmationDelegate(
131 scoped_refptr<MockTimeSingleThreadTaskRunner> runner,
132 LogoutConfirmationDialogTest* tester);
133
134 // LogoutConfirmationDialogView::Delegate:
135 virtual void LogoutCurrentUser() OVERRIDE;
136 virtual base::TimeTicks GetCurrentTime() OVERRIDE const;
137 virtual void ShowDialog(views::DialogDelegate* dialog) OVERRIDE;
138
139 bool logout_called() const { return logout_called_; }
140
141 private:
142 bool logout_called_;
143
144 scoped_refptr<MockTimeSingleThreadTaskRunner> runner_;
145 LogoutConfirmationDialogTest* tester_;
146
147 DISALLOW_COPY_AND_ASSIGN(MockLogoutConfirmationDelegate);
148 };
149
150 class LogoutConfirmationDialogTest : public testing::Test {
151 public:
152 LogoutConfirmationDialogTest();
153 virtual ~LogoutConfirmationDialogTest();
154
155 // testing::Test:
156 virtual void SetUp() OVERRIDE;
157
158 void ChangeDialogDuration(base::TimeDelta duration);
159
160 void CloseDialog();
161 bool IsDialogShowing();
162 void PressButton();
163 void PressDialogButtonYes();
164
165 protected:
166 scoped_ptr<LogoutButtonTray> logout_button_;
167 scoped_refptr<MockTimeSingleThreadTaskRunner> runner_;
168 base::ThreadTaskRunnerHandle runner_handle_;
169 MockLogoutConfirmationDelegate* delegate_;
170
171 private:
172 DISALLOW_COPY_AND_ASSIGN(LogoutConfirmationDialogTest);
173 };
174
175 MockLogoutConfirmationDelegate::MockLogoutConfirmationDelegate(
176 scoped_refptr<MockTimeSingleThreadTaskRunner> runner,
177 LogoutConfirmationDialogTest* tester)
178 : logout_called_(false),
179 runner_(runner),
180 tester_(tester) {
181 }
182
183 void MockLogoutConfirmationDelegate::LogoutCurrentUser() {
184 logout_called_ = true;
185 tester_->CloseDialog();
186 }
187
188 base::TimeTicks MockLogoutConfirmationDelegate::GetCurrentTime() const {
189 return runner_->GetCurrentTime();
190 }
191
192 void MockLogoutConfirmationDelegate::ShowDialog(views::DialogDelegate* dialog) {
193 }
194
195 LogoutConfirmationDialogTest::LogoutConfirmationDialogTest()
196 : runner_(new MockTimeSingleThreadTaskRunner),
197 runner_handle_(runner_) {
198 }
199
200 LogoutConfirmationDialogTest::~LogoutConfirmationDialogTest() {
201 }
202
203 void LogoutConfirmationDialogTest::SetUp() {
204 logout_button_.reset(new LogoutButtonTray(NULL));
205 delegate_ = new MockLogoutConfirmationDelegate(runner_, this);
206 logout_button_->SetDelegateForTest(
207 scoped_ptr<LogoutConfirmationDialogView::Delegate>(delegate_));
208 ChangeDialogDuration(base::TimeDelta::FromSeconds(20));
209 }
210
211 void LogoutConfirmationDialogTest::ChangeDialogDuration(
212 base::TimeDelta duration) {
213 logout_button_->OnLogoutDialogDurationChanged(duration);
214 }
215
216 void LogoutConfirmationDialogTest::CloseDialog() {
217 if (logout_button_->confirmation_dialog_)
218 logout_button_->confirmation_dialog_->OnClosed();
219 }
220
221 bool LogoutConfirmationDialogTest::IsDialogShowing() {
222 return logout_button_->IsConfirmationDialogShowing();
223 }
224
225 void LogoutConfirmationDialogTest::PressButton() {
226 const ui::TranslatedKeyEvent faked_event(
227 false,
228 static_cast<ui::KeyboardCode>(0),
229 0);
230 logout_button_->ButtonPressed(
231 reinterpret_cast<views::Button*>(logout_button_->button_), faked_event);
232 }
233
234 void LogoutConfirmationDialogTest::PressDialogButtonYes() {
235 logout_button_->confirmation_dialog_->Accept();
236 // |confirmation_dialog_| might already be destroyed, if not, manually call
237 // OnClosed() to simulate real browser environment behavior.
238 if (logout_button_->confirmation_dialog_)
239 logout_button_->confirmation_dialog_->OnClosed();
240 }
241
242 TEST_F(LogoutConfirmationDialogTest, NoClickWithDefaultValue) {
243 PressButton();
244
245 // Verify that the dialog is showing immediately after the logout button was
246 // pressed.
247 runner_->FastForwardBy(base::TimeDelta::FromSeconds(0));
248 EXPECT_TRUE(IsDialogShowing());
249 EXPECT_FALSE(delegate_->logout_called());
250
251 // Verify that the dialog is still showing after 19 seconds since the logout
252 // button was pressed.
253 runner_->FastForwardBy(base::TimeDelta::FromSeconds(19));
254 EXPECT_TRUE(IsDialogShowing());
255 EXPECT_FALSE(delegate_->logout_called());
256
257 // Verify that the dialog is closed after 21 seconds since the logout button
258 // was pressed.
259 runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
260 EXPECT_FALSE(IsDialogShowing());
261 EXPECT_TRUE(delegate_->logout_called());
262 }
263
264 TEST_F(LogoutConfirmationDialogTest, ZeroPreferenceValue) {
265 ChangeDialogDuration(base::TimeDelta::FromSeconds(0));
266
267 EXPECT_FALSE(IsDialogShowing());
268
269 PressButton();
270
271 // Verify that user was logged out immediately after the logout button was
272 // pressed.
273 runner_->FastForwardBy(base::TimeDelta::FromSeconds(0));
274 EXPECT_FALSE(IsDialogShowing());
275 EXPECT_TRUE(delegate_->logout_called());
276
277 runner_->FastForwardUntilNoTasksRemain();
278 EXPECT_FALSE(IsDialogShowing());
279 }
280
281 TEST_F(LogoutConfirmationDialogTest, OnTheFlyDialogDurationChange) {
282 ChangeDialogDuration(base::TimeDelta::FromSeconds(5));
283
284 EXPECT_FALSE(IsDialogShowing());
285
286 PressButton();
287
288 // Verify that the dialog is showing immediately after the logout button was
289 // pressed.
290 runner_->FastForwardBy(base::TimeDelta::FromSeconds(0));
291 EXPECT_TRUE(IsDialogShowing());
292 EXPECT_FALSE(delegate_->logout_called());
293
294 // Verify that the dialog is still showing after 3 seconds since the logout
295 // button was pressed.
296 runner_->FastForwardBy(base::TimeDelta::FromSeconds(3));
297 EXPECT_TRUE(IsDialogShowing());
298 EXPECT_FALSE(delegate_->logout_called());
299
300 // And at this point we change the dialog duration preference.
301 ChangeDialogDuration(base::TimeDelta::FromSeconds(10));
302
303 // Verify that the dialog is still showing after 9 seconds since the logout
304 // button was pressed, with dialog duration preference changed.
305 runner_->FastForwardBy(base::TimeDelta::FromSeconds(6));
306 EXPECT_TRUE(IsDialogShowing());
307 EXPECT_FALSE(delegate_->logout_called());
308
309 // Verify that the dialog is closed after 11 seconds since the logout button
310 // was pressed.
311 runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
312 EXPECT_FALSE(IsDialogShowing());
313 EXPECT_TRUE(delegate_->logout_called());
314 }
315
316 TEST_F(LogoutConfirmationDialogTest, UserClickedButton) {
317 PressButton();
318
319 // Verify that the dialog is showing immediately after the logout button was
320 // pressed.
321 runner_->FastForwardBy(base::TimeDelta::FromSeconds(0));
322 EXPECT_TRUE(IsDialogShowing());
323 EXPECT_FALSE(delegate_->logout_called());
324
325 // Verify that the dialog is still showing after 3 seconds since the logout
326 // button was pressed.
327 runner_->FastForwardBy(base::TimeDelta::FromSeconds(3));
328 EXPECT_TRUE(IsDialogShowing());
329 EXPECT_FALSE(delegate_->logout_called());
330
331 // And at this point we click the accept button.
332 PressDialogButtonYes();
333
334 // Verify that the user was logged out immediately after the accept button
335 // was clicked.
336 runner_->FastForwardBy(base::TimeDelta::FromSeconds(0));
337 EXPECT_TRUE(delegate_->logout_called());
338 }
339
340 } // namespace internal
341 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698