1 // Copyright 2019 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 "osp/public/presentation/presentation_controller.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
12 #include "osp/impl/presentation/testing/mock_connection_delegate.h"
13 #include "osp/impl/quic/testing/quic_test_support.h"
14 #include "osp/impl/service_listener_impl.h"
15 #include "osp/public/message_demuxer.h"
16 #include "osp/public/network_service_manager.h"
17 #include "osp/public/testing/message_demuxer_test_support.h"
18 #include "platform/test/fake_clock.h"
19 #include "platform/test/fake_task_runner.h"
20
21 namespace openscreen {
22 namespace osp {
23
24 using ::testing::_;
25 using ::testing::Invoke;
26 using ::testing::NiceMock;
27
28 namespace {
29
30 const char kTestUrl[] = "https://example.foo";
31
32 class MockServiceListenerDelegate final : public ServiceListenerImpl::Delegate {
33 public:
34 ~MockServiceListenerDelegate() override = default;
35
listener()36 ServiceListenerImpl* listener() { return listener_; }
37
38 MOCK_METHOD0(StartListener, void());
39 MOCK_METHOD0(StartAndSuspendListener, void());
40 MOCK_METHOD0(StopListener, void());
41 MOCK_METHOD0(SuspendListener, void());
42 MOCK_METHOD0(ResumeListener, void());
43 MOCK_METHOD1(SearchNow, void(ServiceListener::State from));
44 MOCK_METHOD0(RunTasksListener, void());
45 };
46
47 class MockReceiverObserver final : public ReceiverObserver {
48 public:
49 ~MockReceiverObserver() override = default;
50
51 MOCK_METHOD2(OnRequestFailed,
52 void(const std::string& presentation_url,
53 const std::string& service_id));
54 MOCK_METHOD2(OnReceiverAvailable,
55 void(const std::string& presentation_url,
56 const std::string& service_id));
57 MOCK_METHOD2(OnReceiverUnavailable,
58 void(const std::string& presentation_url,
59 const std::string& service_id));
60 };
61
62 class MockRequestDelegate final : public RequestDelegate {
63 public:
64 MockRequestDelegate() = default;
65 ~MockRequestDelegate() override = default;
66
OnConnection(std::unique_ptr<Connection> connection)67 void OnConnection(std::unique_ptr<Connection> connection) override {
68 OnConnectionMock(connection);
69 }
70 MOCK_METHOD1(OnConnectionMock, void(std::unique_ptr<Connection>& connection));
71 MOCK_METHOD1(OnError, void(const Error& error));
72 };
73
74 } // namespace
75
76 class ControllerTest : public ::testing::Test {
77 public:
ControllerTest()78 ControllerTest() {
79 fake_clock_ = std::make_unique<FakeClock>(
80 Clock::time_point(std::chrono::seconds(11111)));
81 task_runner_ = std::make_unique<FakeTaskRunner>(fake_clock_.get());
82 quic_bridge_ =
83 std::make_unique<FakeQuicBridge>(task_runner_.get(), FakeClock::now);
84 receiver_info1 = {
85 "service-id1", "lucas-auer", 1, quic_bridge_->kReceiverEndpoint, {}};
86 }
87
88 protected:
SetUp()89 void SetUp() override {
90 auto service_listener =
91 std::make_unique<ServiceListenerImpl>(&mock_listener_delegate_);
92 NetworkServiceManager::Create(std::move(service_listener), nullptr,
93 std::move(quic_bridge_->quic_client),
94 std::move(quic_bridge_->quic_server));
95 controller_ = std::make_unique<Controller>(FakeClock::now);
96 ON_CALL(quic_bridge_->mock_server_observer, OnIncomingConnectionMock(_))
97 .WillByDefault(
98 Invoke([this](std::unique_ptr<ProtocolConnection>& connection) {
99 controller_endpoint_id_ = connection->endpoint_id();
100 }));
101
102 availability_watch_ =
103 quic_bridge_->receiver_demuxer->SetDefaultMessageTypeWatch(
104 msgs::Type::kPresentationUrlAvailabilityRequest, &mock_callback_);
105 }
106
TearDown()107 void TearDown() override {
108 availability_watch_ = MessageDemuxer::MessageWatch();
109 controller_.reset();
110 NetworkServiceManager::Dispose();
111 }
112
ExpectAvailabilityRequest(msgs::PresentationUrlAvailabilityRequest * request)113 void ExpectAvailabilityRequest(
114 msgs::PresentationUrlAvailabilityRequest* request) {
115 ssize_t decode_result = -1;
116 msgs::Type msg_type;
117 EXPECT_CALL(mock_callback_, OnStreamMessage(_, _, _, _, _, _))
118 .WillOnce(Invoke([request, &msg_type, &decode_result](
119 uint64_t endpoint_id, uint64_t cid,
120 msgs::Type message_type, const uint8_t* buffer,
121 size_t buffer_size, Clock::time_point now) {
122 msg_type = message_type;
123 decode_result = msgs::DecodePresentationUrlAvailabilityRequest(
124 buffer, buffer_size, request);
125 return decode_result;
126 }));
127 quic_bridge_->RunTasksUntilIdle();
128 ASSERT_EQ(msg_type, msgs::Type::kPresentationUrlAvailabilityRequest);
129 ASSERT_GT(decode_result, 0);
130 }
131
SendAvailabilityResponse(const msgs::PresentationUrlAvailabilityResponse & response)132 void SendAvailabilityResponse(
133 const msgs::PresentationUrlAvailabilityResponse& response) {
134 std::unique_ptr<ProtocolConnection> controller_connection =
135 NetworkServiceManager::Get()
136 ->GetProtocolConnectionServer()
137 ->CreateProtocolConnection(controller_endpoint_id_);
138 ASSERT_TRUE(controller_connection);
139 ASSERT_EQ(Error::Code::kNone,
140 controller_connection
141 ->WriteMessage(
142 response, msgs::EncodePresentationUrlAvailabilityResponse)
143 .code());
144 }
145
SendStartResponse(const msgs::PresentationStartResponse & response)146 void SendStartResponse(const msgs::PresentationStartResponse& response) {
147 std::unique_ptr<ProtocolConnection> protocol_connection =
148 NetworkServiceManager::Get()
149 ->GetProtocolConnectionServer()
150 ->CreateProtocolConnection(controller_endpoint_id_);
151 ASSERT_TRUE(protocol_connection);
152 ASSERT_EQ(
153 Error::Code::kNone,
154 protocol_connection
155 ->WriteMessage(response, msgs::EncodePresentationStartResponse)
156 .code());
157 }
158
SendAvailabilityEvent(const msgs::PresentationUrlAvailabilityEvent & event)159 void SendAvailabilityEvent(
160 const msgs::PresentationUrlAvailabilityEvent& event) {
161 std::unique_ptr<ProtocolConnection> controller_connection =
162 NetworkServiceManager::Get()
163 ->GetProtocolConnectionServer()
164 ->CreateProtocolConnection(controller_endpoint_id_);
165 ASSERT_TRUE(controller_connection);
166 ASSERT_EQ(
167 Error::Code::kNone,
168 controller_connection
169 ->WriteMessage(event, msgs::EncodePresentationUrlAvailabilityEvent)
170 .code());
171 }
172
SendTerminationResponse(const msgs::PresentationTerminationResponse & response)173 void SendTerminationResponse(
174 const msgs::PresentationTerminationResponse& response) {
175 std::unique_ptr<ProtocolConnection> protocol_connection =
176 NetworkServiceManager::Get()
177 ->GetProtocolConnectionServer()
178 ->CreateProtocolConnection(controller_endpoint_id_);
179 ASSERT_TRUE(protocol_connection);
180 ASSERT_EQ(Error::Code::kNone,
181 protocol_connection
182 ->WriteMessage(response,
183 msgs::EncodePresentationTerminationResponse)
184 .code());
185 }
186
SendTerminationEvent(const msgs::PresentationTerminationEvent & event)187 void SendTerminationEvent(const msgs::PresentationTerminationEvent& event) {
188 std::unique_ptr<ProtocolConnection> protocol_connection =
189 NetworkServiceManager::Get()
190 ->GetProtocolConnectionServer()
191 ->CreateProtocolConnection(controller_endpoint_id_);
192 ASSERT_TRUE(protocol_connection);
193 ASSERT_EQ(
194 Error::Code::kNone,
195 protocol_connection
196 ->WriteMessage(event, msgs::EncodePresentationTerminationEvent)
197 .code());
198 }
199
ExpectCloseRequest(MockMessageCallback * mock_callback,msgs::PresentationConnectionCloseRequest * request,Connection * connection)200 void ExpectCloseRequest(MockMessageCallback* mock_callback,
201 msgs::PresentationConnectionCloseRequest* request,
202 Connection* connection) {
203 ssize_t decode_result = -1;
204 msgs::Type msg_type;
205 EXPECT_CALL(*mock_callback, OnStreamMessage(_, _, _, _, _, _))
206 .WillOnce(Invoke([request, &msg_type, &decode_result](
207 uint64_t endpoint_id, uint64_t cid,
208 msgs::Type message_type, const uint8_t* buffer,
209 size_t buffer_size, Clock::time_point now) {
210 msg_type = message_type;
211 decode_result = msgs::DecodePresentationConnectionCloseRequest(
212 buffer, buffer_size, request);
213 return decode_result;
214 }));
215 connection->Close(Connection::CloseReason::kClosed);
216 EXPECT_EQ(connection->state(), Connection::State::kClosed);
217 quic_bridge_->RunTasksUntilIdle();
218 ASSERT_EQ(msg_type, msgs::Type::kPresentationConnectionCloseRequest);
219 ASSERT_GT(decode_result, 0);
220 }
221
SendCloseResponse(const msgs::PresentationConnectionCloseResponse & response)222 void SendCloseResponse(
223 const msgs::PresentationConnectionCloseResponse& response) {
224 std::unique_ptr<ProtocolConnection> protocol_connection =
225 NetworkServiceManager::Get()
226 ->GetProtocolConnectionServer()
227 ->CreateProtocolConnection(controller_endpoint_id_);
228 ASSERT_TRUE(protocol_connection);
229 ASSERT_EQ(Error::Code::kNone,
230 protocol_connection
231 ->WriteMessage(
232 response, msgs::EncodePresentationConnectionCloseResponse)
233 .code());
234 }
235
SendOpenResponse(const msgs::PresentationConnectionOpenResponse & response)236 void SendOpenResponse(
237 const msgs::PresentationConnectionOpenResponse& response) {
238 std::unique_ptr<ProtocolConnection> protocol_connection =
239 NetworkServiceManager::Get()
240 ->GetProtocolConnectionServer()
241 ->CreateProtocolConnection(controller_endpoint_id_);
242 ASSERT_TRUE(protocol_connection);
243 ASSERT_EQ(Error::Code::kNone,
244 protocol_connection
245 ->WriteMessage(response,
246 msgs::EncodePresentationConnectionOpenResponse)
247 .code());
248 }
249
StartPresentation(MockMessageCallback * mock_callback,MockConnectionDelegate * mock_connection_delegate,std::unique_ptr<Connection> * connection)250 void StartPresentation(MockMessageCallback* mock_callback,
251 MockConnectionDelegate* mock_connection_delegate,
252 std::unique_ptr<Connection>* connection) {
253 MessageDemuxer::MessageWatch start_presentation_watch =
254 quic_bridge_->receiver_demuxer->SetDefaultMessageTypeWatch(
255 msgs::Type::kPresentationStartRequest, mock_callback);
256 mock_listener_delegate_.listener()->OnReceiverAdded(receiver_info1);
257 quic_bridge_->RunTasksUntilIdle();
258
259 MockRequestDelegate mock_request_delegate;
260 msgs::PresentationStartRequest request;
261 msgs::Type msg_type;
262 EXPECT_CALL(*mock_callback, OnStreamMessage(_, _, _, _, _, _))
263 .WillOnce(Invoke([&request, &msg_type](
264 uint64_t endpoint_id, uint64_t cid,
265 msgs::Type message_type, const uint8_t* buffer,
266 size_t buffer_size, Clock::time_point now) {
267 msg_type = message_type;
268 ssize_t result = msgs::DecodePresentationStartRequest(
269 buffer, buffer_size, &request);
270 return result;
271 }));
272 Controller::ConnectRequest connect_request = controller_->StartPresentation(
273 "https://example.com/receiver.html", receiver_info1.service_id,
274 &mock_request_delegate, mock_connection_delegate);
275 ASSERT_TRUE(connect_request);
276 quic_bridge_->RunTasksUntilIdle();
277 ASSERT_EQ(msgs::Type::kPresentationStartRequest, msg_type);
278
279 msgs::PresentationStartResponse response;
280 response.request_id = request.request_id;
281 response.result = msgs::PresentationStartResponse_result::kSuccess;
282 response.connection_id = 1;
283 SendStartResponse(response);
284
285 EXPECT_CALL(mock_request_delegate, OnConnectionMock(_))
286 .WillOnce(Invoke([connection](std::unique_ptr<Connection>& c) {
287 *connection = std::move(c);
288 }));
289 EXPECT_CALL(*mock_connection_delegate, OnConnected());
290 quic_bridge_->RunTasksUntilIdle();
291
292 ASSERT_TRUE(*connection);
293 }
294
295 std::unique_ptr<FakeClock> fake_clock_;
296 std::unique_ptr<FakeTaskRunner> task_runner_;
297 MessageDemuxer::MessageWatch availability_watch_;
298 MockMessageCallback mock_callback_;
299 std::unique_ptr<FakeQuicBridge> quic_bridge_;
300 MockServiceListenerDelegate mock_listener_delegate_;
301 std::unique_ptr<Controller> controller_;
302 ServiceInfo receiver_info1;
303 MockReceiverObserver mock_receiver_observer_;
304 uint64_t controller_endpoint_id_{0};
305 };
306
TEST_F(ControllerTest,ReceiverWatchMoves)307 TEST_F(ControllerTest, ReceiverWatchMoves) {
308 std::vector<std::string> urls{"one fish", "two fish", "red fish", "gnu fish"};
309 MockReceiverObserver mock_observer;
310
311 Controller::ReceiverWatch watch1(controller_.get(), urls, &mock_observer);
312 EXPECT_TRUE(watch1);
313 Controller::ReceiverWatch watch2;
314 EXPECT_FALSE(watch2);
315 watch2 = std::move(watch1);
316 EXPECT_FALSE(watch1);
317 EXPECT_TRUE(watch2);
318 Controller::ReceiverWatch watch3(std::move(watch2));
319 EXPECT_FALSE(watch2);
320 EXPECT_TRUE(watch3);
321 }
322
TEST_F(ControllerTest,ConnectRequestMoves)323 TEST_F(ControllerTest, ConnectRequestMoves) {
324 std::string service_id{"service-id1"};
325 uint64_t request_id = 7;
326
327 Controller::ConnectRequest request1(controller_.get(), service_id, false,
328 request_id);
329 EXPECT_TRUE(request1);
330 Controller::ConnectRequest request2;
331 EXPECT_FALSE(request2);
332 request2 = std::move(request1);
333 EXPECT_FALSE(request1);
334 EXPECT_TRUE(request2);
335 Controller::ConnectRequest request3(std::move(request2));
336 EXPECT_FALSE(request2);
337 EXPECT_TRUE(request3);
338 }
339
TEST_F(ControllerTest,ReceiverAvailable)340 TEST_F(ControllerTest, ReceiverAvailable) {
341 mock_listener_delegate_.listener()->OnReceiverAdded(receiver_info1);
342 Controller::ReceiverWatch watch =
343 controller_->RegisterReceiverWatch({kTestUrl}, &mock_receiver_observer_);
344
345 msgs::PresentationUrlAvailabilityRequest request;
346 ExpectAvailabilityRequest(&request);
347
348 msgs::PresentationUrlAvailabilityResponse response;
349 response.request_id = request.request_id;
350 response.url_availabilities.push_back(msgs::UrlAvailability::kAvailable);
351 SendAvailabilityResponse(response);
352 EXPECT_CALL(mock_receiver_observer_, OnReceiverAvailable(_, _));
353 quic_bridge_->RunTasksUntilIdle();
354
355 MockReceiverObserver mock_receiver_observer2;
356 EXPECT_CALL(mock_receiver_observer2, OnReceiverAvailable(_, _));
357 Controller::ReceiverWatch watch2 =
358 controller_->RegisterReceiverWatch({kTestUrl}, &mock_receiver_observer2);
359 }
360
TEST_F(ControllerTest,ReceiverWatchCancel)361 TEST_F(ControllerTest, ReceiverWatchCancel) {
362 mock_listener_delegate_.listener()->OnReceiverAdded(receiver_info1);
363 Controller::ReceiverWatch watch =
364 controller_->RegisterReceiverWatch({kTestUrl}, &mock_receiver_observer_);
365
366 msgs::PresentationUrlAvailabilityRequest request;
367 ExpectAvailabilityRequest(&request);
368
369 msgs::PresentationUrlAvailabilityResponse response;
370 response.request_id = request.request_id;
371 response.url_availabilities.push_back(msgs::UrlAvailability::kAvailable);
372 SendAvailabilityResponse(response);
373 EXPECT_CALL(mock_receiver_observer_, OnReceiverAvailable(_, _));
374 quic_bridge_->RunTasksUntilIdle();
375
376 MockReceiverObserver mock_receiver_observer2;
377 EXPECT_CALL(mock_receiver_observer2, OnReceiverAvailable(_, _));
378 Controller::ReceiverWatch watch2 =
379 controller_->RegisterReceiverWatch({kTestUrl}, &mock_receiver_observer2);
380
381 watch = Controller::ReceiverWatch();
382 msgs::PresentationUrlAvailabilityEvent event;
383 event.watch_id = request.watch_id;
384 event.url_availabilities.push_back(msgs::UrlAvailability::kUnavailable);
385
386 EXPECT_CALL(mock_receiver_observer2, OnReceiverUnavailable(_, _));
387 EXPECT_CALL(mock_receiver_observer_, OnReceiverUnavailable(_, _)).Times(0);
388 SendAvailabilityEvent(event);
389 quic_bridge_->RunTasksUntilIdle();
390 }
391
TEST_F(ControllerTest,StartPresentation)392 TEST_F(ControllerTest, StartPresentation) {
393 MockMessageCallback mock_callback;
394 NiceMock<MockConnectionDelegate> mock_connection_delegate;
395 std::unique_ptr<Connection> connection;
396 StartPresentation(&mock_callback, &mock_connection_delegate, &connection);
397 }
398
TEST_F(ControllerTest,TerminatePresentationFromController)399 TEST_F(ControllerTest, TerminatePresentationFromController) {
400 MockMessageCallback mock_callback;
401 MockConnectionDelegate mock_connection_delegate;
402 std::unique_ptr<Connection> connection;
403 StartPresentation(&mock_callback, &mock_connection_delegate, &connection);
404
405 MessageDemuxer::MessageWatch terminate_presentation_watch =
406 quic_bridge_->receiver_demuxer->SetDefaultMessageTypeWatch(
407 msgs::Type::kPresentationTerminationRequest, &mock_callback);
408 msgs::PresentationTerminationRequest termination_request;
409 msgs::Type msg_type;
410 EXPECT_CALL(mock_callback, OnStreamMessage(_, _, _, _, _, _))
411 .WillOnce(Invoke([&termination_request, &msg_type](
412 uint64_t endpoint_id, uint64_t cid,
413 msgs::Type message_type, const uint8_t* buffer,
414 size_t buffer_size, Clock::time_point now) {
415 msg_type = message_type;
416 ssize_t result = msgs::DecodePresentationTerminationRequest(
417 buffer, buffer_size, &termination_request);
418 return result;
419 }));
420 connection->Terminate(TerminationReason::kControllerTerminateCalled);
421 quic_bridge_->RunTasksUntilIdle();
422
423 ASSERT_EQ(msgs::Type::kPresentationTerminationRequest, msg_type);
424 msgs::PresentationTerminationResponse termination_response;
425 termination_response.request_id = termination_request.request_id;
426 termination_response.result =
427 msgs::PresentationTerminationResponse_result::kSuccess;
428 SendTerminationResponse(termination_response);
429
430 // TODO(btolsch): Check OnTerminated of other connections when reconnect
431 // lands.
432 quic_bridge_->RunTasksUntilIdle();
433 }
434
TEST_F(ControllerTest,TerminatePresentationFromReceiver)435 TEST_F(ControllerTest, TerminatePresentationFromReceiver) {
436 MockMessageCallback mock_callback;
437 MockConnectionDelegate mock_connection_delegate;
438 std::unique_ptr<Connection> connection;
439 StartPresentation(&mock_callback, &mock_connection_delegate, &connection);
440
441 msgs::PresentationTerminationEvent termination_event;
442 termination_event.presentation_id = connection->presentation_info().id;
443 termination_event.reason =
444 msgs::PresentationTerminationEvent_reason::kReceiverCalledTerminate;
445 SendTerminationEvent(termination_event);
446
447 EXPECT_CALL(mock_connection_delegate, OnTerminated());
448 quic_bridge_->RunTasksUntilIdle();
449 }
450
TEST_F(ControllerTest,CloseConnection)451 TEST_F(ControllerTest, CloseConnection) {
452 MockMessageCallback mock_callback;
453 MockConnectionDelegate mock_connection_delegate;
454 std::unique_ptr<Connection> connection;
455 StartPresentation(&mock_callback, &mock_connection_delegate, &connection);
456
457 MessageDemuxer::MessageWatch close_request_watch =
458 quic_bridge_->receiver_demuxer->SetDefaultMessageTypeWatch(
459 msgs::Type::kPresentationConnectionCloseRequest, &mock_callback);
460 msgs::PresentationConnectionCloseRequest close_request;
461 ExpectCloseRequest(&mock_callback, &close_request, connection.get());
462
463 msgs::PresentationConnectionCloseResponse close_response;
464 close_response.request_id = close_request.request_id;
465 close_response.result =
466 msgs::PresentationConnectionCloseResponse_result::kSuccess;
467 SendCloseResponse(close_response);
468 quic_bridge_->RunTasksUntilIdle();
469 }
470
TEST_F(ControllerTest,Reconnect)471 TEST_F(ControllerTest, Reconnect) {
472 MockMessageCallback mock_callback;
473 NiceMock<MockConnectionDelegate> mock_connection_delegate;
474 std::unique_ptr<Connection> connection;
475 StartPresentation(&mock_callback, &mock_connection_delegate, &connection);
476
477 MessageDemuxer::MessageWatch close_request_watch =
478 quic_bridge_->receiver_demuxer->SetDefaultMessageTypeWatch(
479 msgs::Type::kPresentationConnectionCloseRequest, &mock_callback);
480 msgs::PresentationConnectionCloseRequest close_request;
481 ExpectCloseRequest(&mock_callback, &close_request, connection.get());
482
483 msgs::PresentationConnectionCloseResponse close_response;
484 close_response.request_id = close_request.request_id;
485 close_response.result =
486 msgs::PresentationConnectionCloseResponse_result::kSuccess;
487 SendCloseResponse(close_response);
488 quic_bridge_->RunTasksUntilIdle();
489
490 MessageDemuxer::MessageWatch connection_open_watch =
491 quic_bridge_->receiver_demuxer->SetDefaultMessageTypeWatch(
492 msgs::Type::kPresentationConnectionOpenRequest, &mock_callback);
493 msgs::PresentationConnectionOpenRequest open_request;
494 MockRequestDelegate reconnect_delegate;
495 Controller::ConnectRequest reconnect_request =
496 controller_->ReconnectConnection(std::move(connection),
497 &reconnect_delegate);
498 ASSERT_TRUE(reconnect_request);
499 ssize_t decode_result = -1;
500 msgs::Type msg_type;
501 EXPECT_CALL(mock_callback, OnStreamMessage(_, _, _, _, _, _))
502 .WillOnce(Invoke([&open_request, &msg_type, &decode_result](
503 uint64_t endpoint_id, uint64_t cid,
504 msgs::Type message_type, const uint8_t* buffer,
505 size_t buffer_size, Clock::time_point now) {
506 msg_type = message_type;
507 decode_result = msgs::DecodePresentationConnectionOpenRequest(
508 buffer, buffer_size, &open_request);
509 return decode_result;
510 }));
511 quic_bridge_->RunTasksUntilIdle();
512
513 ASSERT_FALSE(connection);
514 ASSERT_EQ(msg_type, msgs::Type::kPresentationConnectionOpenRequest);
515 ASSERT_GT(decode_result, 0);
516 msgs::PresentationConnectionOpenResponse open_response;
517 open_response.request_id = open_request.request_id;
518 open_response.connection_id = 17;
519 open_response.result =
520 msgs::PresentationConnectionOpenResponse_result::kSuccess;
521 SendOpenResponse(open_response);
522
523 EXPECT_CALL(reconnect_delegate, OnConnectionMock(_))
524 .WillOnce(Invoke([&connection](std::unique_ptr<Connection>& c) {
525 connection = std::move(c);
526 }));
527 EXPECT_CALL(mock_connection_delegate, OnConnected());
528 quic_bridge_->RunTasksUntilIdle();
529 ASSERT_TRUE(connection);
530 EXPECT_EQ(connection->state(), Connection::State::kConnected);
531 }
532
533 } // namespace osp
534 } // namespace openscreen
535