Add project files.

This commit is contained in:
2025-05-21 19:39:09 -04:00
parent 7d2b71fe95
commit ec1713c95f
27 changed files with 5843 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<None Remove="WebCrawlers\Samples\MangaNato - Please Go Home, Akutsu-San!.htm" />
<None Remove="WebSearch\NatoManga\SampleSearchResult.json" />
</ItemGroup>
<ItemGroup>
<Content Include="WebCrawlers\NatoManga\SampleMangaPage.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="WebCrawlers\Samples\MangaNato - Please Go Home, Akutsu-San!.htm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="WebSearch\NatoManga\SampleSearchResult.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="Shouldly" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MangaReader.Core\MangaReader.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,23 @@
using System.Reflection;
using System.Text;
namespace MangaReader.Tests.Utilities;
public static class ResourceHelper
{
/// <summary>
/// Reads an embedded JSON resource from the calling assembly.
/// </summary>
/// <param name="resourceName">The full resource name, e.g. "MyNamespace.Folder.sample.json".</param>
public static async Task<string> ReadJsonResourceAsync(string resourceName)
{
Assembly assmbly = Assembly.GetExecutingAssembly();
using Stream? stream = assmbly.GetManifestResourceStream(resourceName)
?? throw new FileNotFoundException($"Resource '{resourceName}' not found.");
using StreamReader reader = new(stream, Encoding.UTF8);
return await reader.ReadToEndAsync();
}
}

View File

@@ -0,0 +1,52 @@
using MangaReader.Core.WebCrawlers.NatoManga;
using Shouldly;
namespace MangaReader.Tests.WebCrawlers.NatoManga;
public class NatoMangaWebCrawlerTests
{
[Fact]
public void Get_Manga()
{
string sampleFilePath = Path.Combine(AppContext.BaseDirectory, "WebCrawlers", "NatoManga", "SampleMangaPage.html");
var webCrawler = new NatoMangaWebCrawler();
var manga = webCrawler.GetManga(sampleFilePath);
manga.ShouldNotBeNull();
manga.Title.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].Name.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].Name.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));
}
}

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,60 @@
using MangaReader.Core.WebCrawlers;
using MangaReader.Core.WebCrawlers.MangaNato;
using Shouldly;
namespace MangaReader.Tests.WebCrawlers;
public class UnitTest1
{
private readonly string samplesPath;
private readonly string mangaNatoSampleFilePath;
public UnitTest1()
{
samplesPath = Path.Combine(AppContext.BaseDirectory, "WebCrawlers", "Samples");
mangaNatoSampleFilePath = Path.Combine(samplesPath, "MangaNato - Please Go Home, Akutsu-San!.htm");
}
[Fact]
public void Get_Manga()
{
var webCrawler = new MangaNatoWebCrawler();
var manga = webCrawler.GetManga(mangaNatoSampleFilePath);
manga.ShouldNotBeNull();
manga.Title.ShouldBe("Please Go Home, Akutsu-San!");
manga.AlternateTitles.ShouldBe([
"Kaette kudasai! Akutsu-san",
"Yankee Musume",
"ヤンキー娘",
"帰ってください! 阿久津さん"]);
manga.Authors.ShouldBe(["Nagaoka Taichi"]);
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.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(236);
manga.Chapters[0].Url.ShouldBe("https://chapmanganato.to/manga-hf984788/chapter-186");
manga.Chapters[0].Number.ShouldBe(186);
manga.Chapters[0].Name.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].Name.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));
}
}

View File

@@ -0,0 +1,32 @@
using MangaReader.Core.HttpService;
using MangaReader.Core.WebSearch;
using MangaReader.Core.WebSearch.NatoManga;
using MangaReader.Tests.Utilities;
using NSubstitute;
using Shouldly;
namespace MangaReader.Tests.WebSearch.NatoManga;
public class NatoMangaWebSearchTests
{
[Fact]
public async Task Get_Search_Result()
{
string resourceName = "MangaReader.Tests.WebSearch.NatoManga.SampleSearchResult.json";
string searchResultJson = await ResourceHelper.ReadJsonResourceAsync(resourceName);
IHttpService httpService = Substitute.For<IHttpService>();
httpService.GetStringAsync(Arg.Any<string>())
.Returns(Task.FromResult(searchResultJson));
NatoMangaWebSearch webSearch = new(httpService);
MangaSearchResult[] searchResult = await webSearch.SearchAsync("Gals Can't Be Kind");
searchResult.Length.ShouldBe(2);
searchResult[0].Title.ShouldBe("Gal Can't Be Kind to Otaku!");
searchResult[1].Title.ShouldBe("Gal Cant Be Kind to Otaku!?");
searchResult[0].Url.ShouldBe("https://www.natomanga.com/manga/gal-can-t-be-kind-to-otaku");
searchResult[1].Url.ShouldBe("https://www.natomanga.com/manga/gal-cant-be-kind-to-otaku");
}
}

View File

@@ -0,0 +1,20 @@
[
{
"id": 51811,
"author": "Norishiro-chan, Sakana Uozumi",
"name": "Gal Can't Be Kind to Otaku!",
"chapterLatest": "Chapter 69",
"url": "https:\/\/www.natomanga.com\/manga\/gal-can-t-be-kind-to-otaku",
"thumb": "https:\/\/img-r1.2xstorage.com\/thumb\/gal-can-t-be-kind-to-otaku.webp",
"slug": "gal-can-t-be-kind-to-otaku"
},
{
"id": 38065,
"author": "Norishiro-chan,Sakana Uozimi",
"name": "Gal Can\u2019t Be Kind to Otaku!?",
"chapterLatest": "Chapter 69",
"url": "https:\/\/www.natomanga.com\/manga\/gal-cant-be-kind-to-otaku",
"thumb": "https:\/\/img-r1.2xstorage.com\/thumb\/gal-cant-be-kind-to-otaku.webp",
"slug": "gal-cant-be-kind-to-otaku"
}
]