mirror of
https://github.com/Kareadita/Kavita.git
synced 2026-06-05 06:15:25 -04:00
Progress Overhaul + Profile Page and a LOT more! (#4262)
Co-authored-by: Amelia <77553571+Fesaa@users.noreply.github.com> Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
@@ -1,177 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Data;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Helpers;
|
||||
using API.Helpers.Builders;
|
||||
using API.Services;
|
||||
using AutoMapper;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
|
||||
namespace API.Tests.Repository;
|
||||
|
||||
public class CollectionTagRepositoryTests
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
|
||||
private readonly DbConnection _connection;
|
||||
private readonly DataContext _context;
|
||||
|
||||
private const string CacheDirectory = "C:/kavita/config/cache/";
|
||||
private const string CoverImageDirectory = "C:/kavita/config/covers/";
|
||||
private const string BackupDirectory = "C:/kavita/config/backups/";
|
||||
private const string DataDirectory = "C:/data/";
|
||||
|
||||
public CollectionTagRepositoryTests()
|
||||
{
|
||||
var contextOptions = new DbContextOptionsBuilder().UseSqlite(CreateInMemoryDatabase()).Options;
|
||||
_connection = RelationalOptionsExtension.Extract(contextOptions).Connection;
|
||||
|
||||
_context = new DataContext(contextOptions);
|
||||
Task.Run(SeedDb).GetAwaiter().GetResult();
|
||||
|
||||
var config = new MapperConfiguration(cfg => cfg.AddProfile<AutoMapperProfiles>());
|
||||
var mapper = config.CreateMapper();
|
||||
_unitOfWork = new UnitOfWork(_context, mapper, null);
|
||||
}
|
||||
|
||||
#region Setup
|
||||
|
||||
private static DbConnection CreateInMemoryDatabase()
|
||||
{
|
||||
var connection = new SqliteConnection("Filename=:memory:");
|
||||
|
||||
connection.Open();
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
private async Task<bool> SeedDb()
|
||||
{
|
||||
await _context.Database.MigrateAsync();
|
||||
var filesystem = CreateFileSystem();
|
||||
|
||||
await Seed.SeedSettings(_context,
|
||||
new DirectoryService(Substitute.For<ILogger<DirectoryService>>(), filesystem));
|
||||
|
||||
var setting = await _context.ServerSetting.Where(s => s.Key == ServerSettingKey.CacheDirectory).SingleAsync();
|
||||
setting.Value = CacheDirectory;
|
||||
|
||||
setting = await _context.ServerSetting.Where(s => s.Key == ServerSettingKey.BackupDirectory).SingleAsync();
|
||||
setting.Value = BackupDirectory;
|
||||
|
||||
_context.ServerSetting.Update(setting);
|
||||
|
||||
|
||||
var lib = new LibraryBuilder("Manga")
|
||||
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
|
||||
.Build();
|
||||
|
||||
_context.AppUser.Add(new AppUser()
|
||||
{
|
||||
UserName = "majora2007",
|
||||
Libraries = new List<Library>()
|
||||
{
|
||||
lib
|
||||
}
|
||||
});
|
||||
|
||||
return await _context.SaveChangesAsync() > 0;
|
||||
}
|
||||
|
||||
private 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());
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private static MockFileSystem CreateFileSystem()
|
||||
{
|
||||
var fileSystem = new MockFileSystem();
|
||||
fileSystem.Directory.SetCurrentDirectory("C:/kavita/");
|
||||
fileSystem.AddDirectory("C:/kavita/config/");
|
||||
fileSystem.AddDirectory(CacheDirectory);
|
||||
fileSystem.AddDirectory(CoverImageDirectory);
|
||||
fileSystem.AddDirectory(BackupDirectory);
|
||||
fileSystem.AddDirectory(DataDirectory);
|
||||
|
||||
return fileSystem;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// #region RemoveTagsWithoutSeries
|
||||
//
|
||||
// [Fact]
|
||||
// public async Task RemoveTagsWithoutSeries_ShouldRemoveTags()
|
||||
// {
|
||||
// var library = new LibraryBuilder("Test", LibraryType.Manga).Build();
|
||||
// var series = new SeriesBuilder("Test 1").Build();
|
||||
// var commonTag = new AppUserCollectionBuilder("Tag 1").Build();
|
||||
// series.Metadata.CollectionTags.Add(commonTag);
|
||||
// series.Metadata.CollectionTags.Add(new AppUserCollectionBuilder("Tag 2").Build());
|
||||
//
|
||||
// var series2 = new SeriesBuilder("Test 1").Build();
|
||||
// series2.Metadata.CollectionTags.Add(commonTag);
|
||||
// library.Series.Add(series);
|
||||
// library.Series.Add(series2);
|
||||
// _unitOfWork.LibraryRepository.Add(library);
|
||||
// await _unitOfWork.CommitAsync();
|
||||
//
|
||||
// Assert.Equal(2, series.Metadata.CollectionTags.Count);
|
||||
// Assert.Single(series2.Metadata.CollectionTags);
|
||||
//
|
||||
// // Delete both series
|
||||
// _unitOfWork.SeriesRepository.Remove(series);
|
||||
// _unitOfWork.SeriesRepository.Remove(series2);
|
||||
//
|
||||
// await _unitOfWork.CommitAsync();
|
||||
//
|
||||
// // Validate that both tags exist
|
||||
// Assert.Equal(2, (await _unitOfWork.CollectionTagRepository.GetAllTagsAsync()).Count());
|
||||
//
|
||||
// await _unitOfWork.CollectionTagRepository.RemoveTagsWithoutSeries();
|
||||
//
|
||||
// Assert.Empty(await _unitOfWork.CollectionTagRepository.GetAllTagsAsync());
|
||||
// }
|
||||
//
|
||||
// [Fact]
|
||||
// public async Task RemoveTagsWithoutSeries_ShouldNotRemoveTags()
|
||||
// {
|
||||
// var library = new LibraryBuilder("Test", LibraryType.Manga).Build();
|
||||
// var series = new SeriesBuilder("Test 1").Build();
|
||||
// var commonTag = new AppUserCollectionBuilder("Tag 1").Build();
|
||||
// series.Metadata.CollectionTags.Add(commonTag);
|
||||
// series.Metadata.CollectionTags.Add(new AppUserCollectionBuilder("Tag 2").Build());
|
||||
//
|
||||
// var series2 = new SeriesBuilder("Test 1").Build();
|
||||
// series2.Metadata.CollectionTags.Add(commonTag);
|
||||
// library.Series.Add(series);
|
||||
// library.Series.Add(series2);
|
||||
// _unitOfWork.LibraryRepository.Add(library);
|
||||
// await _unitOfWork.CommitAsync();
|
||||
//
|
||||
// Assert.Equal(2, series.Metadata.CollectionTags.Count);
|
||||
// Assert.Single(series2.Metadata.CollectionTags);
|
||||
//
|
||||
// await _unitOfWork.CollectionTagRepository.RemoveTagsWithoutSeries();
|
||||
//
|
||||
// // Validate that both tags exist
|
||||
// Assert.Equal(2, (await _unitOfWork.CollectionTagRepository.GetAllTagsAsync()).Count());
|
||||
// }
|
||||
//
|
||||
// #endregion
|
||||
}
|
||||
@@ -6,10 +6,8 @@ using API.Data;
|
||||
using API.DTOs.Metadata.Browse;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Entities.Metadata;
|
||||
using API.Helpers;
|
||||
using API.Helpers.Builders;
|
||||
using Polly;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
@@ -18,7 +16,7 @@ namespace API.Tests.Repository;
|
||||
public class GenreRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTest(outputHelper)
|
||||
{
|
||||
|
||||
private TestGenreSet CreateTestGenres()
|
||||
private static TestGenreSet CreateTestGenres()
|
||||
{
|
||||
return new TestGenreSet
|
||||
{
|
||||
@@ -117,7 +115,7 @@ public class GenreRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTes
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private async Task AssignLibrariesToUsers(DataContext context, AppUser fullAccess, AppUser restrictedAccess, AppUser restrictedAgeAccess)
|
||||
private static async Task AssignLibrariesToUsers(DataContext context, AppUser fullAccess, AppUser restrictedAccess, AppUser restrictedAgeAccess)
|
||||
{
|
||||
var lib0 = context.Library.First(l => l.Name == "lib0");
|
||||
var lib1 = context.Library.First(l => l.Name == "lib1");
|
||||
@@ -151,11 +149,11 @@ public class GenreRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTes
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetBrowseableGenrefullAccess_ReturnsAllGenresWithCorrectCounts()
|
||||
public async Task GetBrowseableGenreFullAccess_ReturnsAllGenresWithCorrectCounts()
|
||||
{
|
||||
var genres = CreateTestGenres();
|
||||
var (unitOfWork, context, mapper) = await CreateDatabase();
|
||||
var (fullAccess, restrictedAccess, restrictedAgeAccess) = await Setup(context, genres);
|
||||
var (unitOfWork, context, _) = await CreateDatabase();
|
||||
var (fullAccess, _, _) = await Setup(context, genres);
|
||||
|
||||
// Act
|
||||
var fullAccessGenres = await unitOfWork.GenreRepository.GetBrowseableGenre(fullAccess.Id, new UserParams());
|
||||
@@ -178,8 +176,8 @@ public class GenreRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTes
|
||||
public async Task GetBrowseableGenre_RestrictedAccess_ReturnsOnlyAccessibleGenres()
|
||||
{
|
||||
var genres = CreateTestGenres();
|
||||
var (unitOfWork, context, mapper) = await CreateDatabase();
|
||||
var (fullAccess, restrictedAccess, restrictedAgeAccess) = await Setup(context, genres);
|
||||
var (unitOfWork, context, _) = await CreateDatabase();
|
||||
var (_, restrictedAccess, _) = await Setup(context, genres);
|
||||
|
||||
// Act
|
||||
var restrictedAccessGenres = await unitOfWork.GenreRepository.GetBrowseableGenre(restrictedAccess.Id, new UserParams());
|
||||
@@ -213,8 +211,8 @@ public class GenreRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTes
|
||||
public async Task GetBrowseableGenre_RestrictedAgeAccess_FiltersAgeRestrictedContent()
|
||||
{
|
||||
var genres = CreateTestGenres();
|
||||
var (unitOfWork, context, mapper) = await CreateDatabase();
|
||||
var (fullAccess, restrictedAccess, restrictedAgeAccess) = await Setup(context, genres);
|
||||
var (unitOfWork, context, _) = await CreateDatabase();
|
||||
var (_, _, restrictedAgeAccess) = await Setup(context, genres);
|
||||
|
||||
// Act
|
||||
var restrictedAgeAccessGenres = await unitOfWork.GenreRepository.GetBrowseableGenre(restrictedAgeAccess.Id, new UserParams());
|
||||
@@ -245,16 +243,16 @@ public class GenreRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTes
|
||||
|
||||
private class TestGenreSet
|
||||
{
|
||||
public Genre SharedSeriesChaptersGenre { get; set; }
|
||||
public Genre SharedSeriesGenre { get; set; }
|
||||
public Genre SharedChaptersGenre { get; set; }
|
||||
public Genre Lib0SeriesChaptersGenre { get; set; }
|
||||
public Genre Lib0SeriesGenre { get; set; }
|
||||
public Genre Lib0ChaptersGenre { get; set; }
|
||||
public Genre Lib1SeriesChaptersGenre { get; set; }
|
||||
public Genre Lib1SeriesGenre { get; set; }
|
||||
public Genre Lib1ChaptersGenre { get; set; }
|
||||
public Genre Lib1ChapterAgeGenre { get; set; }
|
||||
public Genre SharedSeriesChaptersGenre { get; init; }
|
||||
public Genre SharedSeriesGenre { get; init; }
|
||||
public Genre SharedChaptersGenre { get; init; }
|
||||
public Genre Lib0SeriesChaptersGenre { get; init; }
|
||||
public Genre Lib0SeriesGenre { get; init; }
|
||||
public Genre Lib0ChaptersGenre { get; init; }
|
||||
public Genre Lib1SeriesChaptersGenre { get; init; }
|
||||
public Genre Lib1SeriesGenre { get; init; }
|
||||
public Genre Lib1ChaptersGenre { get; init; }
|
||||
public Genre Lib1ChapterAgeGenre { get; init; }
|
||||
|
||||
public List<Genre> GetAllGenres()
|
||||
{
|
||||
|
||||
@@ -10,7 +10,6 @@ using API.Entities.Enums;
|
||||
using API.Entities.Person;
|
||||
using API.Helpers;
|
||||
using API.Helpers.Builders;
|
||||
using Polly;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
@@ -19,7 +18,7 @@ namespace API.Tests.Repository;
|
||||
public class PersonRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTest(outputHelper)
|
||||
{
|
||||
|
||||
private async Task<(AppUser, AppUser, AppUser)> Setup(DataContext context)
|
||||
private static async Task<(AppUser, AppUser, AppUser)> Setup(DataContext context)
|
||||
{
|
||||
var fullAccess = new AppUserBuilder("amelia", "amelia@example.com").Build();
|
||||
var restrictedAccess = new AppUserBuilder("mila", "mila@example.com").Build();
|
||||
|
||||
@@ -1,35 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using API.Data;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Entities.Metadata;
|
||||
using API.Helpers;
|
||||
using API.Helpers.Builders;
|
||||
using API.Services;
|
||||
using AutoMapper;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace API.Tests.Repository;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class SeriesRepositoryTests(ITestOutputHelper testOutputHelper): AbstractDbTest(testOutputHelper)
|
||||
public class SeriesRepositoryTests(ITestOutputHelper testOutputHelper) : AbstractDbTest(testOutputHelper)
|
||||
{
|
||||
|
||||
private async Task SetupSeriesData(IUnitOfWork unitOfWork)
|
||||
private static async Task SetupSeriesData(IUnitOfWork unitOfWork)
|
||||
{
|
||||
var library = new LibraryBuilder("GetFullSeriesByAnyName Manga", LibraryType.Manga)
|
||||
.WithFolderPath(new FolderPathBuilder(DataDirectory+"manga/").Build())
|
||||
.WithFolderPath(new FolderPathBuilder("C:/data/manga/").Build())
|
||||
.WithSeries(new SeriesBuilder("The Idaten Deities Know Only Peace")
|
||||
.WithLocalizedName("Heion Sedai no Idaten-tachi")
|
||||
.WithFormat(MangaFormat.Archive)
|
||||
@@ -70,11 +55,15 @@ public class SeriesRepositoryTests(ITestOutputHelper testOutputHelper): Abstract
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(12345, null, 12345)] // Case 1: Prioritize existing ExternalSeries id
|
||||
[InlineData(0, "https://anilist.co/manga/100664/Ijiranaide-Nagatorosan/", 100664)] // Case 2: Extract from weblink if no external series id
|
||||
[InlineData(0, "", null)] // Case 3: Return null if neither exist
|
||||
// Case 1: Prioritize existing ExternalSeries id
|
||||
[InlineData(12345, null, 12345)]
|
||||
// Case 2: Extract from weblink if no external series id
|
||||
[InlineData(0, "https://anilist.co/manga/100664/Ijiranaide-Nagatorosan/", 100664)]
|
||||
// Case 3: Return null if neither exist
|
||||
[InlineData(0, "", null)]
|
||||
public async Task GetPlusSeriesDto_Should_PrioritizeAniListId_Correctly(int externalAniListId, string? webLinks, int? expectedAniListId)
|
||||
{
|
||||
|
||||
var (unitOfWork, _, _) = await CreateDatabase();
|
||||
await SetupSeriesData(unitOfWork);
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ using API.Entities.Enums;
|
||||
using API.Entities.Metadata;
|
||||
using API.Helpers;
|
||||
using API.Helpers.Builders;
|
||||
using Polly;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
@@ -18,7 +17,7 @@ namespace API.Tests.Repository;
|
||||
public class TagRepositoryTests(ITestOutputHelper outputHelper): AbstractDbTest(outputHelper)
|
||||
{
|
||||
|
||||
private TestTagSet CreateTestTags()
|
||||
private static TestTagSet CreateTestTags()
|
||||
{
|
||||
return new TestTagSet
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user