Skip to content

Commit

Permalink
Replace SummaryComponent properties with VHBooking model; more test c…
Browse files Browse the repository at this point in the history
…overage
  • Loading branch information
oliver-scott committed Dec 20, 2024
1 parent e230904 commit 14dea79
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ <h1 class="govuk-heading-l">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<section
*ngIf="!judgeAssigned"
*ngIf="!hearing.judge"
class="govuk-notification-banner red-theme"
aria-labelledby="govuk-notification-banner-title"
data-module="govuk-notification-banner"
Expand All @@ -31,15 +31,15 @@ <h2 class="govuk-heading-m" id="hearingSummary">
<div class="govuk-form-group vhtable">
<div class="vh-text-break"><app-truncatable-text [id]="'caseNumber'" [text]="caseNumber" [maxLimit]="50"></app-truncatable-text></div>
<div class="vh-text-break"><app-truncatable-text [id]="'caseName'" [text]="caseName" [maxLimit]="50"></app-truncatable-text></div>
<div id="caseType">{{ caseType }}</div>
<div id="caseType">{{ hearing.caseType }}</div>
</div>

<app-booking-edit [title]="'Hearing schedule'" [editLink]="'hearing-schedule'" [elementId]="'hearing-schedule-id'"> </app-booking-edit>
<div class="govuk-form-group vhtable">
<div id="courtAddress" class="vh-text-break">{{ courtRoomAddress }}</div>
<div id="courtAddress" class="vh-text-break">{{ hearing.courtRoomAddress }}</div>

<div id="hearingDate" *ngIf="!multiDays; else multiDaysHearing">
{{ hearingDate | appLongDatetime }}
<div id="hearingDate" *ngIf="!hearing.isMultiDayEdit; else multiDaysHearing">
{{ hearing.scheduledDateTime | appLongDatetime }}
</div>
<ng-template #multiDaysHearing>
<ng-container *ngIf="hearing.hearingDates.length; else dateRange">
Expand All @@ -54,7 +54,7 @@ <h2 class="govuk-heading-m" id="hearingSummary">
</ng-template>
</ng-template>

<div *ngIf="!multiDays" id="hearingDuration">{{ hearingDuration }}</div>
<div *ngIf="!hearing.isMultiDayEdit" id="hearingDuration">{{ hearing.hearingDuration }}</div>
</div>

<div *ngIf="switchOffRecording; else switchOnRecording">
Expand All @@ -68,7 +68,7 @@ <h2 class="govuk-heading-m" id="hearingSummary">
></app-booking-edit>
</ng-template>
<div class="govuk-form-group vhtable">
<div class="vh-text-break" id="audioRecording">{{ audioChoice }}</div>
<div class="vh-text-break" id="audioRecording">{{ hearing.audioChoice }}</div>
</div>

<div *ngIf="hasEndpoints">
Expand All @@ -79,7 +79,7 @@ <h2 class="govuk-heading-m" id="hearingSummary">
></app-booking-edit>

<div class="govuk-form-group vhtable">
<div *ngFor="let endpoint of endpoints; let i = index" id="endpointtext{{ +i }}" class="vh-text-break">
<div *ngFor="let endpoint of hearing.endpoints; let i = index" id="endpointtext{{ +i }}" class="vh-text-break">
<div class="govuk-grid-row govuk-!-padding-bottom-1">
<div class="govuk-grid-column-one-half" id="displayName{{ +i }}">
{{ endpoint.displayName }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
BookHearingException,
BookingStatus,
HearingDetailsResponse,
JudiciaryParticipantResponse,
MultiHearingRequest,
UpdateBookingStatusResponse,
ValidationProblemDetails
Expand All @@ -39,7 +40,7 @@ import { TruncatableTextComponent } from 'src/app/shared/truncatable-text/trunca
import { ReferenceDataService } from 'src/app/services/reference-data.service';
import { VHBooking } from 'src/app/common/model/vh-booking';
import { VHParticipant } from 'src/app/common/model/vh-participant';
import { HearingRoles } from 'src/app/common/model/hearing-roles.model';
import { JudicialMemberDto } from '../judicial-office-holders/models/add-judicial-member.model';

function initExistingHearingRequest(): VHBooking {
const pat1 = new VHParticipant();
Expand Down Expand Up @@ -272,9 +273,9 @@ describe('SummaryComponent with valid request', () => {
expect(component.otherInformation.OtherInformation).toEqual(
stringifier.decode<OtherInformationModel>(existingRequest.otherInformation).OtherInformation
);
expect(component.hearingDate).toEqual(existingRequest.scheduledDateTime);
expect(component.hearing.scheduledDateTime).toEqual(existingRequest.scheduledDateTime);
const courtString = MockValues.Courts.find(c => c.id === existingRequest.hearingVenueId);
expect(component.courtRoomAddress).toEqual(`${courtString.name}, 123W`);
expect(component.hearing.courtRoomAddress).toEqual(`${courtString.name}, 123W`);
});
it('should remove participant', () => {
component.ngOnInit();
Expand Down Expand Up @@ -325,14 +326,14 @@ describe('SummaryComponent with valid request', () => {
expect(component.hearing.audioRecordingRequired).toBe(false);
});
it('should set audio recording to true if an interpreter is present', () => {
component.interpreterPresent = true;
component.hasParticipantsRequiringAudioRecording = true;
component.isAudioRecordingRequired();
fixture.detectChanges();
expect(component.hearing.audioRecordingRequired).toBe(true);
});
it('should set audio recording to false if Service is CACD and an interpreter is present', () => {
component.hearing.caseType = component.constants.CaseTypes.CourtOfAppealCriminalDivision;
component.interpreterPresent = true;
component.hasParticipantsRequiringAudioRecording = true;
component.isAudioRecordingRequired();
component.ngOnInit();
expect(component.hearing.audioRecordingRequired).toBe(false);
Expand All @@ -344,7 +345,7 @@ describe('SummaryComponent with valid request', () => {
});
it('should set audio recording to false if Service is Crime Crown Court and an interpreter is present', () => {
component.hearing.caseType = component.constants.CaseTypes.CrimeCrownCourt;
component.interpreterPresent = true;
component.hasParticipantsRequiringAudioRecording = true;
component.isAudioRecordingRequired();
component.ngOnInit();
expect(component.hearing.audioRecordingRequired).toBe(false);
Expand All @@ -354,13 +355,13 @@ describe('SummaryComponent with valid request', () => {
component.ngOnInit();
fixture.detectChanges();
const courtString = MockValues.Courts.find(c => c.id === existingRequest.hearingVenueId);
expect(component.courtRoomAddress).toEqual(`${courtString.name}`);
expect(component.hearing.courtRoomAddress).toEqual(`${courtString.name}`);
});
it('should display valid audio recording selected option', () => {
component.hearing.audioRecordingRequired = false;
component.ngOnInit();
fixture.detectChanges();
expect(component.audioChoice).toBe('No');
expect(component.hearing.audioChoice).toBe('No');
});
it('should remove interpretee and interpreter and clear the linked participant list on remove interpretee', () => {
component.ngOnInit();
Expand Down Expand Up @@ -524,20 +525,23 @@ describe('SummaryComponent with valid request', () => {

it('When booking status false will re-poll', fakeAsync(async () => {
videoHearingsServiceSpy.getStatus.calls.reset();
const participants: VHParticipant[] = [];
const participant = new VHParticipant();
participant.firstName = 'firstname';
participant.lastName = 'lastname';
participant.email = '[email protected]';
participant.hearingRoleName = HearingRoles.JUDGE;
participant.id = '100';
participants.push(participant);
component.hearing.participants = participants;
const judiciaryParticipants: JudiciaryParticipantResponse[] = [];
const judge = new JudiciaryParticipantResponse({
first_name: 'firstname',
last_name: 'lastname',
full_name: 'fullname',
email: '[email protected]',
personal_code: 'personalCode',
role_code: 'Judge'
});
judiciaryParticipants.push(judge);
const mappedJudiciaryParticipants = judiciaryParticipants.map(j => JudicialMemberDto.fromJudiciaryParticipantResponse(j));
component.hearing.judiciaryParticipants = mappedJudiciaryParticipants;
const response = {
id: 'hearing_id',
status: BookingStatus.Failed,
created_by: '[email protected]',
participants: participants
judiciary_participants: judiciaryParticipants
} as unknown as HearingDetailsResponse;

videoHearingsServiceSpy.saveHearing.and.returnValue(Promise.resolve(response));
Expand Down Expand Up @@ -745,8 +749,8 @@ describe('SummaryComponent with existing request', () => {
fixture.detectChanges();
expect(component.caseNumber).toBe('TX/12345/2018');
expect(component.caseName).toBe('Mr. Test User vs HMRC');
expect(component.courtRoomAddress).toBeTruthy();
expect(component.hearingDuration).toBe('listed for 1 hour 20 minutes');
expect(component.hearing.courtRoomAddress).toBeTruthy();
expect(component.hearing.hearingDuration).toBe('listed for 1 hour 20 minutes');
});
it('should hide pop up if continue booking pressed', () => {
component.continueBooking();
Expand Down Expand Up @@ -947,13 +951,15 @@ describe('SummaryComponent with multi days request', () => {
component.hearing.endHearingDateTime.setDate(component.hearing.endHearingDateTime.getDate() + 7);
component.ngOnInit();

expect(new Date(component.hearingDate).getDate()).toEqual(new Date(existingRequest.scheduledDateTime).getDate());
expect(new Date(component.hearing.scheduledDateTime).getDate()).toEqual(new Date(existingRequest.scheduledDateTime).getDate());
expect(new Date(component.endHearingDate).getDate()).toEqual(new Date(existingRequest.endHearingDateTime).getDate());

expect(new Date(component.hearingDate).getMonth()).toEqual(new Date(existingRequest.scheduledDateTime).getMonth());
expect(new Date(component.hearing.scheduledDateTime).getMonth()).toEqual(new Date(existingRequest.scheduledDateTime).getMonth());
expect(new Date(component.endHearingDate).getMonth()).toEqual(new Date(existingRequest.endHearingDateTime).getMonth());

expect(new Date(component.hearingDate).getFullYear()).toEqual(new Date(existingRequest.scheduledDateTime).getFullYear());
expect(new Date(component.hearing.scheduledDateTime).getFullYear()).toEqual(
new Date(existingRequest.scheduledDateTime).getFullYear()
);
expect(new Date(component.endHearingDate).getFullYear()).toEqual(new Date(existingRequest.endHearingDateTime).getFullYear());
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { Subject, Subscription, combineLatest } from 'rxjs';
import { EndpointModel } from 'src/app/common/model/endpoint.model';
import { HearingRoles } from 'src/app/common/model/hearing-roles.model';
import { RemoveInterpreterPopupComponent } from 'src/app/popups/remove-interpreter-popup/remove-interpreter-popup.component';
import { Constants } from '../../common/constants';
import { FormatShortDuration } from '../../common/formatters/format-short-duration';
import { VHBooking } from 'src/app/common/model/vh-booking';
import { RemovePopupComponent } from '../../popups/remove-popup/remove-popup.component';
import { BookingService } from '../../services/booking.service';
Expand Down Expand Up @@ -41,13 +39,7 @@ export class SummaryComponent implements OnInit, OnDestroy {
canNavigate = true;
failedSubmission: boolean;
bookingsSaving = false;
caseNumber: string;
caseName: string;
hearingDate: Date;
courtRoomAddress: string;
hearingDuration: string;
otherInformation: OtherInformationModel;
audioChoice: string;
showConfirmationRemoveParticipant = false;
selectedParticipantEmail: string;
removerFullName: string;
Expand All @@ -56,21 +48,17 @@ export class SummaryComponent implements OnInit, OnDestroy {
private readonly newHearingSessionKey = 'newHearingId';
isExistingBooking = false;
$subscriptions: Subscription[] = [];
caseType: string;
bookinConfirmed = false;
endpoints: EndpointModel[] = [];
switchOffRecording = false;
multiDays: boolean;
endHearingDate: Date;
interpreterPresent: boolean;
hasParticipantsRequiringAudioRecording: boolean;

@ViewChild(ParticipantListComponent, { static: true })
participantsListComponent: ParticipantListComponent;
showConfirmRemoveInterpretee = false;

@ViewChild(RemovePopupComponent) removePopupComponent: RemovePopupComponent;
@ViewChild(RemoveInterpreterPopupComponent) removeInterpreterPopupComponent: RemoveInterpreterPopupComponent;
judgeAssigned: boolean;
saveFailedMessages: string[];
multiDayBookingEnhancementsEnabled: boolean;

Expand All @@ -97,7 +85,9 @@ export class SummaryComponent implements OnInit, OnDestroy {
this.otherInformation = OtherInformationModel.init(this.hearing.otherInformation);
this.retrieveHearingSummary();
this.switchOffRecording = this.recordingGuardService.switchOffRecording(this.hearing.caseType);
this.interpreterPresent = this.recordingGuardService.mandatoryRecordingForHearingRole(this.hearing.participants);
this.hasParticipantsRequiringAudioRecording = this.recordingGuardService.mandatoryRecordingForHearingRole(
this.hearing.participants
);
this.hearing.audioRecordingRequired = this.isAudioRecordingRequired();
this.retrieveHearingSummary();
if (this.participantsListComponent) {
Expand All @@ -109,9 +99,6 @@ export class SummaryComponent implements OnInit, OnDestroy {
})
);
}
this.judgeAssigned =
this.hearing.participants.filter(e => e.isJudge).length > 0 ||
this.hearing.judiciaryParticipants?.some(e => e.roleCode === 'Judge');

const multiDayBookingEnhancementsFlag$ = this.featureService
.getFlag<boolean>(FeatureFlags.multiDayBookingEnhancements)
Expand Down Expand Up @@ -141,13 +128,13 @@ export class SummaryComponent implements OnInit, OnDestroy {
isAudioRecordingRequired(): boolean {
// CACD hearings should always have recordings set to off
if (
this.caseType === this.constants.CaseTypes.CourtOfAppealCriminalDivision ||
this.caseType === this.constants.CaseTypes.CrimeCrownCourt
this.hearing.caseType === this.constants.CaseTypes.CourtOfAppealCriminalDivision ||
this.hearing.caseType === this.constants.CaseTypes.CrimeCrownCourt
) {
return false;
}
// Hearings with an interpreter should always have recording set to on
if (this.interpreterPresent) {

if (this.hasParticipantsRequiringAudioRecording) {
return true;
}
return this.hearing.audioRecordingRequired;
Expand Down Expand Up @@ -219,15 +206,6 @@ export class SummaryComponent implements OnInit, OnDestroy {
}

private retrieveHearingSummary() {
this.caseNumber = this.hearing.case ? this.hearing.case.number : '';
this.caseName = this.hearing.case ? this.hearing.case.name : '';
this.hearingDate = this.hearing.scheduledDateTime;
this.hearingDuration = `listed for ${FormatShortDuration(this.hearing.scheduledDuration)}`;
this.courtRoomAddress = this.formatCourtRoom(this.hearing.courtName, this.hearing.courtRoom);
this.audioChoice = this.hearing.audioRecordingRequired ? 'Yes' : 'No';
this.caseType = this.hearing.caseType;
this.endpoints = this.hearing.endpoints;
this.multiDays = this.hearing.isMultiDayEdit;
this.endHearingDate = this.hearing.endHearingDateTime;

if (
Expand All @@ -240,7 +218,7 @@ export class SummaryComponent implements OnInit, OnDestroy {
}

get hasEndpoints(): boolean {
return this.endpoints.length > 0;
return this.hearing.endpoints.length > 0;
}

removeEndpoint(rowIndex: number): void {
Expand Down Expand Up @@ -301,7 +279,7 @@ export class SummaryComponent implements OnInit, OnDestroy {

const hearingDetailsResponse = await this.hearingService.saveHearing(this.hearing);

if (this.judgeAssigned) {
if (this.hearing.judge) {
this.bookingStatusService.pollForStatus(hearingDetailsResponse.id).subscribe(async response => {
await this.processBooking(hearingDetailsResponse, response);
});
Expand Down Expand Up @@ -433,7 +411,7 @@ export class SummaryComponent implements OnInit, OnDestroy {
return;
}
sessionStorage.setItem(this.newHearingSessionKey, hearingDetailsResponse.id);
if (this.judgeAssigned && noJudgePrior) {
if (this.hearing.judge && noJudgePrior) {
this.showWaitSaving = true;
this.bookingStatusService
.pollForStatus(hearingDetailsResponse.id)
Expand Down Expand Up @@ -548,4 +526,12 @@ export class SummaryComponent implements OnInit, OnDestroy {
navToAddJudge() {
this.router.navigate([PageUrls.AddJudicialOfficeHolders]);
}

get caseNumber(): string {
return this.hearing.case.number;
}

get caseName(): string {
return this.hearing.case.name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ describe('mapHearingToVHBooking', () => {
});

describe('mapBookingsHearingResponseToVHBooking', () => {
it('should map BookingsHearingResponse to VHBooking', () => {
// Arrange
const response = new BookingsHearingResponse();
let response: BookingsHearingResponse;

beforeEach(() => {
response = new BookingsHearingResponse();
response.hearing_id = 'hearing-id';
response.scheduled_date_time = new Date();
response.scheduled_duration = 90;
Expand All @@ -111,8 +112,10 @@ describe('mapBookingsHearingResponseToVHBooking', () => {
response.conference_supplier = VideoSupplier.Vodafone;
response.judge_name = 'judge-name';
response.group_id = 'group-id';
});

// Act
it('should map BookingsHearingResponse to VHBooking', () => {
// Arrange & Act
const result = mapBookingsHearingResponseToVHBooking(response);

// Assert
Expand All @@ -130,9 +133,23 @@ describe('mapBookingsHearingResponseToVHBooking', () => {
expect(result.status).toBe(response.status.toString());
expect(result.audioRecordingRequired).toBe(response.audio_recording_required);
expect(result.supplier).toBe(response.conference_supplier);
expect(result.judiciaryParticipants.length).toBe(1);
expect(result.judiciaryParticipants[0].displayName).toBe(response.judge_name);
expect(result.judge.displayName).toBe(response.judge_name);
expect(result.groupId).toBe(response.group_id);
});

it('should map BookingsHearingResponse to VHBooking without judge', () => {
// Arrange
response.judge_name = null;

// Act
const result = mapBookingsHearingResponseToVHBooking(response);

// Assert
expect(result.judiciaryParticipants.length).toBe(0);
expect(result.judge).toBe(null);
});
});

describe('mapParticipantResponseToVHParticipant', () => {
Expand Down
Loading

0 comments on commit 14dea79

Please sign in to comment.