using JSMR.Application.Scanning.Contracts; using JSMR.Application.Scanning.Ports; using JSMR.Domain.Entities; using JSMR.Infrastructure.Common.Languages; using JSMR.Infrastructure.Data; using JSMR.Infrastructure.Ingestion; using JSMR.Tests.Fixtures; using Microsoft.EntityFrameworkCore; using Shouldly; namespace JSMR.Tests.Ingestion; public class EnglishLocalizationTests(MariaDbContainerFixture container) : IClassFixture { private readonly LanguageIdentifier languageIdentifier = new(); [Fact] public async Task Insert_Then_Update() { await using AppDbContext dbContext = await MariaTestDb.CreateIsolatedAsync( container.RootConnectionString, seed: VoiceWorkIngestionSeedData.SeedAsync); // Part 1 -- Insert VoiceWorkIngest ingest = new() { MakerId = "RG00001", MakerName = "Good Dreams", ProductId = "RJ0000001", Title = "Today Sounds (EN)", Description = "An average product. (EN)" }; EnglishVoiceWorkUpdater updater = new(dbContext, languageIdentifier); VoiceWorkUpsertResult[] results = await updater.UpsertAsync([ingest], CancellationToken.None); VoiceWork voiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == "RJ0000001"); EnglishVoiceWork? englishVoiceWork = await dbContext.EnglishVoiceWorks.SingleOrDefaultAsync(e => e.VoiceWorkId == voiceWork.VoiceWorkId); englishVoiceWork.ShouldNotBeNull(); englishVoiceWork.ProductName.ShouldBe("Today Sounds (EN)"); englishVoiceWork.Description.ShouldBe("An average product. (EN)"); englishVoiceWork.IsValid?.ShouldBeTrue(); results.Length.ShouldBe(1); results.Count(r => r.Status == VoiceWorkUpsertStatus.Inserted).ShouldBe(1); results.Count(r => r.Status == VoiceWorkUpsertStatus.Updated).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Skipped).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Unchanged).ShouldBe(0); results.Sum(r => r.Issues.Count).ShouldBe(0); // Part 2 -- Update VoiceWorkIngest ingestUpdate = ingest with { Title = "Today Sounds (EN v2)", Description = "Updated English description." }; VoiceWorkUpsertResult[] updatedResults = await updater.UpsertAsync([ingestUpdate], CancellationToken.None); EnglishVoiceWork? updatedEnglishVoiceWork = await dbContext.EnglishVoiceWorks.SingleOrDefaultAsync(e => e.VoiceWorkId == voiceWork.VoiceWorkId); updatedEnglishVoiceWork.ShouldNotBeNull(); updatedEnglishVoiceWork.ProductName.ShouldBe("Today Sounds (EN v2)"); updatedEnglishVoiceWork.Description.ShouldBe("Updated English description."); updatedEnglishVoiceWork.IsValid?.ShouldBeTrue(); updatedResults.Length.ShouldBe(1); updatedResults.Count(r => r.Status == VoiceWorkUpsertStatus.Inserted).ShouldBe(0); updatedResults.Count(r => r.Status == VoiceWorkUpsertStatus.Updated).ShouldBe(1); updatedResults.Count(r => r.Status == VoiceWorkUpsertStatus.Skipped).ShouldBe(0); updatedResults.Count(r => r.Status == VoiceWorkUpsertStatus.Unchanged).ShouldBe(0); updatedResults.Sum(r => r.Issues.Count).ShouldBe(0); // Part 3 -- Update Again (No Change) VoiceWorkUpsertResult[] updatedAgainResults = await updater.UpsertAsync([ingestUpdate], CancellationToken.None); EnglishVoiceWork? updatedAgainEnglishVoiceWork = await dbContext.EnglishVoiceWorks.SingleOrDefaultAsync(e => e.VoiceWorkId == voiceWork.VoiceWorkId); updatedAgainEnglishVoiceWork.ShouldNotBeNull(); updatedAgainEnglishVoiceWork.ProductName.ShouldBe("Today Sounds (EN v2)"); updatedAgainEnglishVoiceWork.Description.ShouldBe("Updated English description."); updatedAgainEnglishVoiceWork.IsValid?.ShouldBeTrue(); updatedAgainResults.Length.ShouldBe(1); updatedAgainResults.Count(r => r.Status == VoiceWorkUpsertStatus.Inserted).ShouldBe(0); updatedAgainResults.Count(r => r.Status == VoiceWorkUpsertStatus.Updated).ShouldBe(0); updatedAgainResults.Count(r => r.Status == VoiceWorkUpsertStatus.Skipped).ShouldBe(0); updatedAgainResults.Count(r => r.Status == VoiceWorkUpsertStatus.Unchanged).ShouldBe(1); updatedAgainResults.Sum(r => r.Issues.Count).ShouldBe(0); } [Fact] public async Task Fail_Attempted_Insert_With_Missing_Circle() { await using AppDbContext dbContext = await MariaTestDb.CreateIsolatedAsync( container.RootConnectionString, seed: VoiceWorkIngestionSeedData.SeedAsync); VoiceWorkIngest ingest = new() { MakerId = "RG99999", MakerName = "Missing Maker", ProductId = "RJ9999999", Title = "EN Title", Description = "EN Desc" }; EnglishVoiceWorkUpdater updater = new(dbContext, languageIdentifier); VoiceWorkUpsertResult[] results = await updater.UpsertAsync([ingest], CancellationToken.None); int englishVoiceWorkCount = await dbContext.EnglishVoiceWorks.CountAsync(CancellationToken.None); englishVoiceWorkCount.ShouldBe(0); results.Length.ShouldBe(1); results.Count(r => r.Status == VoiceWorkUpsertStatus.Inserted).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Updated).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Skipped).ShouldBe(1); results.Sum(r => r.Issues.Count).ShouldBe(1); VoiceWorkUpsertIssue issue = results[0].Issues.ElementAt(0); issue.Severity.ShouldBe(VoiceWorkUpsertIssueSeverity.Error); issue.Message.ShouldBe($"Unable to find circle for maker id: {ingest.MakerId}"); } [Fact] public async Task Fail_Attempted_Insert_With_Missing_Product() { await using AppDbContext dbContext = await MariaTestDb.CreateIsolatedAsync( container.RootConnectionString, seed: VoiceWorkIngestionSeedData.SeedAsync); VoiceWorkIngest ingest = new() { MakerId = "RG00001", MakerName = "Good Dreams", ProductId = "RJ9999999", Title = "EN Title", Description = "EN Desc" }; EnglishVoiceWorkUpdater updater = new(dbContext, languageIdentifier); VoiceWorkUpsertResult[] results = await updater.UpsertAsync([ingest], CancellationToken.None); int englishVoiceWorkCount = await dbContext.EnglishVoiceWorks.CountAsync(CancellationToken.None); englishVoiceWorkCount.ShouldBe(0); results.Length.ShouldBe(1); results.Count(r => r.Status == VoiceWorkUpsertStatus.Inserted).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Updated).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Skipped).ShouldBe(1); results.Sum(r => r.Issues.Count).ShouldBe(1); VoiceWorkUpsertIssue issue = results[0].Issues.ElementAt(0); issue.Severity.ShouldBe(VoiceWorkUpsertIssueSeverity.Error); issue.Message.ShouldBe($"Unable to find voice work for product id: {ingest.ProductId}"); } [Fact] public async Task Fail_Attempted_Insert_When_Not_English() { await using AppDbContext dbContext = await MariaTestDb.CreateIsolatedAsync( container.RootConnectionString, seed: VoiceWorkIngestionSeedData.SeedAsync); VoiceWorkIngest ingest = new() { MakerId = "RG00001", MakerName = "Good Dreams", ProductId = "RJ0000001", Title = "すごく快適なASMR", Description = "最高の製品です!" }; EnglishVoiceWorkUpdater updater = new(dbContext, languageIdentifier); VoiceWorkUpsertResult[] results = await updater.UpsertAsync([ingest], CancellationToken.None); int englishVoiceWorkCount = await dbContext.EnglishVoiceWorks.CountAsync(CancellationToken.None); englishVoiceWorkCount.ShouldBe(0); results.Length.ShouldBe(1); results.Count(r => r.Status == VoiceWorkUpsertStatus.Inserted).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Updated).ShouldBe(0); results.Count(r => r.Status == VoiceWorkUpsertStatus.Skipped).ShouldBe(1); results.Sum(r => r.Issues.Count).ShouldBe(1); VoiceWorkUpsertIssue issue = results[0].Issues.ElementAt(0); issue.Severity.ShouldBe(VoiceWorkUpsertIssueSeverity.Information); issue.Message.ShouldBe("Product title and/or description is not in English"); } }