public async Task SendMediaDeviceStatus(Guid conferenceId, Guid participantId,
                                                ParticipantMediaStatus mediaStatus)
        {
            try
            {
                var conference = await GetConference(conferenceId);

                var participant = conference.Participants.SingleOrDefault(x => x.Id == participantId);
                if (participant == null)
                {
                    _logger.LogDebug("Participant {ParticipantId} does not exist in {ConferenceId}", participantId,
                                     conferenceId);
                    throw new ParticipantNotFoundException(conferenceId, Context.User.Identity.Name);
                }

                await Clients.Group(VhOfficersGroupName)
                .ParticipantMediaStatusMessage(participantId, conferenceId, mediaStatus);

                var judge = conference.Participants.Single(x => x.IsJudge());
                await Clients.Group(judge.Username.ToLowerInvariant())
                .ParticipantMediaStatusMessage(participantId, conferenceId, mediaStatus);

                _logger.LogTrace(
                    "Participant device status updated: Participant Id: {ParticipantId} | Conference Id: {ConferenceId}",
                    participantId, conferenceId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error occured when updating participant device status");
            }
        }
        public async Task should_not_publish_media_status_when_participant_id_does_not_exist()
        {
            var participantUsername = "******";
            var conference          = CreateTestConference(participantUsername);

            var conferenceId  = conference.Id;
            var participantId = Guid.NewGuid();
            var deviceStatus  = new ParticipantMediaStatus
            {
                IsLocalAudioMuted = false,
                IsLocalVideoMuted = true
            };

            ConferenceCacheMock.Setup(cache =>
                                      cache.GetOrAddConferenceAsync(conference.Id, It.IsAny <Func <Task <ConferenceDetailsResponse> > >()))
            .Callback(async(Guid anyGuid, Func <Task <ConferenceDetailsResponse> > factory) => await factory())
            .ReturnsAsync(conference);

            await Hub.SendMediaDeviceStatus(conferenceId, participantId, deviceStatus);

            VerifyMessageCallCount(conference, participantId, deviceStatus, Times.Never());
        }
        public async Task should_publish_media_status_to_participants_and_admin_when_ids_are_valid()
        {
            var participantUsername = "******";
            var conference          = CreateTestConference(participantUsername);

            var conferenceId = conference.Id;
            var participant  = conference.Participants.First(x => x.Username == participantUsername);
            var deviceStatus = new ParticipantMediaStatus
            {
                IsLocalAudioMuted = true,
                IsLocalVideoMuted = false
            };

            SetupEventHubClientsForAllParticipantsInConference(conference, true);

            ConferenceCacheMock.Setup(cache =>
                                      cache.GetOrAddConferenceAsync(conference.Id, It.IsAny <Func <Task <ConferenceDetailsResponse> > >()))
            .Callback(async(Guid anyGuid, Func <Task <ConferenceDetailsResponse> > factory) => await factory())
            .ReturnsAsync(conference);

            await Hub.SendMediaDeviceStatus(conferenceId, participant.Id, deviceStatus);

            VerifyMessageCallCount(conference, participant.Id, deviceStatus, Times.Once());
        }
        private void VerifyMessageCallCount(Conference conference, Guid participantId, ParticipantMediaStatus message,
                                            Times times)
        {
            var judge = conference.Participants.Single(x => x.IsJudge());

            EventHubClientMock.Verify(
                x => x.Group(judge.Username.ToLowerInvariant())
                .ParticipantMediaStatusMessage(participantId, conference.Id,
                                               It.Is <ParticipantMediaStatus>(s =>
                                                                              s.IsLocalAudioMuted == message.IsLocalAudioMuted &&
                                                                              s.IsLocalVideoMuted == message.IsLocalVideoMuted)), times);


            EventHubClientMock.Verify(
                x => x.Group(EventHub.Hub.EventHub.VhOfficersGroupName)
                .ParticipantMediaStatusMessage(participantId, conference.Id, message), times);
        }