[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / presentation / presentation_service_impl_unittest.cc
blob09cb2376d65089485ea7befd5c5ce57190df233e
1 // Copyright 2015 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.
5 #include <string>
6 #include <vector>
8 #include "base/location.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/test/test_timeouts.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "content/browser/presentation/presentation_service_impl.h"
15 #include "content/public/browser/presentation_service_delegate.h"
16 #include "content/public/browser/presentation_session.h"
17 #include "content/public/common/presentation_constants.h"
18 #include "content/test/test_render_frame_host.h"
19 #include "content/test/test_render_view_host.h"
20 #include "content/test/test_web_contents.h"
21 #include "mojo/public/cpp/bindings/interface_ptr.h"
22 #include "mojo/public/cpp/bindings/string.h"
23 #include "testing/gmock/include/gmock/gmock.h"
25 using ::testing::_;
26 using ::testing::Eq;
27 using ::testing::InvokeWithoutArgs;
28 using ::testing::Mock;
29 using ::testing::Return;
30 using ::testing::SaveArg;
32 namespace content {
34 namespace {
36 // Matches mojo structs.
37 MATCHER_P(Equals, expected, "") {
38 return expected.Equals(arg);
41 const char *const kPresentationId = "presentationId";
42 const char *const kPresentationUrl = "http://foo.com/index.html";
44 bool ArePresentationSessionsEqual(
45 const presentation::PresentationSessionInfo& expected,
46 const presentation::PresentationSessionInfo& actual) {
47 return expected.url == actual.url && expected.id == actual.id;
50 bool ArePresentationSessionMessagesEqual(
51 const presentation::SessionMessage* expected,
52 const presentation::SessionMessage* actual) {
53 return expected->type == actual->type &&
54 expected->message == actual->message &&
55 expected->data.Equals(actual->data);
58 void DoNothing(
59 presentation::PresentationSessionInfoPtr info,
60 presentation::PresentationErrorPtr error) {
63 } // namespace
65 class MockPresentationServiceDelegate : public PresentationServiceDelegate {
66 public:
67 MOCK_METHOD3(AddObserver,
68 void(int render_process_id,
69 int render_frame_id,
70 PresentationServiceDelegate::Observer* observer));
71 MOCK_METHOD2(RemoveObserver,
72 void(int render_process_id, int render_frame_id));
73 MOCK_METHOD3(AddScreenAvailabilityListener,
74 bool(
75 int render_process_id,
76 int routing_id,
77 PresentationScreenAvailabilityListener* listener));
78 MOCK_METHOD3(RemoveScreenAvailabilityListener,
79 void(
80 int render_process_id,
81 int routing_id,
82 PresentationScreenAvailabilityListener* listener));
83 MOCK_METHOD2(Reset,
84 void(
85 int render_process_id,
86 int routing_id));
87 MOCK_METHOD3(SetDefaultPresentationUrl,
88 void(
89 int render_process_id,
90 int routing_id,
91 const std::string& default_presentation_url));
92 MOCK_METHOD5(StartSession,
93 void(
94 int render_process_id,
95 int render_frame_id,
96 const std::string& presentation_url,
97 const PresentationSessionSuccessCallback& success_cb,
98 const PresentationSessionErrorCallback& error_cb));
99 MOCK_METHOD6(JoinSession,
100 void(
101 int render_process_id,
102 int render_frame_id,
103 const std::string& presentation_url,
104 const std::string& presentation_id,
105 const PresentationSessionSuccessCallback& success_cb,
106 const PresentationSessionErrorCallback& error_cb));
107 MOCK_METHOD3(CloseSession,
108 void(int render_process_id,
109 int render_frame_id,
110 const std::string& presentation_id));
111 MOCK_METHOD4(ListenForSessionMessages,
112 void(int render_process_id,
113 int render_frame_id,
114 const content::PresentationSessionInfo& session,
115 const PresentationSessionMessageCallback& message_cb));
116 MOCK_METHOD5(SendMessageRawPtr,
117 void(int render_process_id,
118 int render_frame_id,
119 const content::PresentationSessionInfo& session,
120 PresentationSessionMessage* message_request,
121 const SendMessageCallback& send_message_cb));
122 void SendMessage(int render_process_id,
123 int render_frame_id,
124 const content::PresentationSessionInfo& session,
125 scoped_ptr<PresentationSessionMessage> message_request,
126 const SendMessageCallback& send_message_cb) override {
127 SendMessageRawPtr(render_process_id, render_frame_id, session,
128 message_request.release(), send_message_cb);
130 MOCK_METHOD3(
131 ListenForSessionStateChange,
132 void(int render_process_id,
133 int render_frame_id,
134 const content::SessionStateChangedCallback& state_changed_cb));
137 class MockPresentationServiceClient :
138 public presentation::PresentationServiceClient {
139 public:
140 MOCK_METHOD2(OnScreenAvailabilityUpdated,
141 void(const mojo::String& url, bool available));
142 void OnSessionStateChanged(
143 presentation::PresentationSessionInfoPtr session_info,
144 presentation::PresentationSessionState new_state) override {
145 OnSessionStateChanged(*session_info, new_state);
147 MOCK_METHOD2(OnSessionStateChanged,
148 void(const presentation::PresentationSessionInfo& session_info,
149 presentation::PresentationSessionState new_state));
150 void OnScreenAvailabilityNotSupported(const mojo::String& url) override {
151 NOTIMPLEMENTED();
154 void OnSessionMessagesReceived(
155 presentation::PresentationSessionInfoPtr session_info,
156 mojo::Array<presentation::SessionMessagePtr> messages) override {
157 messages_received_ = messages.Pass();
158 MessagesReceived();
160 MOCK_METHOD0(MessagesReceived, void());
162 mojo::Array<presentation::SessionMessagePtr> messages_received_;
165 class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
166 public:
167 PresentationServiceImplTest() : default_session_started_count_(0) {}
169 void SetUp() override {
170 RenderViewHostImplTestHarness::SetUp();
172 auto request = mojo::GetProxy(&service_ptr_);
173 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
174 service_impl_.reset(new PresentationServiceImpl(
175 contents()->GetMainFrame(), contents(), &mock_delegate_));
176 service_impl_->Bind(request.Pass());
178 presentation::PresentationServiceClientPtr client_ptr;
179 client_binding_.reset(
180 new mojo::Binding<presentation::PresentationServiceClient>(
181 &mock_client_, mojo::GetProxy(&client_ptr)));
182 service_impl_->SetClient(client_ptr.Pass());
185 void TearDown() override {
186 service_ptr_.reset();
187 if (service_impl_.get()) {
188 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
189 service_impl_.reset();
191 RenderViewHostImplTestHarness::TearDown();
194 void ListenForScreenAvailabilityAndWait(
195 const mojo::String& url, bool delegate_success) {
196 base::RunLoop run_loop;
197 // This will call to |service_impl_| via mojo. Process the message
198 // using RunLoop.
199 // The callback shouldn't be invoked since there is no availability
200 // result yet.
201 EXPECT_CALL(mock_delegate_, AddScreenAvailabilityListener(_, _, _))
202 .WillOnce(DoAll(
203 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
204 Return(delegate_success)));
205 service_ptr_->ListenForScreenAvailability(url);
206 run_loop.Run();
208 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
211 void RunLoopFor(base::TimeDelta duration) {
212 base::RunLoop run_loop;
213 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
214 FROM_HERE, run_loop.QuitClosure(), duration);
215 run_loop.Run();
218 void SaveQuitClosureAndRunLoop() {
219 base::RunLoop run_loop;
220 run_loop_quit_closure_ = run_loop.QuitClosure();
221 run_loop.Run();
222 run_loop_quit_closure_.Reset();
225 void SimulateScreenAvailabilityChangeAndWait(
226 const std::string& url, bool available) {
227 auto listener_it = service_impl_->screen_availability_listeners_.find(url);
228 ASSERT_TRUE(listener_it->second);
230 base::RunLoop run_loop;
231 EXPECT_CALL(mock_client_,
232 OnScreenAvailabilityUpdated(mojo::String(url), available))
233 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
234 listener_it->second->OnScreenAvailabilityChanged(available);
235 run_loop.Run();
238 void ExpectReset() {
239 EXPECT_CALL(mock_delegate_, Reset(_, _)).Times(1);
242 void ExpectCleanState() {
243 EXPECT_TRUE(service_impl_->default_presentation_url_.empty());
244 EXPECT_EQ(
245 service_impl_->screen_availability_listeners_.find(kPresentationUrl),
246 service_impl_->screen_availability_listeners_.end());
247 EXPECT_FALSE(service_impl_->default_session_start_context_.get());
248 EXPECT_FALSE(service_impl_->on_session_messages_callback_.get());
251 void ExpectNewSessionMojoCallbackSuccess(
252 presentation::PresentationSessionInfoPtr info,
253 presentation::PresentationErrorPtr error) {
254 EXPECT_FALSE(info.is_null());
255 EXPECT_TRUE(error.is_null());
256 if (!run_loop_quit_closure_.is_null())
257 run_loop_quit_closure_.Run();
260 void ExpectNewSessionMojoCallbackError(
261 presentation::PresentationSessionInfoPtr info,
262 presentation::PresentationErrorPtr error) {
263 EXPECT_TRUE(info.is_null());
264 EXPECT_FALSE(error.is_null());
265 if (!run_loop_quit_closure_.is_null())
266 run_loop_quit_closure_.Run();
269 void ExpectDefaultSessionStarted(
270 const presentation::PresentationSessionInfo& expected_session,
271 presentation::PresentationSessionInfoPtr actual_session) {
272 ASSERT_TRUE(!actual_session.is_null());
273 EXPECT_TRUE(ArePresentationSessionsEqual(
274 expected_session, *actual_session));
275 ++default_session_started_count_;
276 if (!run_loop_quit_closure_.is_null())
277 run_loop_quit_closure_.Run();
280 void ExpectDefaultSessionNull(
281 presentation::PresentationSessionInfoPtr actual_session) {
282 EXPECT_TRUE(actual_session.is_null());
283 ++default_session_started_count_;
284 if (!run_loop_quit_closure_.is_null())
285 run_loop_quit_closure_.Run();
288 void ExpectSessionMessages(
289 const mojo::Array<presentation::SessionMessagePtr>& expected_msgs,
290 const mojo::Array<presentation::SessionMessagePtr>& actual_msgs) {
291 EXPECT_EQ(expected_msgs.size(), actual_msgs.size());
292 for (size_t i = 0; i < actual_msgs.size(); ++i) {
293 EXPECT_TRUE(ArePresentationSessionMessagesEqual(expected_msgs[i].get(),
294 actual_msgs[i].get()));
298 void ExpectSendMessageMojoCallback(bool success) {
299 EXPECT_TRUE(success);
300 EXPECT_FALSE(service_impl_->send_message_callback_);
301 if (!run_loop_quit_closure_.is_null())
302 run_loop_quit_closure_.Run();
305 void RunListenForSessionMessages(const std::string& text_msg,
306 const std::vector<uint8_t>& binary_data,
307 bool pass_ownership) {
308 mojo::Array<presentation::SessionMessagePtr> expected_msgs(2);
309 expected_msgs[0] = presentation::SessionMessage::New();
310 expected_msgs[0]->type =
311 presentation::PresentationMessageType::PRESENTATION_MESSAGE_TYPE_TEXT;
312 expected_msgs[0]->message = text_msg;
313 expected_msgs[1] = presentation::SessionMessage::New();
314 expected_msgs[1]->type = presentation::PresentationMessageType::
315 PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
316 expected_msgs[1]->data = mojo::Array<uint8_t>::From(binary_data);
318 presentation::PresentationSessionInfoPtr session(
319 presentation::PresentationSessionInfo::New());
320 session->url = kPresentationUrl;
321 session->id = kPresentationId;
323 PresentationSessionMessageCallback message_cb;
325 base::RunLoop run_loop;
326 EXPECT_CALL(mock_delegate_, ListenForSessionMessages(_, _, _, _))
327 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
328 SaveArg<3>(&message_cb)));
329 service_ptr_->ListenForSessionMessages(session.Clone());
330 run_loop.Run();
333 ScopedVector<PresentationSessionMessage> messages;
334 scoped_ptr<content::PresentationSessionMessage> message;
335 message.reset(
336 new content::PresentationSessionMessage(PresentationMessageType::TEXT));
337 message->message = text_msg;
338 messages.push_back(message.Pass());
339 message.reset(new content::PresentationSessionMessage(
340 PresentationMessageType::ARRAY_BUFFER));
341 message->data.reset(new std::vector<uint8_t>(binary_data));
342 messages.push_back(message.Pass());
344 std::vector<presentation::SessionMessagePtr> actual_msgs;
346 base::RunLoop run_loop;
347 EXPECT_CALL(mock_client_, MessagesReceived())
348 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
349 message_cb.Run(messages.Pass(), pass_ownership);
350 run_loop.Run();
352 ExpectSessionMessages(expected_msgs, mock_client_.messages_received_);
355 MockPresentationServiceDelegate mock_delegate_;
357 scoped_ptr<PresentationServiceImpl> service_impl_;
358 mojo::InterfacePtr<presentation::PresentationService> service_ptr_;
360 MockPresentationServiceClient mock_client_;
361 scoped_ptr<mojo::Binding<presentation::PresentationServiceClient>>
362 client_binding_;
364 base::Closure run_loop_quit_closure_;
365 int default_session_started_count_;
368 TEST_F(PresentationServiceImplTest, ListenForScreenAvailability) {
369 ListenForScreenAvailabilityAndWait(kPresentationUrl, true);
371 SimulateScreenAvailabilityChangeAndWait(kPresentationUrl, true);
372 SimulateScreenAvailabilityChangeAndWait(kPresentationUrl, false);
373 SimulateScreenAvailabilityChangeAndWait(kPresentationUrl, true);
376 TEST_F(PresentationServiceImplTest, Reset) {
377 ListenForScreenAvailabilityAndWait(kPresentationUrl, true);
379 ExpectReset();
380 service_impl_->Reset();
381 ExpectCleanState();
384 TEST_F(PresentationServiceImplTest, DidNavigateThisFrame) {
385 ListenForScreenAvailabilityAndWait(kPresentationUrl, true);
387 ExpectReset();
388 service_impl_->DidNavigateAnyFrame(
389 contents()->GetMainFrame(),
390 content::LoadCommittedDetails(),
391 content::FrameNavigateParams());
392 ExpectCleanState();
395 TEST_F(PresentationServiceImplTest, DidNavigateOtherFrame) {
396 ListenForScreenAvailabilityAndWait(kPresentationUrl, true);
398 // TODO(imcheng): How to get a different RenderFrameHost?
399 service_impl_->DidNavigateAnyFrame(
400 nullptr,
401 content::LoadCommittedDetails(),
402 content::FrameNavigateParams());
404 // Availability is reported and callback is invoked since it was not
405 // removed.
406 SimulateScreenAvailabilityChangeAndWait(kPresentationUrl, true);
409 TEST_F(PresentationServiceImplTest, ThisRenderFrameDeleted) {
410 ListenForScreenAvailabilityAndWait(kPresentationUrl, true);
412 ExpectReset();
414 // Since the frame matched the service, |service_impl_| will be deleted.
415 PresentationServiceImpl* service = service_impl_.release();
416 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
417 service->RenderFrameDeleted(contents()->GetMainFrame());
420 TEST_F(PresentationServiceImplTest, OtherRenderFrameDeleted) {
421 ListenForScreenAvailabilityAndWait(kPresentationUrl, true);
423 // TODO(imcheng): How to get a different RenderFrameHost?
424 service_impl_->RenderFrameDeleted(nullptr);
426 // Availability is reported and callback should be invoked since listener
427 // has not been deleted.
428 SimulateScreenAvailabilityChangeAndWait(kPresentationUrl, true);
431 TEST_F(PresentationServiceImplTest, DelegateFails) {
432 ListenForScreenAvailabilityAndWait(kPresentationUrl, false);
433 ASSERT_EQ(
434 service_impl_->screen_availability_listeners_.find(kPresentationUrl),
435 service_impl_->screen_availability_listeners_.end());
438 TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrl) {
439 std::string url1("http://fooUrl");
440 EXPECT_CALL(mock_delegate_,
441 SetDefaultPresentationUrl(_, _, Eq(url1)))
442 .Times(1);
443 service_impl_->SetDefaultPresentationURL(url1);
444 EXPECT_EQ(url1, service_impl_->default_presentation_url_);
446 std::string url2("http://barUrl");
447 // Sets different DPU.
448 EXPECT_CALL(mock_delegate_,
449 SetDefaultPresentationUrl(_, _, Eq(url2)))
450 .Times(1);
451 service_impl_->SetDefaultPresentationURL(url2);
452 EXPECT_EQ(url2, service_impl_->default_presentation_url_);
455 TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrl) {
456 EXPECT_CALL(mock_delegate_,
457 SetDefaultPresentationUrl(_, _, Eq(kPresentationUrl)))
458 .Times(1);
459 service_impl_->SetDefaultPresentationURL(kPresentationUrl);
460 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
461 EXPECT_EQ(kPresentationUrl, service_impl_->default_presentation_url_);
463 // Same URL as before; no-ops.
464 service_impl_->SetDefaultPresentationURL(kPresentationUrl);
465 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
466 EXPECT_EQ(kPresentationUrl, service_impl_->default_presentation_url_);
469 TEST_F(PresentationServiceImplTest, StartSessionSuccess) {
470 service_ptr_->StartSession(
471 kPresentationUrl,
472 base::Bind(
473 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackSuccess,
474 base::Unretained(this)));
475 base::RunLoop run_loop;
476 base::Callback<void(const PresentationSessionInfo&)> success_cb;
477 EXPECT_CALL(mock_delegate_, StartSession(_, _, Eq(kPresentationUrl), _, _))
478 .WillOnce(DoAll(
479 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
480 SaveArg<3>(&success_cb)));
481 run_loop.Run();
482 success_cb.Run(PresentationSessionInfo(kPresentationUrl, kPresentationId));
483 SaveQuitClosureAndRunLoop();
486 TEST_F(PresentationServiceImplTest, StartSessionError) {
487 service_ptr_->StartSession(
488 kPresentationUrl,
489 base::Bind(
490 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
491 base::Unretained(this)));
492 base::RunLoop run_loop;
493 base::Callback<void(const PresentationError&)> error_cb;
494 EXPECT_CALL(mock_delegate_, StartSession(_, _, Eq(kPresentationUrl), _, _))
495 .WillOnce(DoAll(
496 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
497 SaveArg<4>(&error_cb)));
498 run_loop.Run();
499 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message"));
500 SaveQuitClosureAndRunLoop();
503 TEST_F(PresentationServiceImplTest, JoinSessionSuccess) {
504 service_ptr_->JoinSession(
505 kPresentationUrl,
506 kPresentationId,
507 base::Bind(
508 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackSuccess,
509 base::Unretained(this)));
510 base::RunLoop run_loop;
511 base::Callback<void(const PresentationSessionInfo&)> success_cb;
512 EXPECT_CALL(mock_delegate_, JoinSession(
513 _, _, Eq(kPresentationUrl), Eq(kPresentationId), _, _))
514 .WillOnce(DoAll(
515 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
516 SaveArg<4>(&success_cb)));
517 run_loop.Run();
518 success_cb.Run(PresentationSessionInfo(kPresentationUrl, kPresentationId));
519 SaveQuitClosureAndRunLoop();
522 TEST_F(PresentationServiceImplTest, JoinSessionError) {
523 service_ptr_->JoinSession(
524 kPresentationUrl,
525 kPresentationId,
526 base::Bind(
527 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
528 base::Unretained(this)));
529 base::RunLoop run_loop;
530 base::Callback<void(const PresentationError&)> error_cb;
531 EXPECT_CALL(mock_delegate_, JoinSession(
532 _, _, Eq(kPresentationUrl), Eq(kPresentationId), _, _))
533 .WillOnce(DoAll(
534 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
535 SaveArg<5>(&error_cb)));
536 run_loop.Run();
537 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message"));
538 SaveQuitClosureAndRunLoop();
541 TEST_F(PresentationServiceImplTest, CloseSession) {
542 service_ptr_->CloseSession(kPresentationUrl, kPresentationId);
543 base::RunLoop run_loop;
544 EXPECT_CALL(mock_delegate_, CloseSession(_, _, Eq(kPresentationId)))
545 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
546 run_loop.Run();
549 TEST_F(PresentationServiceImplTest, ListenForSessionMessagesPassed) {
550 std::string text_msg("123");
551 std::vector<uint8_t> binary_data(3, '\1');
552 RunListenForSessionMessages(text_msg, binary_data, true);
555 TEST_F(PresentationServiceImplTest, ListenForSessionMessagesCopied) {
556 std::string text_msg("123");
557 std::vector<uint8_t> binary_data(3, '\1');
558 RunListenForSessionMessages(text_msg, binary_data, false);
561 TEST_F(PresentationServiceImplTest, ListenForSessionMessagesWithEmptyMsg) {
562 std::string text_msg("");
563 std::vector<uint8_t> binary_data;
564 RunListenForSessionMessages(text_msg, binary_data, false);
567 TEST_F(PresentationServiceImplTest, StartSessionInProgress) {
568 std::string presentation_url1("http://fooUrl");
569 std::string presentation_url2("http://barUrl");
570 service_ptr_->StartSession(presentation_url1,
571 base::Bind(&DoNothing));
572 // This request should fail immediately, since there is already a StartSession
573 // in progress.
574 service_ptr_->StartSession(
575 presentation_url2,
576 base::Bind(
577 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
578 base::Unretained(this)));
579 SaveQuitClosureAndRunLoop();
582 TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStart) {
583 presentation::PresentationSessionInfo expected_session;
584 expected_session.url = kPresentationUrl;
585 expected_session.id = kPresentationId;
586 service_ptr_->ListenForDefaultSessionStart(
587 base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
588 base::Unretained(this),
589 expected_session));
590 RunLoopFor(base::TimeDelta::FromMilliseconds(50));
591 service_impl_->OnDefaultPresentationStarted(
592 content::PresentationSessionInfo(kPresentationUrl, kPresentationId));
593 SaveQuitClosureAndRunLoop();
594 EXPECT_EQ(1, default_session_started_count_);
597 TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStartAfterSet) {
598 // Note that the callback will only pick up presentation_url2/id2 since
599 // ListenForDefaultSessionStart wasn't called yet when the DPU was still
600 // presentation_url1.
601 std::string presentation_url1("http://fooUrl1");
602 std::string presentation_id1("presentationId1");
603 std::string presentation_url2("http://fooUrl2");
604 std::string presentation_id2("presentationId2");
605 service_impl_->OnDefaultPresentationStarted(
606 content::PresentationSessionInfo(presentation_url1, presentation_id1));
608 presentation::PresentationSessionInfo expected_session;
609 expected_session.url = presentation_url2;
610 expected_session.id = presentation_id2;
611 service_ptr_->ListenForDefaultSessionStart(
612 base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
613 base::Unretained(this),
614 expected_session));
615 RunLoopFor(base::TimeDelta::FromMilliseconds(50));
616 service_impl_->OnDefaultPresentationStarted(
617 content::PresentationSessionInfo(presentation_url2, presentation_id2));
618 SaveQuitClosureAndRunLoop();
619 EXPECT_EQ(1, default_session_started_count_);
622 TEST_F(PresentationServiceImplTest, DefaultSessionStartReset) {
623 service_ptr_->ListenForDefaultSessionStart(
624 base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionNull,
625 base::Unretained(this)));
626 RunLoopFor(TestTimeouts::tiny_timeout());
628 ExpectReset();
629 service_impl_->Reset();
630 ExpectCleanState();
631 SaveQuitClosureAndRunLoop();
632 EXPECT_EQ(1, default_session_started_count_);
635 TEST_F(PresentationServiceImplTest, SendStringMessage) {
636 std::string message("Test presentation session message");
638 presentation::PresentationSessionInfoPtr session(
639 presentation::PresentationSessionInfo::New());
640 session->url = kPresentationUrl;
641 session->id = kPresentationId;
642 presentation::SessionMessagePtr message_request(
643 presentation::SessionMessage::New());
644 message_request->type = presentation::PresentationMessageType::
645 PRESENTATION_MESSAGE_TYPE_TEXT;
646 message_request->message = message;
647 service_ptr_->SendSessionMessage(
648 session.Pass(), message_request.Pass(),
649 base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
650 base::Unretained(this)));
652 base::RunLoop run_loop;
653 base::Callback<void(bool)> send_message_cb;
654 PresentationSessionMessage* test_message = nullptr;
655 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(_, _, _, _, _))
656 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
657 SaveArg<3>(&test_message), SaveArg<4>(&send_message_cb)));
658 run_loop.Run();
660 // Make sure |test_message| gets deleted.
661 scoped_ptr<PresentationSessionMessage> scoped_test_message(test_message);
662 EXPECT_TRUE(test_message);
663 EXPECT_FALSE(test_message->is_binary());
664 EXPECT_LE(test_message->message.size(), kMaxPresentationSessionMessageSize);
665 EXPECT_EQ(message, test_message->message);
666 ASSERT_FALSE(test_message->data);
667 send_message_cb.Run(true);
668 SaveQuitClosureAndRunLoop();
671 TEST_F(PresentationServiceImplTest, SendArrayBuffer) {
672 // Test Array buffer data.
673 const uint8 buffer[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
674 std::vector<uint8> data;
675 data.assign(buffer, buffer + sizeof(buffer));
677 presentation::PresentationSessionInfoPtr session(
678 presentation::PresentationSessionInfo::New());
679 session->url = kPresentationUrl;
680 session->id = kPresentationId;
681 presentation::SessionMessagePtr message_request(
682 presentation::SessionMessage::New());
683 message_request->type = presentation::PresentationMessageType::
684 PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
685 message_request->data = mojo::Array<uint8>::From(data);
686 service_ptr_->SendSessionMessage(
687 session.Pass(), message_request.Pass(),
688 base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
689 base::Unretained(this)));
691 base::RunLoop run_loop;
692 base::Callback<void(bool)> send_message_cb;
693 PresentationSessionMessage* test_message = nullptr;
694 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(_, _, _, _, _))
695 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
696 SaveArg<3>(&test_message), SaveArg<4>(&send_message_cb)));
697 run_loop.Run();
699 // Make sure |test_message| gets deleted.
700 scoped_ptr<PresentationSessionMessage> scoped_test_message(test_message);
701 EXPECT_TRUE(test_message);
702 EXPECT_TRUE(test_message->is_binary());
703 EXPECT_EQ(PresentationMessageType::ARRAY_BUFFER, test_message->type);
704 EXPECT_TRUE(test_message->message.empty());
705 ASSERT_TRUE(test_message->data);
706 EXPECT_EQ(data.size(), test_message->data->size());
707 EXPECT_LE(test_message->data->size(), kMaxPresentationSessionMessageSize);
708 EXPECT_EQ(0, memcmp(buffer, &(*test_message->data)[0], sizeof(buffer)));
709 send_message_cb.Run(true);
710 SaveQuitClosureAndRunLoop();
713 TEST_F(PresentationServiceImplTest, SendArrayBufferWithExceedingLimit) {
714 // Create buffer with size exceeding the limit.
715 // Use same size as in content::kMaxPresentationSessionMessageSize.
716 const size_t kMaxBufferSizeInBytes = 64 * 1024; // 64 KB.
717 uint8 buffer[kMaxBufferSizeInBytes+1];
718 memset(buffer, 0, kMaxBufferSizeInBytes+1);
719 std::vector<uint8> data;
720 data.assign(buffer, buffer + sizeof(buffer));
722 presentation::PresentationSessionInfoPtr session(
723 presentation::PresentationSessionInfo::New());
724 session->url = kPresentationUrl;
725 session->id = kPresentationId;
726 presentation::SessionMessagePtr message_request(
727 presentation::SessionMessage::New());
728 message_request->type = presentation::PresentationMessageType::
729 PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
730 message_request->data = mojo::Array<uint8>::From(data);
731 service_ptr_->SendSessionMessage(
732 session.Pass(), message_request.Pass(),
733 base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
734 base::Unretained(this)));
736 base::RunLoop run_loop;
737 base::Callback<void(bool)> send_message_cb;
738 PresentationSessionMessage* test_message = nullptr;
739 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(_, _, _, _, _))
740 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
741 SaveArg<3>(&test_message), SaveArg<4>(&send_message_cb)));
742 run_loop.Run();
744 EXPECT_FALSE(test_message);
745 send_message_cb.Run(true);
746 SaveQuitClosureAndRunLoop();
749 TEST_F(PresentationServiceImplTest, SendBlobData) {
750 const uint8 buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
751 std::vector<uint8> data;
752 data.assign(buffer, buffer + sizeof(buffer));
754 presentation::PresentationSessionInfoPtr session(
755 presentation::PresentationSessionInfo::New());
756 session->url = kPresentationUrl;
757 session->id = kPresentationId;
758 presentation::SessionMessagePtr message_request(
759 presentation::SessionMessage::New());
760 message_request->type =
761 presentation::PresentationMessageType::PRESENTATION_MESSAGE_TYPE_BLOB;
762 message_request->data = mojo::Array<uint8>::From(data);
763 service_ptr_->SendSessionMessage(
764 session.Pass(), message_request.Pass(),
765 base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
766 base::Unretained(this)));
768 base::RunLoop run_loop;
769 base::Callback<void(bool)> send_message_cb;
770 PresentationSessionMessage* test_message = nullptr;
771 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(_, _, _, _, _))
772 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
773 SaveArg<3>(&test_message), SaveArg<4>(&send_message_cb)));
774 run_loop.Run();
776 // Make sure |test_message| gets deleted.
777 scoped_ptr<PresentationSessionMessage> scoped_test_message(test_message);
778 EXPECT_TRUE(test_message);
779 EXPECT_TRUE(test_message->is_binary());
780 EXPECT_EQ(PresentationMessageType::BLOB, test_message->type);
781 EXPECT_TRUE(test_message->message.empty());
782 ASSERT_TRUE(test_message->data);
783 EXPECT_EQ(data.size(), test_message->data->size());
784 EXPECT_LE(test_message->data->size(), kMaxPresentationSessionMessageSize);
785 EXPECT_EQ(0, memcmp(buffer, &(*test_message->data)[0], sizeof(buffer)));
786 send_message_cb.Run(true);
787 SaveQuitClosureAndRunLoop();
790 TEST_F(PresentationServiceImplTest, MaxPendingJoinSessionRequests) {
791 const char* presentation_url = "http://fooUrl%d";
792 const char* presentation_id = "presentationId%d";
793 int num_requests = PresentationServiceImpl::kMaxNumQueuedSessionRequests;
794 int i = 0;
795 EXPECT_CALL(mock_delegate_, JoinSession(_, _, _, _, _, _))
796 .Times(num_requests);
797 for (; i < num_requests; ++i) {
798 service_ptr_->JoinSession(
799 base::StringPrintf(presentation_url, i),
800 base::StringPrintf(presentation_id, i),
801 base::Bind(&DoNothing));
804 // Exceeded maximum queue size, should invoke mojo callback with error.
805 service_ptr_->JoinSession(
806 base::StringPrintf(presentation_url, i),
807 base::StringPrintf(presentation_id, i),
808 base::Bind(
809 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
810 base::Unretained(this)));
811 SaveQuitClosureAndRunLoop();
814 TEST_F(PresentationServiceImplTest, ListenForSessionStateChange) {
815 base::RunLoop run_loop;
816 EXPECT_CALL(mock_delegate_, ListenForSessionStateChange(_, _, _))
817 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
818 service_ptr_->ListenForSessionStateChange();
819 run_loop.Run();
821 presentation::PresentationSessionInfo session_info;
822 session_info.url = kPresentationUrl;
823 session_info.id = kPresentationId;
825 EXPECT_CALL(mock_client_,
826 OnSessionStateChanged(
827 Equals(session_info),
828 presentation::PRESENTATION_SESSION_STATE_CONNECTED));
829 service_impl_->OnSessionStateChanged(
830 content::PresentationSessionInfo(kPresentationUrl, kPresentationId),
831 content::PRESENTATION_SESSION_STATE_CONNECTED);
834 } // namespace content