Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / ash / system / chromeos / session / logout_confirmation_controller_unittest.cc
1 // Copyright 2014 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/chromeos/session/logout_confirmation_controller.h"
6
7 #include <queue>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/compiler_specific.h"
14 #include "base/location.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "base/time/tick_clock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace ash {
22 namespace internal {
23
24 namespace {
25
26 // A SingleThreadTaskRunner that mocks the current time and allows it to be
27 // fast-forwarded. TODO(bartfab): Copies of this class exist in several tests.
28 // Consolidate them (crbug.com/329911).
29 class MockTimeSingleThreadTaskRunner : public base::SingleThreadTaskRunner {
30  public:
31   MockTimeSingleThreadTaskRunner();
32
33   // base::SingleThreadTaskRunner:
34   virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
35   virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
36                                const base::Closure& task,
37                                base::TimeDelta delay) OVERRIDE;
38   virtual bool PostNonNestableDelayedTask(
39       const tracked_objects::Location& from_here,
40       const base::Closure& task,
41       base::TimeDelta delay) OVERRIDE;
42
43   const base::TimeTicks& GetCurrentTime() const;
44
45   void FastForwardBy(base::TimeDelta delta);
46   void FastForwardUntilNoTasksRemain();
47
48  private:
49   // Strict weak temporal ordering of tasks.
50   class TemporalOrder {
51    public:
52     bool operator()(
53         const std::pair<base::TimeTicks, base::Closure>& first_task,
54         const std::pair<base::TimeTicks, base::Closure>& second_task) const;
55   };
56
57   virtual ~MockTimeSingleThreadTaskRunner();
58
59   base::TimeTicks now_;
60   std::priority_queue<std::pair<base::TimeTicks, base::Closure>,
61                       std::vector<std::pair<base::TimeTicks, base::Closure> >,
62                       TemporalOrder> tasks_;
63
64   DISALLOW_COPY_AND_ASSIGN(MockTimeSingleThreadTaskRunner);
65 };
66
67 // A base::TickClock that uses a MockTimeSingleThreadTaskRunner as the source of
68 // the current time.
69 class MockClock : public base::TickClock {
70  public:
71   explicit MockClock(scoped_refptr<MockTimeSingleThreadTaskRunner> task_runner);
72   virtual ~MockClock();
73
74   // base::TickClock:
75   virtual base::TimeTicks NowTicks() OVERRIDE;
76
77  private:
78   scoped_refptr<MockTimeSingleThreadTaskRunner> task_runner_;
79
80   DISALLOW_COPY_AND_ASSIGN(MockClock);
81 };
82
83
84 MockTimeSingleThreadTaskRunner::MockTimeSingleThreadTaskRunner() {
85 }
86
87 bool MockTimeSingleThreadTaskRunner::RunsTasksOnCurrentThread() const {
88   return true;
89 }
90
91 bool MockTimeSingleThreadTaskRunner::PostDelayedTask(
92     const tracked_objects::Location& from_here,
93     const base::Closure& task,
94     base::TimeDelta delay) {
95   tasks_.push(std::make_pair(now_ + delay, task));
96   return true;
97 }
98
99 bool MockTimeSingleThreadTaskRunner::PostNonNestableDelayedTask(
100     const tracked_objects::Location& from_here,
101     const base::Closure& task,
102     base::TimeDelta delay) {
103   NOTREACHED();
104   return false;
105 }
106
107 const base::TimeTicks& MockTimeSingleThreadTaskRunner::GetCurrentTime() const {
108   return now_;
109 }
110
111 void MockTimeSingleThreadTaskRunner::FastForwardBy(base::TimeDelta delta) {
112   const base::TimeTicks latest = now_ + delta;
113   while (!tasks_.empty() && tasks_.top().first <= latest) {
114     now_ = tasks_.top().first;
115     base::Closure task = tasks_.top().second;
116     tasks_.pop();
117     task.Run();
118   }
119   now_ = latest;
120 }
121
122 void MockTimeSingleThreadTaskRunner::FastForwardUntilNoTasksRemain() {
123   while (!tasks_.empty()) {
124     now_ = tasks_.top().first;
125     base::Closure task = tasks_.top().second;
126     tasks_.pop();
127     task.Run();
128   }
129 }
130
131 bool MockTimeSingleThreadTaskRunner::TemporalOrder::operator()(
132     const std::pair<base::TimeTicks, base::Closure>& first_task,
133     const std::pair<base::TimeTicks, base::Closure>& second_task) const {
134   return first_task.first > second_task.first;
135 }
136
137 MockTimeSingleThreadTaskRunner::~MockTimeSingleThreadTaskRunner() {
138 }
139
140 MockClock::MockClock(scoped_refptr<MockTimeSingleThreadTaskRunner> task_runner)
141     : task_runner_(task_runner) {
142 }
143
144 MockClock::~MockClock() {
145 }
146
147 base::TimeTicks MockClock::NowTicks() {
148   return task_runner_->GetCurrentTime();
149 }
150
151 }  // namespace
152
153 class LogoutConfirmationControllerTest : public testing::Test {
154  protected:
155   LogoutConfirmationControllerTest();
156   virtual ~LogoutConfirmationControllerTest();
157
158   void LogOut();
159
160   bool log_out_called_;
161
162   scoped_refptr<MockTimeSingleThreadTaskRunner> runner_;
163   base::ThreadTaskRunnerHandle runner_handle_;
164
165   LogoutConfirmationController controller_;
166
167  private:
168   DISALLOW_COPY_AND_ASSIGN(LogoutConfirmationControllerTest);
169 };
170
171 LogoutConfirmationControllerTest::LogoutConfirmationControllerTest()
172     : log_out_called_(false),
173       runner_(new MockTimeSingleThreadTaskRunner),
174       runner_handle_(runner_),
175       controller_(base::Bind(&LogoutConfirmationControllerTest::LogOut,
176                              base::Unretained(this))) {
177   controller_.SetClockForTesting(
178       scoped_ptr<base::TickClock>(new MockClock(runner_)));
179 }
180
181 LogoutConfirmationControllerTest::~LogoutConfirmationControllerTest() {
182 }
183
184 void LogoutConfirmationControllerTest::LogOut() {
185   log_out_called_ = true;
186 }
187
188 // Verifies that the user is logged out immediately if logout confirmation with
189 // a zero-length countdown is requested.
190 TEST_F(LogoutConfirmationControllerTest, ZeroDuration) {
191   controller_.ConfirmLogout(runner_->GetCurrentTime());
192   EXPECT_FALSE(log_out_called_);
193   runner_->FastForwardBy(base::TimeDelta());
194   EXPECT_TRUE(log_out_called_);
195 }
196
197 // Verifies that the user is logged out when the countdown expires.
198 TEST_F(LogoutConfirmationControllerTest, DurationExpired) {
199   controller_.ConfirmLogout(
200       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
201   EXPECT_FALSE(log_out_called_);
202   runner_->FastForwardBy(base::TimeDelta::FromSeconds(9));
203   EXPECT_FALSE(log_out_called_);
204   runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
205   EXPECT_TRUE(log_out_called_);
206 }
207
208 // Verifies that when a second request to confirm logout is made and the second
209 // request's countdown ends before the original request's, the user is logged
210 // out when the new countdown expires.
211 TEST_F(LogoutConfirmationControllerTest, DurationShortened) {
212   controller_.ConfirmLogout(
213       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(30));
214   EXPECT_FALSE(log_out_called_);
215   runner_->FastForwardBy(base::TimeDelta::FromSeconds(9));
216   EXPECT_FALSE(log_out_called_);
217   controller_.ConfirmLogout(
218       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
219   runner_->FastForwardBy(base::TimeDelta::FromSeconds(9));
220   EXPECT_FALSE(log_out_called_);
221   runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
222   EXPECT_TRUE(log_out_called_);
223 }
224
225 // Verifies that when a second request to confirm logout is made and the second
226 // request's countdown ends after the original request's, the user is logged
227 // out when the original countdown expires.
228 TEST_F(LogoutConfirmationControllerTest, DurationExtended) {
229   controller_.ConfirmLogout(
230       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
231   EXPECT_FALSE(log_out_called_);
232   runner_->FastForwardBy(base::TimeDelta::FromSeconds(9));
233   EXPECT_FALSE(log_out_called_);
234   controller_.ConfirmLogout(
235       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
236   runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
237   EXPECT_TRUE(log_out_called_);
238 }
239
240 // Verifies that when the screen is locked while the countdown is running, the
241 // user is not logged out, even when the original countdown expires.
242 TEST_F(LogoutConfirmationControllerTest, Lock) {
243   controller_.ConfirmLogout(
244       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
245   EXPECT_FALSE(log_out_called_);
246   controller_.OnLockStateChanged(true);
247   runner_->FastForwardUntilNoTasksRemain();
248   EXPECT_FALSE(log_out_called_);
249 }
250
251 // Verifies that when the user confirms the logout request, the user is logged
252 // out immediately.
253 TEST_F(LogoutConfirmationControllerTest, UserAccepted) {
254   controller_.ConfirmLogout(
255       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
256   EXPECT_FALSE(log_out_called_);
257   controller_.OnLogoutConfirmed();
258   EXPECT_TRUE(log_out_called_);
259 }
260
261 // Verifies that when the user denies the logout request, the user is not logged
262 // out, even when the original countdown expires.
263 TEST_F(LogoutConfirmationControllerTest, UserDenied) {
264   controller_.ConfirmLogout(
265       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
266   EXPECT_FALSE(log_out_called_);
267   controller_.OnDialogClosed();
268   runner_->FastForwardUntilNoTasksRemain();
269   EXPECT_FALSE(log_out_called_);
270 }
271
272 // Verifies that after the user has denied a logout request, a subsequent logout
273 // request is handled correctly and the user is logged out when the countdown
274 // expires.
275 TEST_F(LogoutConfirmationControllerTest, DurationExpiredAfterDeniedRequest) {
276   controller_.ConfirmLogout(
277       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
278   EXPECT_FALSE(log_out_called_);
279   controller_.OnDialogClosed();
280   runner_->FastForwardUntilNoTasksRemain();
281   EXPECT_FALSE(log_out_called_);
282
283   controller_.ConfirmLogout(
284       runner_->GetCurrentTime() + base::TimeDelta::FromSeconds(10));
285   EXPECT_FALSE(log_out_called_);
286   runner_->FastForwardBy(base::TimeDelta::FromSeconds(9));
287   EXPECT_FALSE(log_out_called_);
288   runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
289   EXPECT_TRUE(log_out_called_);
290 }
291
292 }  // namespace internal
293 }  // namespace ash