public void GetDestinationPrices_BadRequest(
            FlightDestinationRequest request,
            FlightsController flightsController
            )
        {
            // Act
            var result = flightsController.GetDestinationPrices(request).Result;

            // Assert
            result.Should().NotBeNull();
            result.Value.Should().BeNull();
            result.Result.Should().BeOfType <BadRequestResult>();
            ((StatusCodeResult)result.Result).StatusCode.Should().Be(400);
        }
        public void GetDestinationPrices_NoContent(
            [Frozen] Mock <IFlightsService> flightsService,
            FlightsController flightsController
            )
        {
            // Arrange
            //var request = new Fixture().Create<FlightDestinationRequest>();
            var request = new FlightDestinationRequest
            {
                DepartureAirportId = "MEL",
                Dates  = new DatesRequest(),
                Budget = new Budget()
                {
                    Min = 0, Max = 1000
                },
                SearchArea = new SearchArea()
                {
                    Nw = new Coordinates(43, -32),
                    Se = new Coordinates(32, 36)
                }
            };

            var airports = new List <AirportDto>()
            {
                new AirportDto
                {
                    // TODO ...
                }
            };
            var flights = new List <ReturnFlightDestinationDto>()
            {
                new ReturnFlightDestinationDto
                {
                    // TODO ...
                }
            };

            flightsService.Setup(_ => _.GetFlights(It.IsAny <string>())).Returns(flights);
            flightsService.Setup(_ => _.GetAirports()).Returns(airports);

            // Act
            var result = flightsController.GetDestinationPrices(request).Result;

            // Assert
            result.Should().NotBeNull();
            result.Result.Should().BeOfType <NoContentResult>();
            ((NoContentResult)result.Result).StatusCode.Should().Be(204);
        }
        public async Task <ActionResult <IEnumerable <FlightDestinationResponse> > > GetDestinationPrices(
            [FromBody] FlightDestinationRequest inputData)
        {
            // just for testing and must be deleted soon
            await Task.Delay(100); // TODO: remove this line

            if (inputData == null)
            {
                return(new BadRequestResult());
            }

            // Find related flights
            var allFlights      = _flightsService.GetFlights(inputData.DepartureAirportId);
            var allAirports     = _flightsService.GetAirports();
            var relatedAirports = _destinationsFilter
                                  .FilterAirports(allAirports, inputData.SearchArea)
                                  .ToList();
            var airportsIatas = relatedAirports.Select(a => a.IataCode);

            if (allFlights is null)
            {
                return(NoContent());
            }

            // Filtering:
            // Filter by flights to airports within requested area
            var filteredFlights = allFlights.Where(f => airportsIatas.Contains(f.To)).ToList();

            // Filter by Budget
            if (inputData.Budget != null)
            {
                filteredFlights = filteredFlights.Where(f =>
                                                        inputData.Budget.Min < f.LowestPrice && f.LowestPrice < inputData.Budget.Max).ToList();
            }

            // Filter by Dates
            filteredFlights = _destinationsFilter
                              .FilterFlightsByDates(filteredFlights, inputData.Dates)
                              .ToList();

            // It may happen that when unknown dates -> many same flights (with same from-to airports) filtered,
            // but with different prices
            // so need to select only MIN price for all same destinations
            filteredFlights = _destinationsFilter.FilterLowestPriceOnly(filteredFlights).ToList();

            // Map filtered flights to response
            var repsData = filteredFlights.Select(f =>
            {
                var destinationAirport = relatedAirports.First(a => a.IataCode == f.To);
                var priorityIdx        = FindPriorityIdx(relatedAirports, destinationAirport);
                return(new FlightDestinationResponse
                {
                    Price = f.LowestPrice * inputData.NumberOfPeople,
                    DestAirportCode = destinationAirport.IataCode,
                    CityName = destinationAirport.RelatedCityName,
                    Lat = destinationAirport.Lat,
                    Lng = destinationAirport.Lng,
                    PersonalPriorityIdx = priorityIdx,
                    FlightDates = new FlightDates
                    {
                        FlightMonthidx = f.DateDeparture.Month
                    }
                });
            }).ToList();

            return(repsData.Count > 0 ? Ok(repsData) : NoContent() as ActionResult);
        }
        public void GetDestinationPrices_OkResult(
            [Frozen] Mock <IFlightsService> flightsServiceMock,
            [Frozen] Mock <IDestinationsFilter> destinationsFilterMock,
            FlightsController flightsController
            )
        {
            // Arrange
            var request = new FlightDestinationRequest
            {
                DepartureAirportId = "MEL",
                Dates  = new DatesRequest(),
                Budget = new Budget()
                {
                    Min = 0, Max = 1000
                },
                SearchArea = new SearchArea()
                {
                    Nw = new Coordinates(43, -32),
                    Se = new Coordinates(32, 36)
                }
            };

            var flights = new List <ReturnFlightDestinationDto>()
            {
                new ReturnFlightDestinationDto
                {
                    To            = "MEL",
                    LowestPrice   = 50,
                    DateDeparture = DateTime.Now,
                    DateBack      = DateTime.Now
                }
            };

            var airports = new List <AirportDto>()
            {
                new AirportDto
                {
                    Lat             = -5.1912441010878609,
                    Lng             = 104.71056084999998,
                    IataCode        = "MEL",
                    AirportName     = "Tullamarine",
                    RelatedCityName = "Melbourne"
                }
            };

            flightsServiceMock.Setup(fs => fs.GetFlights(It.IsAny <string>())).Returns(flights);
            flightsServiceMock.Setup(fs => fs.GetAirports()).Returns(airports);
            destinationsFilterMock.Setup(df => df.FilterAirports(It.IsAny <List <AirportDto> >(), It.IsAny <SearchArea>()))
            .Returns(airports);
            destinationsFilterMock
            .Setup(df => df.FilterFlightsByDates(It.IsAny <List <ReturnFlightDestinationDto> >(), request.Dates))
            .Returns(flights);
            destinationsFilterMock
            .Setup(df => df.FilterLowestPriceOnly(It.IsAny <List <ReturnFlightDestinationDto> >()))
            .Returns <IEnumerable <ReturnFlightDestinationDto> >((sourceAirports) => sourceAirports);

            //            // Act
            var result = flightsController.GetDestinationPrices(request).Result;

//            // Assert
            result.Should().NotBeNull();
            result.Result.Should().BeOfType <OkObjectResult>();
            ((OkObjectResult)result.Result).StatusCode.Should().Be(200);
        }
        public void GetDestinationPrices_FlightDestinationWithinSearchArea_False(
            [Frozen] Mock <IFlightsService> flightsServiceMock,
            [Frozen] Mock <IDestinationsFilter> destinationsFilterMock,
            FlightsController flightsController
            )
        {
            // Arrange
            var request = new FlightDestinationRequest
            {
                DepartureAirportId = "MEL",
                Dates = new DatesRequest
                {
                    MonthIdx = 5
                },
                Budget = new Budget()
                {
                    Min = 0, Max = 1000
                },
                SearchArea = new SearchArea()
                {
                    Nw = new Coordinates(6, -7),
                    Se = new Coordinates(12, 11)
                }
            };

            var flights = new List <ReturnFlightDestinationDto>()
            {
                new ReturnFlightDestinationDto
                {
                    To            = "GOH",
                    LowestPrice   = 50,
                    DateDeparture = DateTime.Now,
                    DateBack      = DateTime.Now
                }
            };

            var airports = new List <AirportDto>()
            {
                new AirportDto
                {
                    Lat             = 64.187832582,
                    Lng             = -51.673497306,
                    IataCode        = "GOH",
                    AirportName     = "Nuuk Airport",
                    RelatedCityName = "Nuuk"
                }
            };

            flightsServiceMock.Setup(fs => fs.GetFlights(It.IsAny <string>())).Returns(flights);
            flightsServiceMock.Setup(fs => fs.GetAirports()).Returns(airports);
            destinationsFilterMock.Setup(df => df.FilterAirports(It.IsAny <List <AirportDto> >(), It.IsAny <SearchArea>()))
            .Returns(airports);
            destinationsFilterMock
            .Setup(df => df.FilterFlightsByDates(It.IsAny <List <ReturnFlightDestinationDto> >(), request.Dates))
            .Returns <IEnumerable <ReturnFlightDestinationDto>, DatesRequest>((sourceAirports, dates) => sourceAirports);
            destinationsFilterMock
            .Setup(df => df.FilterLowestPriceOnly(It.IsAny <List <ReturnFlightDestinationDto> >()))
            .Returns <IEnumerable <ReturnFlightDestinationDto> >((sourceAirports) => sourceAirports);

            // Act
            var result       = flightsController.GetDestinationPrices(request).Result;
            var okResult     = ((OkObjectResult)result.Result);
            var responseList = okResult.Value as List <FlightDestinationResponse>;

            // Assert
            responseList.Should().NotBeNull();
            responseList.Should().HaveCount(1);
        }
        public void GetDestinationPrices_DateDepartureMatchDateFrom_True(
            [Frozen] Mock <IFlightsService> flightsServiceMock,
            [Frozen] Mock <IDestinationsFilter> destinationsFilterMock,
            FlightsController flightsController
            )
        {
            // Arrange
            var request = new FlightDestinationRequest
            {
                DepartureAirportId = "MEL",
                Dates = new DatesRequest
                {
                    MonthIdx = 9
                },
                Budget = new Budget()
                {
                    Min = 0, Max = 1000
                },
                SearchArea = new SearchArea()
                {
                    Nw = new Coordinates(43, -32),
                    Se = new Coordinates(32, 36)
                }
            };

            var flights = new List <ReturnFlightDestinationDto>()
            {
                new ReturnFlightDestinationDto
                {
                    To            = "MEL",
                    LowestPrice   = 50,
                    DateDeparture = DateTime.Parse("2019-09-15"),
                    DateBack      = DateTime.Parse("2019-9-25")
                }
            };

            var airports = new List <AirportDto>()
            {
                new AirportDto
                {
                    Lat             = -5.1912441010878609,
                    Lng             = 104.71056084999998,
                    IataCode        = "MEL",
                    AirportName     = "Tullamarine",
                    RelatedCityName = "Melbourne"
                }
            };

            flightsServiceMock.Setup(fs => fs.GetFlights(It.IsAny <string>())).Returns(flights);
            flightsServiceMock.Setup(fs => fs.GetAirports()).Returns(airports);
            destinationsFilterMock.Setup(df => df.FilterAirports(It.IsAny <List <AirportDto> >(), It.IsAny <SearchArea>()))
            .Returns(airports);
            destinationsFilterMock
            .Setup(df => df.FilterFlightsByDates(It.IsAny <List <ReturnFlightDestinationDto> >(), request.Dates))
            .Returns(flights);
            destinationsFilterMock
            .Setup(df => df.FilterLowestPriceOnly(It.IsAny <List <ReturnFlightDestinationDto> >()))
            .Returns <IEnumerable <ReturnFlightDestinationDto> >((sourceAirports) => sourceAirports);

            // Act
            var result       = flightsController.GetDestinationPrices(request).Result;
            var okResult     = ((OkObjectResult)result.Result);
            var responseList = okResult.Value as List <FlightDestinationResponse>;

            // Assert
            responseList.Should().NotBeNull();
            responseList.Should().OnlyContain(i => i.FlightDates.FlightMonthidx == request.Dates.MonthIdx);
        }