using System.Collections.Generic;
namespace FlightRoutesCalculatorApp
using FlightRoutesCalculatorApp.DataAccess.Models;
using FlightRoutesCalculatorApp.DataAccess.Interfaces;
public class FlightRoutesController : Controller
private readonly DataAccess.Interfaces.IFlightRepository flightRepository = new DataAccess.Repositories.FlightRepository();
public ActionResult Index()
FlightRoutesViewModel flightRoutesViewModel = new FlightRoutesViewModel();
return View(flightRoutesViewModel);
public ActionResult CalculateFlightRoutes(string flightCode)
List<Flight> flights = flightRepository.GetAllFlights();
if (flights == null || !flights.Any())
return View(new List<FlightRoute>());
var inboundFlights = flights.OfType<InboundFlight>();
var outboundFlights = flights.OfType<OutboundFlight>();
return View(new Api.Core.FlightRoutesCalculator()
.CalculateFlightRoutes(outboundFlights, inboundFlights));
namespace FlightRoutesCalculatorApp.DataAccess.Interfaces
using FlightRoutesCalculatorApp.DataAccess.Models;
public interface IFlightRepository
List<Flight> GetAllFlights();
namespace FlightRoutesCalculatorApp.DataAccess.Exceptions
public class ApiException : Exception
public int StatusCode { get; set; }
public string Content { get; set; }
namespace FlightRoutesCalculatorApp.DataAccess.Repositories
using FlightRoutesCalculatorApp.DataAccess.Models;
using FlightRoutesCalculatorApp.DataAccess.Exceptions;
public class FlightRepository : Interfaces.IFlightRepository
private static readonly HttpClient httpClient = new HttpClient();
private static readonly string FlightsUrl = "http://www.mocky.io/v2/5ce66fb8330000660073156e";
public List<Flight> GetAllFlights()
var mockyFlights = GetAllFlightsFromMockyIO();
return new List<Flight>()
.Concat(mockyFlights.InboundFlights)
.Concat(mockyFlights.OutboundFlights)
private MockyFlights GetAllFlightsFromMockyIO()
return DeserializeFlights();
private MockyFlights DeserializeFlights()
using (var request = new HttpRequestMessage(HttpMethod.Get, FlightsUrl))
using (var responseTask = httpClient.SendAsync(request))
var readTask = responseTask.Result.Content.ReadAsStringAsync();
string textResult = readTask.Result;
if (responseTask.Result.IsSuccessStatusCode)
return JsonConvert.DeserializeObject<MockyFlights>(ReconstructMockyJSON(textResult));
string content = textResult;
throw new ApiException { StatusCode = (int)responseTask.Result.StatusCode, Content = content };
private static string ReconstructMockyJSON(string text)
return text.Replace('=', ':');
namespace FlightRoutesCalculatorApp.Api.Core
using FlightRoutesCalculatorApp.DataAccess.Models;
public class FlightRoutesCalculator
public IEnumerable<FlightRoute> CalculateFlightRoutes(IEnumerable<OutboundFlight> outboundFlights, IEnumerable<InboundFlight> inboundFlights)
var flightRoutes = new List<FlightRoute>();
foreach (var outboundFlight in outboundFlights)
IEnumerable<InboundFlight> combinableInboundFlights;
combinableInboundFlights = inboundFlights.Where(x => x.Airline == outboundFlight.Airline && x.DepartureAirportCode == outboundFlight.ArrivalAirportCode
&& x.ArrivalAirportCode == outboundFlight.DepartureAirportCode);
if (combinableInboundFlights == null || !combinableInboundFlights.Any())
combinableInboundFlights = inboundFlights.Where(x => x.DepartureAirportCode == outboundFlight.ArrivalAirportCode
&& x.ArrivalAirportCode == outboundFlight.DepartureAirportCode);
foreach (var combinableInboundFlight in combinableInboundFlights)
flightRoutes.Add(new FlightRoute() { OutboundFlight = outboundFlight, InboundFlight = combinableInboundFlight });
namespace FlightRoutesCalculatorApp.Tests
using FlightRoutesCalculatorApp.DataAccess.Models;
using FlightRoutesCalculatorApp.Api.Core;
public OutboundFlight outboundFlight1 = new OutboundFlight()
DepartureAirportCode = "BCN",
ArrivalAirportCode = "AMS",
public OutboundFlight outboundFlight2 = new OutboundFlight()
DepartureAirportCode = "BCN",
ArrivalAirportCode = "AMS",
public OutboundFlight outboundFlight3 = new OutboundFlight()
DepartureAirportCode = "GIR",
ArrivalAirportCode = "AMS",
public OutboundFlight outboundFlight4 = new OutboundFlight()
DepartureAirportCode = "BCN",
ArrivalAirportCode = "AMS",
public OutboundFlight outboundFlight5 = new OutboundFlight()
DepartureAirportCode = "BCN",
ArrivalAirportCode = "ROT",
public InboundFlight inboundFlight11 = new InboundFlight()
DepartureAirportCode = "AMS",
ArrivalAirportCode = "BCN",
public InboundFlight inboundFlight12 = new InboundFlight()
DepartureAirportCode = "AMS",
ArrivalAirportCode = "BCN",
public InboundFlight inboundFlight13 = new InboundFlight()
DepartureAirportCode = "AMS",
ArrivalAirportCode = "GIR",
public InboundFlight inboundFlight14 = new InboundFlight()
DepartureAirportCode = "AMS",
ArrivalAirportCode = "GIR",
public InboundFlight inboundFlight15 = new InboundFlight()
DepartureAirportCode = "AMS",
ArrivalAirportCode = "BCN",
public class TestFlightRoutesCalculator
private static readonly FlightMocks flightMocks = new FlightMocks();
public void TestAirlineCombinations()
var mockOutboundFlights = new List<OutboundFlight>() { flightMocks.outboundFlight1, flightMocks.outboundFlight2, flightMocks.outboundFlight3, flightMocks.outboundFlight4, flightMocks.outboundFlight5 };
var mockInboundFlights = new List<InboundFlight>() { flightMocks.inboundFlight11, flightMocks.inboundFlight12, flightMocks.inboundFlight13, flightMocks.inboundFlight14, flightMocks.inboundFlight15 };
List<FlightRoute> routes = new FlightRoutesCalculator().CalculateFlightRoutes(mockOutboundFlights, mockInboundFlights)
Assert.AreEqual(routes[0].OutboundFlight.ID, flightMocks.outboundFlight1.ID);
Assert.AreEqual(routes[0].InboundFlight.ID, flightMocks.inboundFlight11.ID);
Assert.AreEqual(routes[1].OutboundFlight.ID, flightMocks.outboundFlight1.ID);
Assert.AreEqual(routes[1].InboundFlight.ID, flightMocks.inboundFlight15.ID);
Assert.AreEqual(routes[2].OutboundFlight.ID, flightMocks.outboundFlight2.ID);
Assert.AreEqual(routes[2].InboundFlight.ID, flightMocks.inboundFlight12.ID);
Assert.AreEqual(routes[3].OutboundFlight.ID, flightMocks.outboundFlight3.ID);
Assert.AreEqual(routes[3].InboundFlight.ID, flightMocks.inboundFlight14.ID);
Assert.AreEqual(routes[4].OutboundFlight.ID, flightMocks.outboundFlight4.ID);
Assert.AreEqual(routes[4].InboundFlight.ID, flightMocks.inboundFlight11.ID);
Assert.AreEqual(routes[5].OutboundFlight.ID, flightMocks.outboundFlight4.ID);
Assert.AreEqual(routes[5].InboundFlight.ID, flightMocks.inboundFlight15.ID);
public void TestEmptyOutboundFlights()
var mockOutboundFlights = new List<OutboundFlight>() { flightMocks.outboundFlight1, flightMocks.outboundFlight2, flightMocks.outboundFlight3, flightMocks.outboundFlight4, flightMocks.outboundFlight5 };
var mockInboundFlights = new List<InboundFlight>();
List<FlightRoute> routes = new FlightRoutesCalculator().CalculateFlightRoutes(mockOutboundFlights, mockInboundFlights)
public void TestEmptyInboundFlights()
var mockOutboundFlights = new List<OutboundFlight>();
var mockInboundFlights = new List<InboundFlight>() { flightMocks.inboundFlight11, flightMocks.inboundFlight12, flightMocks.inboundFlight13, flightMocks.inboundFlight14, flightMocks.inboundFlight15 };
List<FlightRoute> routes = new FlightRoutesCalculator().CalculateFlightRoutes(mockOutboundFlights, mockInboundFlights)