public async Task CalculateProviderLocationDistanceInMiles_Calculate_Distance_In_Miles_From_StudentPostcode_To_ProviderLocation_Using_LocationApi( string studentPostcode, double studentLat, double studentLon, double providerLat, double providerLon, int expectedMileageInMilesAfterRounding) { var postcodeLookupResultDto = new PostcodeLookupResultDto { Postcode = studentPostcode, Latitude = studentLat, Longitude = studentLon }; _locationApiClient.GetGeoLocationDataAsync(studentPostcode).Returns(postcodeLookupResultDto); var providerLocation = new ProviderLocation { Latitude = providerLat, Longitude = providerLon }; var providerLocations = new List <ProviderLocation> { providerLocation }; await _distanceCalculationService.CalculateProviderLocationDistanceInMiles(new PostcodeLocation { Postcode = studentPostcode }, providerLocations.AsQueryable()); var roundedDistanceInMiles = (int)Math.Round(providerLocation.DistanceInMiles, MidpointRounding.AwayFromZero); roundedDistanceInMiles.Should().Be(expectedMileageInMilesAfterRounding); await _locationApiClient.Received(1).GetGeoLocationDataAsync(studentPostcode); }
public async Task <(int totalCount, IEnumerable <ProviderLocation> searchResults)> Search( SearchRequest searchRequest) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug( "Search::requested search for {postcode} with {numberOfItems} for qualification {qualificationId}", searchRequest.Postcode, searchRequest.NumberOfItems, searchRequest.QualificationId); } var providerLocations = _providerDataService .GetProviderLocations(searchRequest.QualificationId); var providerLocationsWithDistances = await _distanceCalculationService.CalculateProviderLocationDistanceInMiles( new PostcodeLocation { Postcode = searchRequest.Postcode, Latitude = Convert.ToDouble(searchRequest.OriginLatitude), Longitude = Convert.ToDouble(searchRequest.OriginLongitude) }, providerLocations); var searchResults = providerLocationsWithDistances .OrderBy(pl => pl.DistanceInMiles) .Take(searchRequest.NumberOfItems) .Select(s => { s.JourneyUrl = _journeyService.GetDirectionsLink(searchRequest.Postcode, s); return(s); }); return(providerLocationsWithDistances.Count, searchResults); }
public async Task <(int totalCount, IEnumerable <ProviderLocation> searchResults)> Search(SearchRequest searchRequest) { _logger.LogInformation($"Search::requested search for {searchRequest.Postcode} with {searchRequest.NumberOfItems} for qualification {searchRequest.QualificationId}"); var stopwatch = Stopwatch.StartNew(); var providers = _providerDataService.GetProviders(); if (!providers.Any()) { return(0, new List <ProviderLocation>()); } var locations = _providerDataService.GetLocations(providers, searchRequest.QualificationId); var providerLocations = _providerDataService.GetProviderLocations(locations, providers); var providerLocationsWithDistances = await _distanceCalculationService.CalculateProviderLocationDistanceInMiles( new PostcodeLocation { Postcode = searchRequest.Postcode, Latitude = Convert.ToDouble(searchRequest.OriginLatitude), Longitude = Convert.ToDouble(searchRequest.OriginLongitude) }, providerLocations); var searchResults = providerLocationsWithDistances .OrderBy(pl => pl.DistanceInMiles) .Take(searchRequest.NumberOfItems) .Select(s => { s.JourneyUrl = _journeyService.GetDirectionsLink(searchRequest.Postcode, s); return(s); }) .ToList(); stopwatch.Stop(); _logger.LogInformation($"Search::Returning {searchResults.Count} results from {providerLocationsWithDistances.Count} locations in {stopwatch.ElapsedMilliseconds}ms {stopwatch.ElapsedTicks} ticks"); return(providerLocationsWithDistances.Count, searchResults); }
public async Task Search_Returns_ProviderLocations_With_Expected_Details() { var providers = new ProviderListBuilder() .Add() .Build() .AsQueryable(); _providerDataService.GetProviders().Returns(providers); const int numberOfItems = 1; const string postcode = "CV1 2WT"; var searchRequest = new SearchRequest { NumberOfItems = numberOfItems, Postcode = postcode, OriginLatitude = "1.5", OriginLongitude = "50" }; var locations = new List <Location> { providers.First().Locations.First() }.AsQueryable(); _providerDataService.GetLocations( Arg.Is <IQueryable <Provider> >(p => p == providers), Arg.Any <int?>()) .Returns(locations); var deliveryYears = new List <DeliveryYear> { new DeliveryYear { Year = providers.First().Locations.First().DeliveryYears.First().Year, Qualifications = new List <Qualification>() { new Qualification() { Id = providers.First().Locations.First().DeliveryYears.First() .Qualifications.First(), Name = "Test qualification" } } } }; var providerLocations = new List <ProviderLocation> { new ProviderLocation { ProviderName = providers.First().Name, Name = providers.First().Locations.First().Name, Postcode = providers.First().Locations.First().Postcode, Town = providers.First().Locations.First().Town, Latitude = providers.First().Locations.First().Latitude, Longitude = providers.First().Locations.First().Longitude, DistanceInMiles = 0, DeliveryYears = deliveryYears, Website = providers.First().Locations.First().Website, JourneyUrl = "" } }.AsQueryable(); _providerDataService.GetProviderLocations( Arg.Is <IQueryable <Location> >(l => l == locations), Arg.Is <IQueryable <Provider> >(p => p == providers)) .Returns(providerLocations); _distanceCalculationService.CalculateProviderLocationDistanceInMiles( Arg.Is <PostcodeLocation>(p => p.Postcode == searchRequest.Postcode), Arg.Any <IQueryable <ProviderLocation> >()) .Returns(args => { var pList = ((IEnumerable <ProviderLocation>)args[1]).ToList(); pList.ForEach(x => x.DistanceInMiles = 10); return(pList); }); _journeyService .GetDirectionsLink(searchRequest.Postcode, Arg.Any <ProviderLocation>()) .Returns("https://x.com"); var(totalCount, searchResults) = await _service.Search(searchRequest); totalCount.Should().Be(providerLocations.Count()); var searchResultsList = searchResults.ToList(); searchResultsList.Count.Should().Be(numberOfItems); var firstResult = searchResultsList.First(); firstResult.ProviderName.Should().Be(providers.First().Name); firstResult.Name.Should().Be(providers.First().Locations.First().Name); firstResult.Postcode.Should().Be(providers.First().Locations.First().Postcode); firstResult.Town.Should().Be(providers.First().Locations.First().Town); firstResult.Latitude.Should().Be(providers.First().Locations.First().Latitude); firstResult.Longitude.Should().Be(providers.First().Locations.First().Longitude); firstResult.Website.Should().Be(providers.First().Locations.First().Website); firstResult.DeliveryYears.Should().HaveCount(1); firstResult.DeliveryYears.First().Year.Should() .Be(providers.First().Locations.First().DeliveryYears.First().Year); firstResult.DeliveryYears.First().Qualifications.Should().HaveCount(1); firstResult.DeliveryYears.First().Qualifications.First().Id.Should() .Be(providers.First().Locations.First().DeliveryYears.First().Qualifications.First()); firstResult.DeliveryYears.First().Qualifications.First().Name.Should() .Be("Test qualification"); firstResult.JourneyUrl.Should().Be("https://x.com"); firstResult.DistanceInMiles.Should().Be(10); }