mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-06-03 21:54:47 -04:00
* Moved libraryType into chapter info * Fixed a bug where you could not reset cover on a series * Patched in relevant changes from another polish branch * Refactored invite user setup to shift the checking for accessibility to the backend and always show the link. This will help with users who have some unique setups in docker. * Refactored invite user to always print the url to setup a new account. * Single page renderer uses canvasImage rather than re-requesting and relying on cache * Fixed a rendering issue where fit to split on single on a cover wouldn't force width scaling just for that image * Fixed a rendering bug with split image functionality * Added title to copy button * Fixed a bug in GetContinuePoint when a chapter is added to an already read volume and a new chapter is added loose leaf. The loose leaf would be prioritized over the volume chapter. Refactored 2 methods from controller into service and unit tested. * Fixed a bug on opening a volume in series detail that had a chapter added to it after the volume (0 chapter) was read would cause a loose leaf chapter to be opened. * Added mark as read/actionables on Files in volume detail modal. Fixed a bug where we were showing the wrong page count in a volume detail modal. * Removed OnDeck page and replaced it with a pre-filtered All-Series. Hooked up the ability to pass read state to the filter via query params. Fixed some spacing on filter post bootstrap update. * Fixed up some poor documentation on FilterDto. * Some string equals enhancements to reduce extra allocations * Fixed an issue when trying to download via a url, to remove query parameters to get the format * Made an optimization to Normalize method to reduce memory pressure by 100MB over the course of a scan (16k files) * Adjusted the styles on dashboard for first time setup and used a routerlink rather than href to avoid a fresh load. * Use framgment on router link * Hooked in the ability to search by release year (along with series optionally) and series will be returned back. * Fixed a bug in the filter format code where it was sending the wrong type * Only show clear all on typeahead when there are at least one selected item * Cleaned up the styles of the styles of the typeahead * Removed some dead code * Implemented the ability to filter against a series name. * Fixed filter top offset * Ensure that when we add or remove libraries, the side nav of users gets updated. * Tweaked the width on the mobile side nav * Close side nav on clicking overlay on mobile viewport * Don't show a pointer if the carousel section title is not actually selectable * Removed the User profile on the side nav so home is always first. Tweaked styles to match * Fixed up some poor documentation on FilterDto. * Fixed a bug where Latest read date wasn't being set due to an early short circuit. * When sending the chapter file, format the title of the FeedEntry more like Series Detail. * Removed dead code
233 lines
9.0 KiB
C#
233 lines
9.0 KiB
C#
using System.Linq;
|
|
using Xunit;
|
|
using static API.Parser.Parser;
|
|
|
|
namespace API.Tests.Parser
|
|
{
|
|
public class ParserTests
|
|
{
|
|
[Theory]
|
|
[InlineData("Joe Shmo, Green Blue", "Joe Shmo, Green Blue")]
|
|
[InlineData("Shmo, Joe", "Shmo, Joe")]
|
|
[InlineData(" Joe Shmo ", "Joe Shmo")]
|
|
public void CleanAuthorTest(string input, string expected)
|
|
{
|
|
Assert.Equal(expected, CleanAuthor(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("", "")]
|
|
[InlineData("DEAD Tube Prologue", "DEAD Tube Prologue")]
|
|
[InlineData("DEAD Tube Prologue SP01", "DEAD Tube Prologue")]
|
|
[InlineData("DEAD_Tube_Prologue SP01", "DEAD Tube Prologue")]
|
|
public void CleanSpecialTitleTest(string input, string expected)
|
|
{
|
|
Assert.Equal(expected, CleanSpecialTitle(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("Beastars - SP01", true)]
|
|
[InlineData("Beastars SP01", true)]
|
|
[InlineData("Beastars Special 01", false)]
|
|
[InlineData("Beastars Extra 01", false)]
|
|
[InlineData("Batman Beyond - Return of the Joker (2001) SP01", true)]
|
|
public void HasSpecialTest(string input, bool expected)
|
|
{
|
|
Assert.Equal(expected, HasSpecialMarker(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("0001", "1")]
|
|
[InlineData("1", "1")]
|
|
[InlineData("0013", "13")]
|
|
public void RemoveLeadingZeroesTest(string input, string expected)
|
|
{
|
|
Assert.Equal(expected, RemoveLeadingZeroes(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("1", "001")]
|
|
[InlineData("10", "010")]
|
|
[InlineData("100", "100")]
|
|
public void PadZerosTest(string input, string expected)
|
|
{
|
|
Assert.Equal(expected, PadZeros(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("Hello_I_am_here", false, "Hello I am here")]
|
|
[InlineData("Hello_I_am_here ", false, "Hello I am here")]
|
|
[InlineData("[ReleaseGroup] The Title", false, "The Title")]
|
|
[InlineData("[ReleaseGroup]_The_Title", false, "The Title")]
|
|
[InlineData("-The Title", false, "The Title")]
|
|
[InlineData("- The Title", false, "The Title")]
|
|
[InlineData("[Suihei Kiki]_Kasumi_Otoko_no_Ko_[Taruby]_v1.1", false, "Kasumi Otoko no Ko v1.1")]
|
|
[InlineData("Batman - Detective Comics - Rebirth Deluxe Edition Book 04 (2019) (digital) (Son of Ultron-Empire)", true, "Batman - Detective Comics - Rebirth Deluxe Edition")]
|
|
public void CleanTitleTest(string input, bool isComic, string expected)
|
|
{
|
|
Assert.Equal(expected, CleanTitle(input, isComic));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("src: url(fonts/AvenirNext-UltraLight.ttf)", true)]
|
|
[InlineData("src: url(ideal-sans-serif.woff)", true)]
|
|
[InlineData("src: local(\"Helvetica Neue Bold\")", true)]
|
|
[InlineData("src: url(\"/fonts/OpenSans-Regular-webfont.woff2\")", true)]
|
|
[InlineData("src: local(\"/fonts/OpenSans-Regular-webfont.woff2\")", true)]
|
|
[InlineData("src: url(data:application/x-font-woff", false)]
|
|
public void FontCssRewriteMatches(string input, bool expectedMatch)
|
|
{
|
|
Assert.Equal(expectedMatch, FontSrcUrlRegex.Matches(input).Count > 0);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("src: url(fonts/AvenirNext-UltraLight.ttf)", new [] {"src: url(", "fonts/AvenirNext-UltraLight.ttf", ")"})]
|
|
[InlineData("src: url(ideal-sans-serif.woff)", new [] {"src: url(", "ideal-sans-serif.woff", ")"})]
|
|
[InlineData("src: local(\"Helvetica Neue Bold\")", new [] {"src: local(\"", "Helvetica Neue Bold", "\")"})]
|
|
[InlineData("src: url(\"/fonts/OpenSans-Regular-webfont.woff2\")", new [] {"src: url(\"", "/fonts/OpenSans-Regular-webfont.woff2", "\")"})]
|
|
[InlineData("src: local(\"/fonts/OpenSans-Regular-webfont.woff2\")", new [] {"src: local(\"", "/fonts/OpenSans-Regular-webfont.woff2", "\")"})]
|
|
public void FontCssCorrectlySeparates(string input, string[] expected)
|
|
{
|
|
Assert.Equal(expected, FontSrcUrlRegex.Match(input).Groups.Values.Select(g => g.Value).Where((_, i) => i > 0).ToArray());
|
|
}
|
|
|
|
|
|
[Theory]
|
|
[InlineData("test.cbz", true)]
|
|
[InlineData("test.cbr", true)]
|
|
[InlineData("test.zip", true)]
|
|
[InlineData("test.rar", true)]
|
|
[InlineData("test.rar.!qb", false)]
|
|
[InlineData("[shf-ma-khs-aqs]negi_pa_vol15007.jpg", false)]
|
|
public void IsArchiveTest(string input, bool expected)
|
|
{
|
|
Assert.Equal(expected, IsArchive(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("test.epub", true)]
|
|
[InlineData("test.pdf", true)]
|
|
[InlineData("test.mobi", false)]
|
|
[InlineData("test.djvu", false)]
|
|
[InlineData("test.zip", false)]
|
|
[InlineData("test.rar", false)]
|
|
[InlineData("test.epub.!qb", false)]
|
|
[InlineData("[shf-ma-khs-aqs]negi_pa_vol15007.ebub", false)]
|
|
public void IsBookTest(string input, bool expected)
|
|
{
|
|
Assert.Equal(expected, IsBook(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("test.epub", true)]
|
|
[InlineData("test.EPUB", true)]
|
|
[InlineData("test.mobi", false)]
|
|
[InlineData("test.epub.!qb", false)]
|
|
[InlineData("[shf-ma-khs-aqs]negi_pa_vol15007.ebub", false)]
|
|
public void IsEpubTest(string input, bool expected)
|
|
{
|
|
Assert.Equal(expected, IsEpub(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("12-14", 12)]
|
|
[InlineData("24", 24)]
|
|
[InlineData("18-04", 4)]
|
|
[InlineData("18-04.5", 4.5)]
|
|
[InlineData("40", 40)]
|
|
[InlineData("40a-040b", 0)]
|
|
[InlineData("40.1_a", 0)]
|
|
public void MinimumNumberFromRangeTest(string input, float expected)
|
|
{
|
|
Assert.Equal(expected, MinimumNumberFromRange(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("12-14", 14)]
|
|
[InlineData("24", 24)]
|
|
[InlineData("18-04", 18)]
|
|
[InlineData("18-04.5", 18)]
|
|
[InlineData("40", 40)]
|
|
[InlineData("40a-040b", 0)]
|
|
[InlineData("40.1_a", 0)]
|
|
public void MaximumNumberFromRangeTest(string input, float expected)
|
|
{
|
|
Assert.Equal(expected, MaximumNumberFromRange(input));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("Darker Than Black", "darkerthanblack")]
|
|
[InlineData("Darker Than Black - Something", "darkerthanblacksomething")]
|
|
[InlineData("Darker Than_Black", "darkerthanblack")]
|
|
[InlineData("Citrus", "citrus")]
|
|
[InlineData("Citrus+", "citrus+")]
|
|
[InlineData("Again!!!!", "again")]
|
|
[InlineData("카비타", "카비타")]
|
|
[InlineData("06", "06")]
|
|
[InlineData("", "")]
|
|
public void NormalizeTest(string input, string expected)
|
|
{
|
|
Assert.Equal(expected, Normalize(input));
|
|
}
|
|
|
|
|
|
|
|
[Theory]
|
|
[InlineData("test.jpg", true)]
|
|
[InlineData("test.jpeg", true)]
|
|
[InlineData("test.png", true)]
|
|
[InlineData(".test.jpg", false)]
|
|
[InlineData("!test.jpg", true)]
|
|
[InlineData("test.webp", true)]
|
|
public void IsImageTest(string filename, bool expected)
|
|
{
|
|
Assert.Equal(expected, IsImage(filename));
|
|
}
|
|
|
|
|
|
|
|
[Theory]
|
|
[InlineData("Love Hina - Special.jpg", false)]
|
|
[InlineData("folder.jpg", true)]
|
|
[InlineData("DearS_v01_cover.jpg", true)]
|
|
[InlineData("DearS_v01_covers.jpg", false)]
|
|
[InlineData("!cover.jpg", true)]
|
|
[InlineData("cover.jpg", true)]
|
|
[InlineData("cover.png", true)]
|
|
[InlineData("ch1/cover.png", true)]
|
|
[InlineData("ch1/backcover.png", false)]
|
|
[InlineData("backcover.png", false)]
|
|
public void IsCoverImageTest(string inputPath, bool expected)
|
|
{
|
|
Assert.Equal(expected, IsCoverImage(inputPath));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("__MACOSX/Love Hina - Special.jpg", true)]
|
|
[InlineData("TEST/Love Hina - Special.jpg", false)]
|
|
[InlineData("__macosx/Love Hina/", false)]
|
|
[InlineData("MACOSX/Love Hina/", false)]
|
|
[InlineData("._Love Hina/Love Hina/", true)]
|
|
[InlineData("@Recently-Snapshot/Love Hina/", true)]
|
|
[InlineData("@recycle/Love Hina/", true)]
|
|
[InlineData("@recycle/Love Hina/", true)]
|
|
[InlineData("E:/Test/__MACOSX/Love Hina/", true)]
|
|
public void HasBlacklistedFolderInPathTest(string inputPath, bool expected)
|
|
{
|
|
Assert.Equal(expected, HasBlacklistedFolderInPath(inputPath));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/manga/1/1/1", "/manga/1/1/1")]
|
|
[InlineData("/manga/1/1/1.jpg", "/manga/1/1/1.jpg")]
|
|
[InlineData(@"/manga/1/1\1.jpg", @"/manga/1/1/1.jpg")]
|
|
[InlineData("/manga/1/1//1", "/manga/1/1//1")]
|
|
[InlineData("/manga/1\\1\\1", "/manga/1/1/1")]
|
|
[InlineData("C:/manga/1\\1\\1.jpg", "C:/manga/1/1/1.jpg")]
|
|
public void NormalizePathTest(string inputPath, string expected)
|
|
{
|
|
Assert.Equal(expected, NormalizePath(inputPath));
|
|
}
|
|
}
|
|
}
|