* Updated number inputs with a more mobile friendly control

* Started writing lots of unit tests on PersonHelper to try and hammer out foreign constraint

* Fixes side-nav actionable alignment

* Added some unit tests

* Buffed out the unit tests

* Applied input modes throughout the app

* Fixed a small bug in refresh token validation to make it work correctly

* Try out a new way to block multithreading from interacting with people during series metadata update.

* Fixed the lock code to properly lock, which should help with any constraint issues.

* Locking notes

* Tweaked locking on people to prevent a constraint issue. This slows down the scanner a bit, but not much. Will tweak after validating on a user's server.

* Replaced all DBFactory.Series with SeriesBuilder.

* Replaced all DBFactory.Volume() with VolumeBuilder

* Replaced SeriesMetadata with Builder

* Replaced DBFactory.CollectionTag

* Lots of refactoring to streamline entity creation

* Fixed one of the unit tests

* Refactored all of new Library()

* Removed tag and genre

* Removed new SeriesMetadata

* Refactored new Volume()

* MangaFile()

* ReadingList()

* Refactored all of Chapter and ReadingList

* Add title to all event widget flows

* Updated Base Url to inform user it doesn't work for docker users with non-root user.

* Added unit test coverage to FormatChapterTitle and FormatChapterName.

* Started on Unit test for scanner, but need to finish it later.

---------

Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
Joe Milazzo 2023-03-19 12:52:44 -05:00 committed by GitHub
parent eec03d7e96
commit 385f61f9f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
105 changed files with 2257 additions and 2660 deletions

View File

@ -348,7 +348,7 @@ jobs:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: true
tags: kizaing/kavita:latest, kizaing/kavita:${{ steps.parse-version.outputs.VERSION }}, ghcr.io/${{ github.repository_owner }}/kavita:latest, ghcr.io/${{ github.repository_owner }}/kavita:${{ steps.parse-version.outputs.VERSION }}
tags: kizaing/kavita:latest, kizaing/kavita:${{ steps.parse-version.outputs.VERSION }}, ghcr.io/kareadita/kavita:latest, ghcr.io/kareadita/kavita:${{ steps.parse-version.outputs.VERSION }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

View File

@ -7,6 +7,7 @@ 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;
@ -78,18 +79,9 @@ public abstract class AbstractDbTest
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga",
Folders = new List<FolderPath>()
{
new FolderPath()
{
Path = "C:/data/"
}
},
Series = new List<Series>()
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build());
return await _context.SaveChangesAsync() > 0;
}

View File

@ -1,27 +0,0 @@
using API.Data;
using API.Extensions;
using Xunit;
namespace API.Tests.Entities;
/// <summary>
/// Tests for <see cref="API.Entities.Series"/>
/// </summary>
public class SeriesTest
{
[Theory]
[InlineData("Darker than Black")]
public void CreateSeries(string name)
{
var key = name.ToNormalized();
var series = DbFactory.Series(name);
Assert.Equal(0, series.Id);
Assert.Equal(0, series.Pages);
Assert.Equal(name, series.Name);
Assert.Null(series.CoverImage);
Assert.Equal(name, series.LocalizedName);
Assert.Equal(name, series.SortName);
Assert.Equal(name, series.OriginalName);
Assert.Equal(key, series.NormalizedName);
}
}

View File

@ -4,7 +4,8 @@ using System.Linq;
using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Parser;
using API.Helpers.Builders;
using API.Services.Tasks.Scanner.Parser;
using Xunit;
namespace API.Tests.Extensions;
@ -13,22 +14,15 @@ public class ChapterListExtensionsTests
{
private static Chapter CreateChapter(string range, string number, MangaFile file, bool isSpecial)
{
return new Chapter()
{
Range = range,
Number = number,
Files = new List<MangaFile>() {file},
IsSpecial = isSpecial
};
return new ChapterBuilder(number, range)
.WithIsSpecial(isSpecial)
.WithFile(file)
.Build();
}
private static MangaFile CreateFile(string file, MangaFormat format)
{
return new MangaFile()
{
FilePath = file,
Format = format
};
return new MangaFileBuilder(file, format).Build();
}
[Fact]

View File

@ -3,7 +3,7 @@ using System.IO.Abstractions.TestingHelpers;
using System.Linq;
using API.Entities.Enums;
using API.Extensions;
using API.Parser;
using API.Helpers.Builders;
using API.Services;
using API.Services.Tasks.Scanner.Parser;
using API.Tests.Helpers;
@ -45,8 +45,10 @@ public class ParserInfoListExtensions
string.Empty));
}
var files = inputChapters.Select(s => EntityFactory.CreateMangaFile(s, MangaFormat.Archive, 199)).ToList();
var chapter = EntityFactory.CreateChapter("0-6", false, files);
var files = inputChapters.Select(s => new MangaFileBuilder(s, MangaFormat.Archive, 199).Build()).ToList();
var chapter = new ChapterBuilder("0-6")
.WithFiles(files)
.Build();
Assert.Equal(expectedHasInfo, infos.HasInfo(chapter));
}

View File

@ -22,22 +22,13 @@ public class QueryableExtensionsTests
var items = new List<Series>()
{
new SeriesBuilder("Test 1")
.WithMetadata( new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
})
.WithMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new SeriesBuilder("Test 2")
.WithMetadata( new SeriesMetadata()
{
AgeRating = AgeRating.Unknown,
})
.WithMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Unknown).Build())
.Build(),
new SeriesBuilder("Test 3")
.WithMetadata( new SeriesMetadata()
{
AgeRating = AgeRating.X18Plus,
})
.WithMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.X18Plus).Build())
.Build()
};
@ -56,46 +47,16 @@ public class QueryableExtensionsTests
{
var items = new List<CollectionTag>()
{
new CollectionTag()
{
Title = "Test",
NormalizedTitle = "Test".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
}
}
},
new CollectionTag()
{
Title = "Test",
NormalizedTitle = "Test".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.Unknown,
},
new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
}
}
},
new CollectionTag()
{
Title = "Test",
NormalizedTitle = "Test".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.X18Plus,
}
}
},
new CollectionTagBuilder("Test")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new CollectionTagBuilder("Test 2")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Unknown).Build())
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new CollectionTagBuilder("Test 3")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.X18Plus).Build())
.Build(),
};
var filtered = items.AsQueryable().RestrictAgainstAgeRestriction(new AgeRestriction()
@ -113,46 +74,16 @@ public class QueryableExtensionsTests
{
var items = new List<Genre>()
{
new Genre()
{
Title = "A",
NormalizedTitle = "A".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
}
}
},
new Genre()
{
Title = "B",
NormalizedTitle = "B".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.Unknown,
},
new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
}
}
},
new Genre()
{
Title = "C",
NormalizedTitle = "C".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.X18Plus,
}
}
},
new GenreBuilder("A")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new GenreBuilder("B")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Unknown).Build())
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new GenreBuilder("C")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.X18Plus).Build())
.Build(),
};
var filtered = items.AsQueryable().RestrictAgainstAgeRestriction(new AgeRestriction()
@ -170,46 +101,16 @@ public class QueryableExtensionsTests
{
var items = new List<Tag>()
{
new Tag()
{
Title = "Test 1",
NormalizedTitle = "Test 1".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
}
}
},
new Tag()
{
Title = "Test 2",
NormalizedTitle = "Test 2".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.Unknown,
},
new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
}
}
},
new Tag()
{
Title = "Test 3",
NormalizedTitle = "Test 3".ToNormalized(),
SeriesMetadatas = new List<SeriesMetadata>()
{
new SeriesMetadata()
{
AgeRating = AgeRating.X18Plus,
}
}
},
new TagBuilder("Test 1")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new TagBuilder("Test 2")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Unknown).Build())
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new TagBuilder("Test 3")
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.X18Plus).Build())
.Build(),
};
var filtered = items.AsQueryable().RestrictAgainstAgeRestriction(new AgeRestriction()
@ -228,26 +129,14 @@ public class QueryableExtensionsTests
var items = new List<Person>()
{
new PersonBuilder("Test", PersonRole.Character)
.WithSeriesMetadata(new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
})
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new PersonBuilder("Test", PersonRole.Character)
.WithSeriesMetadata(new SeriesMetadata()
{
AgeRating = AgeRating.Unknown,
})
.WithSeriesMetadata(new SeriesMetadata()
{
AgeRating = AgeRating.Teen,
})
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Unknown).Build())
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.Teen).Build())
.Build(),
new PersonBuilder("Test", PersonRole.Character)
.WithSeriesMetadata(new SeriesMetadata()
{
AgeRating = AgeRating.X18Plus,
})
.WithSeriesMetadata(new SeriesMetadataBuilder().WithAgeRating(AgeRating.X18Plus).Build())
.Build(),
};
@ -267,9 +156,9 @@ public class QueryableExtensionsTests
var items = new List<ReadingList>()
{
DbFactory.ReadingList("Test List", null, false, AgeRating.Teen),
DbFactory.ReadingList("Test List", null, false, AgeRating.Unknown),
DbFactory.ReadingList("Test List", null, false, AgeRating.X18Plus),
new ReadingListBuilder("Test List").WithRating(AgeRating.Teen).Build(),
new ReadingListBuilder("Test List").WithRating(AgeRating.Unknown).Build(),
new ReadingListBuilder("Test List").WithRating(AgeRating.X18Plus).Build(),
};
var filtered = items.AsQueryable().RestrictAgainstAgeRestriction(new AgeRestriction()

View File

@ -2,6 +2,7 @@
using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Helpers.Builders;
using API.Tests.Helpers;
using Xunit;
@ -16,16 +17,14 @@ public class VolumeListExtensionsTests
{
var volumes = new List<Volume>()
{
EntityFactory.CreateVolume("1", new List<Chapter>()
{
EntityFactory.CreateChapter("3", false),
EntityFactory.CreateChapter("4", false),
}),
EntityFactory.CreateVolume("0", new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("0", true),
}),
new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("3").Build())
.WithChapter(new ChapterBuilder("4").Build())
.Build(),
new VolumeBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultVolume)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter).WithIsSpecial(true).Build())
.Build(),
};
Assert.Equal(volumes[0].Number, volumes.GetCoverImage(MangaFormat.Archive).Number);
@ -36,16 +35,14 @@ public class VolumeListExtensionsTests
{
var volumes = new List<Volume>()
{
EntityFactory.CreateVolume("1", new List<Chapter>()
{
EntityFactory.CreateChapter("3", false),
EntityFactory.CreateChapter("4", false),
}),
EntityFactory.CreateVolume("0", new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("0", true),
}),
new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("3").Build())
.WithChapter(new ChapterBuilder("4").Build())
.Build(),
new VolumeBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultVolume)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter).WithIsSpecial(true).Build())
.Build(),
};
Assert.Equal(volumes[1].Name, volumes.GetCoverImage(MangaFormat.Epub).Name);
@ -56,16 +53,14 @@ public class VolumeListExtensionsTests
{
var volumes = new List<Volume>()
{
EntityFactory.CreateVolume("1", new List<Chapter>()
{
EntityFactory.CreateChapter("3", false),
EntityFactory.CreateChapter("4", false),
}),
EntityFactory.CreateVolume("0", new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("0", true),
}),
new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("3").Build())
.WithChapter(new ChapterBuilder("4").Build())
.Build(),
new VolumeBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultVolume)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter).WithIsSpecial(true).Build())
.Build(),
};
Assert.Equal(volumes[1].Name, volumes.GetCoverImage(MangaFormat.Pdf).Name);
@ -76,16 +71,14 @@ public class VolumeListExtensionsTests
{
var volumes = new List<Volume>()
{
EntityFactory.CreateVolume("1", new List<Chapter>()
{
EntityFactory.CreateChapter("3", false),
EntityFactory.CreateChapter("4", false),
}),
EntityFactory.CreateVolume("0", new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("0", true),
}),
new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("3").Build())
.WithChapter(new ChapterBuilder("4").Build())
.Build(),
new VolumeBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultVolume)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter).WithIsSpecial(true).Build())
.Build(),
};
Assert.Equal(volumes[0].Name, volumes.GetCoverImage(MangaFormat.Image).Name);
@ -96,16 +89,14 @@ public class VolumeListExtensionsTests
{
var volumes = new List<Volume>()
{
EntityFactory.CreateVolume("2", new List<Chapter>()
{
EntityFactory.CreateChapter("3", false),
EntityFactory.CreateChapter("4", false),
}),
EntityFactory.CreateVolume("1", new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("0", true),
}),
new VolumeBuilder("2")
.WithChapter(new ChapterBuilder("3").Build())
.WithChapter(new ChapterBuilder("4").Build())
.Build(),
new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder(API.Services.Tasks.Scanner.Parser.Parser.DefaultChapter).Build())
.Build(),
};
Assert.Equal(volumes[1].Name, volumes.GetCoverImage(MangaFormat.Image).Name);

View File

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions.TestingHelpers;
using API.Entities;
using API.Entities.Enums;
using API.Helpers;
using API.Helpers.Builders;
using API.Services;
using Xunit;
@ -51,11 +53,10 @@ public class CacheHelperTests
[Fact]
public void ShouldUpdateCoverImage_OnFirstRun()
{
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = DateTime.Now
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(DateTime.Now)
.Build();
Assert.True(_cacheHelper.ShouldUpdateCoverImage(null, file, DateTime.Now.Subtract(TimeSpan.FromMinutes(1)),
false, false));
}
@ -64,11 +65,9 @@ public class CacheHelperTests
public void ShouldUpdateCoverImage_ShouldNotUpdateOnSecondRunWithCoverImageSetNotLocked()
{
// Represents first run
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = DateTime.Now
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(DateTime.Now)
.Build();
Assert.False(_cacheHelper.ShouldUpdateCoverImage(_testCoverPath, file, DateTime.Now.Subtract(TimeSpan.FromMinutes(1)),
false, false));
}
@ -77,11 +76,9 @@ public class CacheHelperTests
public void ShouldUpdateCoverImage_ShouldNotUpdateOnSecondRunWithCoverImageSetNotLocked_2()
{
// Represents first run
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = DateTime.Now
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(DateTime.Now)
.Build();
Assert.False(_cacheHelper.ShouldUpdateCoverImage(_testCoverPath, file, DateTime.Now,
false, false));
}
@ -90,11 +87,9 @@ public class CacheHelperTests
public void ShouldUpdateCoverImage_ShouldNotUpdateOnSecondRunWithCoverImageSetLocked()
{
// Represents first run
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = DateTime.Now
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(DateTime.Now)
.Build();
Assert.False(_cacheHelper.ShouldUpdateCoverImage(_testCoverPath, file, DateTime.Now.Subtract(TimeSpan.FromMinutes(1)),
false, true));
}
@ -103,11 +98,9 @@ public class CacheHelperTests
public void ShouldUpdateCoverImage_ShouldNotUpdateOnSecondRunWithCoverImageSetLocked_Modified()
{
// Represents first run
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = DateTime.Now
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(DateTime.Now)
.Build();
Assert.False(_cacheHelper.ShouldUpdateCoverImage(_testCoverPath, file, DateTime.Now.Subtract(TimeSpan.FromMinutes(1)),
false, true));
}
@ -129,11 +122,10 @@ public class CacheHelperTests
var cacheHelper = new CacheHelper(fileService);
var created = DateTime.Now.Subtract(TimeSpan.FromHours(1));
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = DateTime.Now.Subtract(TimeSpan.FromMinutes(1))
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(DateTime.Now.Subtract(TimeSpan.FromMinutes(1)))
.Build();
Assert.True(cacheHelper.ShouldUpdateCoverImage(_testCoverPath, file, created,
false, false));
}
@ -154,19 +146,14 @@ public class CacheHelperTests
var fileService = new FileService(fileSystem);
var cacheHelper = new CacheHelper(fileService);
var chapter = new Chapter()
{
Number = "1",
Range = "1",
Created = filesystemFile.LastWriteTime.DateTime,
LastModified = filesystemFile.LastWriteTime.DateTime
};
var chapter = new ChapterBuilder("1")
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.WithCreated(filesystemFile.LastWriteTime.DateTime)
.Build();
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = filesystemFile.LastWriteTime.DateTime
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.Build();
Assert.True(cacheHelper.IsFileUnmodifiedSinceCreationOrLastScan(chapter, false, file));
}
@ -186,19 +173,15 @@ public class CacheHelperTests
var fileService = new FileService(fileSystem);
var cacheHelper = new CacheHelper(fileService);
var chapter = new Chapter()
{
Number = "1",
Range = "1",
Created = filesystemFile.LastWriteTime.DateTime,
LastModified = filesystemFile.LastWriteTime.DateTime
};
var chapter = new ChapterBuilder("1")
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.WithCreated(filesystemFile.LastWriteTime.DateTime)
.Build();
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.Build();
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = filesystemFile.LastWriteTime.DateTime
};
Assert.True(cacheHelper.IsFileUnmodifiedSinceCreationOrLastScan(chapter, false, file));
}
@ -218,19 +201,14 @@ public class CacheHelperTests
var fileService = new FileService(fileSystem);
var cacheHelper = new CacheHelper(fileService);
var chapter = new Chapter()
{
Number = "1",
Range = "1",
Created = filesystemFile.LastWriteTime.DateTime,
LastModified = filesystemFile.LastWriteTime.DateTime
};
var chapter = new ChapterBuilder("1")
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.WithCreated(filesystemFile.LastWriteTime.DateTime)
.Build();
var file = new MangaFile()
{
FilePath = TestCoverArchive,
LastModified = filesystemFile.LastWriteTime.DateTime
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.Build();
Assert.False(cacheHelper.IsFileUnmodifiedSinceCreationOrLastScan(chapter, true, file));
}
@ -251,19 +229,14 @@ public class CacheHelperTests
var fileService = new FileService(fileSystem);
var cacheHelper = new CacheHelper(fileService);
var chapter = new Chapter()
{
Number = "1",
Range = "1",
Created = DateTime.Now.Subtract(TimeSpan.FromMinutes(10)),
LastModified = DateTime.Now.Subtract(TimeSpan.FromMinutes(10))
};
var chapter = new ChapterBuilder("1")
.WithLastModified(DateTime.Now.Subtract(TimeSpan.FromMinutes(10)))
.WithCreated(DateTime.Now.Subtract(TimeSpan.FromMinutes(10)))
.Build();
var file = new MangaFile()
{
FilePath = Path.Join(TestCoverImageDirectory, TestCoverArchive),
LastModified = filesystemFile.LastWriteTime.DateTime
};
var file = new MangaFileBuilder(TestCoverArchive, MangaFormat.Archive)
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.Build();
Assert.False(cacheHelper.IsFileUnmodifiedSinceCreationOrLastScan(chapter, false, file));
}
@ -283,19 +256,15 @@ public class CacheHelperTests
var fileService = new FileService(fileSystem);
var cacheHelper = new CacheHelper(fileService);
var chapter = new Chapter()
{
Number = "1",
Range = "1",
Created = DateTime.Now.Subtract(TimeSpan.FromMinutes(10)),
LastModified = DateTime.Now
};
var chapter = new ChapterBuilder("1")
.WithLastModified(DateTime.Now)
.WithCreated(DateTime.Now.Subtract(TimeSpan.FromMinutes(10)))
.Build();
var file = new MangaFileBuilder(Path.Join(TestCoverImageDirectory, TestCoverArchive), MangaFormat.Archive)
.WithLastModified(filesystemFile.LastWriteTime.DateTime)
.Build();
var file = new MangaFile()
{
FilePath = Path.Join(TestCoverImageDirectory, TestCoverArchive),
LastModified = filesystemFile.LastWriteTime.DateTime
};
Assert.False(cacheHelper.IsFileUnmodifiedSinceCreationOrLastScan(chapter, false, file));
}

View File

@ -1,74 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using API.Data;
using API.Entities;
using API.Entities.Enums;
using API.Entities.Metadata;
using API.Extensions;
namespace API.Tests.Helpers;
/// <summary>
/// Used to help quickly create DB entities for Unit Testing
/// </summary>
public static class EntityFactory
{
public static Series CreateSeries(string name)
{
return new Series()
{
Name = name,
SortName = name,
LocalizedName = name,
NormalizedName = name.ToNormalized(),
OriginalName = name,
NormalizedLocalizedName = name.ToNormalized(),
Volumes = new List<Volume>(),
Metadata = new SeriesMetadata()
};
}
public static Volume CreateVolume(string volumeNumber, List<Chapter> chapters = null)
{
var chaps = chapters ?? new List<Chapter>();
var pages = chaps.Count > 0 ? chaps.Max(c => c.Pages) : 0;
return new Volume()
{
Name = volumeNumber,
Number = (int) API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(volumeNumber),
Pages = pages,
Chapters = chaps
};
}
public static Chapter CreateChapter(string range, bool isSpecial, List<MangaFile> files = null, int pageCount = 0, string title = null)
{
return new Chapter()
{
IsSpecial = isSpecial,
Range = range,
Number = API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(range) + string.Empty,
Files = files ?? new List<MangaFile>(),
Pages = pageCount,
Title = title ?? range
};
}
public static MangaFile CreateMangaFile(string filename, MangaFormat format, int pages)
{
return new MangaFile()
{
FilePath = filename,
Format = format,
Pages = pages
};
}
public static CollectionTag CreateCollectionTag(int id, string title, string summary, bool promoted)
{
return DbFactory.CollectionTag(id, title, summary, promoted);
}
}

View File

@ -2,6 +2,7 @@
using API.Data;
using API.Entities;
using API.Helpers;
using API.Helpers.Builders;
using Xunit;
namespace API.Tests.Helpers;
@ -13,9 +14,9 @@ public class GenreHelperTests
{
var allGenres = new List<Genre>
{
DbFactory.Genre("Action"),
DbFactory.Genre("action"),
DbFactory.Genre("Sci-fi"),
new GenreBuilder("Action").Build(),
new GenreBuilder("action").Build(),
new GenreBuilder("Sci-fi").Build(),
};
var genreAdded = new List<Genre>();
@ -33,9 +34,9 @@ public class GenreHelperTests
{
var allGenres = new List<Genre>
{
DbFactory.Genre("Action"),
DbFactory.Genre("action"),
DbFactory.Genre("Sci-fi"),
new GenreBuilder("Action").Build(),
new GenreBuilder("action").Build(),
new GenreBuilder("Sci-fi").Build(),
};
var genreAdded = new List<Genre>();
@ -54,19 +55,19 @@ public class GenreHelperTests
{
var existingGenres = new List<Genre>
{
DbFactory.Genre("Action"),
DbFactory.Genre("action"),
DbFactory.Genre("Sci-fi"),
new GenreBuilder("Action").Build(),
new GenreBuilder("action").Build(),
new GenreBuilder("Sci-fi").Build(),
};
GenreHelper.AddGenreIfNotExists(existingGenres, DbFactory.Genre("Action"));
GenreHelper.AddGenreIfNotExists(existingGenres, new GenreBuilder("Action").Build());
Assert.Equal(3, existingGenres.Count);
GenreHelper.AddGenreIfNotExists(existingGenres, DbFactory.Genre("action"));
GenreHelper.AddGenreIfNotExists(existingGenres, new GenreBuilder("action").Build());
Assert.Equal(3, existingGenres.Count);
GenreHelper.AddGenreIfNotExists(existingGenres, DbFactory.Genre("Shonen"));
GenreHelper.AddGenreIfNotExists(existingGenres, new GenreBuilder("Shonen").Build());
Assert.Equal(4, existingGenres.Count);
}
@ -75,13 +76,13 @@ public class GenreHelperTests
{
var existingGenres = new List<Genre>
{
DbFactory.Genre("Action"),
DbFactory.Genre("Sci-fi"),
new GenreBuilder("Action").Build(),
new GenreBuilder("Sci-fi").Build(),
};
var peopleFromChapters = new List<Genre>
{
DbFactory.Genre("Action"),
new GenreBuilder("Action").Build(),
};
var genreRemoved = new List<Genre>();
@ -99,8 +100,8 @@ public class GenreHelperTests
{
var existingGenres = new List<Genre>
{
DbFactory.Genre("Action"),
DbFactory.Genre("Sci-fi"),
new GenreBuilder("Action").Build(),
new GenreBuilder("Sci-fi").Build(),
};
var peopleFromChapters = new List<Genre>();

View File

@ -4,8 +4,8 @@ using System.IO;
using System.Linq;
using API.Entities.Enums;
using API.Extensions;
using API.Parser;
using API.Services.Tasks.Scanner;
using API.Services.Tasks.Scanner.Parser;
namespace API.Tests.Helpers;

View File

@ -5,8 +5,8 @@ using API.Entities.Metadata;
using API.Extensions;
using API.Helpers;
using API.Helpers.Builders;
using API.Parser;
using API.Services.Tasks.Scanner;
using API.Services.Tasks.Scanner.Parser;
using Xunit;
namespace API.Tests.Helpers;
@ -25,7 +25,6 @@ public class ParserInfoHelperTests
var series = new SeriesBuilder("Darker Than Black")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithName("1")
.Build())
@ -46,7 +45,6 @@ public class ParserInfoHelperTests
var series = new SeriesBuilder("Darker Than Black")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithName("1")
.Build())

View File

@ -1,8 +1,12 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using API.Data;
using API.DTOs;
using API.Entities;
using API.Entities.Enums;
using API.Helpers;
using API.Helpers.Builders;
using Xunit;
namespace API.Tests.Helpers;
@ -15,8 +19,8 @@ public class PersonHelperTests
{
var allPeople = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist),
DbFactory.Person("Joe Shmo", PersonRole.Writer)
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
};
var peopleAdded = new List<Person>();
@ -34,9 +38,9 @@ public class PersonHelperTests
{
var allPeople = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist),
DbFactory.Person("Joe Shmo", PersonRole.Writer),
DbFactory.Person("Sally Ann", PersonRole.CoverArtist),
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
new PersonBuilder("Sally Ann", PersonRole.CoverArtist).Build(),
};
var peopleAdded = new List<Person>();
@ -52,6 +56,150 @@ public class PersonHelperTests
#region UpdatePeopleList
[Fact]
public void UpdatePeopleList_NullTags_NoChanges()
{
// Arrange
ICollection<PersonDto> tags = null;
var series = new SeriesBuilder("Test Series").Build();
var allTags = new List<Person>();
var handleAddCalled = false;
var onModifiedCalled = false;
// Act
PersonHelper.UpdatePeopleList(PersonRole.Writer, tags, series, allTags, p => handleAddCalled = true, () => onModifiedCalled = true);
// Assert
Assert.False(handleAddCalled);
Assert.False(onModifiedCalled);
}
[Fact]
public void UpdatePeopleList_AddNewTag_TagAddedAndOnModifiedCalled()
{
// Arrange
const PersonRole role = PersonRole.Writer;
var tags = new List<PersonDto>
{
new PersonDto { Id = 1, Name = "John Doe", Role = role }
};
var series = new SeriesBuilder("Test Series").Build();
var allTags = new List<Person>();
var handleAddCalled = false;
var onModifiedCalled = false;
// Act
PersonHelper.UpdatePeopleList(role, tags, series, allTags, p =>
{
handleAddCalled = true;
series.Metadata.People.Add(p);
}, () => onModifiedCalled = true);
// Assert
Assert.True(handleAddCalled);
Assert.True(onModifiedCalled);
Assert.Single(series.Metadata.People);
Assert.Equal("John Doe", series.Metadata.People.First().Name);
}
[Fact]
public void UpdatePeopleList_RemoveExistingTag_TagRemovedAndOnModifiedCalled()
{
// Arrange
const PersonRole role = PersonRole.Writer;
var tags = new List<PersonDto>();
var series = new SeriesBuilder("Test Series").Build();
var person = new PersonBuilder("John Doe", role).Build();
person.Id = 1;
series.Metadata.People.Add(person);
var allTags = new List<Person>
{
person
};
var handleAddCalled = false;
var onModifiedCalled = false;
// Act
PersonHelper.UpdatePeopleList(role, tags, series, allTags, p =>
{
handleAddCalled = true;
series.Metadata.People.Add(p);
}, () => onModifiedCalled = true);
// Assert
Assert.False(handleAddCalled);
Assert.True(onModifiedCalled);
Assert.Empty(series.Metadata.People);
}
[Fact]
public void UpdatePeopleList_UpdateExistingTag_OnModifiedCalled()
{
// Arrange
const PersonRole role = PersonRole.Writer;
var tags = new List<PersonDto>
{
new PersonDto { Id = 1, Name = "John Doe", Role = role }
};
var series = new SeriesBuilder("Test Series").Build();
var person = new PersonBuilder("John Doe", role).Build();
person.Id = 1;
series.Metadata.People.Add(person);
var allTags = new List<Person>
{
person
};
var handleAddCalled = false;
var onModifiedCalled = false;
// Act
PersonHelper.UpdatePeopleList(role, tags, series, allTags, p =>
{
handleAddCalled = true;
series.Metadata.People.Add(p);
}, () => onModifiedCalled = true);
// Assert
Assert.False(handleAddCalled);
Assert.False(onModifiedCalled);
Assert.Single(series.Metadata.People);
Assert.Equal("John Doe", series.Metadata.People.First().Name);
}
[Fact]
public void UpdatePeopleList_NoChanges_HandleAddAndOnModifiedNotCalled()
{
// Arrange
const PersonRole role = PersonRole.Writer;
var tags = new List<PersonDto>
{
new PersonDto { Id = 1, Name = "John Doe", Role = role }
};
var series = new SeriesBuilder("Test Series").Build();
var person = new PersonBuilder("John Doe", role).Build();
person.Id = 1;
series.Metadata.People.Add(person);
var allTags = new List<Person>
{
new PersonBuilder("John Doe", role).Build()
};
var handleAddCalled = false;
var onModifiedCalled = false;
// Act
PersonHelper.UpdatePeopleList(role, tags, series, allTags, p =>
{
handleAddCalled = true;
series.Metadata.People.Add(p);
}, () => onModifiedCalled = true);
// Assert
Assert.False(handleAddCalled);
Assert.False(onModifiedCalled);
Assert.Single(series.Metadata.People);
Assert.Equal("John Doe", series.Metadata.People.First().Name);
}
#endregion
@ -62,8 +210,8 @@ public class PersonHelperTests
{
var existingPeople = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist),
DbFactory.Person("Joe Shmo", PersonRole.Writer)
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
};
var peopleRemoved = new List<Person>();
PersonHelper.RemovePeople(existingPeople, new[] {"Joe Shmo", "Sally Ann"}, PersonRole.Writer, person =>
@ -80,8 +228,8 @@ public class PersonHelperTests
{
var existingPeople = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist),
DbFactory.Person("Joe Shmo", PersonRole.Writer)
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
};
var peopleRemoved = new List<Person>();
PersonHelper.RemovePeople(existingPeople, new[] {"Joe Shmo", "Sally Ann"}, PersonRole.Writer, person =>
@ -106,9 +254,9 @@ public class PersonHelperTests
{
var existingPeople = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.Writer),
DbFactory.Person("Joe Shmo", PersonRole.Writer),
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist)
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
};
var peopleRemoved = new List<Person>();
PersonHelper.RemovePeople(existingPeople, new List<string>(), PersonRole.Writer, person =>
@ -129,14 +277,14 @@ public class PersonHelperTests
{
var existingPeople = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist),
DbFactory.Person("Joe Shmo", PersonRole.Writer),
DbFactory.Person("Sally", PersonRole.Writer),
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
new PersonBuilder("Sally", PersonRole.Writer).Build(),
};
var peopleFromChapters = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist),
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
};
var peopleRemoved = new List<Person>();
@ -152,24 +300,113 @@ public class PersonHelperTests
#region AddPeople
[Fact]
public void AddPersonIfNotExists_ShouldAddPerson_WhenPersonDoesNotExist()
{
// Arrange
var metadataPeople = new List<Person>();
var person = new PersonBuilder("John Smith", PersonRole.Character).Build();
// Act
PersonHelper.AddPersonIfNotExists(metadataPeople, person);
// Assert
Assert.Single(metadataPeople);
Assert.Contains(person, metadataPeople);
}
[Fact]
public void AddPersonIfNotExists_ShouldNotAddPerson_WhenPersonAlreadyExists()
{
// Arrange
var metadataPeople = new List<Person>
{
new PersonBuilder("John Smith", PersonRole.Character)
.WithId(1)
.Build()
};
var person = new PersonBuilder("John Smith", PersonRole.Character).Build();
// Act
PersonHelper.AddPersonIfNotExists(metadataPeople, person);
// Assert
Assert.Single(metadataPeople);
Assert.NotNull(metadataPeople.SingleOrDefault(p =>
p.Name.Equals(person.Name) && p.Role == person.Role && p.NormalizedName == person.NormalizedName));
Assert.Equal(1, metadataPeople.First().Id);
}
[Fact]
public void AddPersonIfNotExists_ShouldNotAddPerson_WhenPersonNameIsNullOrEmpty()
{
// Arrange
var metadataPeople = new List<Person>();
var person2 = new PersonBuilder(string.Empty, PersonRole.Character).Build();
// Act
PersonHelper.AddPersonIfNotExists(metadataPeople, person2);
// Assert
Assert.Empty(metadataPeople);
}
[Fact]
public void AddPersonIfNotExists_ShouldAddPerson_WhenPersonNameIsDifferentButRoleIsSame()
{
// Arrange
var metadataPeople = new List<Person>
{
new PersonBuilder("John Smith", PersonRole.Character).Build()
};
var person = new PersonBuilder("John Doe", PersonRole.Character).Build();
// Act
PersonHelper.AddPersonIfNotExists(metadataPeople, person);
// Assert
Assert.Equal(2, metadataPeople.Count);
Assert.Contains(person, metadataPeople);
}
[Fact]
public void AddPersonIfNotExists_ShouldAddPerson_WhenPersonNameIsSameButRoleIsDifferent()
{
// Arrange
var metadataPeople = new List<Person>
{
new PersonBuilder("John Doe", PersonRole.Writer).Build()
};
var person = new PersonBuilder("John Smith", PersonRole.Character).Build();
// Act
PersonHelper.AddPersonIfNotExists(metadataPeople, person);
// Assert
Assert.Equal(2, metadataPeople.Count);
Assert.Contains(person, metadataPeople);
}
[Fact]
public void AddPeople_ShouldAddOnlyNonExistingPeople()
{
var existingPeople = new List<Person>
{
DbFactory.Person("Joe Shmo", PersonRole.CoverArtist),
DbFactory.Person("Joe Shmo", PersonRole.Writer),
DbFactory.Person("Sally", PersonRole.Writer),
new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build(),
new PersonBuilder("Joe Shmo", PersonRole.Writer).Build(),
new PersonBuilder("Sally", PersonRole.Writer).Build(),
};
PersonHelper.AddPersonIfNotExists(existingPeople, DbFactory.Person("Joe Shmo", PersonRole.CoverArtist));
PersonHelper.AddPersonIfNotExists(existingPeople, new PersonBuilder("Joe Shmo", PersonRole.CoverArtist).Build());
Assert.Equal(3, existingPeople.Count);
PersonHelper.AddPersonIfNotExists(existingPeople, DbFactory.Person("Joe Shmo", PersonRole.Writer));
PersonHelper.AddPersonIfNotExists(existingPeople, new PersonBuilder("Joe Shmo", PersonRole.Writer).Build());
Assert.Equal(3, existingPeople.Count);
PersonHelper.AddPersonIfNotExists(existingPeople, DbFactory.Person("Joe Shmo Two", PersonRole.CoverArtist));
PersonHelper.AddPersonIfNotExists(existingPeople, new PersonBuilder("Joe Shmo Two", PersonRole.CoverArtist).Build());
Assert.Equal(4, existingPeople.Count);
}

View File

@ -5,6 +5,7 @@ using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Helpers;
using API.Helpers.Builders;
using API.Services.Tasks.Scanner;
using Xunit;
@ -16,7 +17,7 @@ public class SeriesHelperTests
[Fact]
public void FindSeries_ShouldFind_SameFormat()
{
var series = DbFactory.Series("Darker than Black");
var series = new SeriesBuilder("Darker than Black").Build();
series.OriginalName = "Something Random";
series.Format = MangaFormat.Archive;
Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries()
@ -44,7 +45,7 @@ public class SeriesHelperTests
[Fact]
public void FindSeries_ShouldFind_NullName()
{
var series = DbFactory.Series("Darker than Black");
var series = new SeriesBuilder("Darker than Black").Build();
series.OriginalName = null;
series.Format = MangaFormat.Archive;
Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries()
@ -58,7 +59,7 @@ public class SeriesHelperTests
[Fact]
public void FindSeries_ShouldNotFind_WrongFormat()
{
var series = DbFactory.Series("Darker than Black");
var series = new SeriesBuilder("Darker than Black").Build();
series.OriginalName = "Something Random";
series.Format = MangaFormat.Archive;
Assert.False(SeriesHelper.FindSeries(series, new ParsedSeries()
@ -86,7 +87,7 @@ public class SeriesHelperTests
[Fact]
public void FindSeries_ShouldFind_UsingOriginalName()
{
var series = DbFactory.Series("Darker than Black");
var series = new SeriesBuilder("Darker than Black").Build();
series.OriginalName = "Something Random";
series.Format = MangaFormat.Image;
Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries()
@ -121,7 +122,7 @@ public class SeriesHelperTests
[Fact]
public void FindSeries_ShouldFind_UsingLocalizedName()
{
var series = DbFactory.Series("Darker than Black");
var series = new SeriesBuilder("Darker than Black").Build();
series.LocalizedName = "Something Random";
series.Format = MangaFormat.Image;
Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries()
@ -156,7 +157,7 @@ public class SeriesHelperTests
[Fact]
public void FindSeries_ShouldFind_UsingLocalizedName_2()
{
var series = DbFactory.Series("My Dress-Up Darling");
var series = new SeriesBuilder("My Dress-Up Darling").Build();
series.LocalizedName = "Sono Bisque Doll wa Koi wo Suru";
series.Format = MangaFormat.Archive;
Assert.True(SeriesHelper.FindSeries(series, new ParsedSeries()
@ -180,13 +181,13 @@ public class SeriesHelperTests
{
var existingSeries = new List<Series>()
{
EntityFactory.CreateSeries("Darker than Black Vol 1"),
EntityFactory.CreateSeries("Darker than Black"),
EntityFactory.CreateSeries("Beastars"),
new SeriesBuilder("Darker than Black Vol 1").Build(),
new SeriesBuilder("Darker than Black").Build(),
new SeriesBuilder("Beastars").Build(),
};
var missingSeries = new List<Series>()
{
EntityFactory.CreateSeries("Darker than Black Vol 1"),
new SeriesBuilder("Darker than Black Vol 1").Build(),
};
existingSeries = SeriesHelper.RemoveMissingSeries(existingSeries, missingSeries, out var removeCount).ToList();

View File

@ -2,6 +2,7 @@
using API.Data;
using API.Entities;
using API.Helpers;
using API.Helpers.Builders;
using Xunit;
namespace API.Tests.Helpers;
@ -13,9 +14,9 @@ public class TagHelperTests
{
var allTags = new List<Tag>
{
DbFactory.Tag("Action"),
DbFactory.Tag("action"),
DbFactory.Tag("Sci-fi"),
new TagBuilder("Action").Build(),
new TagBuilder("action").Build(),
new TagBuilder("Sci-fi").Build(),
};
var tagAdded = new List<Tag>();
@ -37,9 +38,9 @@ public class TagHelperTests
{
var allTags = new List<Tag>
{
DbFactory.Tag("Action"),
DbFactory.Tag("action"),
DbFactory.Tag("Sci-fi"),
new TagBuilder("Action").Build(),
new TagBuilder("action").Build(),
new TagBuilder("Sci-fi").Build(),
};
var tagAdded = new List<Tag>();
@ -62,19 +63,19 @@ public class TagHelperTests
{
var existingTags = new List<Tag>
{
DbFactory.Tag("Action"),
DbFactory.Tag("action"),
DbFactory.Tag("Sci-fi"),
new TagBuilder("Action").Build(),
new TagBuilder("action").Build(),
new TagBuilder("Sci-fi").Build(),
};
TagHelper.AddTagIfNotExists(existingTags, DbFactory.Tag("Action"));
TagHelper.AddTagIfNotExists(existingTags, new TagBuilder("Action").Build());
Assert.Equal(3, existingTags.Count);
TagHelper.AddTagIfNotExists(existingTags, DbFactory.Tag("action"));
TagHelper.AddTagIfNotExists(existingTags, new TagBuilder("action").Build());
Assert.Equal(3, existingTags.Count);
TagHelper.AddTagIfNotExists(existingTags, DbFactory.Tag("Shonen"));
TagHelper.AddTagIfNotExists(existingTags, new TagBuilder("Shonen").Build());
Assert.Equal(4, existingTags.Count);
}
@ -83,13 +84,13 @@ public class TagHelperTests
{
var existingTags = new List<Tag>
{
DbFactory.Tag("Action"),
DbFactory.Tag("Sci-fi"),
new TagBuilder("Action").Build(),
new TagBuilder("Sci-fi").Build(),
};
var peopleFromChapters = new List<Tag>
{
DbFactory.Tag("Action"),
new TagBuilder("Action").Build(),
};
var tagRemoved = new List<Tag>();
@ -107,8 +108,8 @@ public class TagHelperTests
{
var existingTags = new List<Tag>
{
DbFactory.Tag("Action"),
DbFactory.Tag("Sci-fi"),
new TagBuilder("Action").Build(),
new TagBuilder("Sci-fi").Build(),
};
var peopleFromChapters = new List<Tag>();

View File

@ -1,7 +1,8 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
using API.Entities.Enums;
using API.Parser;
using API.Services;
using API.Services.Tasks.Scanner.Parser;
using Microsoft.Extensions.Logging;
@ -100,6 +101,14 @@ public class DefaultParserTests
#region Parse
[Fact]
public void Parse_MangaLibrary_JustCover_ShouldReturnNull()
{
const string rootPath = @"E:/Manga/";
var actual = _defaultParser.Parse(@"E:/Manga/Accel World/cover.png", rootPath);
Assert.Null(actual);
}
[Fact]
public void Parse_ParseInfo_Manga()
{

View File

@ -1,5 +1,5 @@
using API.Entities.Enums;
using API.Parser;
using API.Services.Tasks.Scanner.Parser;
using Xunit;
namespace API.Tests.Parser;

View File

@ -7,6 +7,7 @@ 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;
@ -70,10 +71,10 @@ public class CollectionTagRepositoryTests
_context.ServerSetting.Update(setting);
var lib = new Library()
{
Name = "Manga", Folders = new List<FolderPath>() {new FolderPath() {Path = "C:/data/"}}
};
var lib = new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build();
_context.AppUser.Add(new AppUser()
{
@ -118,13 +119,13 @@ public class CollectionTagRepositoryTests
[Fact]
public async Task RemoveTagsWithoutSeries_ShouldRemoveTags()
{
var library = DbFactory.Library("Test", LibraryType.Manga);
var series = DbFactory.Series("Test 1");
var commonTag = DbFactory.CollectionTag(0, "Tag 1");
var library = new LibraryBuilder("Test", LibraryType.Manga).Build();
var series = new SeriesBuilder("Test 1").Build();
var commonTag = new CollectionTagBuilder("Tag 1").Build();
series.Metadata.CollectionTags.Add(commonTag);
series.Metadata.CollectionTags.Add(DbFactory.CollectionTag(0, "Tag 2"));
series.Metadata.CollectionTags.Add(new CollectionTagBuilder("Tag 2").Build());
var series2 = DbFactory.Series("Test 1");
var series2 = new SeriesBuilder("Test 1").Build();
series2.Metadata.CollectionTags.Add(commonTag);
library.Series.Add(series);
library.Series.Add(series2);
@ -151,13 +152,13 @@ public class CollectionTagRepositoryTests
[Fact]
public async Task RemoveTagsWithoutSeries_ShouldNotRemoveTags()
{
var library = DbFactory.Library("Test", LibraryType.Manga);
var series = DbFactory.Series("Test 1");
var commonTag = DbFactory.CollectionTag(0, "Tag 1");
var library = new LibraryBuilder("Test", LibraryType.Manga).Build();
var series = new SeriesBuilder("Test 1").Build();
var commonTag = new CollectionTagBuilder("Tag 1").Build();
series.Metadata.CollectionTags.Add(commonTag);
series.Metadata.CollectionTags.Add(DbFactory.CollectionTag(0, "Tag 2"));
series.Metadata.CollectionTags.Add(new CollectionTagBuilder("Tag 2").Build());
var series2 = DbFactory.Series("Test 1");
var series2 = new SeriesBuilder("Test 1").Build();
series2.Metadata.CollectionTags.Add(commonTag);
library.Series.Add(series);
library.Series.Add(series2);

View File

@ -72,10 +72,9 @@ public class SeriesRepositoryTests
_context.ServerSetting.Update(setting);
var lib = new Library()
{
Name = "Manga", Folders = new List<FolderPath>() {new FolderPath() {Path = "C:/data/"}}
};
var lib = new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build();
_context.AppUser.Add(new AppUser()
{
@ -117,23 +116,13 @@ public class SeriesRepositoryTests
private async Task SetupSeriesData()
{
var library = new Library()
{
Name = "GetFullSeriesByAnyName Manga",
Type = LibraryType.Manga,
Folders = new List<FolderPath>()
{
new FolderPath() {Path = "C:/data/manga/"}
},
Series = new List<Series>()
{
new SeriesBuilder("The Idaten Deities Know Only Peace")
var library = new LibraryBuilder("GetFullSeriesByAnyName Manga", LibraryType.Manga)
.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)
.Build()
}
};
.Build())
.Build();
_unitOfWork.LibraryRepository.Add(library);
await _unitOfWork.CommitAsync();

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using API.Data;
using API.Entities;
using API.Entities.Enums;
using API.Helpers.Builders;
using API.Services;
using API.Services.Tasks;
using API.SignalR;
@ -80,18 +81,9 @@ public class BackupServiceTests
setting.Value = BackupDirectory;
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga",
Folders = new List<FolderPath>()
{
new FolderPath()
{
Path = "C:/data/"
}
}
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build());
return await _context.SaveChangesAsync() > 0;
}

View File

@ -87,17 +87,9 @@ public class BookmarkServiceTests
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga",
Folders = new List<FolderPath>()
{
new FolderPath()
{
Path = "C:/data/"
}
}
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build());
return await _context.SaveChangesAsync() > 0;
}
@ -140,18 +132,12 @@ public class BookmarkServiceTests
var series = new SeriesBuilder("Test")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1")
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(series);
@ -193,18 +179,13 @@ public class BookmarkServiceTests
var series = new SeriesBuilder("Test")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("0")
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(series);
@ -264,18 +245,13 @@ public class BookmarkServiceTests
var series = new SeriesBuilder("Test")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1")
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(series);
@ -345,18 +321,13 @@ public class BookmarkServiceTests
var series = new SeriesBuilder("Test")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1")
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(series);
@ -403,18 +374,13 @@ public class BookmarkServiceTests
var series = new SeriesBuilder("Test")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1")
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(series);
@ -461,18 +427,13 @@ public class BookmarkServiceTests
await ResetDB();
var series = new SeriesBuilder("Test")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1")
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(series);

View File

@ -8,8 +8,9 @@ using API.Data;
using API.Data.Metadata;
using API.Entities;
using API.Entities.Enums;
using API.Parser;
using API.Helpers.Builders;
using API.Services;
using API.Services.Tasks.Scanner.Parser;
using API.SignalR;
using AutoMapper;
using Microsoft.AspNetCore.SignalR;
@ -116,17 +117,9 @@ public class CacheServiceTests
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga",
Folders = new List<FolderPath>()
{
new FolderPath()
{
Path = "C:/data/"
}
}
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build());
return await _context.SaveChangesAsync() > 0;
}
@ -166,21 +159,11 @@ public class CacheServiceTests
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds), Substitute.For<IBookmarkService>());
await ResetDB();
var s = DbFactory.Series("Test");
var v = DbFactory.Volume("1");
var c = new Chapter()
{
Number = "1",
Range = "1",
Files = new List<MangaFile>()
{
new MangaFile()
{
Format = MangaFormat.Archive,
FilePath = $"{DataDirectory}Test v1.zip",
}
}
};
var s = new SeriesBuilder("Test").Build();
var v = new VolumeBuilder("1").Build();
var c = new ChapterBuilder("1")
.WithFile(new MangaFileBuilder($"{DataDirectory}Test v1.zip", MangaFormat.Archive).Build())
.Build();
v.Chapters.Add(c);
s.Volumes.Add(v);
s.LibraryId = 1;
@ -207,8 +190,8 @@ public class CacheServiceTests
// new ReadingItemService(archiveService, Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds));
//
// await ResetDB();
// var s = DbFactory.Series("Test");
// var v = DbFactory.Volume("1");
// var s = new SeriesBuilder("Test").Build();
// var v = new VolumeBuilder("1").Build();
// var c = new Chapter()
// {
// Number = "1",
@ -271,22 +254,10 @@ public class CacheServiceTests
new ReadingItemService(Substitute.For<IArchiveService>(),
Substitute.For<IBookService>(), Substitute.For<IImageService>(), ds), Substitute.For<IBookmarkService>());
var c = new Chapter()
{
Number = "1",
Range = "1",
Files = new List<MangaFile>()
{
new MangaFile()
{
FilePath = $"{DataDirectory}1.epub"
},
new MangaFile()
{
FilePath = $"{DataDirectory}2.epub"
}
}
};
var c = new ChapterBuilder("1")
.WithFile(new MangaFileBuilder($"{DataDirectory}1.epub", MangaFormat.Epub).Build())
.WithFile(new MangaFileBuilder($"{DataDirectory}2.epub", MangaFormat.Epub).Build())
.Build();
cs.GetCachedFile(c);
Assert.Same($"{DataDirectory}1.epub", cs.GetCachedFile(c));
}
@ -303,13 +274,9 @@ public class CacheServiceTests
filesystem.AddFile($"{DataDirectory}1.zip", new MockFileData(""));
filesystem.AddFile($"{DataDirectory}2.zip", new MockFileData(""));
var c = new Chapter()
{
Id = 1,
Number = "1",
Range = "1",
Files = new List<MangaFile>()
};
var c = new ChapterBuilder("1")
.WithId(1)
.Build();
var fileIndex = 0;
foreach (var file in c.Files)
@ -342,28 +309,17 @@ public class CacheServiceTests
filesystem.AddFile($"{DataDirectory}1.zip", new MockFileData(""));
filesystem.AddFile($"{DataDirectory}2.zip", new MockFileData(""));
var c = new Chapter()
{
Id = 1,
Number = "1",
Range = "1",
Files = new List<MangaFile>()
{
new MangaFile()
{
Id = 1,
FilePath = $"{DataDirectory}1.zip",
Pages = 10
},
new MangaFile()
{
Id = 2,
FilePath = $"{DataDirectory}2.zip",
Pages = 5
}
}
};
var c = new ChapterBuilder("1")
.WithId(1)
.WithFile(new MangaFileBuilder($"{DataDirectory}1.zip", MangaFormat.Archive)
.WithPages(10)
.WithId(1)
.Build())
.WithFile(new MangaFileBuilder($"{DataDirectory}2.zip", MangaFormat.Archive)
.WithPages(5)
.WithId(2)
.Build())
.Build();
var fileIndex = 0;
foreach (var file in c.Files)
@ -396,22 +352,13 @@ public class CacheServiceTests
filesystem.AddDirectory($"{CacheDirectory}1/");
filesystem.AddFile($"{DataDirectory}1.zip", new MockFileData(""));
var c = new Chapter()
{
Id = 1,
Number = "1",
Range = "1",
Files = new List<MangaFile>()
{
new MangaFile()
{
Id = 1,
FilePath = $"{DataDirectory}1.zip",
Pages = 10
}
}
};
var c = new ChapterBuilder("1")
.WithId(1)
.WithFile(new MangaFileBuilder($"{DataDirectory}1.zip", MangaFormat.Archive)
.WithPages(10)
.WithId(1)
.Build())
.Build();
c.Pages = c.Files.Sum(f => f.Pages);
var fileIndex = 0;
@ -446,28 +393,17 @@ public class CacheServiceTests
filesystem.AddFile($"{DataDirectory}1.zip", new MockFileData(""));
filesystem.AddFile($"{DataDirectory}2.zip", new MockFileData(""));
var c = new Chapter()
{
Id = 1,
Number = "1",
Range = "1",
Files = new List<MangaFile>()
{
new MangaFile()
{
Id = 1,
FilePath = $"{DataDirectory}1.zip",
Pages = 10
},
new MangaFile()
{
Id = 2,
FilePath = $"{DataDirectory}2.zip",
Pages = 5
}
}
};
var c = new ChapterBuilder("1")
.WithId(1)
.WithFile(new MangaFileBuilder($"{DataDirectory}1.zip", MangaFormat.Archive)
.WithPages(10)
.WithId(1)
.Build())
.WithFile(new MangaFileBuilder($"{DataDirectory}2.zip", MangaFormat.Archive)
.WithPages(5)
.WithId(2)
.Build())
.Build();
var fileIndex = 0;
foreach (var file in c.Files)

View File

@ -31,17 +31,9 @@ public class CleanupServiceTests : AbstractDbTest
public CleanupServiceTests() : base()
{
_context.Library.Add(new Library()
{
Name = "Manga",
Folders = new List<FolderPath>()
{
new FolderPath()
{
Path = "C:/data/"
}
}
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build());
}
#region Setup
@ -71,15 +63,15 @@ public class CleanupServiceTests : AbstractDbTest
// Delete all Series to reset state
await ResetDb();
var s = DbFactory.Series("Test 1");
var s = new SeriesBuilder("Test 1").Build();
s.CoverImage = $"{ImageService.GetSeriesFormat(1)}.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
s = DbFactory.Series("Test 2");
s = new SeriesBuilder("Test 2").Build();
s.CoverImage = $"{ImageService.GetSeriesFormat(3)}.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
s = DbFactory.Series("Test 3");
s = new SeriesBuilder("Test 3").Build();
s.CoverImage = $"{ImageService.GetSeriesFormat(1000)}.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
@ -105,11 +97,11 @@ public class CleanupServiceTests : AbstractDbTest
await ResetDb();
// Add 2 series with cover images
var s = DbFactory.Series("Test 1");
var s = new SeriesBuilder("Test 1").Build();
s.CoverImage = $"{ImageService.GetSeriesFormat(1)}.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
s = DbFactory.Series("Test 2");
s = new SeriesBuilder("Test 2").Build();
s.CoverImage = $"{ImageService.GetSeriesFormat(3)}.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
@ -139,33 +131,23 @@ public class CleanupServiceTests : AbstractDbTest
await ResetDb();
// Add 2 series with cover images
var s = DbFactory.Series("Test 1");
var v = DbFactory.Volume("1");
v.Chapters.Add(new Chapter()
{
Number = "0",
Range = "0",
CoverImage = "v01_c01.jpg"
});
v.CoverImage = "v01_c01.jpg";
s.Volumes.Add(v);
s.CoverImage = "series_01.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
_context.Series.Add(new SeriesBuilder("Test 1")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("0").WithCoverImage("v01_c01.jpg").Build())
.WithCoverImage("v01_c01.jpg")
.Build())
.WithCoverImage("series_01.jpg")
.WithLibraryId(1)
.Build());
s = DbFactory.Series("Test 2");
v = DbFactory.Volume("1");
v.Chapters.Add(new Chapter()
{
Number = "0",
Range = "0",
CoverImage = "v01_c03.jpg"
});
v.CoverImage = "v01_c03jpg";
s.Volumes.Add(v);
s.CoverImage = "series_03.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
_context.Series.Add(new SeriesBuilder("Test 2")
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("0").WithCoverImage("v01_c03.jpg").Build())
.WithCoverImage("v01_c03.jpg")
.Build())
.WithCoverImage("series_03.jpg")
.WithLibraryId(1)
.Build());
await _context.SaveChangesAsync();
@ -193,29 +175,26 @@ public class CleanupServiceTests : AbstractDbTest
await ResetDb();
// Add 2 series with cover images
var s = DbFactory.Series("Test 1");
s.Metadata.CollectionTags = new List<CollectionTag>();
s.Metadata.CollectionTags.Add(new CollectionTag()
{
Title = "Something",
NormalizedTitle = "Something".ToNormalized(),
CoverImage = $"{ImageService.GetCollectionTagFormat(1)}.jpg"
});
s.CoverImage = $"{ImageService.GetSeriesFormat(1)}.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
s = DbFactory.Series("Test 2");
s.Metadata.CollectionTags = new List<CollectionTag>();
s.Metadata.CollectionTags.Add(new CollectionTag()
{
Title = "Something 2",
NormalizedTitle = "Something 2".ToNormalized(),
CoverImage = $"{ImageService.GetCollectionTagFormat(2)}.jpg"
});
s.CoverImage = $"{ImageService.GetSeriesFormat(3)}.jpg";
s.LibraryId = 1;
_context.Series.Add(s);
_context.Series.Add(new SeriesBuilder("Test 1")
.WithMetadata(new SeriesMetadataBuilder()
.WithCollectionTag(new CollectionTagBuilder("Something")
.WithCoverImage($"{ImageService.GetCollectionTagFormat(1)}.jpg")
.Build())
.Build())
.WithCoverImage($"{ImageService.GetSeriesFormat(1)}.jpg")
.WithLibraryId(1)
.Build());
_context.Series.Add(new SeriesBuilder("Test 2")
.WithMetadata(new SeriesMetadataBuilder()
.WithCollectionTag(new CollectionTagBuilder("Something")
.WithCoverImage($"{ImageService.GetCollectionTagFormat(2)}.jpg")
.Build())
.Build())
.WithCoverImage($"{ImageService.GetSeriesFormat(3)}.jpg")
.WithLibraryId(1)
.Build());
await _context.SaveChangesAsync();
@ -247,20 +226,14 @@ public class CleanupServiceTests : AbstractDbTest
UserName = "Joe",
ReadingLists = new List<ReadingList>()
{
new ReadingList()
{
Title = "Something",
NormalizedTitle = "Something".ToNormalized(),
CoverImage = $"{ImageService.GetReadingListFormat(1)}.jpg",
AgeRating = AgeRating.Unknown
},
new ReadingList()
{
Title = "Something 2",
NormalizedTitle = "Something 2".ToNormalized(),
CoverImage = $"{ImageService.GetReadingListFormat(2)}.jpg",
AgeRating = AgeRating.Unknown
}
new ReadingListBuilder("Something")
.WithRating(AgeRating.Unknown)
.WithCoverImage($"{ImageService.GetReadingListFormat(1)}.jpg")
.Build(),
new ReadingListBuilder("Something 2")
.WithRating(AgeRating.Unknown)
.WithCoverImage($"{ImageService.GetReadingListFormat(2)}.jpg")
.Build(),
}
});
@ -415,17 +388,12 @@ public class CleanupServiceTests : AbstractDbTest
.Build();
var series = new SeriesBuilder("Test")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(1)
.WithChapter(c)
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(series);
@ -474,11 +442,7 @@ public class CleanupServiceTests : AbstractDbTest
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadataBuilder().WithCollectionTag(c).Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
s.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(s);
@ -515,11 +479,7 @@ public class CleanupServiceTests : AbstractDbTest
.WithMetadata(new SeriesMetadataBuilder().WithPublicationStatus(PublicationStatus.Completed).Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
s.Library = new LibraryBuilder("Test LIb").Build();
_context.Series.Add(s);
var user = new AppUser()

View File

@ -6,6 +6,7 @@ using API.Data.Repositories;
using API.DTOs.CollectionTags;
using API.Entities;
using API.Entities.Enums;
using API.Helpers.Builders;
using API.Services;
using API.SignalR;
using API.Tests.Helpers;
@ -33,19 +34,14 @@ public class CollectionTagServiceTests : AbstractDbTest
private async Task SeedSeries()
{
if (_context.CollectionTag.Any()) return;
_context.Library.Add(new Library()
{
Name = "Library 2",
Type = LibraryType.Manga,
Series = new List<Series>()
{
EntityFactory.CreateSeries("Series 1"),
EntityFactory.CreateSeries("Series 2"),
}
});
_context.CollectionTag.Add(DbFactory.CollectionTag(0, "Tag 1", string.Empty, false));
_context.CollectionTag.Add(DbFactory.CollectionTag(0, "Tag 2", string.Empty, true));
_context.Library.Add(new LibraryBuilder("Library 2", LibraryType.Manga)
.WithSeries(new SeriesBuilder("Series 1").Build())
.WithSeries(new SeriesBuilder("Series 2").Build())
.Build());
_context.CollectionTag.Add(new CollectionTagBuilder("Tag 1").Build());
_context.CollectionTag.Add(new CollectionTagBuilder("Tag 2").WithIsPromoted(true).Build());
await _unitOfWork.CommitAsync();
}
@ -63,8 +59,8 @@ public class CollectionTagServiceTests : AbstractDbTest
public async Task UpdateTag_ShouldUpdateFields()
{
await SeedSeries();
_context.CollectionTag.Add(EntityFactory.CreateCollectionTag(3, "UpdateTag_ShouldUpdateFields",
string.Empty, true));
_context.CollectionTag.Add(new CollectionTagBuilder("UpdateTag_ShouldUpdateFields").WithId(3).WithIsPromoted(true).Build());
await _unitOfWork.CommitAsync();
await _service.UpdateTag(new CollectionTagDto()

View File

@ -9,7 +9,7 @@ using API.Data.Metadata;
using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Parser;
using API.Helpers.Builders;
using API.Services;
using API.Services.Tasks.Scanner;
using API.Services.Tasks.Scanner.Parser;
@ -118,17 +118,9 @@ public class ParseScannedFilesTests
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga",
Folders = new List<FolderPath>()
{
new FolderPath()
{
Path = DataDirectory
}
}
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder(DataDirectory).Build())
.Build());
return await _context.SaveChangesAsync() > 0;
}

View File

@ -0,0 +1,72 @@
using System.IO;
using API.Data;
using API.Data.Metadata;
using API.Entities;
using API.Entities.Enums;
using API.Helpers;
using API.Helpers.Builders;
using API.Services;
using API.Services.Tasks.Metadata;
using API.Services.Tasks.Scanner;
using API.SignalR;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Xunit;
namespace API.Tests.Services;
public class ProcessSeriesTests
{
#region UpdateSeriesMetadata
#endregion
#region UpdateVolumes
#endregion
#region UpdateChapters
#endregion
#region AddOrUpdateFileForChapter
#endregion
#region UpdateChapterFromComicInfo
public void UpdateChapterFromComicInfo_()
{
// TODO: Do this
var file = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ScannerService/Library/Manga/Hajime no Ippo/Hajime no Ippo Chapter 1.cbz");
// Chapter and ComicInfo
var chapter = new ChapterBuilder("1")
.WithId(0)
.WithFile(new MangaFileBuilder(file, MangaFormat.Archive).Build())
.Build();
var ps = new ProcessSeries(Substitute.For<IUnitOfWork>(), Substitute.For<ILogger<ProcessSeries>>(),
Substitute.For<IEventHub>(), Substitute.For<IDirectoryService>()
, Substitute.For<ICacheHelper>(), Substitute.For<IReadingItemService>(), Substitute.For<IFileService>(),
Substitute.For<IMetadataService>(),
Substitute.For<IWordCountAnalyzerService>(),
Substitute.For<ICollectionTagService>());
ps.UpdateChapterFromComicInfo(chapter, new ComicInfo()
{
});
}
#endregion
}

View File

@ -81,10 +81,9 @@ public class ReaderServiceTests
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga", Folders = new List<FolderPath>() {new FolderPath() {Path = "C:/data/"}}
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build());
return await _context.SaveChangesAsync() > 0;
}
@ -130,7 +129,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("0")
@ -138,11 +136,8 @@ public class ReaderServiceTests
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -164,7 +159,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("0")
@ -172,11 +166,7 @@ public class ReaderServiceTests
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -208,7 +198,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("0")
@ -216,11 +205,7 @@ public class ReaderServiceTests
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -269,7 +254,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("0")
@ -280,11 +264,7 @@ public class ReaderServiceTests
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -313,7 +293,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("0")
@ -324,11 +303,7 @@ public class ReaderServiceTests
.Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -366,7 +341,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -385,11 +359,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -441,7 +411,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -460,11 +429,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -490,7 +455,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -509,11 +473,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -539,7 +499,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("1").Build())
@ -552,11 +511,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("22").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -582,7 +537,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("66").Build())
@ -599,11 +553,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("0").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -629,7 +579,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -642,11 +591,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("B.cbz").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -672,18 +617,13 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -707,7 +647,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("1").Build())
@ -720,11 +659,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("2").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -749,7 +684,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -762,11 +696,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("B.cbz").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -793,7 +723,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("1").Build())
@ -801,11 +730,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("A.cbz").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -831,7 +756,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("1").Build())
@ -843,11 +767,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("0").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -872,7 +792,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -884,11 +803,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("B.cbz").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -919,7 +834,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -938,11 +852,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -967,7 +877,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -986,11 +895,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
_context.AppUser.Add(new AppUser()
{
@ -1012,7 +917,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("40").WithPages(1).Build())
.WithChapter(new ChapterBuilder("50").WithPages(1).Build())
@ -1032,11 +936,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("31").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
_context.AppUser.Add(new AppUser()
{
@ -1061,7 +961,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -1077,11 +976,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1106,7 +1001,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
@ -1119,11 +1013,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("B.cbz").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1149,18 +1039,13 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1184,17 +1069,12 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("0").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1218,7 +1098,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("1").Build())
@ -1230,11 +1109,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("0").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1258,7 +1133,6 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("5").Build())
@ -1278,11 +1152,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("4").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1311,18 +1181,13 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1346,24 +1211,18 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.Build())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("A.cbz").WithIsSpecial(true).Build())
.WithChapter(new ChapterBuilder("B.cbz").WithIsSpecial(true).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1390,13 +1249,11 @@ public class ReaderServiceTests
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithNumber(0)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.Build())
.WithVolume(new VolumeBuilder("1")
.WithNumber(1)
.WithChapter(new ChapterBuilder("21").Build())
@ -1404,11 +1261,7 @@ public class ReaderServiceTests
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1436,12 +1289,10 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("95").Build())
.WithChapter(new ChapterBuilder("96").Build())
.Build())
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
@ -1456,11 +1307,7 @@ public class ReaderServiceTests
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1485,21 +1332,15 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(3).Build())
.Build())
.WithVolume(new VolumeBuilder("2")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
.WithPages(4)
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1530,7 +1371,6 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -1545,11 +1385,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1600,7 +1436,6 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
// Loose chapters
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("45").WithPages(1).Build())
@ -1624,11 +1459,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1673,12 +1504,10 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
.Build())
.WithVolume(new VolumeBuilder("2")
.WithChapter(new ChapterBuilder("21").WithPages(1).Build())
.Build())
@ -1687,11 +1516,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("32").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1740,7 +1565,6 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("230").WithPages(1).Build())
.WithChapter(new ChapterBuilder("231").WithPages(1).Build())
@ -1754,11 +1578,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("21").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1781,7 +1601,6 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("100").WithPages(1).Build())
.WithChapter(new ChapterBuilder("101").WithPages(1).Build())
@ -1796,11 +1615,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("21").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1845,7 +1660,6 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -1855,11 +1669,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("21").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1907,7 +1717,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -1919,11 +1729,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("22").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -1951,7 +1757,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -1959,11 +1765,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("Some Special Title").WithIsSpecial(true).WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2011,7 +1813,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("230").WithPages(1).Build())
//.WithChapter(new ChapterBuilder("231").WithPages(1).Build()) (Added later)
@ -2026,11 +1828,7 @@ public class ReaderServiceTests
//.WithChapter(new ChapterBuilder("14.9").WithPages(1).Build()) (added later)
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2048,8 +1846,12 @@ public class ReaderServiceTests
await _context.SaveChangesAsync();
// Add 2 new unread series to the Series
series.Volumes[0].Chapters.Add(EntityFactory.CreateChapter("231", false, new List<MangaFile>(), 1));
series.Volumes[2].Chapters.Add(EntityFactory.CreateChapter("14.9", false, new List<MangaFile>(), 1));
series.Volumes[0].Chapters.Add(new ChapterBuilder("231")
.WithPages(1)
.Build());
series.Volumes[2].Chapters.Add(new ChapterBuilder("14.9")
.WithPages(1)
.Build());
_context.Series.Attach(series);
await _context.SaveChangesAsync();
@ -2067,7 +1869,7 @@ public class ReaderServiceTests
var volume = new VolumeBuilder("3").WithChapter(new ChapterBuilder("0").WithPages(1).Build()).Build();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("51").WithPages(1).Build())
.WithChapter(new ChapterBuilder("52").WithPages(1).Build())
@ -2089,11 +1891,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("41").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2130,7 +1928,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -2138,11 +1936,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("Some Special Title").WithIsSpecial(true).WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2171,7 +1965,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -2180,11 +1974,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("Some Special Title").WithIsSpecial(true).WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2214,7 +2004,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
@ -2222,11 +2012,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2252,7 +2038,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("45").WithPages(5).Build())
.WithChapter(new ChapterBuilder("46").WithPages(46).Build())
@ -2275,11 +2061,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("14").WithPages(5).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2323,7 +2105,7 @@ public class ReaderServiceTests
await ResetDb();
// TODO: Validate this is correct, shouldn't be possible to have 2 Volume 0's in a series
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.WithChapter(new ChapterBuilder("1").WithPages(2).Build())
@ -2333,11 +2115,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("1").WithPages(2).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2366,17 +2144,13 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.WithChapter(new ChapterBuilder("1").WithPages(2).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2443,7 +2217,7 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("10").WithPages(1).Build())
.WithChapter(new ChapterBuilder("20").WithPages(1).Build())
@ -2462,11 +2236,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);
@ -2501,7 +2271,6 @@ public class ReaderServiceTests
{
await ResetDb();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("10").WithPages(1).Build())
.WithChapter(new ChapterBuilder("20").WithPages(1).Build())
@ -2520,11 +2289,7 @@ public class ReaderServiceTests
.WithChapter(new ChapterBuilder("3").WithPages(1).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Manga).Build();
_context.Series.Add(series);

View File

@ -11,6 +11,7 @@ using API.DTOs.ReadingLists;
using API.DTOs.ReadingLists.CBL;
using API.Entities;
using API.Entities.Enums;
using API.Entities.Metadata;
using API.Extensions;
using API.Helpers;
using API.Helpers.Builders;
@ -78,10 +79,10 @@ public class ReadingListServiceTests
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga", Folders = new List<FolderPath>() {new FolderPath() {Path = "C:/data/"}}
});
_context.Library.Add(new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build());
return await _context.SaveChangesAsync() > 0;
}
@ -114,20 +115,10 @@ public class ReadingListServiceTests
public async Task AddChaptersToReadingList_ShouldAddFirstItem_AsOrderZero()
{
await ResetDb();
_context.AppUser.Add(new AppUser()
{
UserName = "majora2007",
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
_context.AppUser.Add(new AppUserBuilder("majora2007", "")
.WithLibrary(new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -145,16 +136,16 @@ public class ReadingListServiceTests
)
.Build()
})
.Build(),
}
},
}
});
.Build())
.Build()
)
.Build()
);
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("test");
var readingList = new ReadingListBuilder("test").Build();
user!.ReadingLists = new List<ReadingList>()
{
readingList
@ -171,20 +162,9 @@ public class ReadingListServiceTests
public async Task AddChaptersToReadingList_ShouldNewItems_AfterLastOrder()
{
await ResetDb();
_context.AppUser.Add(new AppUser()
{
UserName = "majora2007",
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
_context.AppUser.Add(new AppUserBuilder("majora2007", "")
.WithLibrary(new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test")
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -202,16 +182,16 @@ public class ReadingListServiceTests
)
.Build()
})
.Build())
.Build()
}
},
}
});
)
.Build()
);
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("test");
var readingList = new ReadingListBuilder("test").Build();
user!.ReadingLists = new List<ReadingList>()
{
readingList
@ -241,14 +221,9 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -266,16 +241,15 @@ public class ReadingListServiceTests
)
.Build()
})
.Build())
.Build()
}
},
}
});
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("Test");
var readingList = new ReadingListBuilder("test").Build();
user.ReadingLists = new List<ReadingList>()
{
readingList
@ -307,14 +281,9 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -332,16 +301,15 @@ public class ReadingListServiceTests
)
.Build()
})
.Build())
.Build()
}
},
}
});
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("test");
var readingList = new ReadingListBuilder("test").Build();
user!.ReadingLists = new List<ReadingList>()
{
readingList
@ -392,14 +360,9 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -413,16 +376,15 @@ public class ReadingListServiceTests
)
.Build()
})
.Build(),
}
},
.Build())
.Build()
}
});
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("Test");
var readingList = new ReadingListBuilder("test").Build();
user.ReadingLists = new List<ReadingList>()
{
readingList
@ -455,14 +417,9 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -480,16 +437,15 @@ public class ReadingListServiceTests
)
.Build()
})
.Build())
.Build()
}
},
}
});
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists | AppUserIncludes.Progress);
var readingList = DbFactory.ReadingList("Test");
var readingList = new ReadingListBuilder("test").Build();
user.ReadingLists = new List<ReadingList>()
{
readingList
@ -529,14 +485,9 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -548,16 +499,15 @@ public class ReadingListServiceTests
)
.Build()
})
.Build())
.Build()
}
},
}
});
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("Test");
var readingList = new ReadingListBuilder("test").Build();
user!.ReadingLists = new List<ReadingList>()
{
readingList
@ -578,7 +528,7 @@ public class ReadingListServiceTests
{
await ResetDb();
var s = new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -597,15 +547,9 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
s
}
},
new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(s)
.Build()
}
});
@ -614,7 +558,7 @@ public class ReadingListServiceTests
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("Test");
var readingList = new ReadingListBuilder("test").Build();
user.ReadingLists = new List<ReadingList>()
{
readingList
@ -639,7 +583,7 @@ public class ReadingListServiceTests
{
await ResetDb();
var s = new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -658,22 +602,16 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
s
}
},
new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(s)
.Build()
}
});
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("Test");
var readingList = new ReadingListBuilder("test").Build();
user.ReadingLists = new List<ReadingList>()
{
readingList
@ -697,7 +635,7 @@ public class ReadingListServiceTests
{
await ResetDb();
var s = new SeriesBuilder("Test")
.WithMetadata(DbFactory.SeriesMetadata(new List<CollectionTag>()))
.WithMetadata(new SeriesMetadataBuilder().Build())
.WithVolumes(new List<Volume>()
{
new VolumeBuilder("0")
@ -718,22 +656,16 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
s
}
},
new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(s)
.Build()
}
});
await _context.SaveChangesAsync();
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.ReadingLists);
var readingList = DbFactory.ReadingList("Test");
var readingList = new ReadingListBuilder("test").Build();
user.ReadingLists = new List<ReadingList>()
{
readingList
@ -817,51 +749,27 @@ public class ReadingListServiceTests
private async Task CreateReadingList_SetupBaseData()
{
var fablesSeries = DbFactory.Series("Fables");
fablesSeries.Volumes.Add(new Volume()
{
Number = 1,
Name = "2002",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
}
});
var fablesSeries = new SeriesBuilder("Fables").Build();
fablesSeries.Volumes.Add(
new VolumeBuilder("1")
.WithNumber(1)
.WithName("2002")
.WithChapter(new ChapterBuilder("1").Build())
.Build()
);
_context.AppUser.Add(new AppUser()
{
UserName = "majora2007",
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test Lib",
Type = LibraryType.Book,
Series = new List<Series>()
{
fablesSeries,
},
},
},
});
_context.AppUser.Add(new AppUser()
{
UserName = "admin",
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test Lib 2",
Type = LibraryType.Book,
Series = new List<Series>()
{
fablesSeries,
},
},
}
});
_context.AppUser.Add(new AppUserBuilder("majora2007", string.Empty)
.WithLibrary(new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fablesSeries)
.Build())
.Build()
);
_context.AppUser.Add(new AppUserBuilder("admin", string.Empty)
.WithLibrary(new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fablesSeries)
.Build())
.Build()
);
await _unitOfWork.CommitAsync();
}
@ -1016,51 +924,33 @@ public class ReadingListServiceTests
var cblReadingList = LoadCblFromPath("Fables.cbl");
// Mock up our series
var fablesSeries = DbFactory.Series("Fables");
var fables2Series = DbFactory.Series("Fables: The Last Castle");
var fablesSeries = new SeriesBuilder("Fables").Build();
var fables2Series = new SeriesBuilder("Fables: The Last Castle").Build();
fablesSeries.Volumes.Add(new Volume()
{
Number = 1,
Name = "2002",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
fablesSeries.Volumes.Add(new VolumeBuilder("1")
.WithNumber(1)
.WithName("2002")
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build()
);
fables2Series.Volumes.Add(new VolumeBuilder("1")
.WithNumber(1)
.WithName("2003")
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build()
);
}
});
fables2Series.Volumes.Add(new Volume()
{
Number = 1,
Name = "2003",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
_context.AppUser.Add(new AppUserBuilder("majora2007", string.Empty).Build());
}
});
_context.AppUser.Add(new AppUser()
{
UserName = "majora2007",
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>(),
});
_context.Library.Add(new Library()
{
Name = "Test Lib 2",
Type = LibraryType.Book,
Series = new List<Series>()
{
fablesSeries,
fables2Series,
},
});
_context.Library.Add(new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fablesSeries)
.WithSeries(fables2Series)
.Build()
);
await _unitOfWork.CommitAsync();
@ -1077,33 +967,21 @@ public class ReadingListServiceTests
var cblReadingList = LoadCblFromPath("Fables.cbl");
// Mock up our series
var fablesSeries = DbFactory.Series("Fablesa");
var fables2Series = DbFactory.Series("Fablesa: The Last Castle");
var fablesSeries = new SeriesBuilder("Fablesa").Build();
var fables2Series = new SeriesBuilder("Fablesa: The Last Castle").Build();
fablesSeries.Volumes.Add(new Volume()
{
Number = 1,
Name = "2002",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
}
});
fables2Series.Volumes.Add(new Volume()
{
Number = 1,
Name = "2003",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
}
});
fablesSeries.Volumes.Add(new VolumeBuilder("2002")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build());
fables2Series.Volumes.Add(new VolumeBuilder("2003")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build());
_context.AppUser.Add(new AppUser()
{
@ -1112,16 +990,10 @@ public class ReadingListServiceTests
Libraries = new List<Library>(),
});
_context.Library.Add(new Library()
{
Name = "Test Lib 2",
Type = LibraryType.Book,
Series = new List<Series>()
{
fablesSeries,
fables2Series,
},
});
_context.Library.Add(new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fablesSeries)
.WithSeries(fables2Series)
.Build());
await _unitOfWork.CommitAsync();
@ -1153,9 +1025,6 @@ public class ReadingListServiceTests
var cblReadingList = LoadCblFromPath("Fables.cbl");
// Mock up our series
// var fablesSeries = DbFactory.Series("Fables");
// var fables2Series = DbFactory.Series("Fables: The Last Castle");
var fablesSeries = new SeriesBuilder("Fables")
.WithVolume(new VolumeBuilder("2002")
.WithNumber(1)
@ -1174,49 +1043,16 @@ public class ReadingListServiceTests
.Build())
.Build();
// fablesSeries.Volumes.Add(new Volume()
// {
// Number = 1,
// Name = "2002",
// Chapters = new List<Chapter>()
// {
// EntityFactory.CreateChapter("1", false),
// EntityFactory.CreateChapter("2", false),
// EntityFactory.CreateChapter("3", false),
//
// }
// });
// fables2Series.Volumes.Add(new Volume()
// {
// Number = 1,
// Name = "2003",
// Chapters = new List<Chapter>()
// {
// EntityFactory.CreateChapter("1", false),
// EntityFactory.CreateChapter("2", false),
// EntityFactory.CreateChapter("3", false),
//
// }
// });
_context.AppUser.Add(new AppUser()
{
UserName = "majora2007",
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
fablesSeries,
fables2Series
},
},
new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fablesSeries)
.WithSeries(fables2Series)
.Build()
},
});
await _unitOfWork.CommitAsync();
@ -1245,33 +1081,21 @@ public class ReadingListServiceTests
var cblReadingList = LoadCblFromPath("Fables.cbl");
// Mock up our series
var fablesSeries = DbFactory.Series("Fables");
var fables2Series = DbFactory.Series("Fables: The Last Castle");
var fablesSeries = new SeriesBuilder("Fables").Build();
var fables2Series = new SeriesBuilder("Fables: The Last Castle").Build();
fablesSeries.Volumes.Add(new Volume()
{
Number = 1,
Name = "2002",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
}
});
fables2Series.Volumes.Add(new Volume()
{
Number = 1,
Name = "2003",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
}
});
fablesSeries.Volumes.Add(new VolumeBuilder("2002")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build());
fables2Series.Volumes.Add(new VolumeBuilder("2003")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build());
_context.AppUser.Add(new AppUser()
{
@ -1279,27 +1103,15 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
fablesSeries,
},
},
new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fablesSeries)
.Build()
},
});
_context.Library.Add(new Library()
{
Name = "Test Lib 2",
Type = LibraryType.Book,
Series = new List<Series>()
{
fables2Series,
},
});
_context.Library.Add(new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fables2Series)
.Build());
await _unitOfWork.CommitAsync();
@ -1328,33 +1140,21 @@ public class ReadingListServiceTests
var cblReadingList = LoadCblFromPath("Fables.cbl");
// Mock up our series
var fablesSeries = DbFactory.Series("Fables");
var fables2Series = DbFactory.Series("Fables: The Last Castle");
var fablesSeries = new SeriesBuilder("Fables").Build();
var fables2Series = new SeriesBuilder("Fables: The Last Castle").Build();
fablesSeries.Volumes.Add(new Volume()
{
Number = 1,
Name = "2002",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
}
});
fables2Series.Volumes.Add(new Volume()
{
Number = 1,
Name = "2003",
Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("1", false),
EntityFactory.CreateChapter("2", false),
EntityFactory.CreateChapter("3", false),
}
});
fablesSeries.Volumes.Add(new VolumeBuilder("2002")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build());
fables2Series.Volumes.Add(new VolumeBuilder("2003")
.WithNumber(1)
.WithChapter(new ChapterBuilder("1").Build())
.WithChapter(new ChapterBuilder("2").Build())
.WithChapter(new ChapterBuilder("3").Build())
.Build());
_context.AppUser.Add(new AppUser()
{
@ -1362,16 +1162,10 @@ public class ReadingListServiceTests
ReadingLists = new List<ReadingList>(),
Libraries = new List<Library>()
{
new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
fablesSeries,
fables2Series
},
},
new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(fablesSeries)
.WithSeries(fables2Series)
.Build()
},
});

View File

@ -5,9 +5,9 @@ using API.Entities.Enums;
using API.Entities.Metadata;
using API.Extensions;
using API.Helpers.Builders;
using API.Parser;
using API.Services.Tasks;
using API.Services.Tasks.Scanner;
using API.Services.Tasks.Scanner.Parser;
using API.Tests.Helpers;
using Xunit;
@ -27,7 +27,7 @@ public class ScannerServiceTests
{
new SeriesBuilder("Darker Than Black")
.WithFormat(MangaFormat.Epub)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithName("1")
.Build())
@ -51,7 +51,7 @@ public class ScannerServiceTests
{
new SeriesBuilder("Cage of Eden")
.WithFormat(MangaFormat.Archive)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithName("1")
.Build())
@ -59,30 +59,11 @@ public class ScannerServiceTests
.Build(),
new SeriesBuilder("Darker Than Black")
.WithFormat(MangaFormat.Archive)
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("1")
.WithName("1")
.Build())
.WithLocalizedName("Darker Than Black")
.Build(),
// new Series()
// {
// Name = "Cage of Eden",
// LocalizedName = "Cage of Eden",
// OriginalName = "Cage of Eden",
// NormalizedName = "Darker Than Black".ToNormalized(),
// Metadata = new SeriesMetadata(),
// Format = MangaFormat.Archive
// },
// new Series()
// {
// Name = "Darker Than Black",
// LocalizedName = "Darker Than Black",
// OriginalName = "Darker Than Black",
// NormalizedName = "Darker Than Black".ToNormalized(),
// Metadata = new SeriesMetadata(),
// Format = MangaFormat.Archive
// }
};
Assert.Empty(ScannerService.FindSeriesNotOnDisk(existingSeries, infos));

View File

@ -74,21 +74,10 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("Omake").WithIsSpecial(true).WithTitle("Omake").WithPages(1).Build())
.WithChapter(new ChapterBuilder("Something SP02").WithIsSpecial(true).WithTitle("Something").WithPages(1).Build())
@ -102,9 +91,8 @@ public class SeriesServiceTests : AbstractDbTest
.WithChapter(new ChapterBuilder("31").WithPages(1).Build())
.WithChapter(new ChapterBuilder("32").WithPages(1).Build())
.Build())
.Build(),
}
});
.Build())
.Build());
await _context.SaveChangesAsync();
@ -122,21 +110,10 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -150,9 +127,9 @@ public class SeriesServiceTests : AbstractDbTest
.WithChapter(new ChapterBuilder("31").WithPages(1).Build())
.WithChapter(new ChapterBuilder("32").WithPages(1).Build())
.Build())
.Build(),
}
});
.Build())
.Build()
);
await _context.SaveChangesAsync();
@ -170,21 +147,10 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -196,9 +162,8 @@ public class SeriesServiceTests : AbstractDbTest
.WithVolume(new VolumeBuilder("3")
.WithChapter(new ChapterBuilder("31").WithPages(1).Build())
.Build())
.Build(),
}
});
.Build())
.Build());
await _context.SaveChangesAsync();
@ -216,21 +181,9 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb")
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithPages(1).Build())
.WithChapter(new ChapterBuilder("2").WithPages(1).Build())
@ -242,9 +195,8 @@ public class SeriesServiceTests : AbstractDbTest
.WithVolume(new VolumeBuilder("3")
.WithChapter(new ChapterBuilder("31").WithPages(1).Build())
.Build())
.Build(),
}
});
.Build())
.Build());
await _context.SaveChangesAsync();
@ -265,21 +217,10 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb", LibraryType.Book)
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("2")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
@ -287,9 +228,8 @@ public class SeriesServiceTests : AbstractDbTest
.WithVolume(new VolumeBuilder("3")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
.Build(),
}
});
.Build())
.Build());
await _context.SaveChangesAsync();
@ -306,30 +246,18 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb", LibraryType.Book)
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("Ano Orokamono ni mo Kyakkou wo! - Volume 1.epub", "Ano Orokamono ni mo Kyakkou wo! - Volume 1.epub").WithIsSpecial(true).WithPages(1).Build())
.Build())
.WithVolume(new VolumeBuilder("2")
.WithChapter(new ChapterBuilder("Ano Orokamono ni mo Kyakkou wo! - Volume 2.epub", "Ano Orokamono ni mo Kyakkou wo! - Volume 2.epub").WithPages(1).Build())
.Build())
.Build(),
}
});
.Build())
.Build());
@ -353,21 +281,10 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.WithSeries(new SeriesBuilder("Test")
.WithVolume(new VolumeBuilder("2")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
@ -378,9 +295,8 @@ public class SeriesServiceTests : AbstractDbTest
.WithVolume(new VolumeBuilder("1")
.WithChapter(new ChapterBuilder("0").WithPages(1).Build())
.Build())
.Build(),
}
});
.Build())
.Build());
await _context.SaveChangesAsync();
@ -402,27 +318,15 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_context.Library.Add(new LibraryBuilder("Test LIb", LibraryType.Manga)
.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())
.Build());
await _context.SaveChangesAsync();
@ -451,27 +355,15 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_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())
.Build());
await _context.SaveChangesAsync();
@ -517,27 +409,15 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_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())
.Build());
await _context.SaveChangesAsync();
@ -564,27 +444,15 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
_context.Library.Add(new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>()
{
new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
_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())
.Build());
await _context.SaveChangesAsync();
@ -612,13 +480,8 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
_context.Series.Add(s);
await _context.SaveChangesAsync();
@ -646,13 +509,8 @@ public class SeriesServiceTests : AbstractDbTest
{
await ResetDb();
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
_context.Series.Add(s);
await _context.SaveChangesAsync();
@ -692,13 +550,9 @@ public class SeriesServiceTests : AbstractDbTest
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
var g = DbFactory.Genre("Existing Genre");
var g = new GenreBuilder("Existing Genre").Build();
s.Metadata.Genres = new List<Genre>() {g};
_context.Series.Add(s);
@ -730,13 +584,9 @@ public class SeriesServiceTests : AbstractDbTest
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
var g = DbFactory.Person("Existing Person", PersonRole.Publisher);
var g = new PersonBuilder("Existing Person", PersonRole.Publisher).Build();
_context.Series.Add(s);
_context.Person.Add(g);
@ -767,14 +617,10 @@ public class SeriesServiceTests : AbstractDbTest
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
var g = DbFactory.Person("Existing Person", PersonRole.Publisher);
s.Metadata.People = new List<Person>() {DbFactory.Person("Existing Writer", PersonRole.Writer),
DbFactory.Person("Existing Translator", PersonRole.Translator), DbFactory.Person("Existing Publisher 2", PersonRole.Publisher)};
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
var g = new PersonBuilder("Existing Person", PersonRole.Publisher).Build();
s.Metadata.People = new List<Person>() {new PersonBuilder("Existing Writer", PersonRole.Writer).Build(),
new PersonBuilder("Existing Translator", PersonRole.Translator).Build(), new PersonBuilder("Existing Publisher 2", PersonRole.Publisher).Build()};
_context.Series.Add(s);
_context.Person.Add(g);
@ -807,12 +653,8 @@ public class SeriesServiceTests : AbstractDbTest
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
var g = DbFactory.Person("Existing Person", PersonRole.Publisher);
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
var g = new PersonBuilder("Existing Person", PersonRole.Publisher).Build();
_context.Series.Add(s);
_context.Person.Add(g);
@ -842,12 +684,8 @@ public class SeriesServiceTests : AbstractDbTest
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
var g = DbFactory.Genre("Existing Genre");
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
var g = new GenreBuilder("Existing Genre").Build();
s.Metadata.Genres = new List<Genre>() {g};
s.Metadata.GenresLocked = true;
_context.Series.Add(s);
@ -881,11 +719,7 @@ public class SeriesServiceTests : AbstractDbTest
var s = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadataBuilder().Build())
.Build();
s.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Book,
};
s.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
_context.Series.Add(s);
await _context.SaveChangesAsync();
@ -913,10 +747,9 @@ public class SeriesServiceTests : AbstractDbTest
private static Series CreateSeriesMock()
{
var file = EntityFactory.CreateMangaFile("Test.cbz", MangaFormat.Archive, 1);
var file = new MangaFileBuilder("Test.cbz", MangaFormat.Archive, 1).Build();
var series = new SeriesBuilder("Test")
.WithMetadata(new SeriesMetadata())
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("95").WithPages(1).WithFile(file).Build())
.WithChapter(new ChapterBuilder("96").WithPages(1).WithFile(file).Build())
@ -937,11 +770,7 @@ public class SeriesServiceTests : AbstractDbTest
.WithChapter(new ChapterBuilder("32").WithPages(1).WithFile(file).Build())
.Build())
.Build();
series.Library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
};
series.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
return series;
}
@ -970,13 +799,13 @@ public class SeriesServiceTests : AbstractDbTest
var series = CreateSeriesMock();
var files = new List<MangaFile>()
{
EntityFactory.CreateMangaFile("Test.cbz", MangaFormat.Archive, 1)
new MangaFileBuilder("Test.cbz", MangaFormat.Archive, 1).Build()
};
series.Volumes[1].Chapters = new List<Chapter>()
{
EntityFactory.CreateChapter("2", false, files, 1),
EntityFactory.CreateChapter("1.1", false, files, 1),
EntityFactory.CreateChapter("1.2", false, files, 1),
new ChapterBuilder("2").WithFiles(files).WithPages(1).Build(),
new ChapterBuilder("1.1").WithFiles(files).WithPages(1).Build(),
new ChapterBuilder("1.2").WithFiles(files).WithPages(1).Build(),
};
var firstChapter = SeriesService.GetFirstChapterForMetadata(series, false);
@ -1038,9 +867,9 @@ public class SeriesServiceTests : AbstractDbTest
Type = LibraryType.Book,
Series = new List<Series>()
{
DbFactory.Series("Test Series"),
DbFactory.Series("Test Series Prequels"),
DbFactory.Series("Test Series Sequels"),
new SeriesBuilder("Test Series").Build(),
new SeriesBuilder("Test Series Prequels").Build(),
new SeriesBuilder("Test Series Sequels").Build(),
}
});
@ -1080,8 +909,8 @@ public class SeriesServiceTests : AbstractDbTest
Type = LibraryType.Book,
Series = new List<Series>()
{
DbFactory.Series("Series A"),
DbFactory.Series("Series B"),
new SeriesBuilder("Series A").Build(),
new SeriesBuilder("Series B").Build(),
}
});
@ -1125,8 +954,8 @@ public class SeriesServiceTests : AbstractDbTest
Type = LibraryType.Book,
Series = new List<Series>()
{
DbFactory.Series("Series A"),
DbFactory.Series("Series B"),
new SeriesBuilder("Series A").Build(),
new SeriesBuilder("Series B").Build(),
}
});
@ -1170,8 +999,8 @@ public class SeriesServiceTests : AbstractDbTest
Type = LibraryType.Book,
Series = new List<Series>()
{
DbFactory.Series("Test Series"),
DbFactory.Series("Test Series Prequels"),
new SeriesBuilder("Test Series").Build(),
new SeriesBuilder("Test Series Prequels").Build(),
}
});
@ -1215,11 +1044,11 @@ public class SeriesServiceTests : AbstractDbTest
Type = LibraryType.Book,
Series = new List<Series>()
{
DbFactory.Series("Test Series"),
DbFactory.Series("Test Series Editions"),
DbFactory.Series("Test Series Prequels"),
DbFactory.Series("Test Series Sequels"),
DbFactory.Series("Test Series Adaption"),
new SeriesBuilder("Test Series").Build(),
new SeriesBuilder("Test Series Editions").Build(),
new SeriesBuilder("Test Series Prequels").Build(),
new SeriesBuilder("Test Series Sequels").Build(),
new SeriesBuilder("Test Series Adaption").Build(),
}
});
await _context.SaveChangesAsync();
@ -1243,24 +1072,12 @@ public class SeriesServiceTests : AbstractDbTest
public async Task SeriesRelation_ShouldAllowDeleteOnLibrary()
{
await ResetDb();
var lib = new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
DbFactory.Series("Test Series"),
DbFactory.Series("Test Series Prequels"),
DbFactory.Series("Test Series Sequels"),
}
};
var lib = new LibraryBuilder("Test LIb")
.WithSeries(new SeriesBuilder("Test Series").Build())
.WithSeries(new SeriesBuilder("Test Series Prequels").Build())
.WithSeries(new SeriesBuilder("Test Series Sequels").Build())
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.Build();
_context.Library.Add(lib);
await _context.SaveChangesAsync();
@ -1291,51 +1108,28 @@ public class SeriesServiceTests : AbstractDbTest
public async Task SeriesRelation_ShouldAllowDeleteOnLibrary_WhenSeriesCrossLibraries()
{
await ResetDb();
var lib1 = new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb",
Type = LibraryType.Book,
Series = new List<Series>()
{
new SeriesBuilder("Test Series")
var lib1 = new LibraryBuilder("Test LIb")
.WithSeries(new SeriesBuilder("Test Series")
.WithVolume(new VolumeBuilder("0")
.WithChapter(new ChapterBuilder("1").WithFile(new MangaFile()
{
Pages = 1,
FilePath = "fake file"
}).Build())
.WithChapter(new ChapterBuilder("1").WithFile(
new MangaFileBuilder($"{DataDirectory}1.zip", MangaFormat.Archive)
.WithPages(1)
.Build()
).Build())
.Build())
.Build(),
new SeriesBuilder("Test Series Prequels").Build(),
new SeriesBuilder("Test Series Sequels").Build(),
}
};
.Build())
.WithSeries(new SeriesBuilder("Test Series Prequels").Build())
.WithSeries(new SeriesBuilder("Test Series Sequels").Build())
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.Build();
_context.Library.Add(lib1);
var lib2 = new Library()
{
AppUsers = new List<AppUser>()
{
new AppUser()
{
UserName = "majora2007"
}
},
Name = "Test LIb 2",
Type = LibraryType.Book,
Series = new List<Series>()
{
DbFactory.Series("Test Series 2"),
DbFactory.Series("Test Series Prequels 2"),
DbFactory.Series("Test Series Prequels 2"),
}
};
var lib2 = new LibraryBuilder("Test LIb 2", LibraryType.Book)
.WithSeries(new SeriesBuilder("Test Series 2").Build())
.WithSeries(new SeriesBuilder("Test Series Prequels 2").Build())
.WithSeries(new SeriesBuilder("Test Series Prequels 2").Build())// TODO: Is this a bug
.WithAppUser(new AppUserBuilder("majora2007", string.Empty).Build())
.Build();
_context.Library.Add(lib2);
await _context.SaveChangesAsync();
@ -1365,7 +1159,81 @@ public class SeriesServiceTests : AbstractDbTest
#region UpdateRelatedList
// TODO: Implement UpdateRelatedList
#endregion
#region FormatChapterName
[Theory]
[InlineData(LibraryType.Manga, false, "Chapter")]
[InlineData(LibraryType.Comic, false, "Issue")]
[InlineData(LibraryType.Comic, true, "Issue #")]
[InlineData(LibraryType.Book, false, "Book")]
public void FormatChapterNameTest(LibraryType libraryType, bool withHash, string expected )
{
Assert.Equal(expected, SeriesService.FormatChapterName(libraryType, withHash));
}
#endregion
#region FormatChapterTitle
[Fact]
public void FormatChapterTitle_Manga_NonSpecial()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(false).Build();
Assert.Equal("Chapter Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Manga, false));
}
[Fact]
public void FormatChapterTitle_Manga_Special()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(true).Build();
Assert.Equal("Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Manga, false));
}
[Fact]
public void FormatChapterTitle_Comic_NonSpecial_WithoutHash()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(false).Build();
Assert.Equal("Issue Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Comic, false));
}
[Fact]
public void FormatChapterTitle_Comic_Special_WithoutHash()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(true).Build();
Assert.Equal("Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Comic, false));
}
[Fact]
public void FormatChapterTitle_Comic_NonSpecial_WithHash()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(false).Build();
Assert.Equal("Issue #Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Comic, true));
}
[Fact]
public void FormatChapterTitle_Comic_Special_WithHash()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(true).Build();
Assert.Equal("Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Comic, true));
}
[Fact]
public void FormatChapterTitle_Book_NonSpecial()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(false).Build();
Assert.Equal("Book Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Book, false));
}
[Fact]
public void FormatChapterTitle_Book_Special()
{
var chapter = new ChapterBuilder("1").WithTitle("Some title").WithIsSpecial(true).Build();
Assert.Equal("Some title", SeriesService.FormatChapterTitle(chapter, LibraryType.Book, false));
}
#endregion
}

View File

@ -81,10 +81,11 @@ public class TachiyomiServiceTests
_context.ServerSetting.Update(setting);
_context.Library.Add(new Library()
{
Name = "Manga", Folders = new List<FolderPath>() {new FolderPath() {Path = "C:/data/"}}
});
_context.Library.Add(
new LibraryBuilder("Manga")
.WithFolderPath(new FolderPathBuilder("C:/data/").Build())
.Build()
);
return await _context.SaveChangesAsync() > 0;
}
@ -139,12 +140,10 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -186,12 +185,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -240,12 +236,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -293,12 +286,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -341,12 +331,9 @@ public class TachiyomiServiceTests
.WithPages(646)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -394,12 +381,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Comic,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -452,12 +436,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -498,12 +479,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -551,12 +529,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{
@ -602,12 +577,9 @@ public class TachiyomiServiceTests
.WithPages(7)
.Build();
var library = new Library()
{
Name = "Test LIb",
Type = LibraryType.Manga,
Series = new List<Series>() { series }
};
var library = new LibraryBuilder("Test LIb", LibraryType.Manga)
.WithSeries(series)
.Build();
_context.AppUser.Add(new AppUser()
{

View File

@ -0,0 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<ComicInfo>
<Series>Accel World</Series>
<Number>2</Number>
</ComicInfo>

View File

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<ComicInfo>
<Series>Hajime no Ippo</Series>
<Number>3</Number>
<AgeRating>M</AgeRating>
</ComicInfo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
This is an example of a layout. All files in here have non-copyrighted data but emulate real series to ensure the Process series Works as expected.

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using API.Entities;
using API.Entities.Enums;
using API.Helpers;
using API.Helpers.Builders;
using API.Services;
using API.Services.Tasks.Metadata;
using API.SignalR;
@ -43,25 +44,26 @@ public class WordCountAnalysisTests : AbstractDbTest
public async Task ReadingTimeShouldBeNonZero()
{
await ResetDb();
var series = EntityFactory.CreateSeries("Test Series");
series.Format = MangaFormat.Epub;
var chapter = EntityFactory.CreateChapter("", false, new List<MangaFile>()
{
EntityFactory.CreateMangaFile(
Path.Join(_testDirectory, "The Golden Harpoon; Or, Lost Among the Floes A Story of the Whaling Grounds.epub"),
MangaFormat.Epub, 0)
});
var series = new SeriesBuilder("Test Series")
.WithFormat(MangaFormat.Epub)
.Build();
_context.Library.Add(new Library()
{
Name = "Test",
Type = LibraryType.Book,
Series = new List<Series>() {series}
});
var chapter = new ChapterBuilder("")
.WithFile(new MangaFileBuilder(
Path.Join(_testDirectory,
"The Golden Harpoon; Or, Lost Among the Floes A Story of the Whaling Grounds.epub"),
MangaFormat.Epub).Build())
.Build();
_context.Library.Add(new LibraryBuilder("Test LIb", LibraryType.Book)
.WithSeries(series)
.Build());
series.Volumes = new List<Volume>()
{
EntityFactory.CreateVolume("0", new List<Chapter>() {chapter})
new VolumeBuilder("0")
.WithChapter(chapter)
.Build(),
};
await _context.SaveChangesAsync();
@ -98,26 +100,23 @@ public class WordCountAnalysisTests : AbstractDbTest
public async Task ReadingTimeShouldIncreaseWhenNewBookAdded()
{
await ResetDb();
var series = EntityFactory.CreateSeries("Test Series");
series.Format = MangaFormat.Epub;
var chapter = EntityFactory.CreateChapter("", false, new List<MangaFile>()
{
EntityFactory.CreateMangaFile(
Path.Join(_testDirectory, "The Golden Harpoon; Or, Lost Among the Floes A Story of the Whaling Grounds.epub"),
MangaFormat.Epub, 0)
});
var chapter = new ChapterBuilder("")
.WithFile(new MangaFileBuilder(
Path.Join(_testDirectory,
"The Golden Harpoon; Or, Lost Among the Floes A Story of the Whaling Grounds.epub"),
MangaFormat.Epub).Build())
.Build();
var series = new SeriesBuilder("Test Series")
.WithFormat(MangaFormat.Epub)
.WithVolume(new VolumeBuilder("0")
.WithChapter(chapter)
.Build())
.Build();
_context.Library.Add(new Library()
{
Name = "Test",
Type = LibraryType.Book,
Series = new List<Series>() {series}
});
_context.Library.Add(new LibraryBuilder("Test", LibraryType.Book)
.WithSeries(series)
.Build());
series.Volumes = new List<Volume>()
{
EntityFactory.CreateVolume("0", new List<Chapter>() {chapter})
};
await _context.SaveChangesAsync();
@ -125,18 +124,19 @@ public class WordCountAnalysisTests : AbstractDbTest
var cacheService = new CacheHelper(new FileService());
var service = new WordCountAnalyzerService(Substitute.For<ILogger<WordCountAnalyzerService>>(), _unitOfWork,
Substitute.For<IEventHub>(), cacheService, _readerService);
await service.ScanSeries(1, 1);
var chapter2 = EntityFactory.CreateChapter("2", false, new List<MangaFile>()
{
EntityFactory.CreateMangaFile(
Path.Join(_testDirectory, "The Golden Harpoon; Or, Lost Among the Floes A Story of the Whaling Grounds.epub"),
MangaFormat.Epub, 0)
});
var chapter2 = new ChapterBuilder("2")
.WithFile(new MangaFileBuilder(
Path.Join(_testDirectory,
"The Golden Harpoon; Or, Lost Among the Floes A Story of the Whaling Grounds.epub"),
MangaFormat.Epub).Build())
.Build();
series.Volumes.Add(EntityFactory.CreateVolume("1", new List<Chapter>() {chapter2}));
series.Volumes.Add(new VolumeBuilder("1")
.WithChapter(chapter2)
.Build());
series.Volumes.First().Chapters.Add(chapter2);
await _unitOfWork.CommitAsync();

View File

@ -13,6 +13,7 @@ using API.Entities;
using API.Entities.Enums;
using API.Errors;
using API.Extensions;
using API.Helpers.Builders;
using API.Middleware.RateLimit;
using API.Services;
using API.SignalR;
@ -126,16 +127,9 @@ public class AccountController : BaseApiController
return BadRequest(usernameValidation);
}
var user = new AppUser()
{
UserName = registerDto.Username,
Email = registerDto.Email,
UserPreferences = new AppUserPreferences
{
Theme = await _unitOfWork.SiteThemeRepository.GetDefaultTheme()
},
ApiKey = HashUtil.ApiKey()
};
var user = new AppUserBuilder(registerDto.Username, registerDto.Email,
await _unitOfWork.SiteThemeRepository.GetDefaultTheme()).Build();
var result = await _userManager.CreateAsync(user, registerDto.Password);
if (!result.Succeeded) return BadRequest(result.Errors);
@ -204,6 +198,8 @@ public class AccountController : BaseApiController
// Update LastActive on account
user.UpdateLastActive();
// NOTE: This can likely be removed
user.UserPreferences ??= new AppUserPreferences
{
Theme = await _unitOfWork.SiteThemeRepository.GetDefaultTheme()
@ -537,7 +533,7 @@ public class AccountController : BaseApiController
}
// Create a new user
var user = DbFactory.AppUser(dto.Email, dto.Email, await _unitOfWork.SiteThemeRepository.GetDefaultTheme());
var user = new AppUserBuilder(dto.Email, dto.Email, await _unitOfWork.SiteThemeRepository.GetDefaultTheme()).Build();
try
{

View File

@ -34,14 +34,12 @@ public class ReaderController : BaseApiController
private readonly IBookmarkService _bookmarkService;
private readonly IAccountService _accountService;
private readonly IEventHub _eventHub;
private readonly IImageService _imageService;
private readonly IDirectoryService _directoryService;
/// <inheritdoc />
public ReaderController(ICacheService cacheService,
IUnitOfWork unitOfWork, ILogger<ReaderController> logger,
IReaderService readerService, IBookmarkService bookmarkService,
IAccountService accountService, IEventHub eventHub, IImageService imageService, IDirectoryService directoryService)
IAccountService accountService, IEventHub eventHub)
{
_cacheService = cacheService;
_unitOfWork = unitOfWork;
@ -50,8 +48,6 @@ public class ReaderController : BaseApiController
_bookmarkService = bookmarkService;
_accountService = accountService;
_eventHub = eventHub;
_imageService = imageService;
_directoryService = directoryService;
}
/// <summary>

View File

@ -229,7 +229,7 @@ public class UploadController : BaseApiController
}
return _imageService.CreateThumbnailFromBase64(uploadFileDto.Url,
filename, convertToWebP); ;
filename, convertToWebP);
}
/// <summary>

View File

@ -1,198 +0,0 @@
using System.Collections.Generic;
using System.IO;
using API.Entities;
using API.Entities.Enums;
using API.Entities.Metadata;
using API.Extensions;
using API.Parser;
using API.Services.Tasks;
using Kavita.Common;
namespace API.Data;
/// <summary>
/// Responsible for creating Series, Volume, Chapter, MangaFiles for use in <see cref="ScannerService"/>
/// </summary>
public static class DbFactory
{
public static Library Library(string name, LibraryType type)
{
return new Library()
{
Name = name,
Type = type,
Series = new List<Series>(),
Folders = new List<FolderPath>(),
AppUsers = new List<AppUser>()
};
}
public static Series Series(string name)
{
return new Series
{
Name = name,
OriginalName = name,
LocalizedName = name,
NormalizedName = name.ToNormalized(),
NormalizedLocalizedName = name.ToNormalized(),
SortName = name,
Volumes = new List<Volume>(),
Metadata = SeriesMetadata(new List<CollectionTag>())
};
}
public static Series Series(string name, string localizedName)
{
if (string.IsNullOrEmpty(localizedName))
{
localizedName = name;
}
return new Series
{
Name = name,
OriginalName = name,
LocalizedName = localizedName,
NormalizedName = name.ToNormalized(),
NormalizedLocalizedName = localizedName.ToNormalized(),
SortName = name,
Volumes = new List<Volume>(),
Metadata = SeriesMetadata(new List<CollectionTag>())
};
}
public static Volume Volume(string volumeNumber)
{
return new Volume()
{
Name = volumeNumber,
Number = (int) Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(volumeNumber),
Chapters = new List<Chapter>()
};
}
public static Chapter Chapter(ParserInfo info)
{
var specialTreatment = info.IsSpecialInfo();
var specialTitle = specialTreatment ? info.Filename : info.Chapters;
return new Chapter()
{
Number = specialTreatment ? "0" : Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(info.Chapters) + string.Empty,
Range = specialTreatment ? info.Filename : info.Chapters,
Title = (specialTreatment && info.Format == MangaFormat.Epub)
? info.Title
: specialTitle,
Files = new List<MangaFile>(),
IsSpecial = specialTreatment,
};
}
public static SeriesMetadata SeriesMetadata(ICollection<CollectionTag> collectionTags)
{
return new SeriesMetadata()
{
CollectionTags = collectionTags,
Summary = string.Empty
};
}
public static CollectionTag CollectionTag(int id, string title, string? summary = null, bool promoted = false)
{
title = title.Trim();
return new CollectionTag()
{
Id = id,
NormalizedTitle = title.ToNormalized(),
Title = title,
Summary = summary?.Trim(),
Promoted = promoted,
SeriesMetadatas = new List<SeriesMetadata>()
};
}
public static ReadingList ReadingList(string title, string? summary = null, bool promoted = false, AgeRating rating = AgeRating.Unknown)
{
title = title.Trim();
return new ReadingList()
{
NormalizedTitle = title.ToNormalized(),
Title = title,
Summary = summary?.Trim(),
Promoted = promoted,
Items = new List<ReadingListItem>(),
AgeRating = rating
};
}
public static ReadingListItem ReadingListItem(int index, int seriesId, int volumeId, int chapterId)
{
return new ReadingListItem()
{
Order = index,
ChapterId = chapterId,
SeriesId = seriesId,
VolumeId = volumeId
};
}
public static Genre Genre(string name)
{
return new Genre()
{
Title = name.Trim().SentenceCase(),
NormalizedTitle = name.ToNormalized()
};
}
public static Tag Tag(string name)
{
return new Tag()
{
Title = name.Trim().SentenceCase(),
NormalizedTitle = name.ToNormalized()
};
}
public static Person Person(string name, PersonRole role)
{
return new Person()
{
Name = name.Trim(),
NormalizedName = name.ToNormalized(),
Role = role
};
}
public static MangaFile MangaFile(string filePath, MangaFormat format, int pages)
{
return new MangaFile()
{
FilePath = filePath,
Format = format,
Pages = pages,
LastModified = File.GetLastWriteTime(filePath),
LastModifiedUtc = File.GetLastWriteTimeUtc(filePath),
};
}
public static Device Device(string name)
{
return new Device()
{
Name = name,
};
}
public static AppUser AppUser(string username, string email, SiteTheme defaultTheme)
{
return new AppUser()
{
UserName = username,
Email = email,
ApiKey = HashUtil.ApiKey(),
UserPreferences = new AppUserPreferences
{
Theme = defaultTheme
}
};
}
}

View File

@ -9,6 +9,7 @@ namespace API.Data;
/// v0.7 introduced UTC dates and GMT+1 users would sometimes have dates stored as '0000-12-31 23:00:00'.
/// This Migration will update those dates.
/// </summary>
// ReSharper disable once InconsistentNaming
public static class MigrateBrokenGMT1Dates
{
public static async Task Migrate(IUnitOfWork unitOfWork, DataContext dataContext, ILogger<Program> logger)

View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using API.Entities.Enums;
using API.Entities.Interfaces;
using API.Parser;
using API.Services.Tasks.Scanner.Parser;
namespace API.Entities;

View File

@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using API.Entities;
using API.Helpers;
using API.Parser;
using API.Services.Tasks.Scanner.Parser;
namespace API.Extensions;

View File

@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using API.Entities;
using API.Parser;
using API.Services.Tasks.Scanner.Parser;
namespace API.Extensions;

View File

@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Linq;
using API.Data;
using API.Entities;
using Kavita.Common;
namespace API.Helpers.Builders;
public class AppUserBuilder : IEntityBuilder<AppUser>
{
private readonly AppUser _appUser;
public AppUser Build() => _appUser;
public AppUserBuilder(string username, string email, SiteTheme? theme = null)
{
_appUser = new AppUser()
{
UserName = username,
Email = email,
ApiKey = HashUtil.ApiKey(),
UserPreferences = new AppUserPreferences
{
Theme = theme ?? Seed.DefaultThemes.First()
},
ReadingLists = new List<ReadingList>(),
Bookmarks = new List<AppUserBookmark>(),
Libraries = new List<Library>(),
Ratings = new List<AppUserRating>(),
Progresses = new List<AppUserProgress>(),
Devices = new List<Device>(),
Id = 0
};
}
public AppUserBuilder WithLibrary(Library library)
{
_appUser.Libraries.Add(library);
return this;
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using API.Entities;
using API.Entities.Enums;
using API.Services.Tasks.Scanner.Parser;
namespace API.Helpers.Builders;
@ -16,12 +17,43 @@ public class ChapterBuilder : IEntityBuilder<Chapter>
{
Range = string.IsNullOrEmpty(range) ? number : range,
Title = string.IsNullOrEmpty(range) ? number : range,
Number = API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(number) + string.Empty,
Number = Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(number) + string.Empty,
Files = new List<MangaFile>(),
Pages = 1
};
}
public static ChapterBuilder FromParserInfo(ParserInfo info)
{
var specialTreatment = info.IsSpecialInfo();
var specialTitle = specialTreatment ? info.Filename : info.Chapters;
var builder = new ChapterBuilder(Services.Tasks.Scanner.Parser.Parser.DefaultChapter);
return builder.WithNumber(specialTreatment ? Services.Tasks.Scanner.Parser.Parser.DefaultChapter : Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(info.Chapters) + string.Empty)
.WithRange(specialTreatment ? info.Filename : info.Chapters)
.WithTitle((specialTreatment && info.Format == MangaFormat.Epub)
? info.Title
: specialTitle)
.WithIsSpecial(specialTreatment);
}
public ChapterBuilder WithId(int id)
{
_chapter.Id = Math.Max(id, 0);
return this;
}
private ChapterBuilder WithNumber(string number)
{
_chapter.Number = number;
return this;
}
private ChapterBuilder WithRange(string range)
{
_chapter.Range = range;
return this;
}
public ChapterBuilder WithReleaseDate(DateTime time)
{
_chapter.ReleaseDate = time;
@ -61,4 +93,24 @@ public class ChapterBuilder : IEntityBuilder<Chapter>
_chapter.Files.Add(file);
return this;
}
public ChapterBuilder WithFiles(IList<MangaFile> files)
{
_chapter.Files = files ?? new List<MangaFile>();
return this;
}
public ChapterBuilder WithLastModified(DateTime lastModified)
{
_chapter.LastModified = lastModified;
_chapter.LastModifiedUtc = lastModified.ToUniversalTime();
return this;
}
public ChapterBuilder WithCreated(DateTime created)
{
_chapter.Created = created;
_chapter.CreatedUtc = created.ToUniversalTime();
return this;
}
}

View File

@ -0,0 +1,57 @@
using System.Collections.Generic;
using API.Entities;
using API.Entities.Metadata;
using API.Extensions;
namespace API.Helpers.Builders;
public class CollectionTagBuilder : IEntityBuilder<CollectionTag>
{
private readonly CollectionTag _collectionTag;
public CollectionTag Build() => _collectionTag;
public CollectionTagBuilder(string title, bool promoted = false)
{
title = title.Trim();
_collectionTag = new CollectionTag()
{
Id = 0,
NormalizedTitle = title.ToNormalized(),
Title = title,
Promoted = promoted,
Summary = string.Empty,
SeriesMetadatas = new List<SeriesMetadata>()
};
}
public CollectionTagBuilder WithId(int id)
{
_collectionTag.Id = id;
return this;
}
public CollectionTagBuilder WithSummary(string summary)
{
_collectionTag.Summary = summary;
return this;
}
public CollectionTagBuilder WithIsPromoted(bool promoted)
{
_collectionTag.Promoted = promoted;
return this;
}
public CollectionTagBuilder WithSeriesMetadata(SeriesMetadata seriesMetadata)
{
_collectionTag.SeriesMetadatas ??= new List<SeriesMetadata>();
_collectionTag.SeriesMetadatas.Add(seriesMetadata);
return this;
}
public CollectionTagBuilder WithCoverImage(string cover)
{
_collectionTag.CoverImage = cover;
return this;
}
}

View File

@ -0,0 +1,30 @@
using API.Entities;
using API.Entities.Enums.Device;
namespace API.Helpers.Builders;
public class DeviceBuilder : IEntityBuilder<Device>
{
private readonly Device _device;
public Device Build() => _device;
public DeviceBuilder(string name)
{
_device = new Device()
{
Name = name,
Platform = DevicePlatform.Custom
};
}
public DeviceBuilder WithPlatform(DevicePlatform platform)
{
_device.Platform = platform;
return this;
}
public DeviceBuilder WithEmail(string email)
{
_device.EmailAddress = email;
return this;
}
}

View File

@ -0,0 +1,19 @@
using System.IO;
using API.Entities;
namespace API.Helpers.Builders;
public class FolderPathBuilder : IEntityBuilder<FolderPath>
{
private readonly FolderPath _folderPath;
public FolderPath Build() => _folderPath;
public FolderPathBuilder(string directory)
{
_folderPath = new FolderPath()
{
Path = directory,
Id = 0
};
}
}

View File

@ -0,0 +1,30 @@
using System.Collections.Generic;
using API.Entities;
using API.Entities.Metadata;
using API.Extensions;
namespace API.Helpers.Builders;
public class GenreBuilder : IEntityBuilder<Genre>
{
private readonly Genre _genre;
public Genre Build() => _genre;
public GenreBuilder(string name)
{
_genre = new Genre()
{
Title = name.Trim().SentenceCase(),
NormalizedTitle = name.ToNormalized(),
Chapters = new List<Chapter>(),
SeriesMetadatas = new List<SeriesMetadata>()
};
}
public GenreBuilder WithSeriesMetadata(SeriesMetadata seriesMetadata)
{
_genre.SeriesMetadatas ??= new List<SeriesMetadata>();
_genre.SeriesMetadatas.Add(seriesMetadata);
return this;
}
}

View File

@ -0,0 +1,46 @@
using System.Collections.Generic;
using System.Linq;
using API.Entities;
using API.Entities.Enums;
using SQLitePCL;
namespace API.Helpers.Builders;
public class LibraryBuilder : IEntityBuilder<Library>
{
private readonly Library _library;
public Library Build() => _library;
public LibraryBuilder(string name, LibraryType type = LibraryType.Manga)
{
_library = new Library()
{
Name = name,
Type = type,
Series = new List<Series>(),
Folders = new List<FolderPath>(),
AppUsers = new List<AppUser>()
};
}
public LibraryBuilder WithFolderPath(FolderPath folderPath)
{
_library.Folders ??= new List<FolderPath>();
if (_library.Folders.All(f => f != folderPath)) _library.Folders.Add(folderPath);
return this;
}
public LibraryBuilder WithSeries(Series series)
{
_library.Series ??= new List<Series>();
_library.Series.Add(series);
return this;
}
public LibraryBuilder WithAppUser(AppUser appUser)
{
_library.AppUsers ??= new List<AppUser>();
_library.AppUsers.Add(appUser);
return this;
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.IO;
using API.Entities;
using API.Entities.Enums;
namespace API.Helpers.Builders;
public class MangaFileBuilder : IEntityBuilder<MangaFile>
{
private readonly MangaFile _mangaFile;
public MangaFile Build() => _mangaFile;
public MangaFileBuilder(string filePath, MangaFormat format, int pages = 0)
{
_mangaFile = new MangaFile()
{
FilePath = filePath,
Format = format,
Pages = pages,
LastModified = File.GetLastWriteTime(filePath),
LastModifiedUtc = File.GetLastWriteTimeUtc(filePath),
};
}
public MangaFileBuilder WithFormat(MangaFormat format)
{
_mangaFile.Format = format;
return this;
}
public MangaFileBuilder WithPages(int pages)
{
_mangaFile.Pages = Math.Max(pages, 0);
return this;
}
public MangaFileBuilder WithExtension(string extension)
{
_mangaFile.Extension = extension.ToLowerInvariant();
return this;
}
public MangaFileBuilder WithBytes(long bytes)
{
_mangaFile.Bytes = Math.Max(0, bytes);
return this;
}
public MangaFileBuilder WithLastModified(DateTime dateTime)
{
_mangaFile.LastModified = dateTime;
_mangaFile.LastModifiedUtc = dateTime.ToUniversalTime();
return this;
}
public MangaFileBuilder WithId(int id)
{
_mangaFile.Id = Math.Max(id, 0);
return this;
}
}

View File

@ -23,6 +23,17 @@ public class PersonBuilder : IEntityBuilder<Person>
};
}
/// <summary>
/// Only call for Unit Tests
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public PersonBuilder WithId(int id)
{
_person.Id = id;
return this;
}
public PersonBuilder WithSeriesMetadata(SeriesMetadata metadata)
{
_person.SeriesMetadatas ??= new List<SeriesMetadata>();

View File

@ -0,0 +1,57 @@
using System.Collections.Generic;
using API.Entities;
using API.Entities.Enums;
using API.Extensions;
namespace API.Helpers.Builders;
public class ReadingListBuilder : IEntityBuilder<ReadingList>
{
private readonly ReadingList _readingList;
public ReadingList Build() => _readingList;
public ReadingListBuilder(string title)
{
title = title.Trim();
_readingList = new ReadingList()
{
Title = title,
NormalizedTitle = title.ToNormalized(),
Summary = string.Empty,
Promoted = false,
Items = new List<ReadingListItem>(),
AgeRating = AgeRating.Unknown
};
}
public ReadingListBuilder WithSummary(string summary)
{
_readingList.Summary = summary ?? string.Empty;
return this;
}
public ReadingListBuilder WithItem(ReadingListItem item)
{
_readingList.Items ??= new List<ReadingListItem>();
_readingList.Items.Add(item);
return this;
}
public ReadingListBuilder WithRating(AgeRating rating)
{
_readingList.AgeRating = rating;
return this;
}
public ReadingListBuilder WithPromoted(bool promoted)
{
_readingList.Promoted = promoted;
return this;
}
public ReadingListBuilder WithCoverImage(string coverImage)
{
_readingList.CoverImage = coverImage;
return this;
}
}

View File

@ -0,0 +1,21 @@
using API.Entities;
namespace API.Helpers.Builders;
public class ReadingListItemBuilder : IEntityBuilder<ReadingListItem>
{
private readonly ReadingListItem _item;
public ReadingListItem Build() => _item;
public ReadingListItemBuilder(int index, int seriesId, int volumeId, int chapterId)
{
_item = new ReadingListItem()
{
Order = index,
ChapterId = chapterId,
SeriesId = seriesId,
VolumeId = volumeId
};
}
}

View File

@ -26,13 +26,22 @@ public class SeriesBuilder : IEntityBuilder<Series>
SortName = name,
NormalizedName = name.ToNormalized(),
NormalizedLocalizedName = name.ToNormalized(),
Metadata = new SeriesMetadata(),
Metadata = new SeriesMetadataBuilder().Build(),
Volumes = new List<Volume>()
};
}
/// <summary>
/// Sets the localized name. If null or empty, defaults back to the
/// </summary>
/// <param name="localizedName"></param>
/// <returns></returns>
public SeriesBuilder WithLocalizedName(string localizedName)
{
if (string.IsNullOrEmpty(localizedName))
{
localizedName = _series.Name;
}
_series.LocalizedName = localizedName;
_series.NormalizedLocalizedName = localizedName.ToNormalized();
return this;
@ -68,4 +77,16 @@ public class SeriesBuilder : IEntityBuilder<Series>
_series.Pages = pages;
return this;
}
public SeriesBuilder WithCoverImage(string cover)
{
_series.CoverImage = cover;
return this;
}
public SeriesBuilder WithLibraryId(int id)
{
_series.LibraryId = id;
return this;
}
}

View File

@ -23,14 +23,26 @@ public class SeriesMetadataBuilder : IEntityBuilder<SeriesMetadata>
public SeriesMetadataBuilder WithCollectionTag(CollectionTag tag)
{
_seriesMetadata.CollectionTags ??= new List<API.Entities.CollectionTag>();
_seriesMetadata.CollectionTags ??= new List<CollectionTag>();
_seriesMetadata.CollectionTags.Add(tag);
return this;
}
public SeriesMetadataBuilder WithCollectionTags(IList<CollectionTag> tags)
{
if (tags == null) return this;
_seriesMetadata.CollectionTags ??= new List<CollectionTag>();
_seriesMetadata.CollectionTags = tags;
return this;
}
public SeriesMetadataBuilder WithPublicationStatus(PublicationStatus status)
{
_seriesMetadata.PublicationStatus = status;
return this;
}
public SeriesMetadataBuilder WithAgeRating(AgeRating rating)
{
_seriesMetadata.AgeRating = rating;
return this;
}
}

View File

@ -0,0 +1,30 @@
using System.Collections.Generic;
using API.Entities;
using API.Entities.Metadata;
using API.Extensions;
namespace API.Helpers.Builders;
public class TagBuilder : IEntityBuilder<Tag>
{
private readonly Tag _tag;
public Tag Build() => _tag;
public TagBuilder(string name)
{
_tag = new Tag()
{
Title = name.Trim().SentenceCase(),
NormalizedTitle = name.ToNormalized(),
Chapters = new List<Chapter>(),
SeriesMetadatas = new List<SeriesMetadata>()
};
}
public TagBuilder WithSeriesMetadata(SeriesMetadata seriesMetadata)
{
_tag.SeriesMetadatas ??= new List<SeriesMetadata>();
_tag.SeriesMetadatas.Add(seriesMetadata);
return this;
}
}

View File

@ -12,7 +12,12 @@ public class VolumeBuilder : IEntityBuilder<Volume>
public VolumeBuilder(string volumeNumber)
{
_volume = DbFactory.Volume(volumeNumber);
_volume = new Volume()
{
Name = volumeNumber,
Number = (int) Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(volumeNumber),
Chapters = new List<Chapter>()
};
}
public VolumeBuilder WithName(string name)
@ -40,4 +45,16 @@ public class VolumeBuilder : IEntityBuilder<Volume>
_volume.Pages = _volume.Chapters.Sum(c => c.Pages);
return this;
}
public VolumeBuilder WithSeriesId(int seriesId)
{
_volume.SeriesId = seriesId;
return this;
}
public VolumeBuilder WithCoverImage(string cover)
{
_volume.CoverImage = cover;
return this;
}
}

View File

@ -5,6 +5,7 @@ using API.Data;
using API.DTOs.Metadata;
using API.Entities;
using API.Extensions;
using API.Helpers.Builders;
namespace API.Helpers;
@ -26,7 +27,7 @@ public static class GenreHelper
var genre = allGenres.FirstOrDefault(p => p.NormalizedTitle != null && p.NormalizedTitle.Equals(normalizedName));
if (genre == null)
{
genre = DbFactory.Genre(name);
genre = new GenreBuilder(name).Build();
allGenres.Add(genre);
}
@ -99,7 +100,7 @@ public static class GenreHelper
else
{
// Add new tag
handleAdd(DbFactory.Genre(tagTitle));
handleAdd(new GenreBuilder(tagTitle).Build());
isModified = true;
}
}

View File

@ -2,8 +2,8 @@
using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Parser;
using API.Services.Tasks.Scanner;
using API.Services.Tasks.Scanner.Parser;
namespace API.Helpers;

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using API.Data;
using API.DTOs;
using API.Entities;
using API.Entities.Enums;
@ -25,6 +23,7 @@ public static class PersonHelper
/// <param name="action"></param>
public static void UpdatePeople(ICollection<Person> allPeople, IEnumerable<string> names, PersonRole role, Action<Person> action)
{
// TODO: Validate if we need this, not used
var allPeopleTypeRole = allPeople.Where(p => p.Role == role).ToList();
foreach (var name in names)
@ -34,7 +33,7 @@ public static class PersonHelper
p.NormalizedName != null && p.NormalizedName.Equals(normalizedName));
if (person == null)
{
person = DbFactory.Person(name, role);
person = new PersonBuilder(name, role).Build();
allPeople.Add(person);
}
@ -102,7 +101,7 @@ public static class PersonHelper
public static void AddPersonIfNotExists(ICollection<Person> metadataPeople, Person person)
{
if (string.IsNullOrEmpty(person.Name)) return;
var existingPerson = metadataPeople.SingleOrDefault(p =>
var existingPerson = metadataPeople.FirstOrDefault(p =>
p.NormalizedName == person.Name.ToNormalized() && p.Role == person.Role);
if (existingPerson == null)
{
@ -110,21 +109,16 @@ public static class PersonHelper
}
}
/// <summary>
/// Adds the person to the list if it's not already in there
/// </summary>
/// <param name="metadataPeople"></param>
/// <param name="person"></param>
public static void AddPersonIfNotExists(BlockingCollection<Person> metadataPeople, Person person)
{
var existingPerson = metadataPeople.SingleOrDefault(p =>
p.NormalizedName == person.Name?.ToNormalized() && p.Role == person.Role);
if (existingPerson == null)
{
metadataPeople.Add(person);
}
}
/// <summary>
/// For a given role and people dtos, update a series
/// </summary>
/// <param name="role"></param>
/// <param name="tags"></param>
/// <param name="series"></param>
/// <param name="allTags"></param>
/// <param name="handleAdd">This will call with an existing or new tag, but the method does not update the series Metadata</param>
/// <param name="onModified"></param>
public static void UpdatePeopleList(PersonRole role, ICollection<PersonDto>? tags, Series series, IReadOnlyCollection<Person> allTags,
Action<Person> handleAdd, Action onModified)
{

View File

@ -6,6 +6,7 @@ using API.Data;
using API.DTOs.Metadata;
using API.Entities;
using API.Extensions;
using API.Helpers.Builders;
namespace API.Helpers;
@ -31,7 +32,7 @@ public static class TagHelper
if (genre == null)
{
added = true;
genre = DbFactory.Tag(name);
genre = new TagBuilder(name).Build();
allTags.Add(genre);
}
@ -129,7 +130,7 @@ public static class TagHelper
else
{
// Add new tag
handleAdd(DbFactory.Tag(tagTitle));
handleAdd(new TagBuilder(tagTitle).Build());
isModified = true;
}
}

View File

@ -11,7 +11,7 @@ using API.Data.Metadata;
using API.DTOs.Reader;
using API.Entities;
using API.Entities.Enums;
using API.Parser;
using API.Services.Tasks.Scanner.Parser;
using Docnet.Core;
using Docnet.Core.Converters;
using Docnet.Core.Models;

View File

@ -7,6 +7,7 @@ using API.Data.Repositories;
using API.DTOs.CollectionTags;
using API.Entities;
using API.Entities.Metadata;
using API.Helpers.Builders;
using API.SignalR;
using Kavita.Common;
@ -163,7 +164,7 @@ public class CollectionTagService : ICollectionTagService
/// <returns></returns>
public CollectionTag CreateTag(string title)
{
var tag = DbFactory.CollectionTag(0, title, string.Empty, false);
var tag = new CollectionTagBuilder(title).Build();
_unitOfWork.CollectionTagRepository.Add(tag);
return tag;
}

View File

@ -8,6 +8,7 @@ using API.DTOs.Email;
using API.Entities;
using API.Entities.Enums;
using API.Entities.Enums.Device;
using API.Helpers.Builders;
using Kavita.Common;
using Microsoft.Extensions.Logging;
@ -42,9 +43,10 @@ public class DeviceService : IDeviceService
var existingDevice = userWithDevices.Devices.SingleOrDefault(d => d.Name!.Equals(dto.Name));
if (existingDevice != null) throw new KavitaException("A device with this name already exists");
existingDevice = DbFactory.Device(dto.Name);
existingDevice.Platform = dto.Platform;
existingDevice.EmailAddress = dto.EmailAddress;
existingDevice = new DeviceBuilder(dto.Name)
.WithPlatform(dto.Platform)
.WithEmail(dto.EmailAddress)
.Build();
userWithDevices.Devices.Add(existingDevice);

View File

@ -1,7 +1,6 @@
using System;
using API.Data.Metadata;
using API.Entities.Enums;
using API.Parser;
using API.Services.Tasks.Scanner.Parser;
namespace API.Services;

View File

@ -12,6 +12,7 @@ using API.DTOs.ReadingLists.CBL;
using API.Entities;
using API.Entities.Enums;
using API.Helpers;
using API.Helpers.Builders;
using API.SignalR;
using Kavita.Common;
using Microsoft.Extensions.Logging;
@ -118,7 +119,7 @@ public class ReadingListService : IReadingListService
throw new KavitaException("A list of this name already exists");
}
var readingList = DbFactory.ReadingList(title, string.Empty, false);
var readingList = new ReadingListBuilder(title).Build();
userWithReadingList.ReadingLists.Add(readingList);
if (!_unitOfWork.HasChanges()) throw new KavitaException("There was a problem creating list");
@ -410,7 +411,7 @@ public class ReadingListService : IReadingListService
var index = readingList.Items.Count == 0 ? 0 : lastOrder + 1;
foreach (var chapter in chaptersForSeries.Where(chapter => !existingChapterExists.Contains(chapter.Id)))
{
readingList.Items.Add(DbFactory.ReadingListItem(index, seriesId, chapter.VolumeId, chapter.Id));
readingList.Items.Add(new ReadingListItemBuilder(index, seriesId, chapter.VolumeId, chapter.Id).Build());
index += 1;
}
@ -509,7 +510,7 @@ public class ReadingListService : IReadingListService
var allReadingLists = (user.ReadingLists).ToDictionary(s => s.NormalizedTitle);
if (!allReadingLists.TryGetValue(readingListNameNormalized, out var readingList))
{
readingList = DbFactory.ReadingList(cblReading.Name, cblReading.Summary, false);
readingList = new ReadingListBuilder(cblReading.Name).WithSummary(cblReading.Summary).Build();
user.ReadingLists.Add(readingList);
}
else
@ -645,8 +646,8 @@ public class ReadingListService : IReadingListService
item.SeriesId == seriesId && item.ChapterId == chapterId);
if (readingListItem != null) return;
readingListItem = DbFactory.ReadingListItem(readingList.Items.Count, seriesId,
volumeId, chapterId);
readingListItem = new ReadingListItemBuilder(readingList.Items.Count, seriesId,
volumeId, chapterId).Build();
readingList.Items.Add(readingListItem);
}

View File

@ -13,6 +13,7 @@ using API.Entities;
using API.Entities.Enums;
using API.Entities.Metadata;
using API.Helpers;
using API.Helpers.Builders;
using API.SignalR;
using Microsoft.Extensions.Logging;
@ -69,8 +70,14 @@ public class SeriesService : ISeriesService
var allPeople = (await _unitOfWork.PersonRepository.GetAllPeople()).ToList();
var allTags = (await _unitOfWork.TagRepository.GetAllTagsAsync()).ToList();
series.Metadata ??= DbFactory.SeriesMetadata((updateSeriesMetadataDto.CollectionTags ?? new List<CollectionTagDto>())
.Select(dto => DbFactory.CollectionTag(dto.Id, dto.Title, dto.Summary, dto.Promoted)).ToList());
series.Metadata ??= new SeriesMetadataBuilder()
.WithCollectionTags(updateSeriesMetadataDto.CollectionTags.Select(dto =>
new CollectionTagBuilder(dto.Title)
.WithId(dto.Id)
.WithSummary(dto.Summary)
.WithIsPromoted(dto.Promoted)
.Build()).ToList())
.Build();
if (series.Metadata.AgeRating != updateSeriesMetadataDto.SeriesMetadata.AgeRating)
{
@ -244,7 +251,11 @@ public class SeriesService : ISeriesService
else
{
// Add new tag
handleAdd(DbFactory.CollectionTag(tag.Id, tag.Title, tag.Summary, tag.Promoted));
handleAdd(new CollectionTagBuilder(tag.Title)
.WithId(tag.Id)
.WithSummary(tag.Summary)
.WithIsPromoted(tag.Promoted)
.Build());
}
}
}

View File

@ -6,7 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using API.Entities.Enums;
using API.Extensions;
using API.Parser;
using API.Services.Tasks.Scanner.Parser;
using API.SignalR;
using Kavita.Common.Helpers;
using Microsoft.Extensions.Logging;

View File

@ -1,7 +1,6 @@
using System.IO;
using System.Linq;
using API.Entities.Enums;
using API.Parser;
namespace API.Services.Tasks.Scanner.Parser;
@ -34,8 +33,9 @@ public class DefaultParser : IDefaultParser
public ParserInfo? Parse(string filePath, string rootPath, LibraryType type = LibraryType.Manga)
{
var fileName = _directoryService.FileSystem.Path.GetFileNameWithoutExtension(filePath);
// TODO: Potential Bug: This will return null, but on Image libraries, if all images, we would want to include this.
// TODO: Potential Bug: This will return null, but on Image libraries, if all images, we would want to include this. (we can probably remove this and have users use kavitaignore)
if (Parser.IsCoverImage(_directoryService.FileSystem.Path.GetFileName(filePath))) return null;
ParserInfo ret;
if (Parser.IsEpub(filePath))

View File

@ -1,8 +1,7 @@
using API.Data.Metadata;
using API.Entities.Enums;
using API.Services.Tasks.Scanner.Parser;
namespace API.Parser;
namespace API.Services.Tasks.Scanner.Parser;
/// <summary>
/// This represents all parsed information from a single file

View File

@ -11,8 +11,9 @@ using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Helpers;
using API.Parser;
using API.Helpers.Builders;
using API.Services.Tasks.Metadata;
using API.Services.Tasks.Scanner.Parser;
using API.SignalR;
using Hangfire;
using Kavita.Common;
@ -29,6 +30,13 @@ public interface IProcessSeries
Task Prime();
Task ProcessSeriesAsync(IList<ParserInfo> parsedInfos, Library library, bool forceUpdate = false);
void EnqueuePostSeriesProcessTasks(int libraryId, int seriesId, bool forceUpdate = false);
// These exists only for Unit testing
void UpdateSeriesMetadata(Series series, Library library);
void UpdateVolumes(Series series, IList<ParserInfo> parsedInfos, bool forceUpdate = false);
void UpdateChapters(Series series, Volume volume, IList<ParserInfo> parsedInfos, bool forceUpdate = false);
void AddOrUpdateFileForChapter(Chapter chapter, ParserInfo info, bool forceUpdate = false);
void UpdateChapterFromComicInfo(Chapter chapter, ComicInfo? info);
}
/// <summary>
@ -51,9 +59,9 @@ public class ProcessSeries : IProcessSeries
private IList<Person> _people;
private Dictionary<string, Tag> _tags;
private Dictionary<string, CollectionTag> _collectionTags;
private readonly object _peopleLock;
private readonly object _genreLock;
private readonly object _tagLock;
private readonly object _peopleLock = new object();
private readonly object _genreLock = new object();
private readonly object _tagLock = new object();
public ProcessSeries(IUnitOfWork unitOfWork, ILogger<ProcessSeries> logger, IEventHub eventHub,
IDirectoryService directoryService, ICacheHelper cacheHelper, IReadingItemService readingItemService,
@ -71,6 +79,7 @@ public class ProcessSeries : IProcessSeries
_wordCountAnalyzerService = wordCountAnalyzerService;
_collectionTagService = collectionTagService;
_genres = new Dictionary<string, Genre>();
_people = new List<Person>();
_tags = new Dictionary<string, Tag>();
@ -122,7 +131,9 @@ public class ProcessSeries : IProcessSeries
if (series == null)
{
seriesAdded = true;
series = DbFactory.Series(firstInfo.Series, firstInfo.LocalizedSeries);
series = new SeriesBuilder(firstInfo.Series)
.WithLocalizedName(firstInfo.LocalizedSeries)
.Build();
_unitOfWork.SeriesRepository.Add(series);
}
@ -217,7 +228,7 @@ public class ProcessSeries : IProcessSeries
//if (!library.ManageReadingLists) return;
_logger.LogInformation("Generating Reading Lists for {SeriesName}", series.Name);
series.Metadata ??= DbFactory.SeriesMetadata(new List<CollectionTag>());
series.Metadata ??= new SeriesMetadataBuilder().Build();
foreach (var chapter in series.Volumes.SelectMany(v => v.Chapters))
{
if (!string.IsNullOrEmpty(chapter.StoryArc))
@ -261,9 +272,9 @@ public class ProcessSeries : IProcessSeries
BackgroundJob.Enqueue(() => _wordCountAnalyzerService.ScanSeries(libraryId, seriesId, forceUpdate));
}
private void UpdateSeriesMetadata(Series series, Library library)
public void UpdateSeriesMetadata(Series series, Library library)
{
series.Metadata ??= DbFactory.SeriesMetadata(new List<CollectionTag>());
series.Metadata ??= new SeriesMetadataBuilder().Build();
var isBook = library.Type == LibraryType.Book;
var firstChapter = SeriesService.GetFirstChapterForMetadata(series, isBook);
@ -333,7 +344,19 @@ public class ProcessSeries : IProcessSeries
}
}
lock (_genreLock)
{
var genres = chapters.SelectMany(c => c.Genres).ToList();
GenreHelper.KeepOnlySameGenreBetweenLists(series.Metadata.Genres.ToList(), genres, genre =>
{
if (series.Metadata.GenresLocked) return; // NOTE: Doesn't it make sense to do the locked skip outside this loop?
series.Metadata.Genres.Remove(genre);
});
}
// Handle People
lock (_peopleLock)
{
foreach (var chapter in chapters)
{
if (!series.Metadata.WriterLocked)
@ -432,14 +455,6 @@ public class ProcessSeries : IProcessSeries
}
}
}
var genres = chapters.SelectMany(c => c.Genres).ToList();
GenreHelper.KeepOnlySameGenreBetweenLists(series.Metadata.Genres.ToList(), genres, genre =>
{
if (series.Metadata.GenresLocked) return; // NOTE: Doesn't it make sense to do the locked skip outside this loop?
series.Metadata.Genres.Remove(genre);
});
// NOTE: The issue here is that people is just from chapter, but series metadata might already have some people on it
// I might be able to filter out people that are in locked fields?
var people = chapters.SelectMany(c => c.People).ToList();
@ -484,8 +499,9 @@ public class ProcessSeries : IProcessSeries
}
});
}
}
private void UpdateVolumes(Series series, IList<ParserInfo> parsedInfos, bool forceUpdate = false)
public void UpdateVolumes(Series series, IList<ParserInfo> parsedInfos, bool forceUpdate = false)
{
var startingVolumeCount = series.Volumes.Count;
// Add new volumes and update chapters per volume
@ -493,7 +509,7 @@ public class ProcessSeries : IProcessSeries
_logger.LogDebug("[ScannerService] Updating {DistinctVolumes} volumes on {SeriesName}", distinctVolumes.Count, series.Name);
foreach (var volumeNumber in distinctVolumes)
{
_logger.LogDebug("[ScannerService] Looking up volume for {VolumeNumber}", volumeNumber);
_logger.LogTrace("[ScannerService] Looking up volume for {VolumeNumber}", volumeNumber);
Volume? volume;
try
{
@ -511,8 +527,9 @@ public class ProcessSeries : IProcessSeries
}
if (volume == null)
{
volume = DbFactory.Volume(volumeNumber);
volume.SeriesId = series.Id;
volume = new VolumeBuilder(volumeNumber)
.WithSeriesId(series.Id)
.Build();
series.Volumes.Add(volume);
}
@ -568,7 +585,7 @@ public class ProcessSeries : IProcessSeries
series.Name, startingVolumeCount, series.Volumes.Count);
}
private void UpdateChapters(Series series, Volume volume, IList<ParserInfo> parsedInfos, bool forceUpdate = false)
public void UpdateChapters(Series series, Volume volume, IList<ParserInfo> parsedInfos, bool forceUpdate = false)
{
// Add new chapters
foreach (var info in parsedInfos)
@ -590,7 +607,7 @@ public class ProcessSeries : IProcessSeries
{
_logger.LogDebug(
"[ScannerService] Adding new chapter, {Series} - Vol {Volume} Ch {Chapter}", info.Series, info.Volumes, info.Chapters);
chapter = DbFactory.Chapter(info);
chapter = ChapterBuilder.FromParserInfo(info).Build();
volume.Chapters.Add(chapter);
series.UpdateLastChapterAdded();
}
@ -628,7 +645,7 @@ public class ProcessSeries : IProcessSeries
}
}
private void AddOrUpdateFileForChapter(Chapter chapter, ParserInfo info, bool forceUpdate = false)
public void AddOrUpdateFileForChapter(Chapter chapter, ParserInfo info, bool forceUpdate = false)
{
chapter.Files ??= new List<MangaFile>();
var existingFile = chapter.Files.SingleOrDefault(f => f.FilePath == info.FullFilePath);
@ -644,15 +661,16 @@ public class ProcessSeries : IProcessSeries
}
else
{
var file = DbFactory.MangaFile(info.FullFilePath, info.Format, _readingItemService.GetNumberOfPages(info.FullFilePath, info.Format));
if (file == null) return;
file.Extension = fileInfo.Extension.ToLowerInvariant();
file.Bytes = fileInfo.Length;
var file = new MangaFileBuilder(info.FullFilePath, info.Format, _readingItemService.GetNumberOfPages(info.FullFilePath, info.Format))
.WithExtension(fileInfo.Extension)
.WithBytes(fileInfo.Length)
.Build();
chapter.Files.Add(file);
}
}
private void UpdateChapterFromComicInfo(Chapter chapter, ComicInfo? info)
public void UpdateChapterFromComicInfo(Chapter chapter, ComicInfo? info)
{
var firstFile = chapter.Files.MinBy(x => x.Chapter);
if (firstFile == null ||
@ -665,7 +683,7 @@ public class ProcessSeries : IProcessSeries
}
if (comicInfo == null) return;
_logger.LogDebug("[ScannerService] Read ComicInfo for {File}", firstFile.FilePath);
_logger.LogTrace("[ScannerService] Read ComicInfo for {File}", firstFile.FilePath);
chapter.AgeRating = ComicInfo.ConvertAgeRatingToEnum(comicInfo.AgeRating);
@ -749,70 +767,59 @@ public class ProcessSeries : IProcessSeries
var people = GetTagValues(comicInfo.Colorist);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Colorist);
UpdatePeople(people, PersonRole.Colorist,
AddPerson);
UpdatePeople(people, PersonRole.Colorist, AddPerson);
people = GetTagValues(comicInfo.Characters);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Character);
UpdatePeople(people, PersonRole.Character,
AddPerson);
UpdatePeople(people, PersonRole.Character, AddPerson);
people = GetTagValues(comicInfo.Translator);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Translator);
UpdatePeople(people, PersonRole.Translator,
AddPerson);
UpdatePeople(people, PersonRole.Translator, AddPerson);
people = GetTagValues(comicInfo.Writer);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Writer);
UpdatePeople(people, PersonRole.Writer,
AddPerson);
UpdatePeople(people, PersonRole.Writer, AddPerson);
people = GetTagValues(comicInfo.Editor);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Editor);
UpdatePeople(people, PersonRole.Editor,
AddPerson);
UpdatePeople(people, PersonRole.Editor, AddPerson);
people = GetTagValues(comicInfo.Inker);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Inker);
UpdatePeople(people, PersonRole.Inker,
AddPerson);
UpdatePeople(people, PersonRole.Inker, AddPerson);
people = GetTagValues(comicInfo.Letterer);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Letterer);
UpdatePeople(people, PersonRole.Letterer,
AddPerson);
UpdatePeople(people, PersonRole.Letterer, AddPerson);
people = GetTagValues(comicInfo.Penciller);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Penciller);
UpdatePeople(people, PersonRole.Penciller,
AddPerson);
UpdatePeople(people, PersonRole.Penciller, AddPerson);
people = GetTagValues(comicInfo.CoverArtist);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.CoverArtist);
UpdatePeople(people, PersonRole.CoverArtist,
AddPerson);
UpdatePeople(people, PersonRole.CoverArtist, AddPerson);
people = GetTagValues(comicInfo.Publisher);
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Publisher);
UpdatePeople(people, PersonRole.Publisher,
AddPerson);
UpdatePeople(people, PersonRole.Publisher, AddPerson);
var genres = GetTagValues(comicInfo.Genre);
GenreHelper.KeepOnlySameGenreBetweenLists(chapter.Genres,
genres.Select(DbFactory.Genre).ToList());
genres.Select(g => new GenreBuilder(g).Build()).ToList());
UpdateGenre(genres, AddGenre);
var tags = GetTagValues(comicInfo.Tags);
TagHelper.KeepOnlySameTagBetweenLists(chapter.Tags, tags.Select(DbFactory.Tag).ToList());
TagHelper.KeepOnlySameTagBetweenLists(chapter.Tags, tags.Select(t => new TagBuilder(t).Build()).ToList());
UpdateTag(tags, AddTag);
}
private static IList<string> GetTagValues(string comicInfoTagSeparatedByComma)
{
// TODO: Move this to an extension and test it
if (!string.IsNullOrEmpty(comicInfoTagSeparatedByComma))
{
return comicInfoTagSeparatedByComma.Split(",").Select(s => s.Trim()).DistinctBy(Parser.Parser.Normalize).ToList();
@ -830,6 +837,8 @@ public class ProcessSeries : IProcessSeries
/// <param name="role"></param>
/// <param name="action"></param>
private void UpdatePeople(IEnumerable<string> names, PersonRole role, Action<Person> action)
{
lock (_peopleLock)
{
var allPeopleTypeRole = _people.Where(p => p.Role == role).ToList();
@ -840,16 +849,14 @@ public class ProcessSeries : IProcessSeries
p.NormalizedName != null && p.NormalizedName.Equals(normalizedName));
if (person == null)
{
person = DbFactory.Person(name, role);
lock (_peopleLock)
{
person = new PersonBuilder(name, role).Build();
_people.Add(person);
}
}
action(person);
}
}
}
/// <summary>
///
@ -867,7 +874,7 @@ public class ProcessSeries : IProcessSeries
var newTag = genre == null;
if (newTag)
{
genre = DbFactory.Genre(name);
genre = new GenreBuilder(name).Build();
lock (_genreLock)
{
_genres.Add(normalizedName, genre);
@ -896,7 +903,7 @@ public class ProcessSeries : IProcessSeries
var added = tag == null;
if (tag == null)
{
tag = DbFactory.Tag(name);
tag = new TagBuilder(name).Build();
lock (_tagLock)
{
_tags.Add(normalizedName, tag);

View File

@ -11,9 +11,9 @@ using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Helpers;
using API.Parser;
using API.Services.Tasks.Metadata;
using API.Services.Tasks.Scanner;
using API.Services.Tasks.Scanner.Parser;
using API.SignalR;
using Hangfire;
using Microsoft.Extensions.Logging;

View File

@ -28,6 +28,7 @@ public class TokenService : ITokenService
{
private readonly UserManager<AppUser> _userManager;
private readonly SymmetricSecurityKey _key;
private const string RefreshTokenName = "RefreshToken";
public TokenService(IConfiguration config, UserManager<AppUser> userManager)
{
@ -65,22 +66,24 @@ public class TokenService : ITokenService
public async Task<string> CreateRefreshToken(AppUser user)
{
await _userManager.RemoveAuthenticationTokenAsync(user, TokenOptions.DefaultProvider, "RefreshToken");
var refreshToken = await _userManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "RefreshToken");
await _userManager.SetAuthenticationTokenAsync(user, TokenOptions.DefaultProvider, "RefreshToken", refreshToken);
await _userManager.RemoveAuthenticationTokenAsync(user, TokenOptions.DefaultProvider, RefreshTokenName);
var refreshToken = await _userManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, RefreshTokenName);
await _userManager.SetAuthenticationTokenAsync(user, TokenOptions.DefaultProvider, RefreshTokenName, refreshToken);
return refreshToken;
}
public async Task<TokenRequestDto?> ValidateRefreshToken(TokenRequestDto request)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var tokenContent = tokenHandler.ReadJwtToken(request.Token);
var username = tokenContent.Claims.FirstOrDefault(q => q.Type == JwtRegisteredClaimNames.NameId)?.Value;
if (string.IsNullOrEmpty(username)) return null;
var user = await _userManager.FindByNameAsync(username);
var user = await _userManager.FindByIdAsync(username);
if (user == null) return null; // This forces a logout
await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, "RefreshToken", request.RefreshToken);
var validated = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, RefreshTokenName, request.RefreshToken);
if (!validated) return null;
await _userManager.UpdateSecurityStampAsync(user);
return new TokenRequestDto()
@ -88,5 +91,15 @@ public class TokenService : ITokenService
Token = await CreateToken(user),
RefreshToken = await CreateRefreshToken(user)
};
} catch (SecurityTokenExpiredException)
{
// Handle expired token
return null;
}
catch (Exception)
{
// Handle other exceptions
return null;
}
}
}

View File

@ -185,13 +185,6 @@ public class Startup
{
options.AddPolicy("Authentication", httpContext =>
new AuthenticationRateLimiterPolicy().GetPartition(httpContext));
// RateLimitPartition.GetFixedWindowLimiter(httpContext.Connection.RemoteIpAddress?.ToString(),
// partition => new FixedWindowRateLimiterOptions
// {
// AutoReplenishment = true,
// PermitLimit = 1,
// Window = TimeSpan.FromMinutes(1),
// }));
});
services.AddHangfire(configuration => configuration

View File

@ -285,9 +285,9 @@ export class AccountService implements OnDestroy {
}
const jwtToken = JSON.parse(atob(this.currentUser.token.split('.')[1]));
// set a timeout to refresh the token a minute before it expires
// set a timeout to refresh the token 10 mins before it expires
const expires = new Date(jwtToken.exp * 1000);
const timeout = expires.getTime() - Date.now() - (60 * 1000);
const timeout = expires.getTime() - Date.now() - (60 * 10000);
this.refreshTokenTimeout = setTimeout(() => this.refreshToken().subscribe(() => {}), timeout);
}

View File

@ -23,7 +23,7 @@
<div class="col-md-6 col-sm-12">
<div class="mb-3" style="width:100%">
<label for="email" class="form-label">Email</label>
<input class="form-control" type="email" id="email" formControlName="email">
<input class="form-control" inputmode="email" type="email" id="email" formControlName="email">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="userForm.dirty || userForm.touched" [class.is-invalid]="userForm.get('email')?.invalid && userForm.get('email')?.touched">
<div *ngIf="userForm.get('email')?.errors?.required">
This field is required

View File

@ -13,7 +13,7 @@
<div class="row g-0">
<div class="mb-3" style="width:100%">
<label for="email" class="form-label">Email</label>
<input class="form-control" type="email" id="email" formControlName="email" required [class.is-invalid]="inviteForm.get('email')?.invalid && inviteForm.get('email')?.touched">
<input class="form-control" type="email" inputmode="email" id="email" formControlName="email" required [class.is-invalid]="inviteForm.get('email')?.invalid && inviteForm.get('email')?.touched">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="inviteForm.dirty || inviteForm.touched">
<div *ngIf="email?.errors?.required">
This field is required

View File

@ -13,7 +13,7 @@
<ng-template #emailServiceTooltip>Use fully qualified URL of the email service. Do not include ending slash.</ng-template>
<span class="visually-hidden" id="settings-emailservice-help"><ng-container [ngTemplateOutlet]="emailServiceTooltip"></ng-container></span>
<div class="input-group">
<input id="settings-emailservice" aria-describedby="settings-emailservice-help" class="form-control" formControlName="emailServiceUrl" type="text" aria-describedby="change-bookmarks-dir">
<input id="settings-emailservice" aria-describedby="settings-emailservice-help" class="form-control" formControlName="emailServiceUrl" type="url" autocapitalize="off" inputmode="url" aria-describedby="change-bookmarks-dir">
<button class="btn btn-outline-secondary" (click)="resetEmailServiceUrl()">
Reset
</button>

View File

@ -35,8 +35,8 @@
<div class="mb-3">
<label for="settings-baseurl" class="form-label">Base Url</label>&nbsp;<i class="fa fa-info-circle" placement="right" [ngbTooltip]="baseUrlTooltip" role="button" tabindex="0"></i>
<ng-template #baseUrlTooltip>Use this if you want to host Kavita on a base url ie) yourdomain.com/kavita</ng-template>
<span class="visually-hidden" id="settings-cachedir-help">Use this if you want to host Kavita on a base url ie) yourdomain.com/kavita</span>
<ng-template #baseUrlTooltip>Use this if you want to host Kavita on a base url ie) yourdomain.com/kavita. Not supported on Docker using non-root user.</ng-template>
<span class="visually-hidden" id="settings-cachedir-help">Use this if you want to host Kavita on a base url ie) yourdomain.com/kavita. Not supported on Docker using non-root user.</span>
<input id="settings-baseurl" aria-describedby="settings-baseurl-help" class="form-control" formControlName="baseUrl" type="text"
[class.is-invalid]="settingsForm.get('baseUrl')?.invalid && settingsForm.get('baseUrl')?.touched">
<div id="baseurl-validations" class="invalid-feedback" *ngIf="settingsForm.dirty || settingsForm.touched">
@ -77,7 +77,7 @@
<ng-template #backupTasksTooltip>The number of backups to maintain. Default is 30, minumum is 1, maximum is 30.</ng-template>
<span class="visually-hidden" id="backup-tasks-help">The number of backups to maintain. Default is 30, minumum is 1, maximum is 30.</span>
<input id="backup-tasks" aria-describedby="backup-tasks-help" class="form-control" formControlName="totalBackups"
type="number" step="1" min="1" max="30" onkeypress="return event.charCode >= 48 && event.charCode <= 57"
type="number" inputmode="numeric" step="1" min="1" max="30" onkeypress="return event.charCode >= 48 && event.charCode <= 57"
[class.is-invalid]="settingsForm.get('totalBackups')?.invalid && settingsForm.get('totalBackups')?.touched">
<ng-container *ngIf="settingsForm.get('totalBackups')?.errors as errors">
<p class="invalid-feedback" *ngIf="errors.min">
@ -97,7 +97,7 @@
<ng-template #logTasksTooltip>The number of logs to maintain. Default is 30, minumum is 1, maximum is 30.</ng-template>
<span class="visually-hidden" id="log-tasks-help">The number of backups to maintain. Default is 30, minumum is 1, maximum is 30.</span>
<input id="log-tasks" aria-describedby="log-tasks-help" class="form-control" formControlName="totalLogs"
type="number" step="1" min="1" max="30" onkeypress="return event.charCode >= 48 && event.charCode <= 57"
type="number" inputmode="numeric" step="1" min="1" max="30" onkeypress="return event.charCode >= 48 && event.charCode <= 57"
[class.is-invalid]="settingsForm.get('totalLogs')?.invalid && settingsForm.get('totalLogs')?.touched">
<ng-container *ngIf="settingsForm.get('totalLogs')?.errors as errors">
<p class="invalid-feedback" *ngIf="errors.min">

View File

@ -88,7 +88,7 @@
<label for="release-year" class="form-label">Release Year</label>
<div class="input-group {{metadata.releaseYearLocked ? 'lock-active' : ''}}">
<ng-container [ngTemplateOutlet]="lock" [ngTemplateOutletContext]="{ item: metadata, field: 'releaseYearLocked' }"></ng-container>
<input type="number" class="form-control" id="release-year" formControlName="releaseYear" maxlength="4" minlength="4" [class.is-invalid]="editSeriesForm.get('releaseYear')?.invalid && editSeriesForm.get('releaseYear')?.touched">
<input type="number" inputmode="numeric" class="form-control" id="release-year" formControlName="releaseYear" maxlength="4" minlength="4" [class.is-invalid]="editSeriesForm.get('releaseYear')?.invalid && editSeriesForm.get('releaseYear')?.touched">
<ng-container *ngIf="editSeriesForm.get('releaseYear')?.errors as errors">
<p class="invalid-feedback" *ngIf="errors.pattern">
This must be a valid year greater than 1000 and 4 characters long

View File

@ -92,7 +92,7 @@
<ng-template #progressEvent>
<li class="list-group-item dark-menu-item">
<div class="h6 mb-1">{{message.title}}</div>
<div class="accent-text mb-1" *ngIf="message.subTitle !== ''">{{message.subTitle}}</div>
<div class="accent-text mb-1" *ngIf="message.subTitle !== ''" [title]="message.subTitle">{{message.subTitle}}</div>
<div class="progress-container row g-0 align-items-center">
<div class="col-2">{{prettyPrintProgress(message.body.progress) + '%'}}</div>
<div class="col-10 progress" style="height: 5px;">
@ -122,7 +122,7 @@
<ng-container *ngFor="let download of activeDownloads">
<li class="list-group-item dark-menu-item">
<div class="h6 mb-1">Downloading {{download.entityType | sentenceCase}}</div>
<div class="accent-text mb-1" *ngIf="download.subTitle !== ''">{{download.subTitle}}</div>
<div class="accent-text mb-1" *ngIf="download.subTitle !== ''" [title]="download.subTitle">{{download.subTitle}}</div>
<div class="progress-container row g-0 align-items-center">
<div class="col-2">{{download.progress}}%</div>
<div class="col-10 progress" style="height: 5px;">

View File

@ -1,7 +1,7 @@
<form [formGroup]="typeaheadForm" class="grouped-typeahead">
<div class="typeahead-input" [ngClass]="{'focused': hasFocus}" (click)="onInputFocus($event)">
<div class="search">
<input #input [id]="id" type="text" autocomplete="off" formControlName="typeahead" [placeholder]="placeholder"
<input #input [id]="id" type="text" inputmode="search" autocomplete="off" formControlName="typeahead" [placeholder]="placeholder"
aria-haspopup="listbox" aria-owns="dropdown" aria-expanded="hasFocus && (grouppedData.persons.length || grouppedData.collections.length || grouppedData.series.length || grouppedData.persons.length || grouppedData.tags.length || grouppedData.genres.length)"
aria-autocomplete="list" (focusout)="close($event)" (focus)="open($event)" role="search"
>

View File

@ -8,7 +8,7 @@
<div class="me-3 align-middle">
<div style="padding-top: 40px">
<label for="reorder-{{i}}" class="form-label visually-hidden">Reorder</label>
<input *ngIf="accessibilityMode" id="reorder-{{i}}" class="form-control" type="number" min="0" [max]="items.length - 1" [value]="i" style="width: 60px"
<input *ngIf="accessibilityMode" id="reorder-{{i}}" class="form-control" type="number" inputmode="numeric" min="0" [max]="items.length - 1" [value]="i" style="width: 60px"
(focusout)="updateIndex(i, item)" (keydown.enter)="updateIndex(i, item)" aria-describedby="instructions">
</div>
</div>
@ -31,7 +31,7 @@
<div class="me-3 align-middle">
<div class="align-middle" style="padding-top: 40px" *ngIf="accessibilityMode">
<label for="reorder-{{i}}" class="form-label visually-hidden">Reorder</label>
<input id="reorder-{{i}}" class="form-control" type="number" min="0" [max]="items.length - 1" [value]="i" style="width: 60px"
<input id="reorder-{{i}}" class="form-control" type="number" inputmode="numeric" min="0" [max]="items.length - 1" [value]="i" style="width: 60px"
(focusout)="updateIndex(i, item)" (keydown.enter)="updateIndex(i, item)" aria-describedby="instructions">
</div>
<i *ngIf="!accessibilityMode" class="fa fa-grip-vertical drag-handle" aria-hidden="true" cdkDragHandle></i>

View File

@ -43,7 +43,7 @@
<div class="col-md-6 col-sm-12" *ngIf="reviewGroup.get('startingMonth') as formControl" style="width: 90%">
<label for="start-month" class="form-label">Month</label>
<input id="start-month" class="form-control" formControlName="startingMonth"
type="number" [class.is-invalid]="formControl?.invalid && formControl?.touched"
type="number" inputmode="numeric" [class.is-invalid]="formControl?.invalid && formControl?.touched"
aria-describedby="starting-year-header">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="reviewGroup.dirty || reviewGroup.touched">
<div *ngIf="formControl.errors?.min || formControl.errors?.max">
@ -53,7 +53,7 @@
</div>
<div class="col-md-6 col-sm-12" *ngIf="reviewGroup.get('startingYear') as formControl" style="width: 90%">
<label for="start-year" class="form-label">Year</label>
<input id="start-year" class="form-control" formControlName="startingYear" type="number"
<input id="start-year" class="form-control" formControlName="startingYear" type="number" inputmode="numeric"
[class.is-invalid]="formControl.invalid && formControl.touched"
aria-describedby="starting-year-header">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="reviewGroup.dirty || reviewGroup.touched">
@ -68,7 +68,7 @@
<h6 id="ending-year-heading">Ending</h6>
<div class="col-md-6 col-sm-12" *ngIf="reviewGroup.get('endingMonth') as formControl" style="width: 90%">
<label for="library-name" class="form-label">Month</label>
<input id="library-name" class="form-control" formControlName="endingMonth" type="number"
<input id="library-name" class="form-control" formControlName="endingMonth" type="number" inputmode="numeric"
[class.is-invalid]="formControl?.invalid && formControl?.touched"
aria-describedby="ending-year-header">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="reviewGroup.dirty || reviewGroup.touched">
@ -79,7 +79,7 @@
</div>
<div class="col-md-6 col-sm-12" *ngIf="reviewGroup.get('endingYear') as formControl" style="width: 90%">
<label for="library-name" class="form-label">Year</label>
<input id="library-name" class="form-control" formControlName="endingYear" type="number"
<input id="library-name" class="form-control" formControlName="endingYear" type="number" inputmode="numeric"
[class.is-invalid]="formControl?.invalid && formControl?.touched"
aria-describedby="ending-year-header">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="reviewGroup.dirty || reviewGroup.touched">

View File

@ -23,7 +23,7 @@
<div class="mb-3" style="width:100%">
<label for="email" class="form-label">Email</label>
<input class="form-control" type="email" id="email" formControlName="email" required readonly
<input class="form-control" type="email" inputmode="email" id="email" formControlName="email" required readonly
[class.is-invalid]="registerForm.get('email')?.invalid && registerForm.get('email')?.touched">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="registerForm.dirty || registerForm.touched">
<div *ngIf="registerForm.get('email')?.errors?.required">

View File

@ -20,7 +20,7 @@
<span class="visually-hidden" id="email-help">
<ng-container [ngTemplateOutlet]="emailTooltip"></ng-container>
</span>
<input class="form-control" type="email" id="email" formControlName="email" required aria-describedby="email-help"
<input class="form-control" type="email" inputmode="email" id="email" formControlName="email" required aria-describedby="email-help"
[class.is-invalid]="registerForm.get('email')?.invalid && registerForm.get('email')?.touched">
<div id="inviteForm-validations" class="invalid-feedback" *ngIf="registerForm.dirty || registerForm.touched">
<div *ngIf="registerForm.get('email')?.errors?.required">

Some files were not shown because too many files have changed in this diff Show More