Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / renderer / screen_orientation / screen_orientation_dispatcher_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 "screen_orientation_dispatcher.h"
6
7 #include <list>
8
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "content/common/screen_orientation_messages.h"
12 #include "content/public/test/test_utils.h"
13 #include "ipc/ipc_test_sink.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/WebKit/public/platform/WebLockOrientationCallback.h"
16
17 namespace content {
18
19 // MockLockOrientationCallback is an implementation of
20 // WebLockOrientationCallback and takes a LockOrientationResultHolder* as a
21 // parameter when being constructed. The |results_| pointer is owned by the
22 // caller and not by the callback object. The intent being that as soon as the
23 // callback is resolved, it will be killed so we use the
24 // LockOrientationResultHolder to know in which state the callback object is at
25 // any time.
26 class MockLockOrientationCallback :
27     public blink::WebLockOrientationCallback {
28  public:
29   struct LockOrientationResultHolder {
30     LockOrientationResultHolder()
31         : succeeded_(false), failed_(false) {}
32
33     bool succeeded_;
34     bool failed_;
35     blink::WebLockOrientationError error_;
36   };
37
38   explicit MockLockOrientationCallback(LockOrientationResultHolder* results)
39       : results_(results) {}
40
41   virtual void onSuccess() {
42     results_->succeeded_ = true;
43   }
44
45   virtual void onError(blink::WebLockOrientationError error) {
46     results_->failed_ = true;
47     results_->error_ = error;
48   }
49
50  private:
51   virtual ~MockLockOrientationCallback() {}
52
53   LockOrientationResultHolder* results_;
54 };
55
56 class ScreenOrientationDispatcherWithSink : public ScreenOrientationDispatcher {
57  public:
58   explicit ScreenOrientationDispatcherWithSink(IPC::TestSink* sink)
59       :ScreenOrientationDispatcher(NULL) , sink_(sink) {
60   }
61
62   virtual bool Send(IPC::Message* message) OVERRIDE {
63     return sink_->Send(message);
64   }
65
66   IPC::TestSink* sink_;
67 };
68
69 class ScreenOrientationDispatcherTest : public testing::Test {
70  protected:
71   virtual void SetUp() OVERRIDE {
72     dispatcher_.reset(new ScreenOrientationDispatcherWithSink(&sink_));
73   }
74
75   int GetFirstLockRequestIdFromSink() {
76     const IPC::Message* msg = sink().GetFirstMessageMatching(
77         ScreenOrientationHostMsg_LockRequest::ID);
78     EXPECT_TRUE(msg != NULL);
79
80     Tuple2<blink::WebScreenOrientationLockType,int> params;
81     ScreenOrientationHostMsg_LockRequest::Read(msg, &params);
82     return params.b;
83   }
84
85   IPC::TestSink& sink() {
86     return sink_;
87   }
88
89   void LockOrientation(blink::WebScreenOrientationLockType orientation,
90                        blink::WebLockOrientationCallback* callback) {
91     dispatcher_->lockOrientation(orientation, callback);
92   }
93
94   void UnlockOrientation() {
95     dispatcher_->unlockOrientation();
96   }
97
98   void OnMessageReceived(const IPC::Message& message) {
99     dispatcher_->OnMessageReceived(message);
100   }
101
102   int routing_id() const {
103     // We return a fake routing_id() in the context of this test.
104     return 0;
105   }
106
107   IPC::TestSink sink_;
108   scoped_ptr<ScreenOrientationDispatcher> dispatcher_;
109 };
110
111 // Test that calling lockOrientation() followed by unlockOrientation() cancel
112 // the lockOrientation().
113 TEST_F(ScreenOrientationDispatcherTest, CancelPending_Unlocking) {
114   MockLockOrientationCallback::LockOrientationResultHolder callback_results;
115   LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
116                   new MockLockOrientationCallback(&callback_results));
117   UnlockOrientation();
118
119   EXPECT_FALSE(callback_results.succeeded_);
120   EXPECT_TRUE(callback_results.failed_);
121   EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results.error_);
122 }
123
124 // Test that calling lockOrientation() twice cancel the first lockOrientation().
125 TEST_F(ScreenOrientationDispatcherTest, CancelPending_DoubleLock) {
126   MockLockOrientationCallback::LockOrientationResultHolder callback_results;
127   // We create the object to prevent leaks but never actually use it.
128   MockLockOrientationCallback::LockOrientationResultHolder callback_results2;
129
130   LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
131                   new MockLockOrientationCallback(&callback_results));
132   LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
133                   new MockLockOrientationCallback(&callback_results2));
134
135   EXPECT_FALSE(callback_results.succeeded_);
136   EXPECT_TRUE(callback_results.failed_);
137   EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results.error_);
138 }
139
140 // Test that when a LockError message is received, the request is set as failed
141 // with the correct values.
142 TEST_F(ScreenOrientationDispatcherTest, LockRequest_Error) {
143   std::list<blink::WebLockOrientationError> errors;
144   errors.push_back(blink::WebLockOrientationErrorNotAvailable);
145   errors.push_back(
146       blink::WebLockOrientationErrorFullScreenRequired);
147   errors.push_back(blink::WebLockOrientationErrorCanceled);
148
149   for (std::list<blink::WebLockOrientationError>::const_iterator
150           it = errors.begin(); it != errors.end(); ++it) {
151     MockLockOrientationCallback::LockOrientationResultHolder callback_results;
152     LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
153                     new MockLockOrientationCallback(&callback_results));
154
155     int request_id = GetFirstLockRequestIdFromSink();
156     OnMessageReceived(
157         ScreenOrientationMsg_LockError(routing_id(), request_id, *it));
158
159     EXPECT_FALSE(callback_results.succeeded_);
160     EXPECT_TRUE(callback_results.failed_);
161     EXPECT_EQ(*it, callback_results.error_);
162
163     sink().ClearMessages();
164   }
165 }
166
167 // Test that when a LockSuccess message is received, the request is set as
168 // succeeded.
169 TEST_F(ScreenOrientationDispatcherTest, LockRequest_Success) {
170   MockLockOrientationCallback::LockOrientationResultHolder callback_results;
171   LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
172                   new MockLockOrientationCallback(&callback_results));
173
174   int request_id = GetFirstLockRequestIdFromSink();
175   OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(),
176                                                      request_id));
177
178   EXPECT_TRUE(callback_results.succeeded_);
179   EXPECT_FALSE(callback_results.failed_);
180
181   sink().ClearMessages();
182 }
183
184 // Test an edge case: a LockSuccess is received but it matches no pending
185 // callback.
186 TEST_F(ScreenOrientationDispatcherTest, SuccessForUnknownRequest) {
187   MockLockOrientationCallback::LockOrientationResultHolder callback_results;
188   LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
189                   new MockLockOrientationCallback(&callback_results));
190
191   int request_id = GetFirstLockRequestIdFromSink();
192   OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(),
193                                                      request_id + 1));
194
195   EXPECT_FALSE(callback_results.succeeded_);
196   EXPECT_FALSE(callback_results.failed_);
197 }
198
199 // Test an edge case: a LockError is received but it matches no pending
200 // callback.
201 TEST_F(ScreenOrientationDispatcherTest, ErrorForUnknownRequest) {
202   MockLockOrientationCallback::LockOrientationResultHolder callback_results;
203   LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
204                   new MockLockOrientationCallback(&callback_results));
205
206   int request_id = GetFirstLockRequestIdFromSink();
207   OnMessageReceived(ScreenOrientationMsg_LockError(
208       routing_id(), request_id + 1, blink::WebLockOrientationErrorCanceled));
209
210   EXPECT_FALSE(callback_results.succeeded_);
211   EXPECT_FALSE(callback_results.failed_);
212 }
213
214 // Test the following scenario:
215 // - request1 is received by the dispatcher;
216 // - request2 is received by the dispatcher;
217 // - request1 is rejected;
218 // - request1 success response is received.
219 // Expected: request1 is still rejected, request2 has not been set as succeeded.
220 TEST_F(ScreenOrientationDispatcherTest, RaceScenario) {
221   MockLockOrientationCallback::LockOrientationResultHolder callback_results1;
222   MockLockOrientationCallback::LockOrientationResultHolder callback_results2;
223
224   LockOrientation(blink::WebScreenOrientationLockPortraitPrimary,
225                   new MockLockOrientationCallback(&callback_results1));
226   int request_id1 = GetFirstLockRequestIdFromSink();
227
228   LockOrientation(blink::WebScreenOrientationLockLandscapePrimary,
229                   new MockLockOrientationCallback(&callback_results2));
230
231   // callback_results1 must be rejected, tested in CancelPending_DoubleLock.
232
233   OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(),
234                                                      request_id1));
235
236   // First request is still rejected.
237   EXPECT_FALSE(callback_results1.succeeded_);
238   EXPECT_TRUE(callback_results1.failed_);
239   EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results1.error_);
240
241   // Second request is still pending.
242   EXPECT_FALSE(callback_results2.succeeded_);
243   EXPECT_FALSE(callback_results2.failed_);
244 }
245
246 }  // namespace content