Added MangaDex Api. Updated project structure.
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Search\MangaDex\SampleSearchResult.json" />
|
||||
<None Remove="WebCrawlers\MangaDex\MetadataSample-Feed.json" />
|
||||
<None Remove="WebCrawlers\MangaDex\MetadataSample.json" />
|
||||
<None Remove="WebCrawlers\Samples\MangaNato - Please Go Home, Akutsu-San!.htm" />
|
||||
<None Remove="Search\NatoManga\SampleSearchResult.json" />
|
||||
</ItemGroup>
|
||||
@@ -27,6 +29,8 @@
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Search\MangaDex\SampleSearchResult.json" />
|
||||
<EmbeddedResource Include="Search\NatoManga\SampleSearchResult.json" />
|
||||
<EmbeddedResource Include="WebCrawlers\MangaDex\MetadataSample-Feed.json" />
|
||||
<EmbeddedResource Include="WebCrawlers\MangaDex\MetadataSample.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -36,7 +36,7 @@ public class MangaDexSearchTests
|
||||
|
||||
IHttpService httpService = Substitute.For<IHttpService>();
|
||||
|
||||
httpService.GetStringAsync(Arg.Any<string>())
|
||||
httpService.GetStringAsync(Arg.Any<string>(), CancellationToken.None)
|
||||
.Returns(Task.FromResult(searchResultJson));
|
||||
|
||||
MangaDexSearchProvider searchProvider = new(httpService);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using MangaReader.Core.HttpService;
|
||||
using MangaReader.Core.Search;
|
||||
using MangaReader.Core.Search.NatoManga;
|
||||
using MangaReader.Core.Sources.NatoManga.Search;
|
||||
using MangaReader.Tests.Utilities;
|
||||
using NSubstitute;
|
||||
using Shouldly;
|
||||
@@ -31,7 +31,7 @@ public class NatoMangaWebSearchTests
|
||||
|
||||
IHttpService httpService = Substitute.For<IHttpService>();
|
||||
|
||||
httpService.GetStringAsync(Arg.Any<string>())
|
||||
httpService.GetStringAsync(Arg.Any<string>(), CancellationToken.None)
|
||||
.Returns(Task.FromResult(searchResultJson));
|
||||
|
||||
NatoMangaSearchProvider searchProvider = new(httpService);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
using MangaReader.Core.HttpService;
|
||||
using MangaReader.Core.Sources.MangaDex.Api;
|
||||
using MangaReader.Tests.Utilities;
|
||||
using NSubstitute;
|
||||
using Shouldly;
|
||||
|
||||
namespace MangaReader.Tests.WebCrawlers.MangaDex;
|
||||
|
||||
public class MangaDexMetadataTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Get_Manga_Metadata()
|
||||
{
|
||||
string resourceName = "MangaReader.Tests.WebCrawlers.MangaDex.MetadataSample.json";
|
||||
string searchResultJson = await ResourceHelper.ReadJsonResourceAsync(resourceName);
|
||||
|
||||
IHttpService httpService = Substitute.For<IHttpService>();
|
||||
|
||||
httpService.GetStringAsync(Arg.Any<string>(), CancellationToken.None)
|
||||
.Returns(Task.FromResult(searchResultJson));
|
||||
|
||||
MangaDexClient mangaDexClient = new(httpService);
|
||||
MangaDexResponse mangaDexResponse = await mangaDexClient.GetMangaAsync(Guid.NewGuid(), CancellationToken.None);
|
||||
|
||||
mangaDexResponse.Response.ShouldBe("entity");
|
||||
mangaDexResponse.ShouldBeOfType<MangaDexEntityResponse>();
|
||||
|
||||
MangaDexEntityResponse? mangaDexEntityResponse = mangaDexResponse as MangaDexEntityResponse;
|
||||
mangaDexEntityResponse.ShouldNotBeNull();
|
||||
mangaDexEntityResponse.Data.ShouldNotBeNull();
|
||||
mangaDexEntityResponse.Data.ShouldBeOfType<MangaEntity>();
|
||||
|
||||
MangaEntity? mangaEntity = mangaDexEntityResponse.Data as MangaEntity;
|
||||
mangaEntity.ShouldNotBeNull();
|
||||
mangaEntity.Attributes.Title.ShouldContainKey("en");
|
||||
mangaEntity.Attributes.Title["en"].ShouldBe("Gals Can’t Be Kind to Otaku!?");
|
||||
mangaEntity.Attributes.Description.ShouldContainKey("en");
|
||||
mangaEntity.Attributes.Description["en"].ShouldBe("Takuya Seo is an otaku who likes \"anime for girls\" and can't say he likes it out loud. One day, he hooks up with two gals from his class, Amane and Ijichi, but it seems that Amane is also an otaku...");
|
||||
mangaEntity.Attributes.Tags.Count.ShouldBe(5);
|
||||
mangaEntity.Attributes.Tags[0].Attributes.Name.ShouldContainKey("en");
|
||||
mangaEntity.Attributes.Tags[0].Attributes.Name["en"].ShouldBe("Romance");
|
||||
mangaEntity.Attributes.Tags[1].Attributes.Name.ShouldContainKey("en");
|
||||
mangaEntity.Attributes.Tags[1].Attributes.Name["en"].ShouldBe("Comedy");
|
||||
mangaEntity.Attributes.Tags[2].Attributes.Name.ShouldContainKey("en");
|
||||
mangaEntity.Attributes.Tags[2].Attributes.Name["en"].ShouldBe("School Life");
|
||||
mangaEntity.Attributes.Tags[3].Attributes.Name.ShouldContainKey("en");
|
||||
mangaEntity.Attributes.Tags[3].Attributes.Name["en"].ShouldBe("Slice of Life");
|
||||
mangaEntity.Attributes.Tags[4].Attributes.Name.ShouldContainKey("en");
|
||||
mangaEntity.Attributes.Tags[4].Attributes.Name["en"].ShouldBe("Gyaru");
|
||||
}
|
||||
}
|
||||
4165
MangaReader.Tests/WebCrawlers/MangaDex/MetadataSample-Feed.json
Normal file
4165
MangaReader.Tests/WebCrawlers/MangaDex/MetadataSample-Feed.json
Normal file
File diff suppressed because it is too large
Load Diff
185
MangaReader.Tests/WebCrawlers/MangaDex/MetadataSample.json
Normal file
185
MangaReader.Tests/WebCrawlers/MangaDex/MetadataSample.json
Normal file
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"result": "ok",
|
||||
"response": "entity",
|
||||
"data": {
|
||||
"id": "ee96e2b7-9af2-4864-9656-649f4d3b6fec",
|
||||
"type": "manga",
|
||||
"attributes": {
|
||||
"title": { "en": "Gals Can\u2019t Be Kind to Otaku!?" },
|
||||
"altTitles": [
|
||||
{ "ja": "\u30aa\u30bf\u30af\u306b\u512a\u3057\u3044\u30ae\u30e3\u30eb\u306f\u3044\u306a\u3044\uff01\uff1f" },
|
||||
{ "ja-ro": "Otaku ni Yasashii Gal wa Inai!?" },
|
||||
{ "ja-ro": "Otaku ni Yasashii Gyaru ha Inai!?" },
|
||||
{ "en": "Gal Can\u0027t Be Kind to Otaku!?" },
|
||||
{ "en": "Gals Can\u0027t Be Kind To A Geek!?" },
|
||||
{ "zh": "\u6ca1\u6709\u8fa3\u59b9\u4f1a\u5bf9\u963f\u5b85\u6e29\u67d4!?" },
|
||||
{ "pt-br": "Gals N\u00e3o Podem ser Gentis com Otakus!?" },
|
||||
{ "es-la": "\u00bf\u00a1Las Gals no pueden ser amables con los Otakus!?" },
|
||||
{ "vi": "Gyaru kh\u00f4ng th\u1ec3 t\u1eed t\u1ebf v\u1edbi Otaku \u01b0?" }
|
||||
],
|
||||
"description": {
|
||||
"en": "Takuya Seo is an otaku who likes \u0022anime for girls\u0022 and can\u0027t say he likes it out loud. One day, he hooks up with two gals from his class, Amane and Ijichi, but it seems that Amane is also an otaku...",
|
||||
"ja": "\u3042\u307e\u308a\u5927\u304d\u306a\u58f0\u3067\u597d\u304d\u3068\u8a00\u3048\u306a\u3044\u201c\u5973\u5150\u5411\u3051\u30a2\u30cb\u30e1\u201d\u304c\u597d\u304d\u306a\u30aa\u30bf\u30af \u702c\u5c3e\u5353\u4e5f\u3002\u3042\u308b\u65e5\u3001\u30af\u30e9\u30b9\u306e\u30ae\u30e3\u30eb \u5929\u97f3\u3055\u3093\u3068\u4f0a\u5730\u77e5\u3055\u3093\u306b\u7d61\u307e\u308c\u305f\u306e\u3060\u304c\u3001\u4f55\u3084\u3089\u5929\u97f3\u3055\u3093\u3082\u30aa\u30bf\u30af\u306e\u5302\u3044\u304c\u2026\uff1f",
|
||||
"vi": "M\u1ed9t anh b\u1ea1n trung b\u00ecnh Otaku th\u00edch anime d\u00e0nh cho b\u00e9 g\u00e1i, gi\u00e1p m\u1eb7t hai n\u00e0ng Gyaru xinh \u0111\u1eb9p n\u1ed5i ti\u1ebfng nh\u1ea5t tr\u01b0\u1eddng. Nh\u01b0ng kh\u00f4ng ch\u1ec9 c\u00f3 th\u1ebf, m\u1ed9t trong hai n\u1eef nh\u00e2n xinh \u0111\u1eb9p \u1ea5y c\u00f3 g\u00ec \u0111\u00f3...h\u01a1i otaku th\u00ec ph\u1ea3i...?",
|
||||
"es-la": "Takuya Seo es un otaku al que le gusta el \u0022anime para chicas\u0022 y no puede decir que le guste en voz alta. Un d\u00eda, se junta con dos chicas de su clase, Amane e Ijichi, pero parece que Amane tambi\u00e9n es una otaku...",
|
||||
"pt-br": "Takuya Seo \u00e9 um otaku que gosta de \u0022animes para garotinhas\u0022 e n\u00e3o pode dizer isso em voz alta. Um dia, ele conversa com duas gals da sua sala, Amane e Ijichi, mas parece que a Amane tamb\u00e9m \u00e9 uma otaku... Uma com\u00e9dia rom\u00e2ntica escolar onde o otaku conhece as gals que ele gosta!"
|
||||
},
|
||||
"isLocked": false,
|
||||
"links": {
|
||||
"al": "138380",
|
||||
"ap": "otaku-ni-yasashii-gal-wa-inai",
|
||||
"bw": "series\/339484",
|
||||
"kt": "69614",
|
||||
"mu": "188325",
|
||||
"amz": "https:\/\/www.amazon.co.jp\/dp\/B0BB2R5WVF",
|
||||
"cdj": "https:\/\/www.cdjapan.co.jp\/searchuni?q=\u30aa\u30bf\u30af\u306b\u512a\u3057\u3044\u30ae\u30e3\u30eb\u306f\u3044\u306a\u3044\uff01\uff1f+(Zenon+Comics)\u0026order=relasc",
|
||||
"ebj": "https:\/\/ebookjapan.yahoo.co.jp\/books\/690493\/",
|
||||
"mal": "144152",
|
||||
"raw": "https:\/\/comic-zenon.com\/episode\/3269754496560134267",
|
||||
"engtl": "https:\/\/x.com\/yenpress\/status\/1913348424826581290"
|
||||
},
|
||||
"originalLanguage": "ja",
|
||||
"lastVolume": "",
|
||||
"lastChapter": "",
|
||||
"publicationDemographic": "seinen",
|
||||
"status": "ongoing",
|
||||
"year": 2021,
|
||||
"contentRating": "safe",
|
||||
"tags": [
|
||||
{
|
||||
"id": "423e2eae-a7a2-4a8b-ac03-a8351462d71d",
|
||||
"type": "tag",
|
||||
"attributes": {
|
||||
"name": { "en": "Romance" },
|
||||
"description": {},
|
||||
"group": "genre",
|
||||
"version": 1
|
||||
},
|
||||
"relationships": []
|
||||
},
|
||||
{
|
||||
"id": "4d32cc48-9f00-4cca-9b5a-a839f0764984",
|
||||
"type": "tag",
|
||||
"attributes": {
|
||||
"name": { "en": "Comedy" },
|
||||
"description": {},
|
||||
"group": "genre",
|
||||
"version": 1
|
||||
},
|
||||
"relationships": []
|
||||
},
|
||||
{
|
||||
"id": "caaa44eb-cd40-4177-b930-79d3ef2afe87",
|
||||
"type": "tag",
|
||||
"attributes": {
|
||||
"name": { "en": "School Life" },
|
||||
"description": {},
|
||||
"group": "theme",
|
||||
"version": 1
|
||||
},
|
||||
"relationships": []
|
||||
},
|
||||
{
|
||||
"id": "e5301a23-ebd9-49dd-a0cb-2add944c7fe9",
|
||||
"type": "tag",
|
||||
"attributes": {
|
||||
"name": { "en": "Slice of Life" },
|
||||
"description": {},
|
||||
"group": "genre",
|
||||
"version": 1
|
||||
},
|
||||
"relationships": []
|
||||
},
|
||||
{
|
||||
"id": "fad12b5e-68ba-460e-b933-9ae8318f5b65",
|
||||
"type": "tag",
|
||||
"attributes": {
|
||||
"name": { "en": "Gyaru" },
|
||||
"description": {},
|
||||
"group": "theme",
|
||||
"version": 1
|
||||
},
|
||||
"relationships": []
|
||||
}
|
||||
],
|
||||
"state": "published",
|
||||
"chapterNumbersResetOnNewVolume": false,
|
||||
"createdAt": "2022-03-08T07:41:47+00:00",
|
||||
"updatedAt": "2025-04-19T23:05:17+00:00",
|
||||
"version": 44,
|
||||
"availableTranslatedLanguages": [ "it", "es-la", "en", "id", "fr", "vi", "pt-br" ],
|
||||
"latestUploadedChapter": "9e8f9776-a8bf-4118-83df-f0d086479d64"
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"id": "518965e7-c26c-4fd9-881c-f7ce0e78323d",
|
||||
"type": "author",
|
||||
"attributes": {
|
||||
"name": "Norishiro-chan",
|
||||
"imageUrl": null,
|
||||
"biography": { "en": "Name (in native language)\n\u306e\u308a\u3057\u308d\u3061\u3083\u3093" },
|
||||
"twitter": "https:\/\/twitter.com\/norishirochan",
|
||||
"pixiv": "https:\/\/www.pixiv.net\/en\/users\/821541",
|
||||
"melonBook": null,
|
||||
"fanBox": null,
|
||||
"booth": null,
|
||||
"namicomi": null,
|
||||
"nicoVideo": null,
|
||||
"skeb": null,
|
||||
"fantia": null,
|
||||
"tumblr": null,
|
||||
"youtube": null,
|
||||
"weibo": null,
|
||||
"naver": null,
|
||||
"website": null,
|
||||
"createdAt": "2021-10-10T03:41:31+00:00",
|
||||
"updatedAt": "2024-08-13T17:35:37+00:00",
|
||||
"version": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "767b8851-6060-478a-a23e-f819fec0fbf2",
|
||||
"type": "artist",
|
||||
"attributes": {
|
||||
"name": "Sakana Uozimi",
|
||||
"imageUrl": null,
|
||||
"biography": { "en": "Name (in native language)\n\u9b5a\u4f4f\u3055\u304b\u306a" },
|
||||
"twitter": "https:\/\/twitter.com\/namekyunta",
|
||||
"pixiv": "https:\/\/www.pixiv.net\/en\/users\/468508",
|
||||
"melonBook": null,
|
||||
"fanBox": null,
|
||||
"booth": null,
|
||||
"namicomi": null,
|
||||
"nicoVideo": null,
|
||||
"skeb": null,
|
||||
"fantia": null,
|
||||
"tumblr": null,
|
||||
"youtube": null,
|
||||
"weibo": null,
|
||||
"naver": null,
|
||||
"website": "https:\/\/galleria.emotionflow.com\/11070\/",
|
||||
"createdAt": "2022-03-08T07:36:27+00:00",
|
||||
"updatedAt": "2023-11-27T23:10:41+00:00",
|
||||
"version": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "a06943fd-6309-49a8-a66a-8df0f6dc41eb",
|
||||
"type": "cover_art",
|
||||
"attributes": {
|
||||
"description": "Volume 9 Cover from BookLive",
|
||||
"volume": "9",
|
||||
"fileName": "6b3073de-bb65-4723-8113-6068bf8c6eb4.jpg",
|
||||
"locale": "ja",
|
||||
"createdAt": "2025-02-20T11:59:45+00:00",
|
||||
"updatedAt": "2025-02-20T11:59:45+00:00",
|
||||
"version": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "6c0a87bf-3adb-4854-a4a6-d5c358b73d21",
|
||||
"type": "creator"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using MangaReader.Core.WebCrawlers.NatoManga;
|
||||
using MangaReader.Core.Sources.NatoManga.Metadata;
|
||||
using Shouldly;
|
||||
|
||||
namespace MangaReader.Tests.WebCrawlers.NatoManga;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using MangaReader.Core.WebCrawlers;
|
||||
using MangaReader.Core.WebCrawlers.MangaNato;
|
||||
using MangaReader.Core.Metadata;
|
||||
using MangaReader.Core.Sources.MangaNato.Metadata;
|
||||
using Shouldly;
|
||||
|
||||
namespace MangaReader.Tests.WebCrawlers;
|
||||
|
||||
Reference in New Issue
Block a user