Untitled
unknown
plain_text
2 years ago
9.7 kB
4
Indexable
import { HttpClient } from '@angular/common/http'; import { HttpClientTestingModule } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { of } from 'rxjs'; import { mockLocationCheckResponse } from 'src/app/mocks/location.mock'; import { AALocation } from '../models'; import { EnvService } from './env.service'; import { AALocationService } from './location.service'; describe('AALocationService', () => { let aaLocationService: AALocationService; let httpClientSpy: jasmine.SpyObj<HttpClient>; let routerSpy: jasmine.SpyObj<Router>; let envServiceSpy: jasmine.SpyObj<EnvService>; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], }); httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']); envServiceSpy = jasmine.createSpyObj('EnvService', ['']); envServiceSpy.customerPoliciesURL = '/test'; routerSpy = jasmine.createSpyObj('Router', ['']); routerSpy.navigate = jasmine.createSpy(); httpClientSpy.get = jasmine.createSpy().and.returnValue(of(mockLocationCheckResponse)); aaLocationService = new AALocationService(httpClientSpy, routerSpy, envServiceSpy); }); it('should be created', () => { expect(aaLocationService).toBeTruthy(); }); it('should call getGeolocation', () => { spyOn(navigator.geolocation, 'getCurrentPosition').and.callFake((...args: any[]) => { const position = { coords: { latitude: 0, longitude: 0 } }; args[0](position); }); aaLocationService.getGeolocation().subscribe((data) => { expect(data.location.latitude).toBe(0); expect(data.location.longitude).toBe(0); }); }); it('should call getGeolocation with error', () => { spyOn(navigator.geolocation, 'getCurrentPosition').and.callFake((...args: any[]) => { const error = { code: 'noPermission', }; args[1](error.code); }); aaLocationService.getGeolocation().subscribe((errorObj) => { expect(errorObj.error).toBe('noPermission'); }); }); it('should call checkLocation', () => { aaLocationService.checkLocation({ latitude: 1, longitude: 1 }).subscribe((data) => { expect(data).toEqual(mockLocationCheckResponse); }); }); it('should call checkLocationFromLocation', () => { spyOn(aaLocationService, 'checkLocation').and.returnValue(of(mockLocationCheckResponse)); aaLocationService.checkLocationFromLocation(mockLocationCheckResponse as AALocation); expect(aaLocationService.checkLocation).toHaveBeenCalled(); }); it('should call checkLocationFromLocation', () => { spyOn(aaLocationService, 'checkLocation').and.returnValue(of(mockLocationCheckResponse)); aaLocationService.checkLocationFromLocation(mockLocationCheckResponse as AALocation).subscribe((_x) => { expect(aaLocationService.checkLocation).toHaveBeenCalled(); }); }); it('should call checkLocationFromLocation', () => { spyOn(aaLocationService, 'checkLocation').and.returnValue(of(null)); aaLocationService.checkLocationFromLocation(mockLocationCheckResponse as AALocation).subscribe((_x) => { expect(aaLocationService.checkLocation).toHaveBeenCalled(); }); }); it('should call getLocationFromGeolocationOnce', () => { spyOn(aaLocationService, 'getGeolocation').and.returnValue(of(mockLocationCheckResponse)); aaLocationService.getLocationFromGeolocation(); expect(aaLocationService.getGeolocation).toHaveBeenCalled(); }); it('should call processLocationResult', () => { let loc = { location: { isAllowed: false, minAccuracy: 1, isAccurate: function () { return true; }, }, }; spyOn(aaLocationService, 'checkLocationFromLocation'); aaLocationService['processLocationResult'](loc); expect(aaLocationService.checkLocationFromLocation).toHaveBeenCalledWith(loc.location); }); it('getLocationFromAddress$', async () => { spyOn(aaLocationService, 'getLocationFromAddress').and.returnValue(of({}).toPromise()); aaLocationService.getLocationFromAddress$('456677').subscribe((_x) => { expect(aaLocationService.getLocationFromAddress).toHaveBeenCalled(); }); }); }); . . . . . import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { from, Observable, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; import { environment } from 'src/environments/environment'; import { SETTINGS } from '../app.settings'; import { AALocation, ILocationCheckResponse, ILocationResult, LocationErrorCode } from '../models'; import { ICustomerDetails } from '../models/policy.model'; import { RaboRoutes } from '../routing/rabo-routes.model'; import { EnvService } from './env.service'; @Injectable({ providedIn: 'root' }) export class AALocationService { constructor(private http: HttpClient, private router: Router, private envService: EnvService) {} getGeolocation(): Observable<ILocationResult> { return new Observable<ILocationResult>((observer) => { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( ({ coords }) => { observer.next({ location: new AALocation(coords) }); observer.complete(); }, (error) => { if (error.code === error.PERMISSION_DENIED) { observer.next({ error: LocationErrorCode.noPermission }); observer.complete(); } if (error.code === error.POSITION_UNAVAILABLE) { observer.next({ error: LocationErrorCode.notAvailable }); observer.complete(); } }, SETTINGS.positionOptions ); } else { observer.next({ error: LocationErrorCode.unknown }); observer.complete(); } }); } getLocationFromGeolocation(): Observable<ILocationResult> { return this.getGeolocation().pipe( switchMap((loc) => { return !loc.error ? this.processLocationResult(loc) : of(loc); }) ); } private processLocationResult(loc: ILocationResult): Observable<ILocationResult> { loc.location.isAllowed = true; loc.location.minAccuracy = SETTINGS.googleMaps.mapOptions.minAccuracy; return loc.location.isAccurate() ? this.checkLocationFromLocation(loc.location) : of({ location: loc.location }); } checkLocationFromLocation(location: AALocation): Observable<ILocationResult> { return this.checkLocation(location).pipe( map((result) => { if (result && result.location) { location.latitude = result.location.coordinates.latitude; location.longitude = result.location.coordinates.longitude; location.dangerousLocation = result.dangerousLocation; location.motorway = result.motorway; location.area = result.location.area; location.text = result.location.text; location.formattedAddressFromGeoLocation = result.formatted_address; return { location }; } else { this.router.navigate([RaboRoutes.Error, 'TryAgainErrorPage'], { queryParamsHandling: 'preserve' }); return { error: LocationErrorCode.nullLocationResponse }; } }) ); } checkLocation({ longitude, latitude }: AALocation): Observable<ILocationCheckResponse> { const params: HttpParams = new HttpParams().set('lat', latitude?.toString()).set('lng', longitude?.toString()); return this.http .get<ILocationCheckResponse>(environment.locationCheckURL, { params }) .pipe(catchError(() => of({} as ILocationCheckResponse))); } getLocationFromAddress$(postCode: string, firstLineOfAddress?: string): Observable<AALocation> { return from(this.getLocationFromAddress(postCode, firstLineOfAddress)); } async getLocationFromAddress(postCode: string, firstLineOfAddress?: string): Promise<AALocation> { const geocoder = new google.maps.Geocoder(); postCode = postCode.trim().replace(/\s+/g, ' ').toUpperCase(); return new Promise((resolve, reject) => { const address = firstLineOfAddress ? `${firstLineOfAddress}, ${postCode}` : postCode; geocoder.geocode( { address, componentRestrictions: { country: 'UK' }, }, (results, status) => { if (status === 'OK') { const slicedPostCode = new RegExp(postCode.replace(/\s.*$/, '').slice(0, 4), 'i'); if (slicedPostCode.test(results[0].formatted_address)) { resolve({ latitude: results[0].geometry.location.lat(), longitude: results[0].geometry.location.lng(), }); } else if (firstLineOfAddress) { resolve(this.getLocationFromAddress(postCode)); } else { reject({ error: status }); } } else if (status === 'ZERO_RESULTS' && firstLineOfAddress) { resolve(this.getLocationFromAddress(postCode)); } else { reject({ error: status }); } } ); }); } getPoliciesDetails(): Observable<ICustomerDetails> { return this.http.get<ICustomerDetails>(this.envService.customerPoliciesURL).pipe( map((value: any) => value.customerDetails as ICustomerDetails), catchError(() => of(null)) ); } }
Editor is loading...