public static ShoeTrackerDbContext WithShoe(this ShoeTrackerDbContext context, 
            string name, 
            string userId,
            DateTime? firstUsedDate=null, 
            DateTime? lastUsedDate=null, 
            decimal? maximumDistance=null,
            string brand=null)
        {
            var maxShoeId = 1L;
            if (context.Shoes.Any())
            {
                maxShoeId = context.Shoes.Max(s => s.ShoeId);
            }
            var shoe = new Shoe
            {
                CreatedAt = DateTime.Now,
                FirstUsed = firstUsedDate.GetValueOrDefault(DateTime.Today),
                LastUsed = lastUsedDate,
                MaximumDistance = maximumDistance.GetValueOrDefault(400),
                Name = name,
                Brand = brand ?? "default brand",
                Workouts = new List<Workout>(),
                ShoeId = maxShoeId+1,
                UserId = userId
            };

            context.Shoes.Attach(shoe);

            return context;
        }
        private static ShoeDetailViewModel MapShoeToViewModel(Shoe s)
        {
            var hasWorkouts = s.Workouts != null && s.Workouts.Any();

            decimal? distanceUsed = 0;
            decimal? percentRemaining = 0;
            DateTime? expirationDate = null;

            if (hasWorkouts)
            {
                distanceUsed = s.Workouts.Sum(w => w.Distance);
                percentRemaining = CalculatePercenRemaining(s);
                expirationDate = s.LastUsed.HasValue ? null : CalculateExpirationDate(s.FirstUsed, s.MaximumDistance, distanceUsed, percentRemaining);
            }

            return new ShoeDetailViewModel
            {
                ShoeId = s.ShoeId,
                Name = s.Name,
                Brand = s.Brand,
                Url = s.Url,
                FirstUsed = s.FirstUsed,
                LastUsed = s.LastUsed,
                DistanceUsed = distanceUsed,
                CanDelete = !hasWorkouts,
                PercentRemaining = percentRemaining * 100,
                ExpirationDate = expirationDate
            };
        }
        public ViewResult Create()
        {
            var shoe = new Shoe
            {
                UserId =  this.GetUserId(),
                FirstUsed = DateTime.Today
            };

            return View(shoe);
        }
 private static decimal? CalculatePercenRemaining(Shoe s)
 {
     var percentRemaining = s.MaximumDistance == 0 ? 0 : (s.Workouts.Sum(w => w.Distance) / s.MaximumDistance);
     return percentRemaining;
 }
 private void AssertShoesWithWorkoutsCannotBeDeleted(ShoeDetailViewModel viewModel, Shoe shoe)
 {
     Assert.That(viewModel.CanDelete, Is.EqualTo(!shoe.Workouts.Any()));
 }
 private void AssertShoeName(ShoeDetailViewModel viewModel, Shoe shoe)
 {
     Assert.That(viewModel.Name,Is.EqualTo(shoe.Name));
 }
 private void AssertPercentRemainigIsRatioOfDistanceToWorkouts(ShoeDetailViewModel viewModel, Shoe shoe)
 {
     if (shoe.Workouts.Any())
     {
         var expectedPercent = shoe.Workouts.Sum(w => w.Distance)/shoe.MaximumDistance * 100;
         Assert.That(viewModel.PercentRemaining, Is.EqualTo(expectedPercent));
     }
     else
     {
         Assert.That(viewModel.PercentRemaining, Is.EqualTo(0));
     }
 }
 private void AssertLastUsed(ShoeDetailViewModel viewModel, Shoe shoe)
 {
     Assert.That(viewModel.LastUsed, Is.EqualTo(shoe.LastUsed));
 }
 private void AssertExpirationDateIsEmptyWhenTheShoeIsNoLongerUsed(ShoeDetailViewModel viewModel, Shoe matchingShoe)
 {
     if (matchingShoe.LastUsed.HasValue)
     {
         Assert.That(viewModel.ExpirationDate,Is.Null);
     }
 }
 private void AssertDistanceUsedIsSumOfWorkouts(ShoeDetailViewModel viewModel, Shoe shoe)
 {
     if (shoe.Workouts.Any())
     {
         Assert.That(viewModel.DistanceUsed, Is.EqualTo(shoe.Workouts.Sum(w => w.Distance)));
     }
     else
     {
         Assert.That(viewModel.DistanceUsed, Is.EqualTo(0));
     }
 }
 private void AssertCurrentUser(Shoe matchingShoe)
 {
     Assert.That(matchingShoe.UserId,Is.EqualTo(_currentUserId));
 }
 private static void MapShoeData(Shoe shoe, Shoe existingEntry)
 {
     existingEntry.Name = shoe.Name;
     existingEntry.Brand = shoe.Brand;
     existingEntry.FirstUsed = shoe.FirstUsed;
     existingEntry.CreatedAt = shoe.CreatedAt;
     existingEntry.MaximumDistance = shoe.MaximumDistance;
     existingEntry.LastUsed = shoe.LastUsed;
     existingEntry.Url = shoe.Url;
 }