From adfbf654a6ba43ef1478670ef3b8cbd1e0603fae Mon Sep 17 00:00:00 2001 From: Brian Bicknell Date: Mon, 30 Mar 2026 23:03:53 -0400 Subject: [PATCH] Added logic to remove supported languages that are no longer supported, rather than just being purely additive. Added ApiClient logging. --- JSMR.Infrastructure/Http/ApiClient.cs | 17 ++++- .../Ingestion/VoiceWorkUpdater.cs | 8 +++ .../Update_Supported_Language_Tests.cs | 63 +++++++++++++++++++ ...te_Upcoming_With_No_Expected_Date_Tests.cs | 2 +- JSMR.Worker/JSMR.Worker.csproj | 2 + JSMR.Worker/Program.cs | 3 +- 6 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 JSMR.Tests/Ingestion/Japanese/Update_Supported_Language_Tests.cs diff --git a/JSMR.Infrastructure/Http/ApiClient.cs b/JSMR.Infrastructure/Http/ApiClient.cs index a6516e3..1faeb79 100644 --- a/JSMR.Infrastructure/Http/ApiClient.cs +++ b/JSMR.Infrastructure/Http/ApiClient.cs @@ -22,8 +22,21 @@ public abstract class ApiClient(HttpClient http, ILogger logger, JsonSerializerO Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - return await JsonSerializer.DeserializeAsync(stream, json, cancellationToken).ConfigureAwait(false) - ?? throw new InvalidOperationException($"Failed to deserialize JSON to {typeof(TResponse).Name} from {url}."); + try + { + return await JsonSerializer.DeserializeAsync(stream, json, cancellationToken).ConfigureAwait(false) + ?? throw new InvalidOperationException($"Failed to deserialize JSON to {typeof(TResponse).Name} from {url}."); + } + catch (JsonException ex) + { + logger.LogError(ex, + "Failed to deserialize JSON from {Url}. ContentLengthHeader={ContentLengthHeader}", + url, + response.Content.Headers.ContentLength); + + throw; + } + } protected async Task GetJsonpAsync( diff --git a/JSMR.Infrastructure/Ingestion/VoiceWorkUpdater.cs b/JSMR.Infrastructure/Ingestion/VoiceWorkUpdater.cs index d5a9218..8f67298 100644 --- a/JSMR.Infrastructure/Ingestion/VoiceWorkUpdater.cs +++ b/JSMR.Infrastructure/Ingestion/VoiceWorkUpdater.cs @@ -439,6 +439,14 @@ public class VoiceWorkUpdater(AppDbContext dbContext, ITimeProvider timeProvider dbContext.VoiceWorkSupportedLanguages.Add(voiceWorkSupportedLanguage); } } + + foreach (string existingLinkCode in existingLanguageLinks.Keys) + { + if (!ingest.SupportedLanguages.Any(x => x.Code == existingLinkCode)) + { + dbContext.VoiceWorkSupportedLanguages.Remove(existingLanguageLinks[existingLinkCode]); + } + } } private void UpsertSeries(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext) diff --git a/JSMR.Tests/Ingestion/Japanese/Update_Supported_Language_Tests.cs b/JSMR.Tests/Ingestion/Japanese/Update_Supported_Language_Tests.cs new file mode 100644 index 0000000..14029b3 --- /dev/null +++ b/JSMR.Tests/Ingestion/Japanese/Update_Supported_Language_Tests.cs @@ -0,0 +1,63 @@ +using JSMR.Application.Scanning.Contracts; +using JSMR.Domain.Entities; +using JSMR.Domain.ValueObjects; +using JSMR.Infrastructure.Data; +using JSMR.Tests.Fixtures; +using Microsoft.EntityFrameworkCore; +using Shouldly; + +namespace JSMR.Tests.Ingestion.Japanese; + +public class Update_Supported_Langauge_Tests(MariaDbContainerFixture container) : JapaneseIngestionTestsBase(container) +{ + [Fact] + public async Task Update_Supported_Langauge() + { + VoiceWorkIngest ingest = new() + { + MakerId = "RG1", + MakerName = "The Maker", + ProductId = "RJ1", + Title = "Title", + Description = "Description", + SupportedLanguages = [SupportedLanguage.Japanese] + }; + + await using AppDbContext dbContext = await GetAppDbContextAsync(); + DateTime currentDateTime = TokyoLocalToUtc(2025, 01, 05, 10, 0, 0); + + await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), ingest, [SupportedLanguage.Japanese]); + + // Add English + VoiceWorkIngest addSupportedLanguageIngest = ingest with + { + SupportedLanguages = [SupportedLanguage.Japanese, SupportedLanguage.English] + }; + + await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), addSupportedLanguageIngest, [SupportedLanguage.Japanese, SupportedLanguage.English]); + + // Remove Japanese + VoiceWorkIngest removeSupportedLanguageIngest = ingest with + { + SupportedLanguages = [SupportedLanguage.English] + }; + + await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), removeSupportedLanguageIngest, [SupportedLanguage.English]); + } + + private static async Task UpsertAndVerify(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest ingest, SupportedLanguage[] expectedSupportedLanguages) + { + await UpsertAsync(dbContext, dateTime, [ingest]); + + VoiceWork? voiceWork = await dbContext.VoiceWorks + .Include(x => x.SupportedLanguages) + .SingleAsync(v => v.ProductId == ingest.ProductId, TestContext.Current.CancellationToken); + + voiceWork.ShouldNotBeNull(); + + string[] languageCodes = [.. voiceWork.SupportedLanguages.Select(x => x.Language).OrderBy(x => x)]; + string[] expectedLanguageCode = [.. expectedSupportedLanguages.Select(x => x.Code).OrderBy(x => x)]; + + languageCodes.ShouldBe(expectedLanguageCode); + } +} \ No newline at end of file diff --git a/JSMR.Tests/Ingestion/Japanese/Update_Upcoming_With_No_Expected_Date_Tests.cs b/JSMR.Tests/Ingestion/Japanese/Update_Upcoming_With_No_Expected_Date_Tests.cs index 2bdadb4..f10bfe1 100644 --- a/JSMR.Tests/Ingestion/Japanese/Update_Upcoming_With_No_Expected_Date_Tests.cs +++ b/JSMR.Tests/Ingestion/Japanese/Update_Upcoming_With_No_Expected_Date_Tests.cs @@ -48,7 +48,7 @@ public class Update_Upcoming_With_No_Expected_Date_Tests(MariaDbContainerFixture }; // Should be exactly the same - await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), ingest, new DateTime(2025, 1, 21)); + await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), updatedIngest, new DateTime(2025, 1, 21)); } private static async Task UpsertAndVerify(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest ingest, DateTime? expectedDate) diff --git a/JSMR.Worker/JSMR.Worker.csproj b/JSMR.Worker/JSMR.Worker.csproj index f01cd0d..39a9934 100644 --- a/JSMR.Worker/JSMR.Worker.csproj +++ b/JSMR.Worker/JSMR.Worker.csproj @@ -28,7 +28,9 @@ + + diff --git a/JSMR.Worker/Program.cs b/JSMR.Worker/Program.cs index 8c05c36..ea28355 100644 --- a/JSMR.Worker/Program.cs +++ b/JSMR.Worker/Program.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Serilog; using System.CommandLine; using System.Text; @@ -30,7 +31,7 @@ string connectionString = builder.Configuration.GetConnectionString("AppDb") //builder.Services.AddSerilog(o => o // .WriteTo.Console() -// .MinimumLevel.Information()); +// .MinimumLevel.Warning()); builder.Services .AddApplication()