public Result <List <UserAchievementDto> > Handle(CompleteLessonCommand command)
        {
            var validationResult = completeLessonValidator.Validate(command);

            if (validationResult.Failure)
            {
                return(Result.Fail <List <UserAchievementDto> >(validationResult.Errors));
            }
            var user = dbContext.Users.Include(x => x.CompletedLessons)
                       .First(x => x.Username == command.Username);
            var completedLesson = user.CompletedLessons.FirstOrDefault(x => x.LessonId == command.LessonId);

            if (completedLesson != null)
            {
                return(UpdateAlreadyCompletedLesson(completedLesson, command));
            }
            var lessonResult = GetLessonOfPublishedCourse(command.LessonId);

            if (lessonResult.Failure)
            {
                return(Result.Fail <List <UserAchievementDto> >(lessonResult.Errors, lessonResult.StatusCode));
            }

            var courseId  = lessonResult.Value.Chapter.Course.Id;
            var chapterId = lessonResult.Value.Chapter.Id;

            user.AddCompletedLesson(BuildCompletedLesson(command, courseId, chapterId));

            var course = dbContext.Courses.Where(x => x.Id == courseId)
                         .Include(x => x.Chapters).ThenInclude(x => x.Lessons)
                         .First();

            var achievementTypesToUpdate = achievementTypesCalculator
                                           .CalculateAchievementTypesToUpdate(user.CompletedLessons, course, chapterId);

            var achievements           = dbContext.Achievements.ToList();
            var achievementsUpdatedNow = userAchievementsUpdater.UpdateUserAchievements(user,
                                                                                        course,
                                                                                        achievementTypesToUpdate,
                                                                                        achievements,
                                                                                        DateTime.UtcNow);

            dbContext.SaveChanges();
            return(Result.Ok(mapper.Map <List <UserAchievementDto> >(achievementsUpdatedNow)));
        }
        public void LessonCompleted_IncrementsProgressOnlyForNotFinishedLessonAchievements()
        {
            //arrange
            var course        = new CourseBuilder().Build();
            var typesToUpdate = new AchievementTypesToUpdate {
                LessonCompleted = true
            };
            var availableAchievements = new List <Achievement>
            {
                new AchievementBuilder().WithValues(3, AchievementType.CompleteLesson).Build(),  //[0]
                new AchievementBuilder().WithValues(5, AchievementType.CompleteLesson).Build(),  //[1]
                new AchievementBuilder().WithValues(2, AchievementType.CompleteChapter).Build(), //[2]
                new AchievementBuilder().WithValues(1, AchievementType.CompleteCourse).Build()   //[3]
            };
            var user = new UserBuilder()
                       .AddAchievement(availableAchievements[0], 1)
                       .AddAchievement(availableAchievements[1], 1)
                       .AddAchievement(availableAchievements[2], 0)
                       .Build();
            var utcNow = DateTime.UtcNow;
            //act
            var achievementsUpdatedNow = updater.UpdateUserAchievements(user, course, typesToUpdate,
                                                                        availableAchievements, utcNow);

            //assert
            //modified achievements
            Assert.Equal(2, achievementsUpdatedNow.Count);
            Assert.Equal(2, achievementsUpdatedNow[0].Progress);
            Assert.False(achievementsUpdatedNow[0].IsCompleted);
            Assert.Equal(2, achievementsUpdatedNow[1].Progress);
            Assert.False(achievementsUpdatedNow[1].IsCompleted);

            //not modified achievements
            Assert.Equal(0, user.Achievements.ToList()[2].Progress);//chapter achievement remains unchanged
            Assert.Equal(3, user.Achievements.Count);
        }