public void MapMyRunAuthorizationCallback_WhenUserIsNotConnected_ThenTheAuthorizationDataIsSaved()
        {
            // Arrange
            const string authorizationCode = "some code";
            const string accessToken = "access token";
            const int mmfUserId = 34;

            var dbContext = new FakeShoeTrackerDbContext();
            dbContext
                .WithFitnessProvider(1, "MapMyFitness");
            var api = Substitute.For<MapMyFitnessApi>();

            var accessTokenResponse = new AccessTokenResponse { access_token = accessToken };
            api.GetAccessToken(authorizationCode).Returns(accessTokenResponse);

            var currentUser = new User { id = mmfUserId };
            api.GetCurrentUser(accessTokenResponse.access_token).Returns(currentUser);

            var controller = new FitnessProviderController(dbContext, api)
                .WithAuthenticatedUser("some user", _currentUserId);

            // Act
            controller.MapMyRunAuthorizationCallback("some status", authorizationCode);

            // Assert
            var savedData = dbContext.UserFitnessProviders
                .First(f => f.UserId == _currentUserId && f.FitnessProvider.Name == "MapMyFitness");

            AssertMapMyFitnessAuthorizationDataIsSaved(savedData, authorizationCode, accessToken, mmfUserId, dbContext);
        }
        public void SyncMapMyFitnessWorkouts_WhenUserIsConnected_ThenWorkoutsAreSynchronized()
        {
            // Arrange
            const string acessToken = "some token";
            const int externalUserId = 23;

            var today = DateTime.Now;
            var yesterday = DateTime.Now.AddDays(-1);
            var dayBeforeYesterday = DateTime.Now.AddDays(-2);
            var lastWeek = DateTime.Now.AddDays(-7);
            var lastMonth = DateTime.Now.AddMonths(-1);

            var dbContext = new FakeShoeTrackerDbContext();
            dbContext
                .WithFitnessProvider(1, "MapMyFitness")
                .WithUserFitnessProvider("MapMyFitness", _currentUserId,externalUserId:externalUserId.ToString(),accessToken:acessToken)

                .WithShoe("current shoe",_currentUserId,firstUsedDate:dayBeforeYesterday.Date)
                .WithShoe("previous shoe",_currentUserId,firstUsedDate:lastWeek.Date.AddDays(-1),lastUsedDate:dayBeforeYesterday.Date)
                ;

            var api = Substitute.For<MapMyFitnessApi>()
                .WithGetWorkoutsByUserStubbed(externalUserId, acessToken)
                .WithWorkout(externalUserId,acessToken,name:"today's workout",distanceInMiles:5,workoutDate:today,activityType:"16")
                .WithWorkout(externalUserId,acessToken,name:"today's swim",distanceInMiles:5,workoutDate:today,activityType:"1") // should not be imported
                .WithWorkout(externalUserId, acessToken, name: "today's bike ride", distanceInMiles: 5, workoutDate: today, activityType: "2")// should not be imported
                .WithWorkout(externalUserId, acessToken, name: "today's saunter", distanceInMiles: 5, workoutDate: today, activityType: "3")// should not be imported
                .WithWorkout(externalUserId, acessToken, name: "yesterday's workout", distanceInMiles: 6, workoutDate: yesterday, activityType: "136")
                .WithWorkout(externalUserId, acessToken, name: "last week's workout", distanceInMiles: 7, workoutDate: lastWeek, activityType: "91")
                .WithWorkout(externalUserId, acessToken, name: "last month's workout", distanceInMiles: 8, workoutDate: lastMonth, activityType: "16")
                ;

            var controller = new FitnessProviderController(dbContext, api)
             .WithAuthenticatedUser("some user", _currentUserId);

            // Act
            var result = controller.SyncMapMyFitnessWorkouts();

            // Assert
            AssertRedirectedToWorkoutIndex(result);
            AssertAllWorkoutsAreSaved(dbContext);

            DateTime? lastImportedAt = null;
            var mmfWorkouts = api.GetWorkoutsByUser(externalUserId, acessToken, lastImportedAt)
                .ToList();
            AssertWorkoutDetails(dbContext, mmfWorkouts);

            AssertShoeMatches(dbContext, "today's workout","current shoe");
            AssertShoeMatches(dbContext, "yesterday's workout", "current shoe");
            AssertShoeMatches(dbContext, "last week's workout","previous shoe");
            AssertShoeMatches(dbContext, "last month's workout",null);
        }
        public void SyncMapMyFitnessWorkouts_WhenUserIsNotConnected_ThenTheUserIsRedirectedToWorkouts()
        {
            // Arrange
            var dbContext = new FakeShoeTrackerDbContext();
            var api = Substitute.For<MapMyFitnessApi>();

            var controller = new FitnessProviderController(dbContext, api)
              .WithAuthenticatedUser("some user", _currentUserId);

            // Act
            var result = controller.SyncMapMyFitnessWorkouts();

            // Assert
            AssertRedirectedToWorkoutIndex(result);
        }