using JSMR.Application.Scanning.Contracts; using JSMR.Infrastructure.Http; using JSMR.Infrastructure.Scanning; using JSMR.Tests.Utilities; using NSubstitute; using Shouldly; namespace JSMR.Tests.Integrations.DLSite; public class VoiceWorkScannerTests { private static async Task ReadResourceAsync(string resourceName) { return await ResourceHelper.ReadAsync($"JSMR.Tests.Scanning.{resourceName}"); } [Fact] public async Task Scan_With_English_Locale() { string englishPageHtml = await ReadResourceAsync("English-Page.html"); IHttpService httpService = Substitute.For(); httpService.GetStringAsync(Arg.Any(), CancellationToken.None) .Returns(Task.FromResult(englishPageHtml)); HtmlLoader loader = new(httpService); EnglishVoiceWorksScanner scanner = new(loader); VoiceWorkScanOptions options = new( PageNumber: 1, PageSize: 100, ExcludeAIGeneratedWorks: true, ExcludePartiallyAIGeneratedWorks: true, ExcludedMakerIds: [] ); var result = await scanner.ScanPageAsync(options, CancellationToken.None); result.Count.ShouldBe(2); result[0].ExpectedDate.ShouldBeNull(); result[0].SalesDate.ShouldBe(new DateOnly(2025, 9, 6)); result[0].ProductId.ShouldBe("RJ00000001"); result[0].ProductName.ShouldBe("Title of Product"); result[0].Description.ShouldBe("Description of the product."); result[0].Maker.ShouldBe("The Maker"); result[0].MakerId.ShouldBe("RG00001"); result[0].Creators.ShouldBe(["Some Creator"]); result[0].Genres.ShouldBe(["Voice", "Trial version"]); result[0].Tags.ShouldBe(["Male Protagonist", "Gal", "Uniform", "Harem", "Big Breasts", "Tanned Skin / Suntan"]); result[0].Type.ShouldBe(DLSiteWorkType.Released); result[0].Downloads.ShouldBe(1000); result[1].ExpectedDate.ShouldBe(new DateOnly(2025, 10, 11)); result[1].SalesDate.ShouldBeNull(); result[1].ProductId.ShouldBe("RJ00000002"); result[1].Type.ShouldBe(DLSiteWorkType.Announced); } }