diff --git a/src/assets/config/config.json b/src/assets/config/config.json index a1eadc0aaa..607b8eb27e 100644 --- a/src/assets/config/config.json +++ b/src/assets/config/config.json @@ -21,7 +21,7 @@ "activity_next_poll_request_ms": 30000, "activity_retry": 30, "timeouts_case_retrieval": [ - 18 + 18, 17 ], "timeouts_case_retrieval_artificial_delay": 0, "activity_url": "/activity", @@ -53,4 +53,4 @@ "oauthCallbackUrl": "oauth2/callback" } } -} \ No newline at end of file +} diff --git a/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.spec.ts b/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.spec.ts index 355d98d3cf..2f980a8418 100644 --- a/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.spec.ts +++ b/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; -import { FormControl } from '@angular/forms'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { RefDataService } from '@hmcts/rpx-xui-common-lib'; import { of } from 'rxjs'; @@ -17,7 +17,8 @@ describe('StaffSelectLocationComponent', () => { refDataServiceMock.getLocationsByServiceCodes.and.returnValue(of([])); await TestBed.configureTestingModule({ - imports: [MatAutocompleteModule], + imports: [MatAutocompleteModule, + ReactiveFormsModule], declarations: [StaffSelectLocationComponent], providers: [ { provide: RefDataService, useValue: refDataServiceMock } @@ -262,8 +263,11 @@ describe('StaffSelectLocationComponent', () => { })); it('should get an array when search term is not an empty string', fakeAsync(() => { + // obsCount added as observable should always run initially + let obsCount = 0; component.filteredList$.subscribe((result) => { - expect(Array.isArray(result)).toBe(true); + obsCount > 0 ? expect(Array.isArray(result)).toBe(true) : expect(Array.isArray(result)).toBe(false); + obsCount++; }); component.searchTermFormControl.setValue('123'); @@ -273,9 +277,10 @@ describe('StaffSelectLocationComponent', () => { it('should filter out locations based on searchTerm', fakeAsync(() => { refDataServiceMock.getLocationsByServiceCodes.and.returnValue(of([dummyLocations[0], dummyLocations[1]])); - component.locationsControl.setValue([dummyLocations[0], dummyLocations[1]]); + let obsCount = 0; component.filteredList$.subscribe((result) => { - expect(result).toEqual([dummyLocations[0]]); + obsCount > 0 ? expect(result).toEqual([dummyLocations[0]]) : expect(Array.isArray(result)).toBe(false); + obsCount++; }); component.searchTermFormControl.setValue(dummyLocations[0].venue_name); @@ -285,14 +290,36 @@ describe('StaffSelectLocationComponent', () => { it('should fill locations with correct service codes', fakeAsync(() => { refDataServiceMock.getLocationsByServiceCodes.and.returnValue(of([dummyLocations[0], dummyLocations[1]])); + let obsCount = 0; component.filteredList$.subscribe((result) => { - expect(result).toEqual([dummyLocations[0]]); - expect(result[0].serviceCodes).toEqual(['BFA1', 'AAA7']); + if (obsCount > 1) { + expect(result).toEqual([dummyLocations[0]]); + expect(result[0].serviceCodes).toEqual(['BFA1', 'AAA7']); + } + obsCount++; }); component.searchTermFormControl.setValue(dummyLocations[0].venue_name); tick(); flush(); })); + + it('should correctly set service codes for locations in formControl', fakeAsync(() => { + refDataServiceMock.getLocationsByServiceCodes.and.returnValue(of([dummyLocations[0], dummyLocations[1]])); + const mockLocationInControl: any = dummyLocations[0]; + // also ensures we are checking numbers as well as strings + mockLocationInControl.location_id = parseInt(mockLocationInControl.epimms_id); + component.locationsControl.setValue([mockLocationInControl]); + let obsCount = 0; + component.filteredList$.subscribe((result) => { + obsCount > 0 ? expect(result).toEqual([dummyLocations[0]]) : expect(result).toEqual(false); + expect(component.locationsControl.value[0].serviceCodes[0]).toEqual('BFA1'); + obsCount++; + }); + + component.searchTermFormControl.setValue(dummyLocations[0].venue_name); + tick(); + flush(); + })); }); }); }); diff --git a/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.ts b/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.ts index 63c7ae71b0..46b6b45f03 100644 --- a/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.ts +++ b/src/staff-administrator/components/staff-add-edit-user/staff-add-edit-user-form/staff-select-location/staff-select-location.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; import { RefDataService } from '@hmcts/rpx-xui-common-lib'; import { combineLatest, iif, Observable, of } from 'rxjs'; -import { map, switchMap, tap } from 'rxjs/operators'; +import { map, startWith, switchMap, tap } from 'rxjs/operators'; import { LocationByEpimmsModelWithServiceCodes } from '../../../../models/location-by-service-code-model'; import { StaffUserLocation } from '../../../../models/staff-user-location.model'; @@ -22,6 +22,8 @@ export class StaffSelectLocationComponent implements OnInit { public autocompleteSelectedLocation: LocationByEpimmsModelWithServiceCodes | false; private fullLocations: LocationByEpimmsModelWithServiceCodes[]; + private initialLocationServicesSet = false; + public get selectedLocations(): StaffUserLocation[] { return this.locationsControl?.value; } @@ -30,7 +32,7 @@ export class StaffSelectLocationComponent implements OnInit { public ngOnInit() { this.filteredList$ = combineLatest([ - this.searchTermFormControl.valueChanges, + this.searchTermFormControl.valueChanges.pipe(startWith('')), this.serviceCodes$ ]).pipe( tap(([term]: [string, string[]]) => { @@ -39,7 +41,7 @@ export class StaffSelectLocationComponent implements OnInit { } }), switchMap(([term, serviceCodes]: [string, string[]]) => iif( - () => (!!term && term.length >= 0), + () => ((!!term && term.length >= 0) || !this.initialLocationServicesSet), this.refDataService.getLocationsByServiceCodes( serviceCodes ).pipe( @@ -64,7 +66,7 @@ export class StaffSelectLocationComponent implements OnInit { private setLocationServiceCodes(locations: LocationByEpimmsModelWithServiceCodes[]): LocationByEpimmsModelWithServiceCodes[] { locations.map((location) => { - const currentId = location.epimms_id; + const currentId = location.epimms_id.toString(); const serviceCodes = location.serviceCodes; location.serviceCodes = this.getAllServiceCodes(serviceCodes, currentId); }); @@ -72,11 +74,12 @@ export class StaffSelectLocationComponent implements OnInit { // note: we could edit location types to produce less code - i.e. making them the same const fixedSelectedLocations = this.locationsControl.value; fixedSelectedLocations.forEach((location) => { - const currentId = location.location_id; - const serviceCodes = location.service_codes; + const currentId = location.location_id.toString(); + const serviceCodes = location.service_codes ? location.service_codes : []; location.service_codes = this.getAllServiceCodes(serviceCodes, currentId); }); this.locationsControl.setValue(fixedSelectedLocations); + this.initialLocationServicesSet = true; return locations; } diff --git a/src/staff-administrator/models/location-by-service-code-model.ts b/src/staff-administrator/models/location-by-service-code-model.ts index 6b75385a03..16a802985d 100644 --- a/src/staff-administrator/models/location-by-service-code-model.ts +++ b/src/staff-administrator/models/location-by-service-code-model.ts @@ -1,5 +1,6 @@ export interface LocationByEpimmsModelWithServiceCodes { epimms_id: string; + location_id?: string; site_name?: string; court_name?: string; open_for_public?: string;