OLD | NEW |
---|---|
(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 "ash/system/logout_button/logout_button_observer.h" | |
bartfab (slow)
2013/12/17 13:21:03
Nit: Already included by logout_button_tray.h.
binjin
2013/12/17 14:58:08
Done.
| |
8 #include "ash/system/logout_button/logout_confirmation_dialog_view.h" | |
bartfab (slow)
2013/12/17 13:21:03
Nit: Already included by logout_button_tray.h.
binjin
2013/12/17 14:58:08
Done.
| |
9 #include "base/memory/scoped_ptr.h" | |
bartfab (slow)
2013/12/17 13:21:03
Nit: Already included by logout_button_tray.h.
binjin
2013/12/17 14:58:08
Done.
| |
10 #include "base/single_thread_task_runner.h" | |
11 #include "base/thread_task_runner_handle.h" | |
12 #include "base/time/time.h" | |
bartfab (slow)
2013/12/17 13:21:03
Nit: Already included by logout_button_tray.h.
binjin
2013/12/17 14:58:08
Done.
| |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
bartfab (slow)
2013/12/17 13:21:03
Nit: The unittest file should have includes for al
binjin
2013/12/17 14:58:08
Done.
| |
15 namespace ash { | |
16 namespace internal { | |
17 | |
18 // A SingleThreadTaskRunner that mocks the current time and allows it to be | |
19 // fast-forwarded. | |
20 class MockTimeSingleThreadTaskRunner : public base::SingleThreadTaskRunner { | |
21 public: | |
22 MockTimeSingleThreadTaskRunner(); | |
23 | |
24 // base::SingleThreadTaskRunner: | |
25 virtual bool RunsTasksOnCurrentThread() const OVERRIDE; | |
26 virtual bool PostDelayedTask(const tracked_objects::Location& from_here, | |
27 const base::Closure& task, | |
28 base::TimeDelta delay) OVERRIDE; | |
29 virtual bool PostNonNestableDelayedTask( | |
30 const tracked_objects::Location& from_here, | |
31 const base::Closure& task, | |
32 base::TimeDelta delay) OVERRIDE; | |
33 | |
34 const base::TimeTicks& GetCurrentTime() const; | |
35 | |
36 void FastForwardBy(int64 milliseconds); | |
bartfab (slow)
2013/12/17 13:21:03
Nit: I know you inherited this from my code in its
binjin
2013/12/17 14:58:08
Done.
| |
37 void FastForwardUntilNoTasksRemain(); | |
38 | |
39 private: | |
40 // Strict weak temporal ordering of tasks. | |
41 class TemporalOrder { | |
42 public: | |
43 bool operator()( | |
44 const std::pair<base::TimeTicks, base::Closure>& first_task, | |
45 const std::pair<base::TimeTicks, base::Closure>& second_task) const; | |
46 }; | |
47 | |
48 virtual ~MockTimeSingleThreadTaskRunner(); | |
49 | |
50 base::TimeTicks now_; | |
51 std::priority_queue<std::pair<base::TimeTicks, base::Closure>, | |
bartfab (slow)
2013/12/17 13:21:03
Nit 1: #include <queue>
Nit 2: #include <util>
Nit
binjin
2013/12/17 14:58:08
Done.
| |
52 std::vector<std::pair<base::TimeTicks, base::Closure> >, | |
bartfab (slow)
2013/12/17 13:21:03
Nit: #include <vector>
binjin
2013/12/17 14:58:08
Done.
| |
53 TemporalOrder> tasks_; | |
54 }; | |
55 | |
56 class MockLogoutConfirmationDelegate | |
57 : public LogoutConfirmationDialogView::Delegate { | |
58 public: | |
59 explicit MockLogoutConfirmationDelegate( | |
60 MockTimeSingleThreadTaskRunner* runner); | |
bartfab (slow)
2013/12/17 13:21:03
Why not use a scoped_refptr to ensure the |runner|
binjin
2013/12/17 14:58:08
Done.
| |
61 | |
62 // LogoutConfirmationDialogView::Delegate: | |
63 virtual void LogoutCurrentUser() OVERRIDE; | |
64 virtual base::TimeTicks GetCurrentTime() OVERRIDE const; | |
65 | |
66 bool WasLogoutCalled() const; | |
67 | |
68 private: | |
69 bool logout_called_; | |
70 | |
71 MockTimeSingleThreadTaskRunner* runner_; | |
72 | |
73 DISALLOW_COPY_AND_ASSIGN(MockLogoutConfirmationDelegate); | |
74 }; | |
75 | |
76 MockTimeSingleThreadTaskRunner::MockTimeSingleThreadTaskRunner() { | |
77 } | |
78 | |
79 bool MockTimeSingleThreadTaskRunner::RunsTasksOnCurrentThread() const { | |
80 return true; | |
81 } | |
82 | |
83 bool MockTimeSingleThreadTaskRunner::PostDelayedTask( | |
84 const tracked_objects::Location& from_here, | |
85 const base::Closure& task, | |
86 base::TimeDelta delay) { | |
87 tasks_.push(std::pair<base::TimeTicks, base::Closure>(now_ + delay, task)); | |
88 return true; | |
89 } | |
90 | |
91 bool MockTimeSingleThreadTaskRunner::PostNonNestableDelayedTask( | |
92 const tracked_objects::Location& from_here, | |
93 const base::Closure& task, | |
94 base::TimeDelta delay) { | |
95 NOTREACHED(); | |
bartfab (slow)
2013/12/17 13:21:03
Nit: #include "base/logging.h"
binjin
2013/12/17 14:58:08
Done.
| |
96 return false; | |
97 } | |
98 | |
99 const base::TimeTicks& MockTimeSingleThreadTaskRunner::GetCurrentTime() const { | |
100 return now_; | |
101 } | |
102 | |
103 void MockTimeSingleThreadTaskRunner::FastForwardBy(int64 delta) { | |
104 const base::TimeTicks latest = | |
105 now_ + base::TimeDelta::FromMilliseconds(delta); | |
106 while (!tasks_.empty() && tasks_.top().first <= latest) { | |
107 now_ = tasks_.top().first; | |
108 base::Closure task = tasks_.top().second; | |
109 tasks_.pop(); | |
110 task.Run(); | |
111 } | |
112 now_ = latest; | |
113 } | |
114 | |
115 void MockTimeSingleThreadTaskRunner::FastForwardUntilNoTasksRemain() { | |
116 while (!tasks_.empty()) { | |
117 now_ = tasks_.top().first; | |
118 base::Closure task = tasks_.top().second; | |
119 tasks_.pop(); | |
120 task.Run(); | |
121 } | |
122 } | |
123 | |
124 bool MockTimeSingleThreadTaskRunner::TemporalOrder::operator()( | |
125 const std::pair<base::TimeTicks, base::Closure>& first_task, | |
126 const std::pair<base::TimeTicks, base::Closure>& second_task) const { | |
127 return first_task.first > second_task.first; | |
128 } | |
129 | |
130 MockTimeSingleThreadTaskRunner::~MockTimeSingleThreadTaskRunner() { | |
131 } | |
132 | |
133 MockLogoutConfirmationDelegate::MockLogoutConfirmationDelegate( | |
134 MockTimeSingleThreadTaskRunner* runner) { | |
135 runner_ = runner; | |
136 logout_called_ = false; | |
137 } | |
138 | |
139 void MockLogoutConfirmationDelegate::LogoutCurrentUser() { | |
140 logout_called_ = true; | |
141 } | |
142 | |
143 base::TimeTicks MockLogoutConfirmationDelegate::GetCurrentTime() const { | |
144 return runner_->GetCurrentTime(); | |
145 } | |
146 | |
147 bool MockLogoutConfirmationDelegate::WasLogoutCalled() const { | |
148 return logout_called_; | |
149 } | |
150 | |
151 class LogoutConfirmationDialogTest : public testing::Test { | |
152 public: | |
153 LogoutConfirmationDialogTest(); | |
154 virtual ~LogoutConfirmationDialogTest(); | |
155 | |
156 // testing::Test: | |
157 virtual void SetUp() OVERRIDE; | |
158 virtual void TearDown() OVERRIDE; | |
159 | |
160 void ChangeDialogDuration(base::TimeDelta duration); | |
161 void PressButton(); | |
162 | |
163 protected: | |
164 scoped_ptr<LogoutButtonTray> logout_button_; | |
165 scoped_refptr<MockTimeSingleThreadTaskRunner> runner_; | |
bartfab (slow)
2013/12/17 13:21:03
Nit: #include "base/memory/ref_counted.h"
binjin
2013/12/17 14:58:08
Done.
| |
166 base::ThreadTaskRunnerHandle runner_handle_; | |
167 MockLogoutConfirmationDelegate* delegate_; | |
168 }; | |
169 | |
170 LogoutConfirmationDialogTest::LogoutConfirmationDialogTest() | |
171 : runner_(new MockTimeSingleThreadTaskRunner), | |
172 runner_handle_(runner_) { | |
173 } | |
174 | |
175 LogoutConfirmationDialogTest::~LogoutConfirmationDialogTest() { | |
176 } | |
177 | |
178 void LogoutConfirmationDialogTest::PressButton() { | |
179 ui::TranslatedKeyEvent faked_event(false, | |
bartfab (slow)
2013/12/17 13:21:03
Nit 1: #include "ui/events/event.h"
Nit 2: const
binjin
2013/12/17 14:58:08
Done.
| |
180 static_cast<ui::KeyboardCode>(0), 0); | |
bartfab (slow)
2013/12/17 13:21:03
Nit: #include "ui/events/keycodes/keyboard_codes.h
binjin
2013/12/17 14:58:08
Done.
| |
181 logout_button_->ButtonPressed( | |
182 reinterpret_cast<views::Button*>(logout_button_->button_), faked_event); | |
183 } | |
184 | |
185 void LogoutConfirmationDialogTest::SetUp() { | |
186 logout_button_.reset(new LogoutButtonTray(NULL)); | |
187 delegate_ = new MockLogoutConfirmationDelegate(runner_.get()); | |
188 logout_button_->SetDelegateForTest( | |
189 scoped_ptr<LogoutConfirmationDialogView::Delegate>(delegate_)); | |
190 ChangeDialogDuration(base::TimeDelta::FromSeconds(20)); | |
191 delegate_ = static_cast<MockLogoutConfirmationDelegate*>( | |
bartfab (slow)
2013/12/17 13:21:03
Why is this necessary? The |delegate_| you get bac
binjin
2013/12/17 14:58:08
Done.
| |
192 logout_button_->GetConfirmationDelegateForTest()); | |
193 } | |
194 | |
195 void LogoutConfirmationDialogTest::TearDown() { | |
bartfab (slow)
2013/12/17 13:21:03
Nit: If your TearDown() is empty, there is no need
binjin
2013/12/17 14:58:08
Done.
| |
196 } | |
197 | |
198 void LogoutConfirmationDialogTest::ChangeDialogDuration( | |
199 base::TimeDelta duration) { | |
200 logout_button_->OnLogoutDialogDurationChanged(duration); | |
201 } | |
202 | |
203 TEST_F(LogoutConfirmationDialogTest, NoClickWithDefaultValue) { | |
204 PressButton(); | |
205 | |
206 // Verify that the dialog is showing immediately after the logout button was | |
207 // pressed. | |
208 runner_->FastForwardBy(0); | |
209 EXPECT_TRUE(logout_button_->IsConfirmationDialogShowing()); | |
210 EXPECT_FALSE(delegate_->WasLogoutCalled()); | |
211 | |
212 // Verify that the dialog is still showing after 19 seconds since the logout | |
213 // button was pressed. | |
214 runner_->FastForwardBy(19 * 1000); | |
215 EXPECT_TRUE(logout_button_->IsConfirmationDialogShowing()); | |
216 EXPECT_FALSE(delegate_->WasLogoutCalled()); | |
217 | |
218 // Verify that the dialog is closed after 21 seconds since the logout button | |
219 // was pressed. | |
220 runner_->FastForwardBy(2 * 1000); | |
221 EXPECT_FALSE(logout_button_->IsConfirmationDialogShowing()); | |
222 EXPECT_TRUE(delegate_->WasLogoutCalled()); | |
223 } | |
224 | |
225 TEST_F(LogoutConfirmationDialogTest, ZeroPreferenceValue) { | |
226 ChangeDialogDuration(base::TimeDelta::FromSeconds(0)); | |
227 | |
228 EXPECT_FALSE(logout_button_->IsConfirmationDialogShowing()); | |
229 | |
230 PressButton(); | |
231 | |
232 // Verify that user was logged out immediately after the logout button was | |
233 // pressed. | |
234 runner_->FastForwardBy(0); | |
235 EXPECT_FALSE(logout_button_->IsConfirmationDialogShowing()); | |
236 EXPECT_TRUE(delegate_->WasLogoutCalled()); | |
237 | |
238 runner_->FastForwardUntilNoTasksRemain(); | |
239 EXPECT_FALSE(logout_button_->IsConfirmationDialogShowing()); | |
240 EXPECT_TRUE(delegate_->WasLogoutCalled()); | |
bartfab (slow)
2013/12/17 13:21:03
Nit: This is a no-op because WasLogoutCalled() ret
binjin
2013/12/17 14:58:08
Done.
| |
241 } | |
242 | |
243 TEST_F(LogoutConfirmationDialogTest, OnTheFlyDialogDurationChange) { | |
244 ChangeDialogDuration(base::TimeDelta::FromSeconds(5)); | |
245 | |
246 EXPECT_FALSE(logout_button_->IsConfirmationDialogShowing()); | |
247 | |
248 PressButton(); | |
249 | |
250 // Verify that the dialog is showing immediately after the logout button was | |
251 // pressed. | |
252 runner_->FastForwardBy(0); | |
253 EXPECT_TRUE(logout_button_->IsConfirmationDialogShowing()); | |
254 EXPECT_FALSE(delegate_->WasLogoutCalled()); | |
255 | |
256 // Verify that the dialog is still showing after 3 seconds since the logout | |
257 // button was pressed. | |
258 runner_->FastForwardBy(3 * 1000); | |
259 EXPECT_TRUE(logout_button_->IsConfirmationDialogShowing()); | |
260 EXPECT_FALSE(delegate_->WasLogoutCalled()); | |
261 | |
262 // And at this point we change the dialog duration preference. | |
263 ChangeDialogDuration(base::TimeDelta::FromSeconds(10)); | |
264 | |
265 // Verify that the dialog is still showing after 9 seconds since the logout | |
266 // button was pressed, with dialog duration preference changed. | |
267 runner_->FastForwardBy(6 * 1000); | |
268 EXPECT_TRUE(logout_button_->IsConfirmationDialogShowing()); | |
269 EXPECT_FALSE(delegate_->WasLogoutCalled()); | |
270 | |
271 // Verify that the dialog is closed after 11 seconds since the logout button | |
272 // was pressed. | |
273 runner_->FastForwardBy(2 * 1000); | |
274 EXPECT_FALSE(logout_button_->IsConfirmationDialogShowing()); | |
275 EXPECT_TRUE(delegate_->WasLogoutCalled()); | |
276 } | |
277 | |
278 TEST_F(LogoutConfirmationDialogTest, UserClickedButton) { | |
279 PressButton(); | |
280 | |
281 // Verify that the dialog is showing immediately after the logout button was | |
282 // pressed. | |
283 runner_->FastForwardBy(0); | |
284 EXPECT_TRUE(logout_button_->IsConfirmationDialogShowing()); | |
285 EXPECT_FALSE(delegate_->WasLogoutCalled()); | |
286 | |
287 // Verify that the dialog is still showing after 3 seconds since the logout | |
288 // button was pressed. | |
289 runner_->FastForwardBy(3 * 1000); | |
290 EXPECT_TRUE(logout_button_->IsConfirmationDialogShowing()); | |
291 EXPECT_FALSE(delegate_->WasLogoutCalled()); | |
292 | |
293 // And at this point we click the accept button. | |
294 logout_button_->GetConfirmationDialogForTest()->Accept(); | |
bartfab (slow)
2013/12/17 13:21:03
Nit: This is the only use of GetConfirmationDialog
binjin
2013/12/17 14:58:08
Done.
| |
295 | |
296 // Verify that the user was logged out immediately after the accept button | |
297 // was clicked. | |
298 runner_->FastForwardBy(0); | |
299 EXPECT_TRUE(delegate_->WasLogoutCalled()); | |
300 } | |
301 | |
302 } // namespace internal | |
303 } // namespace ash | |
OLD | NEW |