public async Task UpdateReviewScoreUpdatingReview_WhenParametersAreCorrect() { // Arrange const int reviewID = 1; const double rating = 5; var movieRepoStub = new Mock <IRepository <Movie> >(); var reviewRepoMock = new Mock <IRepository <Review> >(); var reviewRatingsStub = new Mock <IRepository <ReviewRatings> >(); var user = new User() { Id = "1", UserName = "******" }; var movie = new Movie() { Name = "Mecho Puh" }; var reviewRating = new ReviewRatings() { ID = 1, ReviewId = 1, UserId = "1", ReviewRating = 6 }; //thats gonna change to 5 var reviewRating2 = new ReviewRatings() { ID = 2, ReviewId = 1, UserId = "2", ReviewRating = 4 }; var reviewMock = new Review() { ID = 1, IsDeleted = false, Text = "Text", Movie = movie, User = user, UserID = user.Id, MovieID = movie.ID, ReviewRatings = new List <ReviewRatings>() { reviewRating, reviewRating2 }, NumberOfVotes = 2, MovieRating = 9.95, ReviewScore = 5 }; //The review score is 5 = (6 + 4)/ 2 var allReviews = new List <Review>() { reviewMock }.AsQueryable().BuildMock().Object; reviewRepoMock.Setup(m => m.All()).Returns(allReviews); var reviewServices = new ReviewsService(reviewRepoMock.Object, movieRepoStub.Object, reviewRatingsStub.Object); // Act var result = await reviewServices.RateReviewAsync(reviewID, rating, "1"); // Assert reviewRepoMock.Verify(revRepo => revRepo.SaveAsync(), Times.Once); reviewRepoMock.Verify(revRepo => revRepo.Update(reviewMock), Times.Once); Assert.AreSame(result, reviewMock); Assert.IsTrue(reviewMock.ReviewScore == 4.5); //the rating for userID 1 has changed from 6 to 5, hence now the score should be (4 + 5) / 2 = 4.5 }
public async Task <Review> RateReviewAsync(int reviewID, double rating, string currentUserId) { Validator.IfIsNotPositive(reviewID, "ReviewID cannot be negative or 0."); Validator.IfIsNotInRangeInclusive(rating, 0D, 10D, "Score is in incorrect range."); var foundReview = await reviewRepo.All() .Where(rev => rev.ID == reviewID && rev.IsDeleted == false) .Include(r => r.User) .Include(r => r.Movie) .Include(r => r.ReviewRatings) .FirstOrDefaultAsync(); if (foundReview is null) { throw new ReviewNotFoundException($"Review with ID: {reviewID} not found."); } // Check logic!!! var reviewRatingToUpdate = foundReview.ReviewRatings .FirstOrDefault(r => r.UserId == currentUserId && r.ReviewId == foundReview.ID); if (reviewRatingToUpdate is null) { var reviewRatingToAdd = new ReviewRatings() { ReviewId = foundReview.ID, UserId = currentUserId, ReviewRating = rating, }; foundReview.NumberOfVotes++; foundReview.ReviewScore += (rating - foundReview.ReviewScore) / foundReview.NumberOfVotes; foundReview.ReviewRatings.Add(reviewRatingToAdd); } else { if (foundReview.NumberOfVotes == 1) { foundReview.ReviewScore = rating; } else { if (foundReview.NumberOfVotes == 0) { foundReview.ReviewScore = 0; } else { foundReview.ReviewScore = ((foundReview.ReviewScore * foundReview.NumberOfVotes) - reviewRatingToUpdate.ReviewRating) / (foundReview.NumberOfVotes - 1); } foundReview.ReviewScore += (rating - foundReview.ReviewScore) / foundReview.NumberOfVotes; } reviewRatingToUpdate.ReviewRating = rating; } reviewRepo.Update(foundReview); await reviewRepo.SaveAsync(); return(foundReview); }