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

Side by Side Diff: content/renderer/presentation/presentation_dispatcher_unittest.cc

Issue 2597853002: Unit test for PresentationDispatcher (Closed)
Patch Set: Address Mark's comments Created 3 years, 11 months 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
« no previous file with comments | « content/renderer/presentation/presentation_dispatcher.h ('k') | content/test/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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 <memory>
6 #include <utility>
7
8 #include "base/run_loop.h"
9 #include "content/public/test/test_browser_thread_bundle.h"
10 #include "content/renderer/presentation/presentation_dispatcher.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentatio nAvailabilityObserver.h"
13 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentatio nError.h"
14 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentatio nSessionInfo.h"
15 #include "third_party/WebKit/public/web/WebArrayBuffer.h"
16
17 using ::testing::_;
18 using ::testing::Invoke;
19 using blink::WebArrayBuffer;
20 using blink::WebPresentationAvailabilityCallbacks;
21 using blink::WebPresentationAvailabilityObserver;
22 using blink::WebPresentationConnectionCallback;
23 using blink::WebPresentationError;
24 using blink::WebPresentationSessionInfo;
25 using blink::WebString;
26 using blink::WebURL;
27 using blink::WebVector;
28 using blink::mojom::PresentationError;
29 using blink::mojom::PresentationErrorPtr;
30 using blink::mojom::PresentationErrorType;
31 using blink::mojom::PresentationService;
32 using blink::mojom::PresentationServiceClientPtr;
33 using blink::mojom::PresentationSessionInfo;
34 using blink::mojom::PresentationSessionInfoPtr;
35 using blink::mojom::ConnectionMessage;
36 using blink::mojom::ConnectionMessagePtr;
37
38 // TODO(crbug.com/576808): Add test cases for the following:
39 // - State changes
40 // - Messages received
41 // - Discarding queued messages when the frame navigates
42 // - Screen availability not supported
43 // - Default presentation starting
44
45 namespace content {
46
47 class MockPresentationAvailabilityObserver
48 : public WebPresentationAvailabilityObserver {
49 public:
50 explicit MockPresentationAvailabilityObserver(WebURL url) : url_(url) {}
51 ~MockPresentationAvailabilityObserver() override {}
52
53 MOCK_METHOD1(availabilityChanged, void(bool is_available));
54 const WebURL url() const override { return url_; }
55
56 private:
57 const WebURL url_;
58 };
59
60 class MockPresentationService : public PresentationService {
61 public:
62 void SetClient(PresentationServiceClientPtr client) override {}
63 MOCK_METHOD1(SetDefaultPresentationUrls,
64 void(const std::vector<GURL>& presentation_urls));
65 MOCK_METHOD1(ListenForScreenAvailability, void(const GURL& availability_url));
66 MOCK_METHOD1(StopListeningForScreenAvailability,
67 void(const GURL& availability_url));
68 MOCK_METHOD2(StartSession,
69 void(const std::vector<GURL>& presentation_urls,
70 const StartSessionCallback& callback));
71 MOCK_METHOD3(JoinSession,
72 void(const std::vector<GURL>& presentation_urls,
73 const base::Optional<std::string>& presentation_id,
74 const JoinSessionCallback& callback));
75
76 // *Internal method is to work around lack of support for move-only types in
77 // GMock.
78 void SendConnectionMessage(
79 PresentationSessionInfoPtr session_info,
80 ConnectionMessagePtr message_request,
81 const SendConnectionMessageCallback& callback) override {
82 SendConnectionMessageInternal(session_info.get(), message_request.get(),
83 callback);
84 }
85 MOCK_METHOD3(SendConnectionMessageInternal,
86 void(PresentationSessionInfo* session_info,
87 ConnectionMessage* message_request,
88 const SendConnectionMessageCallback& callback));
89
90 MOCK_METHOD2(CloseConnection,
91 void(const GURL& presentation_url,
92 const std::string& presentation_id));
93 MOCK_METHOD2(Terminate,
94 void(const GURL& presentation_url,
95 const std::string& presentation_id));
96
97 // *Internal method is to work around lack of support for move-only types in
98 // GMock.
99 void ListenForConnectionMessages(
100 PresentationSessionInfoPtr session_info) override {
101 ListenForConnectionMessagesInternal(session_info.get());
102 }
103 MOCK_METHOD1(ListenForConnectionMessagesInternal,
104 void(PresentationSessionInfo* session_info));
105 };
106
107 class TestWebPresentationConnectionCallback
108 : public WebPresentationConnectionCallback {
109 public:
110 TestWebPresentationConnectionCallback(WebURL url, WebString id)
111 : url_(url), id_(id), callback_called_(false) {}
112 ~TestWebPresentationConnectionCallback() override {
113 EXPECT_TRUE(callback_called_);
114 }
115
116 void onSuccess(const WebPresentationSessionInfo& info) override {
117 callback_called_ = true;
118 EXPECT_EQ(info.url, url_);
119 EXPECT_EQ(info.id, id_);
120 }
121
122 private:
123 const WebURL url_;
124 const WebString id_;
125 bool callback_called_;
126 };
127
128 class TestWebPresentationConnectionErrorCallback
129 : public WebPresentationConnectionCallback {
130 public:
131 TestWebPresentationConnectionErrorCallback(
132 WebPresentationError::ErrorType error_type,
133 WebString message)
134 : error_type_(error_type), message_(message), callback_called_(false) {}
135 ~TestWebPresentationConnectionErrorCallback() override {
136 EXPECT_TRUE(callback_called_);
137 }
138
139 void onError(const WebPresentationError& error) override {
140 callback_called_ = true;
141 EXPECT_EQ(error.errorType, error_type_);
142 EXPECT_EQ(error.message, message_);
143 }
144
145 private:
146 const WebPresentationError::ErrorType error_type_;
147 const WebString message_;
148 bool callback_called_;
149 };
150
151 class TestPresentationDispatcher : public PresentationDispatcher {
152 public:
153 explicit TestPresentationDispatcher(
154 MockPresentationService* presentation_service)
155 : PresentationDispatcher(nullptr),
156 mock_presentation_service_(presentation_service) {}
157 ~TestPresentationDispatcher() override {}
158
159 private:
160 void ConnectToPresentationServiceIfNeeded() override {
161 if (!mock_binding_) {
162 mock_binding_ = base::MakeUnique<mojo::Binding<PresentationService>>(
163 mock_presentation_service_,
164 mojo::MakeRequest(&presentation_service_));
165 }
166 }
167
168 MockPresentationService* mock_presentation_service_;
169 std::unique_ptr<mojo::Binding<PresentationService>> mock_binding_;
170 };
171
172 class PresentationDispatcherTest : public ::testing::Test {
173 public:
174 PresentationDispatcherTest()
175 : gurl1_(GURL("https://www.example.com/1.html")),
176 gurl2_(GURL("https://www.example.com/2.html")),
177 gurls_({gurl1_, gurl2_}),
178 url1_(WebURL(gurl1_)),
179 url2_(WebURL(gurl2_)),
180 urls_(WebVector<WebURL>(gurls_)),
181 presentation_id_(WebString::fromUTF8("test-id")),
182 array_buffer_(WebArrayBuffer::create(4, 1)),
183 observer_(url1_),
184 dispatcher_(&presentation_service_) {}
185 ~PresentationDispatcherTest() override {}
186
187 void SetUp() override {
188 // Set some test data.
189 *array_buffer_data() = 42;
190 }
191
192 uint8_t* array_buffer_data() {
193 return static_cast<uint8_t*>(array_buffer_.data());
194 }
195
196 protected:
197 const GURL gurl1_;
198 const GURL gurl2_;
199 const std::vector<GURL> gurls_;
200 const WebURL url1_;
201 const WebURL url2_;
202 const WebVector<WebURL> urls_;
203 const WebString presentation_id_;
204 const WebArrayBuffer array_buffer_;
205 MockPresentationAvailabilityObserver observer_;
206 MockPresentationService presentation_service_;
207 TestPresentationDispatcher dispatcher_;
208
209 private:
210 content::TestBrowserThreadBundle thread_bundle_;
211 };
212
213 TEST_F(PresentationDispatcherTest, TestStartSession) {
214 base::RunLoop run_loop;
215
216 EXPECT_CALL(presentation_service_, StartSession(gurls_, _))
217 .WillOnce(Invoke([this](
218 const std::vector<GURL>& presentation_urls,
219 const PresentationService::StartSessionCallback& callback) {
220 PresentationSessionInfoPtr session_info(PresentationSessionInfo::New());
221 session_info->url = gurl1_;
222 session_info->id = presentation_id_.utf8();
223 callback.Run(std::move(session_info), PresentationErrorPtr());
224 }));
225 dispatcher_.startSession(
226 urls_, base::MakeUnique<TestWebPresentationConnectionCallback>(
227 url1_, presentation_id_));
228 run_loop.RunUntilIdle();
229 }
230
231 TEST_F(PresentationDispatcherTest, TestStartSessionError) {
232 WebString error_message = WebString::fromUTF8("Test error message");
233 base::RunLoop run_loop;
234
235 EXPECT_CALL(presentation_service_, StartSession(gurls_, _))
236 .WillOnce(Invoke([this, &error_message](
237 const std::vector<GURL>& presentation_urls,
238 const PresentationService::StartSessionCallback& callback) {
239 PresentationErrorPtr error(PresentationError::New());
240 error->error_type = PresentationErrorType::NO_AVAILABLE_SCREENS;
241 error->message = error_message.utf8();
242 callback.Run(PresentationSessionInfoPtr(), std::move(error));
243 }));
244 dispatcher_.startSession(
245 urls_,
246 base::MakeUnique<TestWebPresentationConnectionErrorCallback>(
247 WebPresentationError::ErrorTypeNoAvailableScreens, error_message));
248 run_loop.RunUntilIdle();
249 }
250
251 TEST_F(PresentationDispatcherTest, TestJoinSessionError) {
252 WebString error_message = WebString::fromUTF8("Test error message");
253 base::RunLoop run_loop;
254
255 EXPECT_CALL(presentation_service_, JoinSession(gurls_, _, _))
256 .WillOnce(Invoke([this, &error_message](
257 const std::vector<GURL>& presentation_urls,
258 const base::Optional<std::string>& presentation_id,
259 const PresentationService::JoinSessionCallback& callback) {
260 EXPECT_TRUE(presentation_id.has_value());
261 EXPECT_EQ(presentation_id_.utf8(), presentation_id.value());
262 PresentationErrorPtr error(PresentationError::New());
263 error->error_type = PresentationErrorType::NO_AVAILABLE_SCREENS;
264 error->message = error_message.utf8();
265 callback.Run(PresentationSessionInfoPtr(), std::move(error));
266 }));
267 dispatcher_.joinSession(
268 urls_, presentation_id_,
269 base::MakeUnique<TestWebPresentationConnectionErrorCallback>(
270 WebPresentationError::ErrorTypeNoAvailableScreens, error_message));
271 run_loop.RunUntilIdle();
272 }
273
274 TEST_F(PresentationDispatcherTest, TestJoinSession) {
275 base::RunLoop run_loop;
276
277 EXPECT_CALL(presentation_service_, JoinSession(gurls_, _, _))
278 .WillOnce(Invoke([this](
279 const std::vector<GURL>& presentation_urls,
280 const base::Optional<std::string>& presentation_id,
281 const PresentationService::JoinSessionCallback& callback) {
282 EXPECT_TRUE(presentation_id.has_value());
283 EXPECT_EQ(presentation_id_.utf8(), presentation_id.value());
284 PresentationSessionInfoPtr session_info(PresentationSessionInfo::New());
285 session_info->url = gurl1_;
286 session_info->id = presentation_id_.utf8();
287 callback.Run(std::move(session_info), PresentationErrorPtr());
288 }));
289 dispatcher_.joinSession(
290 urls_, presentation_id_,
291 base::MakeUnique<TestWebPresentationConnectionCallback>(
292 url1_, presentation_id_));
293 run_loop.RunUntilIdle();
294 }
295
296 TEST_F(PresentationDispatcherTest, TestSendString) {
297 WebString message = WebString::fromUTF8("test message");
298 base::RunLoop run_loop;
299 EXPECT_CALL(presentation_service_, SendConnectionMessageInternal(_, _, _))
300 .WillOnce(Invoke([this, &message](
301 PresentationSessionInfo* session_info,
302 ConnectionMessage* message_request,
303 const PresentationService::SendConnectionMessageCallback& callback) {
304 EXPECT_EQ(gurl1_, session_info->url);
305 EXPECT_EQ(presentation_id_.utf8(), session_info->id);
306 EXPECT_TRUE(message_request->message.has_value());
307 EXPECT_EQ(message.utf8(), message_request->message.value());
308 callback.Run(true);
309 }));
310 dispatcher_.sendString(url1_, presentation_id_, message);
311 run_loop.RunUntilIdle();
312 }
313
314 TEST_F(PresentationDispatcherTest, TestSendArrayBuffer) {
315 base::RunLoop run_loop;
316 EXPECT_CALL(presentation_service_, SendConnectionMessageInternal(_, _, _))
317 .WillOnce(Invoke([this](
318 PresentationSessionInfo* session_info,
319 ConnectionMessage* message_request,
320 const PresentationService::SendConnectionMessageCallback& callback) {
321 EXPECT_EQ(gurl1_, session_info->url);
322 EXPECT_EQ(presentation_id_.utf8(), session_info->id);
323 std::vector<uint8_t> data(
324 array_buffer_data(),
325 array_buffer_data() + array_buffer_.byteLength());
326 EXPECT_TRUE(message_request->data.has_value());
327 EXPECT_EQ(data, message_request->data.value());
328 callback.Run(true);
329 }));
330 dispatcher_.sendArrayBuffer(url1_, presentation_id_, array_buffer_data(),
331 array_buffer_.byteLength());
332 run_loop.RunUntilIdle();
333 }
334
335 TEST_F(PresentationDispatcherTest, TestSendBlobData) {
336 base::RunLoop run_loop;
337 EXPECT_CALL(presentation_service_, SendConnectionMessageInternal(_, _, _))
338 .WillOnce(Invoke([this](
339 PresentationSessionInfo* session_info,
340 ConnectionMessage* message_request,
341 const PresentationService::SendConnectionMessageCallback& callback) {
342 EXPECT_EQ(gurl1_, session_info->url);
343 EXPECT_EQ(presentation_id_.utf8(), session_info->id);
344 std::vector<uint8_t> data(
345 array_buffer_data(),
346 array_buffer_data() + array_buffer_.byteLength());
347 EXPECT_TRUE(message_request->data.has_value());
348 EXPECT_EQ(data, message_request->data.value());
349 callback.Run(true);
350 }));
351 dispatcher_.sendBlobData(url1_, presentation_id_, array_buffer_data(),
352 array_buffer_.byteLength());
353 run_loop.RunUntilIdle();
354 }
355
356 TEST_F(PresentationDispatcherTest, TestCloseSession) {
357 base::RunLoop run_loop;
358 EXPECT_CALL(presentation_service_,
359 CloseConnection(gurl1_, presentation_id_.utf8()));
360 dispatcher_.closeSession(url1_, presentation_id_);
361 run_loop.RunUntilIdle();
362 }
363
364 TEST_F(PresentationDispatcherTest, TestTerminateSession) {
365 base::RunLoop run_loop;
366 EXPECT_CALL(presentation_service_,
367 Terminate(gurl1_, presentation_id_.utf8()));
368 dispatcher_.terminateSession(url1_, presentation_id_);
369 run_loop.RunUntilIdle();
370 }
371
372 TEST_F(PresentationDispatcherTest, TestListenForScreenAvailability) {
373 base::RunLoop run_loop1;
374 EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl1_));
375 dispatcher_.getAvailability(
376 url1_, base::MakeUnique<WebPresentationAvailabilityCallbacks>());
377 dispatcher_.OnScreenAvailabilityUpdated(url1_, true);
378 run_loop1.RunUntilIdle();
379
380 base::RunLoop run_loop2;
381 EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl1_));
382 dispatcher_.startListening(&observer_);
383 run_loop2.RunUntilIdle();
384
385 base::RunLoop run_loop3;
386 EXPECT_CALL(observer_, availabilityChanged(false));
387 dispatcher_.OnScreenAvailabilityUpdated(url1_, false);
388 EXPECT_CALL(observer_, availabilityChanged(true));
389 dispatcher_.OnScreenAvailabilityUpdated(url1_, true);
390 EXPECT_CALL(presentation_service_,
391 StopListeningForScreenAvailability(gurl1_));
392 dispatcher_.stopListening(&observer_);
393 run_loop3.RunUntilIdle();
394
395 // After stopListening(), |observer_| should no longer be notified.
396 base::RunLoop run_loop4;
397 EXPECT_CALL(observer_, availabilityChanged(false)).Times(0);
398 dispatcher_.OnScreenAvailabilityUpdated(url1_, false);
399 run_loop4.RunUntilIdle();
400 }
401
402 TEST_F(PresentationDispatcherTest, TestSetDefaultPresentationUrls) {
403 base::RunLoop run_loop;
404 EXPECT_CALL(presentation_service_, SetDefaultPresentationUrls(gurls_));
405 dispatcher_.setDefaultPresentationUrls(urls_);
406 run_loop.RunUntilIdle();
407 }
408
409 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/presentation/presentation_dispatcher.h ('k') | content/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698