Fix Unit Tests

This commit is contained in:
Amelia 2025-04-26 20:29:46 +02:00
parent f29c63c6c4
commit 749fb24185
No known key found for this signature in database
GPG key ID: D6D0ECE365407EAA
7 changed files with 219 additions and 178 deletions

View file

@ -929,17 +929,13 @@ public class SeriesFilterTests : AbstractDbTest
_context.Library.Add(library); _context.Library.Add(library);
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
var ratingService = new RatingService(_unitOfWork, Substitute.For<IScrobblingService>(), Substitute.For<ILogger<RatingService>>());
var seriesService = new SeriesService(_unitOfWork, Substitute.For<IEventHub>(),
Substitute.For<ITaskScheduler>(), Substitute.For<ILogger<SeriesService>>(),
Substitute.For<IScrobblingService>(), Substitute.For<ILocalizationService>(),
Substitute.For<IReadingListService>());
// Select 0 Rating // Select 0 Rating
var zeroRating = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(2); var zeroRating = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(2);
Assert.NotNull(zeroRating); Assert.NotNull(zeroRating);
Assert.True(await seriesService.UpdateRating(user, new UpdateRatingDto() Assert.True(await ratingService.UpdateRating(user, new UpdateRatingDto()
{ {
SeriesId = zeroRating.Id, SeriesId = zeroRating.Id,
UserRating = 0 UserRating = 0
@ -948,7 +944,7 @@ public class SeriesFilterTests : AbstractDbTest
// Select 4.5 Rating // Select 4.5 Rating
var partialRating = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(3); var partialRating = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(3);
Assert.True(await seriesService.UpdateRating(user, new UpdateRatingDto() Assert.True(await ratingService.UpdateRating(user, new UpdateRatingDto()
{ {
SeriesId = partialRating.Id, SeriesId = partialRating.Id,
UserRating = 4.5f UserRating = 4.5f

View file

@ -0,0 +1,189 @@
using System.Linq;
using System.Threading.Tasks;
using API.Data.Repositories;
using API.DTOs;
using API.Entities.Enums;
using API.Helpers.Builders;
using API.Services;
using API.Services.Plus;
using Hangfire;
using Hangfire.InMemory;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Xunit;
namespace API.Tests.Services;
public class RatingServiceTests: AbstractDbTest
{
private readonly RatingService _ratingService;
public RatingServiceTests()
{
_ratingService = new RatingService(_unitOfWork, Substitute.For<IScrobblingService>(), Substitute.For<ILogger<RatingService>>());
}
[Fact]
public async Task UpdateRating_ShouldSetRating()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
JobStorage.Current = new InMemoryStorage();
var result = await _ratingService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 3,
});
Assert.True(result);
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))!
.Ratings;
Assert.NotEmpty(ratings);
Assert.Equal(3, ratings.First().Rating);
}
[Fact]
public async Task UpdateRating_ShouldUpdateExistingRating()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
var result = await _ratingService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 3,
});
Assert.True(result);
JobStorage.Current = new InMemoryStorage();
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))
.Ratings;
Assert.NotEmpty(ratings);
Assert.Equal(3, ratings.First().Rating);
// Update the DB again
var result2 = await _ratingService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 5,
});
Assert.True(result2);
var ratings2 = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))
.Ratings;
Assert.NotEmpty(ratings2);
Assert.True(ratings2.Count == 1);
Assert.Equal(5, ratings2.First().Rating);
}
[Fact]
public async Task UpdateRating_ShouldClampRatingAt5()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
var result = await _ratingService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 10,
});
Assert.True(result);
JobStorage.Current = new InMemoryStorage();
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007",
AppUserIncludes.Ratings)!)
.Ratings;
Assert.NotEmpty(ratings);
Assert.Equal(5, ratings.First().Rating);
}
[Fact]
public async Task UpdateRating_ShouldReturnFalseWhenSeriesDoesntExist()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb", LibraryType.Book)
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
var result = await _ratingService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 2,
UserRating = 5,
});
Assert.False(result);
var ratings = user.Ratings;
Assert.Empty(ratings);
}
protected override async Task ResetDb()
{
_context.Series.RemoveRange(_context.Series.ToList());
_context.AppUserRating.RemoveRange(_context.AppUserRating.ToList());
_context.Genre.RemoveRange(_context.Genre.ToList());
_context.CollectionTag.RemoveRange(_context.CollectionTag.ToList());
_context.Person.RemoveRange(_context.Person.ToList());
_context.Library.RemoveRange(_context.Library.ToList());
await _context.SaveChangesAsync();
}
}

View file

@ -590,164 +590,6 @@ public class SeriesServiceTests : AbstractDbTest
#endregion
#region UpdateRating
[Fact]
public async Task UpdateRating_ShouldSetRating()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
JobStorage.Current = new InMemoryStorage();
var result = await _seriesService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 3,
});
Assert.True(result);
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))!
.Ratings;
Assert.NotEmpty(ratings);
Assert.Equal(3, ratings.First().Rating);
}
[Fact]
public async Task UpdateRating_ShouldUpdateExistingRating()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
var result = await _seriesService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 3,
});
Assert.True(result);
JobStorage.Current = new InMemoryStorage();
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))
.Ratings;
Assert.NotEmpty(ratings);
Assert.Equal(3, ratings.First().Rating);
// Update the DB again
var result2 = await _seriesService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 5,
});
Assert.True(result2);
var ratings2 = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))
.Ratings;
Assert.NotEmpty(ratings2);
Assert.True(ratings2.Count == 1);
Assert.Equal(5, ratings2.First().Rating);
}
[Fact]
public async Task UpdateRating_ShouldClampRatingAt5()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
var result = await _seriesService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 1,
UserRating = 10,
});
Assert.True(result);
JobStorage.Current = new InMemoryStorage();
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007",
AppUserIncludes.Ratings)!)
.Ratings;
Assert.NotEmpty(ratings);
Assert.Equal(5, ratings.First().Rating);
}
[Fact]
public async Task UpdateRating_ShouldReturnFalseWhenSeriesDoesntExist()
{
await ResetDb();
_context.Library.Add(new LibraryBuilder("Test LIb", LibraryType.Book)
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.Build())
.Build())
.Build());
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings);
var result = await _seriesService.UpdateRating(user, new UpdateRatingDto
{
SeriesId = 2,
UserRating = 5,
});
Assert.False(result);
var ratings = user.Ratings;
Assert.Empty(ratings);
}
#endregion #endregion
#region UpdateSeriesMetadata #region UpdateSeriesMetadata

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using API.Constants; using API.Constants;
using API.Data; using API.Data;
using API.Data.Repositories;
using API.DTOs; using API.DTOs;
using API.Extensions; using API.Extensions;
using API.Services; using API.Services;
@ -35,7 +36,10 @@ public class RatingController : BaseApiController
[HttpPost] [HttpPost]
public async Task<ActionResult> UpdateRating(UpdateRatingDto updateRating) public async Task<ActionResult> UpdateRating(UpdateRatingDto updateRating)
{ {
if (await _ratingService.UpdateRating(User.GetUserId(), updateRating)) var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Ratings);
if (user == null) throw new UnauthorizedAccessException();
if (await _ratingService.UpdateRating(user, updateRating))
{ {
return Ok(); return Ok();
} }

View file

@ -58,5 +58,4 @@ public class UserReviewDto
/// If this review is External, which Provider did it come from /// If this review is External, which Provider did it come from
/// </summary> /// </summary>
public ScrobbleProvider Provider { get; set; } = ScrobbleProvider.Kavita; public ScrobbleProvider Provider { get; set; } = ScrobbleProvider.Kavita;
public ReviewAuthority Authority { get; set; } = ReviewAuthority.User;
} }

View file

@ -1086,6 +1086,8 @@ public class ExternalMetadataService : IExternalMetadataService
madeModification = await UpdateChapterCoverImage(chapter, settings, potentialMatch.CoverImageUrl) || madeModification; madeModification = await UpdateChapterCoverImage(chapter, settings, potentialMatch.CoverImageUrl) || madeModification;
madeModification = await UpdateChapterReviews(chapter, settings, potentialMatch) || madeModification;
_unitOfWork.ChapterRepository.Update(chapter); _unitOfWork.ChapterRepository.Update(chapter);
await _unitOfWork.CommitAsync(); await _unitOfWork.CommitAsync();
} }
@ -1094,6 +1096,18 @@ public class ExternalMetadataService : IExternalMetadataService
return madeModification; return madeModification;
} }
private async Task<bool> UpdateChapterReviews(Chapter chapter, MetadataSettingsDto settings, ExternalChapterDto metadata)
{
if (!settings.Enabled) return false;
if (metadata.UserReviews.Count == 0 && metadata.CriticReviews.Count == 0) return false;
// Clear current ratings
chapter.Ratings.Clear();
return true;
}
private static bool UpdateChapterSummary(Chapter chapter, MetadataSettingsDto settings, string? summary) private static bool UpdateChapterSummary(Chapter chapter, MetadataSettingsDto settings, string? summary)
{ {

View file

@ -13,7 +13,13 @@ namespace API.Services;
public interface IRatingService public interface IRatingService
{ {
Task<bool> UpdateRating(int userId, UpdateRatingDto updateRatingDto); /// <summary>
///
/// </summary>
/// <param name="user">Should include ratings</param>
/// <param name="updateRatingDto"></param>
/// <returns></returns>
Task<bool> UpdateRating(AppUser user, UpdateRatingDto updateRatingDto);
} }
public class RatingService: IRatingService public class RatingService: IRatingService
@ -30,17 +36,8 @@ public class RatingService: IRatingService
_logger = logger; _logger = logger;
} }
/// <summary> public async Task<bool> UpdateRating(AppUser user, UpdateRatingDto updateRatingDto)
///
/// </summary>
/// <param name="userId"></param>
/// <param name="updateRatingDto"></param>
/// <returns></returns>
public async Task<bool> UpdateRating(int userId, UpdateRatingDto updateRatingDto)
{ {
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(userId, AppUserIncludes.Ratings);
if (user == null) throw new UnauthorizedAccessException();
var userRating = var userRating =
await _unitOfWork.UserRepository.GetUserRatingAsync(updateRatingDto.SeriesId, user.Id, updateRatingDto.ChapterId) ?? await _unitOfWork.UserRepository.GetUserRatingAsync(updateRatingDto.SeriesId, user.Id, updateRatingDto.ChapterId) ??
new AppUserRating(); new AppUserRating();