Example #1
0
        public async Task <Unit> Handle(TalkingStickPassRequest request, CancellationToken cancellationToken)
        {
            var(participant, roomId, failIfHasSpeaker) = request;

            await using (await _repository.LockRoom(participant.ConferenceId, roomId))
            {
                await _mediator.Send(new ClearCacheRequest());

                if (failIfHasSpeaker)
                {
                    var currentSpeaker = await _repository.GetCurrentSpeaker(participant.ConferenceId, roomId);

                    if (currentSpeaker != null)
                    {
                        throw SceneError.AlreadyHasSpeaker.ToException();
                    }
                }

                if (!await CheckParticipantIsInRoom(participant, roomId))
                {
                    throw new ParticipantNotFoundException(participant);
                }

                await _repository.SetCurrentSpeakerAndRemoveFromQueue(participant, roomId);

                await _modeHandler.InvalidateTalkingSceneWithLockAcquired(participant.ConferenceId, roomId);
            }

            await _mediator.Send(new UpdateSynchronizedObjectRequest(participant.ConferenceId,
                                                                     SynchronizedSceneTalkingStick.SyncObjId(roomId)));

            return(Unit.Value);
        }
Example #2
0
        public async Task TalkingStick_Queue_Enqueue_MakePresenter()
        {
            // arrange
            var(conn, conference) = await ConnectToOpenedConference();

            AssertSuccess(await conn.Hub.InvokeAsync <SuccessOrError <Unit> >(nameof(CoreHub.SetScene),
                                                                              new TalkingStickScene(TalkingStickMode.Queue)));

            var pleb     = CreateUser();
            var plebConn = await ConnectUserToConference(pleb, conference);

            // act
            AssertSuccess(await plebConn.Hub.InvokeAsync <SuccessOrError <Unit> >(nameof(CoreHub.TalkingStickEnqueue)));

            // assert
            await conn.SyncObjects.AssertSyncObject <SynchronizedScene>(
                SynchronizedScene.SyncObjId(RoomOptions.DEFAULT_ROOM_ID), syncObj =>
            {
                Assert.Equal(syncObj.SceneStack, new IScene[]
                {
                    new TalkingStickScene(TalkingStickMode.Queue), new PresenterScene(pleb.Sub),
                    new ActiveSpeakerScene(),
                });
            });

            await conn.SyncObjects.AssertSyncObject <SynchronizedSceneTalkingStick>(
                SynchronizedSceneTalkingStick.SyncObjId(RoomOptions.DEFAULT_ROOM_ID), syncObj =>
            {
                Assert.Equal(pleb.Sub, syncObj.CurrentSpeakerId);
                Assert.Empty(syncObj.SpeakerQueue);
            });
        }
Example #3
0
        public async Task TalkingStick_Moderated_Dequeue_RemoveFromQueue()
        {
            // arrange
            var(conn, conference) = await ConnectToOpenedConference();

            AssertSuccess(await conn.Hub.InvokeAsync <SuccessOrError <Unit> >(nameof(CoreHub.SetScene),
                                                                              new TalkingStickScene(TalkingStickMode.Moderated)));

            var pleb     = CreateUser();
            var plebConn = await ConnectUserToConference(pleb, conference);

            AssertSuccess(await plebConn.Hub.InvokeAsync <SuccessOrError <Unit> >(nameof(CoreHub.TalkingStickEnqueue)));
            await conn.SyncObjects.AssertSyncObject <SynchronizedSceneTalkingStick>(
                SynchronizedSceneTalkingStick.SyncObjId(RoomOptions.DEFAULT_ROOM_ID), syncObj =>
            {
                Assert.Null(syncObj.CurrentSpeakerId);
                Assert.Single(syncObj.SpeakerQueue, pleb.Sub);
            });

            // act
            AssertSuccess(await plebConn.Hub.InvokeAsync <SuccessOrError <Unit> >(nameof(CoreHub.TalkingStickDequeue)));

            // assert
            await conn.SyncObjects.AssertSyncObject <SynchronizedSceneTalkingStick>(
                SynchronizedSceneTalkingStick.SyncObjId(RoomOptions.DEFAULT_ROOM_ID),
                syncObj => { Assert.Empty(syncObj.SpeakerQueue); });
        }
Example #4
0
        public async Task <Unit> Handle(TalkingStickReturnRequest request, CancellationToken cancellationToken)
        {
            var participant = request.Participant;

            var rooms = await _mediator.FetchSynchronizedObject <SynchronizedRooms>(participant.ConferenceId,
                                                                                    SynchronizedRooms.SyncObjId);

            if (!rooms.Participants.TryGetValue(participant.Id, out var roomId))
            {
                throw SceneError.RoomNotFound.ToException();
            }

            await using (await _repository.LockRoom(participant.ConferenceId, roomId))
            {
                var currentSpeaker = await _repository.GetCurrentSpeaker(participant.ConferenceId, roomId);

                if (currentSpeaker != null && currentSpeaker.Value.Equals(participant))
                {
                    await _repository.RemoveCurrentSpeaker(currentSpeaker.Value.ConferenceId, roomId);

                    await _modeHandler.InvalidateTalkingSceneWithLockAcquired(currentSpeaker.Value.ConferenceId,
                                                                              roomId);
                }
                else
                {
                    return(Unit.Value);
                }
            }

            await _mediator.Send(new UpdateSynchronizedObjectRequest(participant.ConferenceId,
                                                                     SynchronizedSceneTalkingStick.SyncObjId(roomId)));

            return(Unit.Value);
        }
Example #5
0
        public async Task TalkingStick_Moderated_PassToParticipant_MakePresenter()
        {
            // arrange
            var(conn, conference) = await ConnectToOpenedConference();

            AssertSuccess(await conn.Hub.InvokeAsync <SuccessOrError <Unit> >(nameof(CoreHub.SetScene),
                                                                              new TalkingStickScene(TalkingStickMode.Moderated)));

            var pleb = CreateUser();

            await ConnectUserToConference(pleb, conference);

            await conn.SyncObjects.AssertSyncObject <SynchronizedRooms>(SynchronizedRooms.SyncObjId,
                                                                        participants => Assert.Equal(2, participants.Participants.Count));

            // act
            AssertSuccess(await conn.Hub.InvokeAsync <SuccessOrError <Unit> >(nameof(CoreHub.TalkingStickPass), pleb.Sub));

            // assert
            await conn.SyncObjects.AssertSyncObject <SynchronizedScene>(
                SynchronizedScene.SyncObjId(RoomOptions.DEFAULT_ROOM_ID), syncObj =>
            {
                Assert.Equal(syncObj.SceneStack, new IScene[]
                {
                    new TalkingStickScene(TalkingStickMode.Moderated), new PresenterScene(pleb.Sub),
                    new ActiveSpeakerScene(),
                });
            });

            await conn.SyncObjects.AssertSyncObject <SynchronizedSceneTalkingStick>(
                SynchronizedSceneTalkingStick.SyncObjId(RoomOptions.DEFAULT_ROOM_ID),
                syncObj => { Assert.Equal(pleb.Sub, syncObj.CurrentSpeakerId); });
        }
        public async Task Handle(ParticipantsRoomChangedNotification notification, CancellationToken cancellationToken)
        {
            var updatedRooms = GetRoomsWithAParticipantLeft(notification);

            foreach (var updatedRoom in updatedRooms)
            {
                await using (await _repository.LockRoom(notification.ConferenceId, updatedRoom))
                {
                    var participants = GetParticipantsThatLeftRoom(notification, updatedRoom);

                    await _repository.RemoveFromQueue(participants, updatedRoom);

                    await _modeHandler.InvalidateTalkingSceneWithLockAcquired(notification.ConferenceId, updatedRoom);
                }

                await _mediator.Send(new UpdateSynchronizedObjectRequest(notification.ConferenceId,
                                                                         SynchronizedSceneTalkingStick.SyncObjId(updatedRoom)));
            }
        }
        public async Task <Unit> Handle(TalkingStickEnqueueRequest request, CancellationToken cancellationToken)
        {
            var(participant, remove) = request;

            var rooms = await _mediator.FetchSynchronizedObject <SynchronizedRooms>(participant.ConferenceId,
                                                                                    SynchronizedRooms.SyncObjId);

            if (!rooms.Participants.TryGetValue(participant.Id, out var roomId))
            {
                throw SceneError.RoomNotFound.ToException();
            }

            await using (await _repository.LockRoom(participant.ConferenceId, roomId))
            {
                await _mediator.Send(new ClearCacheRequest());

                if (!await CheckParticipantIsInRoom(participant, roomId))
                {
                    throw new ConcurrencyException("Participant switched room.");
                }

                if (remove)
                {
                    await _repository.RemoveFromQueue(participant.Yield(), roomId);
                }
                else
                {
                    var queue = await _repository.FetchQueue(participant.ConferenceId, roomId);

                    if (!queue.Contains(participant.Id))
                    {
                        await _repository.Enqueue(participant, roomId);
                    }

                    await _modeHandler.InvalidateTalkingSceneWithLockAcquired(participant.ConferenceId, roomId);
                }
            }

            await _mediator.Send(new UpdateSynchronizedObjectRequest(participant.ConferenceId,
                                                                     SynchronizedSceneTalkingStick.SyncObjId(roomId)));

            return(Unit.Value);
        }
 private async ValueTask <SynchronizedSceneTalkingStick> GetSyncObj(string conferenceId, string roomId)
 {
     return(await _mediator.FetchSynchronizedObject <SynchronizedSceneTalkingStick>(conferenceId,
                                                                                    SynchronizedSceneTalkingStick.SyncObjId(roomId)));
 }
Example #9
0
        public async Task ReturnStick_NoQueueMode_RemovePresenter()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Moderated);

            await Mediator.Send(new TalkingStickPassRequest(participant, DefaultRoomId, true));

            // act
            await Mediator.Send(new TalkingStickReturnRequest(participant));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Null(talkingStick.CurrentSpeakerId);
            AssertSceneStack(participant, new TalkingStickScene(TalkingStickMode.Moderated));
        }
Example #10
0
        public async Task EnqueueRequest_NoQueueMode_StayInQueue()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Moderated);

            // act
            await Mediator.Send(new TalkingStickEnqueueRequest(participant, false));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Single(talkingStick.SpeakerQueue, participant.Id);
        }
Example #11
0
        public async Task PassTalkingStickRequest_ParticipantWasInQueue_RemoveFromQueue()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Moderated);

            await Mediator.Send(new TalkingStickEnqueueRequest(participant, false));

            await Mediator.Send(new TalkingStickPassRequest(participant, DefaultRoomId, true));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Empty(talkingStick.SpeakerQueue);
        }
Example #12
0
        public async Task PassTalkingStickRequestWithFailFlag_HasPresenter_ThrowError()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Moderated);

            await Mediator.Send(new TalkingStickPassRequest(participant, DefaultRoomId, true));

            await JoinParticipant(TestData.Vincent);

            var participant2 = TestData.Vincent.Participant;

            // act
            await Assert.ThrowsAsync <IdErrorException>(async() =>
                                                        await Mediator.Send(new TalkingStickPassRequest(participant2, DefaultRoomId, true)));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Equal(participant.Id, talkingStick.CurrentSpeakerId);
        }
Example #13
0
        public async Task PassTalkingStickRequest_HasPresenter_ReplacePresenter()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Moderated);

            await Mediator.Send(new TalkingStickPassRequest(participant, DefaultRoomId, true));

            await JoinParticipant(TestData.Vincent);

            var participant2 = TestData.Vincent.Participant;

            // act
            await Mediator.Send(new TalkingStickPassRequest(participant2, DefaultRoomId, false));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Equal(participant2.Id, talkingStick.CurrentSpeakerId);
            Assert.Empty(talkingStick.SpeakerQueue);

            AssertSceneStack(participant2, SceneStackWithPresenter(TalkingStickMode.Moderated, participant2.Id));
        }
Example #14
0
        public async Task Queue_ReturnStick_NonEmptyQueue_SetNewPresenter()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Queue);

            await Mediator.Send(new TalkingStickEnqueueRequest(participant, false));

            await JoinParticipant(TestData.Vincent);

            var participant2 = TestData.Vincent.Participant;
            await Mediator.Send(new TalkingStickEnqueueRequest(participant2, false));

            // act
            await Mediator.Send(new TalkingStickReturnRequest(participant));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Equal(participant2.Id, talkingStick.CurrentSpeakerId);
            Assert.Empty(talkingStick.SpeakerQueue);

            AssertSceneStack(participant, SceneStackWithPresenter(TalkingStickMode.Queue, participant2.Id));
        }
Example #15
0
        public async Task Queue_DequeueRequest_HasPresenter_RemoveFromQueue()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Queue);

            await Mediator.Send(new TalkingStickEnqueueRequest(participant, false));

            await JoinParticipant(TestData.Vincent);

            var participant2 = TestData.Vincent.Participant;
            await Mediator.Send(new TalkingStickEnqueueRequest(participant2, false));

            // act
            await Mediator.Send(new TalkingStickEnqueueRequest(participant2, true));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Equal(participant.Id, talkingStick.CurrentSpeakerId);
            Assert.Empty(talkingStick.SpeakerQueue);
        }
Example #16
0
        public async Task Queue_EnqueueRequest_NoPresenter_MakeParticipantPresenter()
        {
            // arrange
            var participant = await PrepareTalkingStick(TalkingStickMode.Queue);

            // act
            await Mediator.Send(new TalkingStickEnqueueRequest(participant, false));

            // assert
            var talkingStick =
                SynchronizedObjectListener.GetSynchronizedObject <SynchronizedSceneTalkingStick>(participant,
                                                                                                 SynchronizedSceneTalkingStick.SyncObjId(DefaultRoomId));

            Assert.Equal(participant.Id, talkingStick.CurrentSpeakerId);
            Assert.Empty(talkingStick.SpeakerQueue);

            AssertSceneStack(participant, SceneStackWithPresenter(TalkingStickMode.Queue, participant.Id));
        }