Added abstraction layeer IHtmlLoader. Finished reorganizing test project folder structure.

This commit is contained in:
2025-06-09 00:09:59 -04:00
parent b5d22c3c7e
commit c26ed11bfc
30 changed files with 1966 additions and 132 deletions

View File

@@ -1,4 +1,4 @@
using MangaReader.Core.HttpService;
using MangaReader.Core.Http;
using MangaReader.Core.Sources.MangaDex.Api;
using MangaReader.Tests.Utilities;
using NSubstitute;

View File

@@ -229,23 +229,23 @@ public class MangaDexMetadataTests
SourceManga? sourceManga = await metadataProvider.GetMangaAsync("https://mangadex.org/title/ee96e2b7-9af2-4864-9656-649f4d3b6fec/gals-can-t-be-kind-to-otaku", CancellationToken.None);
sourceManga.ShouldNotBeNull();
sourceManga.Title.ShouldBe("Gals Cant Be Kind to Otaku!?");
sourceManga.Title.Name.ShouldBe("Gals Cant Be Kind to Otaku!?");
sourceManga.AlternateTitles.Count.ShouldBe(5);
sourceManga.AlternateTitles[0].Title.ShouldBe("オタクに優しいギャルはいない!?");
sourceManga.AlternateTitles[0].Name.ShouldBe("オタクに優しいギャルはいない!?");
sourceManga.AlternateTitles[0].Language.ShouldBe(Language.Japanese);
sourceManga.AlternateTitles[1].Title.ShouldBe("Otaku ni Yasashii Gal wa Inai!?");
sourceManga.AlternateTitles[1].Name.ShouldBe("Otaku ni Yasashii Gal wa Inai!?");
sourceManga.AlternateTitles[1].Language.ShouldBe(Language.Romaji);
sourceManga.AlternateTitles[2].Title.ShouldBe("Otaku ni Yasashii Gyaru ha Inai!?");
sourceManga.AlternateTitles[2].Name.ShouldBe("Otaku ni Yasashii Gyaru ha Inai!?");
sourceManga.AlternateTitles[2].Language.ShouldBe(Language.Romaji);
sourceManga.AlternateTitles[3].Title.ShouldBe("Gal Can't Be Kind to Otaku!?");
sourceManga.AlternateTitles[3].Name.ShouldBe("Gal Can't Be Kind to Otaku!?");
sourceManga.AlternateTitles[3].Language.ShouldBe(Language.English);
sourceManga.AlternateTitles[4].Title.ShouldBe("Gals Can't Be Kind To A Geek!?");
sourceManga.AlternateTitles[4].Name.ShouldBe("Gals Can't Be Kind To A Geek!?");
sourceManga.AlternateTitles[4].Language.ShouldBe(Language.English);
sourceManga.Genres.Count.ShouldBe(5);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,75 @@
using MangaReader.Core.Http;
using MangaReader.Core.Metadata;
using MangaReader.Core.Sources.MangaNato.Metadata;
using MangaReader.Tests.Utilities;
using NSubstitute;
using Shouldly;
using System.Data;
namespace MangaReader.Tests.Sources.MangaNato.Metadata;
public class MangaNatoMetadataTests
{
[Fact]
public async Task Get_Manga()
{
string mangaHtml = await ReadJsonResourceAsync("Manga-Response.html");
IHttpService httpService = Substitute.For<IHttpService>();
httpService.GetStringAsync(Arg.Any<string>(), CancellationToken.None)
.Returns(Task.FromResult(mangaHtml));
HtmlLoader htmlLoader = new(httpService);
MangaNatoWebCrawler webCrawler = new(htmlLoader);
SourceManga? manga = await webCrawler.GetMangaAsync("/test-url", CancellationToken.None);
manga.ShouldNotBeNull();
manga.Title.Name.ShouldBe("Please Go Home, Akutsu-San!");
manga.AlternateTitles.Select(x => x.Name).ShouldBe([
"Kaette kudasai! Akutsu-san",
"Yankee Musume",
"ヤンキー娘",
"帰ってください! 阿久津さん"]);
SourceMangaContributor[] expectedContributors =
[
new() { Name = "Nagaoka Taichi", Role = SourceMangaContributorRole.Author }
];
manga.Contributors.ShouldBeEquivalentTo(expectedContributors);
manga.Status.ShouldBe(MangaStatus.Ongoing);
manga.Genres.ShouldBe(["Comedy", "Romance", "School life"]);
manga.UpdateDate.ShouldBe(new DateTime(2024, 9, 26, 0, 12, 0));
manga.Views.ShouldBe(93_300_000);
manga.RatingPercent.ShouldBe(97);
manga.Votes.ShouldBe(15979);
//manga.Description.ShouldStartWith("Ooyama-kun normally doesnt get involved with Akutsu-san, a delinquent girl in his class");
manga.Description?.Name.ShouldStartWith("Ooyama-kun normally doesnt get involved with Akutsu-san, a delinquent girl in his class");
manga.Description?.Name.ShouldEndWith("Artist's Pixiv: https://www.pixiv.net/member.php?id=133935");
manga.Chapters.Count.ShouldBe(236);
manga.Chapters[0].Url.ShouldBe("https://chapmanganato.to/manga-hf984788/chapter-186");
manga.Chapters[0].Number.ShouldBe(186);
manga.Chapters[0].Title.ShouldBe("Chapter 186");
manga.Chapters[0].Views.ShouldBe(37_900);
manga.Chapters[0].UploadDate.ShouldBe(new DateTime(2024, 9, 26, 0, 9, 0));
manga.Chapters[235].Url.ShouldBe("https://chapmanganato.to/manga-hf984788/chapter-0.1");
manga.Chapters[235].Number.ShouldBe(0.1f);
manga.Chapters[235].Title.ShouldBe("Vol.0 Chapter : Oneshot");
manga.Chapters[235].Views.ShouldBe(232_200);
manga.Chapters[235].UploadDate.ShouldBe(new DateTime(2021, 8, 24, 1, 8, 0));
}
private static async Task<string> ReadJsonResourceAsync(string resourceName)
{
return await ResourceHelper.ReadJsonResourceAsync($"MangaReader.Tests.Sources.MangaNato.Metadata.{resourceName}");
}
}

View File

@@ -1,4 +1,4 @@
using MangaReader.Core.HttpService;
using MangaReader.Core.Http;
using MangaReader.Core.Sources.NatoManga.Api;
using MangaReader.Tests.Utilities;
using NSubstitute;
@@ -34,6 +34,9 @@ public class NatoMangaClientTests
httpService.GetStringAsync(Arg.Any<string>(), CancellationToken.None)
.Returns(Task.FromResult(searchResultJson));
httpService.GetStringAsync(Arg.Any<string>(), Arg.Any<IDictionary<string,string>>(), CancellationToken.None)
.Returns(Task.FromResult(searchResultJson));
NatoMangaClient natoMangaClient = new(httpService);
NatoMangaSearchResult[] searchResults = await natoMangaClient.SearchAsync("Gal Can't Be Kind", CancellationToken.None);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,68 @@
using MangaReader.Core.Http;
using MangaReader.Core.Metadata;
using MangaReader.Core.Sources.NatoManga.Metadata;
using MangaReader.Tests.Utilities;
using NSubstitute;
using Shouldly;
namespace MangaReader.Tests.Sources.NatoManga.Metadata;
public class NatoMangaWebCrawlerTests
{
[Fact]
public async Task Get_Manga()
{
string mangaHtml = await ReadJsonResourceAsync("Manga-Response.html");
IHttpService httpService = Substitute.For<IHttpService>();
httpService.GetStringAsync(Arg.Any<string>(), CancellationToken.None)
.Returns(Task.FromResult(mangaHtml));
HtmlLoader htmlLoader = new(httpService);
NatoMangaWebCrawler webCrawler = new(htmlLoader);
SourceManga? manga = await webCrawler.GetMangaAsync("/test-url", CancellationToken.None);
manga.ShouldNotBeNull();
manga.Title.Name.ShouldBe("Gal Cant Be Kind to Otaku!?");
//manga.AlternateTitles.ShouldBe([
// "Kaette kudasai! Akutsu-san",
// "Yankee Musume",
// "ヤンキー娘",
// "帰ってください! 阿久津さん"]);
//manga.Authors.ShouldBe(["Nagaoka Taichi"]);
//manga.Status.ShouldBe(MangaStatus.Ongoing);
manga.Genres.ShouldBe(["Comedy", "Harem", "Romance", "School life", "Seinen", "Slice of life"]);
//manga.UpdateDate.ShouldBe(new DateTime(2024, 9, 26, 0, 12, 0));
//manga.Views.ShouldBe(93_300_000);
//manga.RatingPercent.ShouldBe(97);
//manga.Votes.ShouldBe(15979);
////manga.Description.ShouldStartWith("Ooyama-kun normally doesnt get involved with Akutsu-san, a delinquent girl in his class");
//manga.Description.ShouldStartWith("Ooyama-kun normally doesnt get involved with Akutsu-san, a delinquent girl in his class");
//manga.Description.ShouldEndWith("Artist's Pixiv: https://www.pixiv.net/member.php?id=133935");
manga.Chapters.Count.ShouldBe(83);
manga.Chapters[0].Url.ShouldBe("https://www.natomanga.com/manga/gal-cant-be-kind-to-otaku/chapter-69");
manga.Chapters[0].Number.ShouldBe(69);
manga.Chapters[0].Title.ShouldBe("Chapter 69");
manga.Chapters[0].Views.ShouldBe(8146);
//manga.Chapters[0].UploadDate.ShouldBe(new DateTime(2025, 4, 23, 17, 17, 0));
//manga.Chapters[235].URL.ShouldBe("https://chapmanganato.to/manga-hf984788/chapter-0.1");
//manga.Chapters[235].Number.ShouldBe(0.1f);
//manga.Chapters[235].Title.ShouldBe("Vol.0 Chapter : Oneshot");
//manga.Chapters[235].Views.ShouldBe(232_200);
//manga.Chapters[235].UploadDate.ShouldBe(new DateTime(2021, 8, 24, 1, 8, 0));
}
private static async Task<string> ReadJsonResourceAsync(string resourceName)
{
return await ResourceHelper.ReadJsonResourceAsync($"MangaReader.Tests.Sources.NatoManga.Metadata.{resourceName}");
}
}