Skip to content

Commit

Permalink
#1-2 テストを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
miyaji255 committed Mar 16, 2024
1 parent f1579e5 commit 0671402
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 46 deletions.
2 changes: 1 addition & 1 deletion Epub/KoeBook.Epub/Models/Chapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public class Chapter
{
public List<Section> Sections { get; } = [];
public List<Section> Sections { get; init; } = [];
public string? Title { get; set; }
}
27 changes: 13 additions & 14 deletions Epub/KoeBook.Epub/Services/ScrapingNaroService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public async ValueTask<EpubDocument> ScrapingAsync(string url, string coverFileP
return document;
}

private async ValueTask<NovelInfo> GetNovelInfoAsync(string ncode, CancellationToken ct)
internal async ValueTask<NovelInfo> GetNovelInfoAsync(string ncode, CancellationToken ct)
{
// APIを利用して、noveltype : 連載(1)か短編(2)か、general_all_no : 全掲載部分数
var request = new HttpRequestMessage(System.Net.Http.HttpMethod.Get, $"https://api.syosetu.com/novelapi/api/?of=ga-nt-n&out=json&ncode={ncode}");
Expand Down Expand Up @@ -130,23 +130,22 @@ private async ValueTask<NovelInfo> GetNovelInfoAsync(string ncode, CancellationT
return novelInfo;
}

private static string GetNcode(string url)
internal static string GetNcode(string url)
{
var uri = new Uri(url);
var uri = new Uri(url, new UriCreationOptions() { DangerousDisablePathAndQueryCanonicalization = true});
if (uri.GetLeftPart(UriPartial.Authority) != "https://ncode.syosetu.com")
throw new EbookException(ExceptionType.InvalidUrl);

switch (uri.Segments)
return uri.Segments switch
{
case [var ncode] when IsAscii(ncode): // https://ncode.syosetu.com/n0000a/ のとき
return ncode;
case [var ncode, var num] when IsAscii(ncode) && num.All(char.IsAsciiDigit): // https://ncode.syosetu.com/n0000a/12 のとき
return ncode;
case ["novelview", "infotop", "ncode", var ncode] when IsAscii(ncode): // https://ncode.syosetu.com/novelview/infotop/ncode/n0000a/ のとき
return ncode;
}

throw new EbookException(ExceptionType.InvalidUrl);
// https://ncode.syosetu.com/n0000a/ のとき
["/", var ncode] when IsAscii(ncode) => ncode.TrimEnd('/'),
// https://ncode.syosetu.com/n0000a/12 のとき
["/", var ncode, var num] when IsAscii(ncode) && num.TrimEnd('/').All(char.IsAsciiDigit) => ncode.TrimEnd('/'),
// https://ncode.syosetu.com/novelview/infotop/ncode/n0000a/ のとき
["/", "novelview/", "infotop/", "ncode/", var ncode] when IsAscii(ncode) => ncode.TrimEnd('/'),
_ => throw new EbookException(ExceptionType.InvalidUrl),
};

static bool IsAscii(string str)
=> str.All(char.IsAscii);
Expand All @@ -160,7 +159,7 @@ private record NaroResponseFirstElement(int Allcount);
/// <param name="Ncode">ncode</param>
/// <param name="Noveltype">1: 連載, 2: 短編</param>
/// <param name="GeneralAllNo">話数 (短編の場合は1)</param>
private record NovelInfo(
internal record NovelInfo(
[property: JsonRequired] string Ncode,
[property: JsonRequired] int Noveltype,
[property: JsonPropertyName("general_all_no"), JsonRequired] int GeneralAllNo)
Expand Down
3 changes: 2 additions & 1 deletion KoeBook.Core/EbookException.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using FastEnumUtility;

namespace KoeBook.Core;

Expand All @@ -13,7 +14,7 @@ public class EbookException : Exception

public EbookException(ExceptionType exceptionType, string? message = null, Exception? innerException = null) : base(null, innerException)
{
Message = message;
Message = message ?? exceptionType.GetEnumMemberValue();
ExceptionType = exceptionType;
}

Expand Down
18 changes: 18 additions & 0 deletions KoeBook.Test/DiTestBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using KoeBook.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace KoeBook.Test;

public class DiTestBase
{
protected IHost Host { get; } = Microsoft.Extensions.Hosting.Host
.CreateDefaultBuilder()
.ConfigureCore()
.Build();

protected T GetService<T>() where T: notnull
{
return Host.Services.GetRequiredService<T>();
}
}
47 changes: 47 additions & 0 deletions KoeBook.Test/Epub/ScrapingNaroServiceTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using KoeBook.Core;
using KoeBook.Epub.Contracts.Services;
using KoeBook.Epub.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace KoeBook.Test.Epub;

public class ScrapingNaroServiceTest : DiTestBase
{
private readonly ScrapingNaroService _scrapingNaroService;

public ScrapingNaroServiceTest()
{
_scrapingNaroService = Host.Services
.GetServices<IScrapingService>()
.OfType<ScrapingNaroService>()
.Single();
}

[Theory]
[InlineData("https://ncode.syosetu.com/n0000a", "n0000a")]
[InlineData("https://ncode.syosetu.com/n0000a/", "n0000a")]
[InlineData("https://ncode.syosetu.com/n0000a/123", "n0000a")]
[InlineData("https://ncode.syosetu.com/n0000a/123/", "n0000a")]
[InlineData("https://ncode.syosetu.com/novelview/infotop/ncode/n0000a", "n0000a")]
[InlineData("https://ncode.syosetu.com/novelview/infotop/ncode/n0000a/", "n0000a")]
public void GetNcode_Success(string url, string? expected)
{
var result = ScrapingNaroService.GetNcode(url);

Assert.Equal(expected, result);
}

[Theory]
[InlineData("https://ncode.syosetu.com/n0000あ")]
[InlineData("https://ncode.syosetu.com/n0000あ/")]
[InlineData("https://ncode.syosetu.com/n0000aあ/123")]
[InlineData("https://ncode.syosetu.com/n0000aあ/123/")]
public void GetNcode_Error(string url)
{
var exception = Record.Exception(() => ScrapingNaroService.GetNcode(url));

var ebookException = Assert.IsType<EbookException>(exception);
Assert.Equal(ExceptionType.InvalidUrl, ebookException.ExceptionType);
}
}
4 changes: 4 additions & 0 deletions KoeBook.Test/KoeBook.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
Expand All @@ -25,4 +26,7 @@
<Using Include="Xunit" />
</ItemGroup>

<ItemGroup>
<Compile Include="../KoeBook/Startup.cs" />
</ItemGroup>
</Project>
31 changes: 1 addition & 30 deletions KoeBook/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,9 @@ public App()
Host = Microsoft.Extensions.Hosting.Host
.CreateDefaultBuilder()
.UseContentRoot(AppContext.BaseDirectory)
.ConfigureCore()
.ConfigureServices((context, services) =>
{
// System
services.AddSingleton(TimeProvider.System);
// Default Activation Handler
services.AddTransient<ActivationHandler<LaunchActivatedEventArgs>, DefaultActivationHandler>();
Expand All @@ -85,33 +83,6 @@ public App()
services.AddSingleton<IDialogService, DialogService>();
services.AddSingleton<IDisplayStateChangeService, DisplayStateChangeService>();
// Core Services
services.AddHttpClient()
.ConfigureHttpClientDefaults(builder =>
{
builder.SetHandlerLifetime(TimeSpan.FromMinutes(5));
});
services.AddSingleton<IFileService, FileService>();
services.AddSingleton<ISecretSettingsService, SecretSettingsService>();
services.AddSingleton<IStyleBertVitsClientService, StyleBertVitsClientService>();
services.AddSingleton<ISoundGenerationSelectorService, SoundGenerationSelectorService>();
services.AddSingleton<ISoundGenerationService, SoundGenerationService>();
services.AddSingleton<IEpubGenerateService, EpubGenerateService>();
services.AddSingleton<IEpubDocumentStoreService, EpubDocumentStoreService>();
services.AddSingleton<IAnalyzerService, AnalyzerService>();
services.AddSingleton<ILlmAnalyzerService, ChatGptAnalyzerService>();
services.AddSingleton<OpenAI.Interfaces.IOpenAIService, MyOpenAiService>();
// Epub Services
services
.AddKeyedSingleton<IScrapingClientService, ScrapingClientService>(nameof(ScrapingAozoraService))
.AddKeyedSingleton<IScrapingClientService, ScrapingClientService>(nameof(ScrapingNaroService))
.AddSingleton<IScraperSelectorService, ScraperSelectorService>()
.AddSingleton<IScrapingService, ScrapingAozoraService>()
.AddSingleton<IScrapingService, ScrapingNaroService>();
services.AddSingleton<IEpubCreateService, EpubCreateService>();
services.AddSingleton<IFileExtensionService, FileExtensionService>();
// Views and ViewModels
services.AddTransient<SettingsViewModel>();
services.AddTransient<SettingsPage>();
Expand Down
52 changes: 52 additions & 0 deletions KoeBook/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using KoeBook.Core.Contracts.Services;
using KoeBook.Core.Services;
using KoeBook.Epub.Contracts.Services;
using KoeBook.Epub.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace KoeBook.Core;

internal static class Startup
{
/// <summary>
/// System, Core, Epub のDIを登録します
/// </summary>
public static IHostBuilder ConfigureCore(this IHostBuilder builder)
{
builder.ConfigureServices((context, services) =>
{
// System
services.AddSingleton(TimeProvider.System);
// Core Services
services.AddHttpClient()
.ConfigureHttpClientDefaults(builder =>
{
builder.SetHandlerLifetime(TimeSpan.FromMinutes(5));
});
services.AddSingleton<IFileService, FileService>();
services.AddSingleton<ISecretSettingsService, SecretSettingsService>();
services.AddSingleton<IStyleBertVitsClientService, StyleBertVitsClientService>();
services.AddSingleton<ISoundGenerationSelectorService, SoundGenerationSelectorService>();
services.AddSingleton<ISoundGenerationService, SoundGenerationService>();
services.AddSingleton<IEpubGenerateService, EpubGenerateService>();
services.AddSingleton<IEpubDocumentStoreService, EpubDocumentStoreService>();
services.AddSingleton<IAnalyzerService, AnalyzerService>();
services.AddSingleton<ILlmAnalyzerService, ChatGptAnalyzerService>();
services.AddSingleton<OpenAI.Interfaces.IOpenAIService, MyOpenAiService>();
// Epub Services
services
.AddKeyedSingleton<IScrapingClientService, ScrapingClientService>(nameof(ScrapingAozoraService))
.AddKeyedSingleton<IScrapingClientService, ScrapingClientService>(nameof(ScrapingNaroService))
.AddSingleton<IScraperSelectorService, ScraperSelectorService>()
.AddSingleton<IScrapingService, ScrapingAozoraService>()
.AddSingleton<IScrapingService, ScrapingNaroService>();
services.AddSingleton<IEpubCreateService, EpubCreateService>();
services.AddSingleton<IFileExtensionService, FileExtensionService>();
});

return builder;
}
}

0 comments on commit 0671402

Please sign in to comment.