private Route CreateGpx_1_1_Route(XDocument routeDocument, XNamespace ns)
        {
            XElement track = routeDocument.Root.Element(ns + "trk");
            string name = track.Element(ns + "name").Value;

            Route newRoute = new Route {Name = name, DateCreated = DateTime.Now};
            List<RoutePoint> routePoints = new List<RoutePoint>();
            var trackPoints = track.Descendants(ns + "trkpt");
            foreach (XElement trackPoint in trackPoints)
            {
                RoutePoint routePoint = new RoutePoint();
                routePoint.Latitude = double.Parse(trackPoint.Attribute("lat").Value);
                routePoint.Longitude = double.Parse(trackPoint.Attribute("lon").Value);
                routePoint.Elevation = double.Parse(trackPoint.Element(ns + "ele").Value);
                routePoint.TimeRecorded = DateTime.Parse(trackPoint.Element(ns + "time").Value);
                routePoints.Add(routePoint);
            }
            routePoints = routePoints.OrderBy(rp => rp.TimeRecorded).ToList();
            int index = 0;
            foreach (RoutePoint routePoint in routePoints)
            {
                routePoint.SequenceIndex = index;
                index++;
            }
            newRoute.RoutePoints = routePoints;
            newRoute.Distance = CalculateDistance(newRoute.RoutePoints);
            Tuple<double, double> ascentDescent = CalculateAscentDescent(newRoute.RoutePoints);
            newRoute.TotalAscent += ascentDescent.Item1;
            newRoute.TotalDescent += ascentDescent.Item2;
            return newRoute;
        }
        public void Test_Details_UnauthorizedRequest()
        {
            // Arrange
            bool isFavourited;
            bool isOwner;
            Route route = new Route();
            IAccountService accountService = MockRepository.GenerateStub<IAccountService>();
            IRouteService routeService = MockRepository.GenerateStub<IRouteService>();
            IFavouriteService favouriteService = MockRepository.GenerateStub<IFavouriteService>();
            routeService.Stub(s => s.Details(Arg<int>.Is.Anything, Arg<int?>.Is.Anything, out Arg<bool>.Out(true).Dummy, out Arg<bool>.Out(false).Dummy)).Return(route);
            RouteController controller = new RouteController(accountService, routeService, favouriteService);
            HttpRequestBase requestBase = MockRepository.GenerateStub<HttpRequestBase>();
            HttpContextBase contextBase = MockRepository.GenerateStub<HttpContextBase>();
            contextBase.Stub(s => s.Request).Return(requestBase);
            controller.ControllerContext = new ControllerContext(contextBase, new RouteData(), controller);

            // Act
            ViewResult result = controller.Details(1);

            // Assert
            Assert.AreSame(result.Model, route);
            Assert.IsTrue(result.ViewBag.IsFavourited);
            Assert.IsFalse(result.ViewBag.IsOwner);
            routeService.AssertWasCalled(s => s.Details(Arg<int>.Is.Equal(1), Arg<int?>.Is.Null, out Arg<bool>.Out(true).Dummy, out Arg<bool>.Out(false).Dummy));
        }
 public RouteSummary FromRoute(Route route, Account account)
 {
     return new RouteSummary
     {
         AverageRating = route.AverageRating,
         CreatedBy = route.Account.Username,
         DateCreated = route.DateCreated,
         Name = route.Name,
         Reviewed = account != null && route.RouteReviews.Where(rv => rv.RouteID == route.RouteID && rv.AccountID == account.AccountID).Any(),
         RouteID = route.RouteID
     };
 }
        public void Test_Update_Succeeds()
        {
            // Arrange
            Route repositoryRoute = new Route() {AccountID = 1, Name = "Route1", RouteID = 1};
            Route updateRoute = new Route() {AccountID = 1, Name = "Update", RouteID = 1};
            _routeRepository.Stub(f => f.Find(1)).Return(repositoryRoute);

            // Act
            _routeService.Update(updateRoute, 1);

            // Assert
            Assert.AreEqual("Update", repositoryRoute.Name);
            _unitOfWork.AssertWasCalled(s => s.Save());
        }
        public void Test_Update_FailsOnAuthorizationCheck()
        {
            // Arrange
            Route repositoryRoute = new Route() { AccountID = 2, Name = "Route1", RouteID = 1 };
            Route updateRoute = new Route() { AccountID = 1, Name = "Update", RouteID = 1 };
            _routeRepository.Stub(f => f.Find(1)).Return(repositoryRoute);
            bool exceptionRaised = false;
            
            // Act
            try
            {
                _routeService.Update(updateRoute, 1);
            }
            catch (SecurityException se)
            {
                exceptionRaised = true;
            }
            

            // Assert
            Assert.IsTrue(exceptionRaised);
        }
 public ActionResult Edit(Route route)
 {
     if (ModelState.IsValid)
     {
         Route updatedRoute;
         try
         {
             updatedRoute= _routeService.Update(route, Account.AccountID);
         }
         catch (SecurityException)
         {
             return RedirectToAction("Unauthorised", "Home");
         }
         
         return RedirectToAction("Details", new { id = updatedRoute.RouteID});
     }
     return View();
 }
        public void Test_Edit_Get_UnauthorizedRedirects()
        {
            // Arrange
            Route route = new Route();
            IAccountService accountService = MockRepository.GenerateStub<IAccountService>();
            IRouteService routeService = MockRepository.GenerateStub<IRouteService>();
            IFavouriteService favouriteService = MockRepository.GenerateStub<IFavouriteService>();
            routeService.Stub(s => s.Details(Arg<int>.Is.Anything, Arg<int?>.Is.Anything, out Arg<bool>.Out(true).Dummy, out Arg<bool>.Out(false).Dummy)).Return(route);
            RouteController controller = new RouteController(accountService, routeService, favouriteService);
            controller.Account = new Account { AccountID = 1 };

            // Act
            RedirectToRouteResult result = (RedirectToRouteResult)controller.Edit(1);

            // Assert
            Assert.AreEqual("Home", result.RouteValues["controller"]);
            Assert.AreEqual("Unauthorised", result.RouteValues["action"]);
        }
        public void Test_Edit_Get_Authorized()
        {
            // Arrange
            Route route = new Route();
            IAccountService accountService = MockRepository.GenerateStub<IAccountService>();
            IRouteService routeService = MockRepository.GenerateStub<IRouteService>();
            IFavouriteService favouriteService = MockRepository.GenerateStub<IFavouriteService>();
            routeService.Stub(s => s.Details(Arg<int>.Is.Anything, Arg<int?>.Is.Anything, out Arg<bool>.Out(true).Dummy, out Arg<bool>.Out(true).Dummy)).Return(route);
            RouteController controller = new RouteController(accountService, routeService, favouriteService);
            controller.Account = new Account {AccountID = 1};

            // Act
            ViewResult result = (ViewResult)controller.Edit(1);

            // Assert
            Assert.AreSame(route, result.Model);
        }
        public void Test_Insert_Succeeds()
        {
            // Arrange
            List<RouteReview> testData = new List<RouteReview>
                                             {
                                                 new RouteReview
                                                     {
                                                         AccountID = 1,
                                                         RouteID = 2,
                                                         Rating = 2
                                                     }
                                             };
            Route route = new Route {RouteID = 2};
            IUnitOfWork unitOfWork = MockRepository.GenerateStub<IUnitOfWork>();
            IRepository<RouteReview> routeReviewRepository = MockRepository.GenerateStub<IRepository<RouteReview>>();
            IRepository<Route> routeRepository = MockRepository.GenerateStub<IRepository<Route>>();
            unitOfWork.Stub(s => s.GetRepository<RouteReview>()).Return(routeReviewRepository);
            unitOfWork.Stub(s => s.GetRepository<Route>()).Return(routeRepository);
            routeRepository.Stub(s => s.Find(Arg<int>.Is.Anything)).Return(route);
            routeReviewRepository.Stub(s => s.All).Return(testData.AsQueryable());
            RouteReview review = new RouteReview
                                     {
                                         Rating = 4,
                                         DateCreated = DateTime.MinValue,
                                         RouteID = 2
                                     };
            RouteReviewService service = new RouteReviewService(unitOfWork);

            // Act
            RouteReview result = service.Insert(review);

            // Assert
            Assert.IsTrue(result.DateCreated != DateTime.MinValue);
            routeReviewRepository.AssertWasCalled(s => s.Insert(Arg<RouteReview>.Is.Anything));
            routeRepository.AssertWasCalled(s => s.Update(Arg<Route>.Is.Anything));
            unitOfWork.AssertWasCalled(s => s.Save());
        }
        public void Test_Insert_ThrowsServiceExceptionOnUnitOfWorkError()
        {
            // Arrange
            List<RouteReview> testData = new List<RouteReview>
                                             {
                                                 new RouteReview
                                                     {
                                                         AccountID = 1,
                                                         RouteID = 2,
                                                         Rating = 2
                                                     }
                                             };
            Route route = new Route { RouteID = 2 };
            IUnitOfWork unitOfWork = MockRepository.GenerateStub<IUnitOfWork>();
            IRepository<RouteReview> routeReviewRepository = MockRepository.GenerateStub<IRepository<RouteReview>>();
            IRepository<Route> routeRepository = MockRepository.GenerateStub<IRepository<Route>>();
            unitOfWork.Stub(s => s.GetRepository<RouteReview>()).Return(routeReviewRepository);
            unitOfWork.Stub(s => s.GetRepository<Route>()).Return(routeRepository);
            unitOfWork.Stub(s => s.Save()).Throw(new Exception());
            routeRepository.Stub(s => s.Find(Arg<int>.Is.Anything)).Return(route);
            routeReviewRepository.Stub(s => s.All).Return(testData.AsQueryable());
            RouteReview review = new RouteReview
            {
                Rating = 4,
                DateCreated = DateTime.MinValue,
                RouteID = 2
            };
            RouteReviewService service = new RouteReviewService(unitOfWork);
            bool exceptionThrown = false;

            // Act
            try
            {
                service.Insert(review);
            }
            catch (ServiceException)
            {
                exceptionThrown = true;
            }
            

            // Assert
            Assert.IsTrue(exceptionThrown);
        }
        public void Test_Insert_SetsAverageRating()
        {
            // Arrange
            List<RouteReview> testData = new List<RouteReview>
                                             {
                                                 new RouteReview
                                                     {
                                                         AccountID = 1,
                                                         RouteID = 2,
                                                         Rating = 2
                                                     }
                                             };
            Route route = new Route { RouteID = 2 };
            IUnitOfWork unitOfWork = MockRepository.GenerateStub<IUnitOfWork>();
            IRepository<RouteReview> routeReviewRepository = MockRepository.GenerateStub<IRepository<RouteReview>>();
            IRepository<Route> routeRepository = MockRepository.GenerateStub<IRepository<Route>>();
            unitOfWork.Stub(s => s.GetRepository<RouteReview>()).Return(routeReviewRepository);
            unitOfWork.Stub(s => s.GetRepository<Route>()).Return(routeRepository);
            routeRepository.Stub(s => s.Find(Arg<int>.Is.Anything)).Return(route);
            routeReviewRepository.Stub(s => s.All).Return(testData.AsQueryable());
            RouteReview review = new RouteReview
            {
                Rating = 4,
                DateCreated = DateTime.MinValue,
                RouteID = 2
            };
            RouteReviewService service = new RouteReviewService(unitOfWork);

            // Act
            service.Insert(review);

            // Assert
            Assert.AreEqual(3, route.AverageRating);
        }
        public Bitmap HeightMapImage(Route route, int width, int height)
        {
            const double percentageSpace = 0.20;

            if (width > 1024 || height > 1024)
                throw new ServiceException("Requested height map is too large. Maximum size is 1024x1024 pixels");

            try
            {
                Bitmap bitmap = new Bitmap(width, height);
                Graphics graphics = Graphics.FromImage(bitmap);

                double minimumElevation = route.RoutePoints.Min(rp => rp.Elevation);
                double maximumElevation = route.RoutePoints.Max(rp => rp.Elevation);
                double elevationOffset = (maximumElevation - minimumElevation) * percentageSpace;
                minimumElevation = Math.Round(minimumElevation - elevationOffset / 2);
                maximumElevation = Math.Round(maximumElevation + elevationOffset / 2);

                TimeSpan timeRange = route.RoutePoints.Last().TimeRecorded - route.RoutePoints.First().TimeRecorded;
                double minutesPerPixel = timeRange.TotalMinutes / (double)width;
                double metersPerPixel = (double)height / (maximumElevation - minimumElevation);

                DateTime currentDate = route.RoutePoints.First().TimeRecorded;
                Brush backgroundBrush = new LinearGradientBrush(new Point(0, 0),
                    new Point(0, height),
                    Color.FromArgb(255, 0, 99, 248),
                    Color.FromArgb(255, 0, 164, 250));

                Brush foregroundBrush = new LinearGradientBrush(new Point(0, 0),
                                                                new Point(0, height),
                                                                Color.DarkGreen,
                                                                Color.LightGreen);

                graphics.FillRectangle(backgroundBrush, 0, 0, width, height);
                Pen pen = new Pen(foregroundBrush);
                double previousElevation = 0;
                GraphicsPath path = new GraphicsPath();
                Point oldPoint = new Point(0, 0);
                for (int x = 0; x < width; x++)
                {
                    DateTime endDate = currentDate.AddMinutes(minutesPerPixel);
                    IEnumerable<RoutePoint> routePoints = route.RoutePoints.Where(rp => rp.TimeRecorded >= currentDate && rp.TimeRecorded <= endDate);
                    double averageElevation = 0;
                    if (routePoints.Any())
                    {
                        averageElevation = routePoints.Average(rp => rp.Elevation);
                    }
                    else
                    {
                        averageElevation = previousElevation;
                    }
                    graphics.DrawLine(pen, (float)x, height, (float)x, height - (float)((averageElevation - minimumElevation) * metersPerPixel));
                    Point point = new Point(x, (int)(height - (float)((averageElevation - minimumElevation) * metersPerPixel)));
                    
                    if (x >= 1)
                    {
                        Point newPoint = point;
                        path.AddLine(oldPoint, newPoint);
                        oldPoint = newPoint;
                    }
                    else
                    {
                        oldPoint = point;
                    }

                    currentDate = currentDate.AddMinutes(minutesPerPixel);
                    previousElevation = averageElevation;
                }
                Pen linePen = new Pen(Color.Black, 3);
                linePen.DashCap = DashCap.Round;
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
                graphics.DrawPath(linePen, path);

                return bitmap;
            }
            catch (Exception ex)
            {
                throw new ServiceException("Unable to build height profile bitmap.", ex);
            }
        }