Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mes-9988-CancellingMOTRequests #1730

Merged
merged 5 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[category]="pageState.category$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -47,6 +48,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[category]="pageState.category$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -67,6 +68,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
[category]="pageState.category$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -63,6 +64,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
[category]="pageState.category$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand All @@ -33,6 +34,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
[category]="pageState.category$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -53,6 +54,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[isDelegated]="pageState.delegatedTest$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -43,6 +44,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[isDelegated]="pageState.delegatedTest$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -43,6 +44,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>
<ion-row *ngIf="(pageState.motEvidenceProvided$ | async) === false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[isDelegated]="pageState.delegatedTest$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -43,6 +44,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
[category]="pageState.category$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand Down Expand Up @@ -56,6 +57,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[isDelegated]="pageState.delegatedTest$ | async"
[isPracticeMode]="isPracticeMode"
[shouldAuthenticate]="false"
(endTestLinkClicked)="abortMOTCall()"
>
</end-test-link>
</ion-buttons>
Expand All @@ -34,6 +35,7 @@
[isPracticeMode]="isEndToEndPracticeMode"
[vehicleRegistration]="pageState.registrationNumber$ | async"
[isRekeyMode]="pageState.isRekeyMode$ | async"
[abortSubject]="abortSubject"
>
</vehicle-registration>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ describe('VehicleRegistrationComponent', () => {
});
});

describe('abortMOTCall', () => {
it('should emit a value from abortSubject', () => {
spyOn(component.abortSubject, 'next');
component.abortMOTCall();
expect(component.abortSubject.next).toHaveBeenCalled();
});
});

describe('invalid', () => {
it('should return true if the formControl is invalid and dirty', () => {
component.formControl.setValue(null);
Expand Down Expand Up @@ -117,23 +125,23 @@ describe('VehicleRegistrationComponent', () => {
});
describe('shouldDisableMOTButton', () => {
it('should return true if the search spinner is shown', () => {
component.showSearchSpinner = true;
component.isSearchingForMOT = true;
component.formControl.setValue('valid');
spyOn(component['networkState'], 'getNetworkState').and.returnValue(ConnectionStatus.ONLINE);

expect(component.shouldDisableMOTButton()).toBeTrue();
});

it('should return true if the form control is not valid', () => {
component.showSearchSpinner = false;
component.isSearchingForMOT = false;
component.formControl.setValue(null);
spyOn(component['networkState'], 'getNetworkState').and.returnValue(ConnectionStatus.ONLINE);

expect(component.shouldDisableMOTButton()).toBeTrue();
});

it('should return true if the network state is offline and not in practice mode', () => {
component.showSearchSpinner = false;
component.isSearchingForMOT = false;
component.formControl.setValue('valid');
component.isPracticeMode = false;
spyOn(component['networkState'], 'getNetworkState').and.returnValue(ConnectionStatus.OFFLINE);
Expand All @@ -142,15 +150,15 @@ describe('VehicleRegistrationComponent', () => {
});

it('should return false if the search spinner is not shown, form control is valid, and network state is online', () => {
component.showSearchSpinner = false;
component.isSearchingForMOT = false;
component.formControl.setValue('valid');
spyOn(component['networkState'], 'getNetworkState').and.returnValue(ConnectionStatus.ONLINE);

expect(component.shouldDisableMOTButton()).toBeFalse();
});

it('should return false if the search spinner is not shown, form control is valid, and in practice mode', () => {
component.showSearchSpinner = false;
component.isSearchingForMOT = false;
component.formControl.setValue('valid');
component.isPracticeMode = true;
spyOn(component['networkState'], 'getNetworkState').and.returnValue(ConnectionStatus.OFFLINE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</ion-button>
</ion-col>
<ion-col size="10">
<ion-spinner class="search-spinner" name="bubbles" *ngIf="showSearchSpinner"></ion-spinner>
<ion-spinner class="search-spinner" name="bubbles" *ngIf="isSearchingForMOT"></ion-spinner>
</ion-col>
</ion-row>
<ion-row class="validation-message-row ion-align-items-center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
nonAlphaNumericValues,
} from '@shared/constants/field-validators/field-validators';
import { isEmpty } from 'lodash-es';
import { Subject } from 'rxjs';
import { finalize, takeUntil } from 'rxjs/operators';

@Component({
selector: 'vehicle-registration',
Expand All @@ -32,6 +34,8 @@ export class VehicleRegistrationComponent implements OnChanges {
isPracticeMode: boolean;
@Input()
isRekeyMode: boolean;
@Input()
abortSubject: Subject<void> = new Subject<void>();

@Output()
vehicleRegistrationChange = new EventEmitter<string>();
Expand All @@ -48,7 +52,7 @@ export class VehicleRegistrationComponent implements OnChanges {
motData: MotHistoryWithStatus = null;
modalData: string = null;
hasCalledMOT = false;
showSearchSpinner = false;
isSearchingForMOT = false;

readonly registrationNumberValidator: FieldValidators = getRegistrationNumberValidator();

Expand All @@ -73,61 +77,61 @@ export class VehicleRegistrationComponent implements OnChanges {
async getMOT(value: string) {
this.clearData();
this.hasCalledMOT = false;
this.showSearchSpinner = true;
this.isSearchingForMOT = true;

if (!this.isPracticeMode) {
const apiCall$ = this.motApiService.getMotHistoryByIdentifier(value);

apiCall$.subscribe(async (val) => {
// Assign the API response to the motData property
this.motData = val;
// Emit the vehicle registration number to update the search list
this.vrnSearchListUpdate.emit(value);

// If the MOT status is not valid, open the reconfirm modal
if (this.motData?.data?.status === MotStatusCodes.NOT_VALID) {
await this.loadFailedMOTModal();
// If the modal was cancelled, stop the spinner and return
if (this.modalData === ModalEvent.CANCEL) {
this.showSearchSpinner = false;
return;
apiCall$
.pipe(
takeUntil(this.abortSubject),
finalize(() => {
// Stop the search spinner
this.isSearchingForMOT = false;
})
)
.subscribe(async (val) => {
// Assign the API response to the motData property
this.motData = val;
// Emit the vehicle registration number to update the search list
this.vrnSearchListUpdate.emit(value);

// If the MOT status is not valid, open the reconfirm modal
if (this.motData?.data?.status === MotStatusCodes.NOT_VALID) {
await this.loadFailedMOTModal();
// If the modal was cancelled, stop the spinner and return
if (this.modalData === ModalEvent.CANCEL) {
this.isSearchingForMOT = false;
return;
}
}

// Set the flag indicating that the MOT call has been made
this.hasCalledMOT = true;
// Stop the search spinner
this.isSearchingForMOT = false;
// If motData is not null, emit the vehicle details
if (this.motData) {
this.motDetailsUpdate.emit(this.motData?.data);
}
}

// Set the flag indicating that the MOT call has been made
this.hasCalledMOT = true;
// Stop the search spinner
this.showSearchSpinner = false;
// If motData is not null, emit the vehicle details
if (this.motData) {
this.motDetailsUpdate.emit(this.motData?.data);
}
});
});
} else {
// Load the practice mode modal and wait for the user's response
const fakeModalReturn = await this.loadPracticeModeModal();

// If the user indicates that the MOT failed, load the failed MOT modal
if (fakeModalReturn === PracticeModeMOTType.FAILED) {
await this.loadFailedMOTModal();
// If the modal was cancelled, stop the spinner and return
if (this.modalData === ModalEvent.CANCEL) {
this.showSearchSpinner = false;
return;
}
}

// If the user cancelled the practice mode modal, reset motData and stop the spinner
if (fakeModalReturn === ModalEvent.CANCEL) {
this.motData = null;
this.showSearchSpinner = false;
return;
}

// Set the flag indicating that the MOT call has been made
this.hasCalledMOT = true;
// Stop the search spinner
this.showSearchSpinner = false;

// Make a mock API call to get the MOT result based on the practice mode response
this.motApiService
Expand Down Expand Up @@ -179,6 +183,9 @@ export class VehicleRegistrationComponent implements OnChanges {

vehicleRegistrationChanged(event: any): void {
this.clearData();
if (this.isSearchingForMOT) {
this.abortMOTCall();
}
this.hasCalledMOT = false;
if (typeof event.target.value === 'string' && !this.registrationNumberValidator.pattern.test(event.target.value)) {
event.target.value = event.target.value?.replace(nonAlphaNumericValues, '');
Expand Down Expand Up @@ -220,9 +227,19 @@ export class VehicleRegistrationComponent implements OnChanges {
*/
shouldDisableMOTButton(): boolean {
return !(
!this.showSearchSpinner &&
!this.isSearchingForMOT &&
this.formControl.valid &&
(this.networkState.getNetworkState() == ConnectionStatus.ONLINE || this.isPracticeMode)
);
}

/**
* Aborts the ongoing MOT call.
*
* This method emits a value from the `abortSubject`,
* which is used to signal the abortion of the ongoing HTTP request.
*/
abortMOTCall() {
this.abortSubject.next();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,12 @@ describe('WaitingRoomToCarBasePageComponent', () => {
] as QuestionResult[]);
});
});

describe('abortMOTCall', () => {
it('should emit a value from abortSubject', () => {
spyOn(basePageComponent.abortSubject, 'next');
basePageComponent.abortMOTCall();
expect(basePageComponent.abortSubject.next).toHaveBeenCalled();
});
});
});
Loading
Loading