Skip to content

Commit

Permalink
VIH-11052 Fix for audio recording setting not updating in waiting room (
Browse files Browse the repository at this point in the history
#2275)

* Fetch conference when conference is updated

* Push conference object as part of HearingDetailsUpdated event

* Formatting

* Remove ConferenceDto

* Set conference from the hearing details updated message
  • Loading branch information
oliver-scott committed Oct 21, 2024
1 parent 52106de commit e479f75
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 20 deletions.
2 changes: 1 addition & 1 deletion VideoWeb/VideoWeb.EventHub/Hub/IEventHubClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public interface IEventHubClient
Task AllocationHearings(string csoUserName, List<HearingDetailRequest> hearings);
Task EndpointsUpdated(Guid conferenceId, UpdateEndpointsDto endpoints);
Task HearingCancelledMessage(Guid conferenceId);
Task HearingDetailsUpdatedMessage(Guid conferenceId);
Task HearingDetailsUpdatedMessage(ConferenceResponse conference);
/// <summary>
/// Request a participant's local mute be update. Not to be confused with remote mute (and lock).
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Moq;
using NUnit.Framework;
using VideoWeb.Common.Models;
using VideoWeb.Contract.Responses;
using VideoWeb.EventHub.Hub;
using VideoWeb.Helpers;
using VideoWeb.UnitTests.Builders;
Expand Down Expand Up @@ -40,7 +41,8 @@ public async Task should_publish_message()
// Assert
const int vhoCount = 1;
const int staffMemberCount = 1;
_eventHelper.EventHubClientMock.Verify(x => x.HearingDetailsUpdatedMessage(_conference.Id), Times.Exactly(_conference.Participants.Count + vhoCount + staffMemberCount));
var expectedMessageCount = _conference.Participants.Count + vhoCount + staffMemberCount;
VerifyHearingDetailsUpdatedMessagePublished(expectedMessageCount);
}

[Test]
Expand All @@ -57,7 +59,7 @@ public async Task should_only_publish_one_message_to_staff_member_participants()
const int nonParticipantStaffMemberCount = 1; // Non-participant staff member = a staff member who is not a participant on the conference
var nonStaffMemberParticipantCount = _conference.Participants.Count(p => p.Role != Role.StaffMember); // Non-staff member participants = participants minus staff members
var expectedMessageCount = nonParticipantStaffMemberCount + vhoCount + nonStaffMemberParticipantCount;
_eventHelper.EventHubClientMock.Verify(x => x.HearingDetailsUpdatedMessage(_conference.Id), Times.Exactly(expectedMessageCount));
VerifyHearingDetailsUpdatedMessagePublished(expectedMessageCount);
}

private void AddParticipantToConference(Role role)
Expand All @@ -70,5 +72,12 @@ private void AddParticipantToConference(Role role)
_conference.Participants.Add(staffMemberParticipant);
_eventHelper.RegisterParticipantForHubContext(staffMemberParticipant);
}

private void VerifyHearingDetailsUpdatedMessagePublished(int times)
{
_eventHelper.EventHubClientMock.Verify(x => x.HearingDetailsUpdatedMessage(It.Is<ConferenceResponse>(r =>
r.Id == _conference.Id)),
Times.Exactly(times));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { EventsHubService } from './events-hub.service';
import { Heartbeat } from '../shared/models/heartbeat';
import { TransferDirection } from './models/hearing-transfer';
import { ParticipantMediaStatus } from '../shared/models/participant-media-status';
import { ParticipantResponse, VideoEndpointResponse } from './clients/api-client';
import { ConferenceResponse, ParticipantResponse, VideoEndpointResponse } from './clients/api-client';
import { UpdateEndpointsDto } from '../shared/models/update-endpoints-dto';
import { createMockStore, MockStore } from '@ngrx/store/testing';
import { ConferenceState, initialState as initialConferenceState } from '../waiting-space/store/reducers/conference.reducer';
Expand Down Expand Up @@ -290,17 +290,19 @@ describe('EventsService', () => {
});

it('should handle event', () => {
const conferenceId = 'TestConferenceId';
const conference = new ConferenceResponse({
id: 'TestConferenceId'
});

const hubConnectionSpy = jasmine.createSpyObj<signalR.HubConnection>('HubConnection', ['on']);
hubConnectionSpy.on.withArgs(jasmine.any(String), jasmine.any(Function)).and.callFake((eventType: string, func: any) => {
if (eventType === eventName) {
func(conferenceId);
func(conference);
}
});

serviceUnderTest.getHearingDetailsUpdated().subscribe(message => {
expect(message.conferenceId).toBe(conferenceId);
expect(message.conference.id).toBe(conference.id);
});

spyPropertyGetter(eventsHubServiceSpy, 'connection').and.returnValue(hubConnectionSpy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { EndpointsUpdatedMessage } from '../shared/models/endpoints-updated-mess
import { Room } from '../shared/models/room';
import { RoomTransfer } from '../shared/models/room-transfer';
import {
ConferenceResponse,
ConferenceStatus,
ConsultationAnswer,
EndpointStatus,
Expand Down Expand Up @@ -106,8 +107,8 @@ export class EventsService {
this.newConferenceAddedSubject.next(message);
},

HearingDetailsUpdatedMessage: (conferenceId: string) => {
const message = new HearingDetailsUpdatedMessage(conferenceId);
HearingDetailsUpdatedMessage: (conference: ConferenceResponse) => {
const message = new HearingDetailsUpdatedMessage(conference);
this.logger.debug('[EventsService] - HearingDetailsUpdatedMessage received', message);
this.hearingDetailsUpdatedSubject.next(message);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ConferenceResponse } from '../clients/api-client';

export class HearingDetailsUpdatedMessage {
constructor(public conferenceId: string) {}
constructor(public conference: ConferenceResponse) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ import {
hearingLayoutChangedSubjectMock,
getEndpointLinkedUpdatedMock,
getEndpointUnlinkedUpdatedMock,
getEndpointDisconnectUpdatedMock
getEndpointDisconnectUpdatedMock,
getHearingDetailsUpdatedMock
} from 'src/app/testing/mocks/mock-events-service';
import {
clockService,
Expand Down Expand Up @@ -94,6 +95,8 @@ import { EndpointRepMessage } from '../../../shared/models/endpoint-rep-message'
import { provideMockStore } from '@ngrx/store/testing';
import { FEATURE_FLAGS, LaunchDarklyService } from 'src/app/services/launch-darkly.service';
import { of } from 'rxjs';
import { HearingDetailsUpdatedMessage } from 'src/app/services/models/hearing-details-updated-message';
import { videoWebServiceSpy } from 'src/app/vh-officer/vho-shared/tests/participant-status-base-setup';

describe('WaitingRoomComponent EventHub Call', () => {
let fixture: ComponentFixture<WRTestComponent>;
Expand Down Expand Up @@ -1999,4 +2002,28 @@ describe('WaitingRoomComponent EventHub Call', () => {
});
});
});

describe('getHearingDetailsUpdated', () => {
it('should update the conference', () => {
// Arrange
const newScheduledDateTime = new Date(globalConference.scheduled_date_time);
newScheduledDateTime.setHours(newScheduledDateTime.getHours() + 2);
const updatedConference = new ConferenceResponse({
id: globalConference.id,
scheduled_date_time: newScheduledDateTime,
audio_recording_required: !globalConference.audio_recording_required
});
updatedConference.audio_recording_required = !updatedConference.audio_recording_required;

const hearingDetailsUpdatedMessage = new HearingDetailsUpdatedMessage(updatedConference);

// Act
getHearingDetailsUpdatedMock.next(hearingDetailsUpdatedMessage);

// Assert
expect(component.conference.id).toBe(updatedConference.id);
expect(component.conference.scheduled_date_time).toBe(updatedConference.scheduled_date_time);
expect(component.conference.audio_recording_required).toBe(updatedConference.audio_recording_required);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,7 @@ export abstract class WaitingRoomBaseDirective implements AfterContentChecked {
});
try {
const data = await this.videoWebService.getConferenceById(this.conferenceId);
this.hearingVenueFlagsService.setHearingVenueIsScottish(data.hearing_venue_is_scottish);
this.errorCount = 0;
this.loadingData = false;
this.countdownComplete = data.status === ConferenceStatus.InSession;
this.hearing = new Hearing(data);
this.conference = this.hearing.getConference();
this.setConference(data);
this.videoWebService.getAllowedEndpointsForConference(this.conferenceId).then((endpoints: AllowedEndpointResponse[]) => {
this.participantEndpoints = endpoints;
});
Expand Down Expand Up @@ -616,6 +611,16 @@ export abstract class WaitingRoomBaseDirective implements AfterContentChecked {
this.handleHearingLayoutUpdatedMessage(hearingLayout);
})
);

this.logger.debug('[WR] - Subscribing to hearing details updated message');
this.eventHubSubscription$.add(
this.eventService.getHearingDetailsUpdated().subscribe(hearingDetailsUpdatedMessage => {
hearingDetailsUpdatedMessage.conference.scheduled_date_time = new Date(
hearingDetailsUpdatedMessage.conference.scheduled_date_time
);
this.setConference(hearingDetailsUpdatedMessage.conference);
})
);
}

resolveParticipant(participantId: any): Participant {
Expand Down Expand Up @@ -1475,4 +1480,13 @@ export abstract class WaitingRoomBaseDirective implements AfterContentChecked {
this.logger.debug('[WR] - Hearing Layout Changed showing notification', participant);
this.notificationToastrService.showHearingLayoutchanged(participant, this.isParticipantInConference);
}

private setConference(conferenceResponse: ConferenceResponse) {
this.hearingVenueFlagsService.setHearingVenueIsScottish(conferenceResponse.hearing_venue_is_scottish);
this.errorCount = 0;
this.loadingData = false;
this.countdownComplete = conferenceResponse.status === ConferenceStatus.InSession;
this.hearing = new Hearing(conferenceResponse);
this.conference = this.hearing.getConference();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using VideoWeb.Common.Models;
using VideoWeb.EventHub.Hub;
using VideoWeb.Helpers.Interfaces;
using VideoWeb.Mappings;
using Hub = VideoWeb.EventHub.Hub;

namespace VideoWeb.Helpers
Expand All @@ -13,17 +14,19 @@ public class HearingDetailsUpdatedEventNotifier(IHubContext<Hub.EventHub, IEvent
{
public async Task PushHearingDetailsUpdatedEvent(Conference conference)
{
var conferenceResponse = ConferenceResponseMapper.Map(conference);

foreach (var participant in conference.Participants.Where(participant => participant.Role != Role.StaffMember))
{
await hubContext.Clients.Group(participant.Username.ToLowerInvariant())
.HearingDetailsUpdatedMessage(conference.Id);
.HearingDetailsUpdatedMessage(conferenceResponse);
}

await hubContext.Clients.Group(Hub.EventHub.VhOfficersGroupName)
.HearingDetailsUpdatedMessage(conference.Id);
.HearingDetailsUpdatedMessage(conferenceResponse);

await hubContext.Clients.Group(Hub.EventHub.StaffMembersGroupName)
.HearingDetailsUpdatedMessage(conference.Id);
.HearingDetailsUpdatedMessage(conferenceResponse);
}
}
}

0 comments on commit e479f75

Please sign in to comment.