using LehrerApp.Core.AiPlanning; using LehrerApp.Desktop.Services; using System.Text.Json; using Xunit; namespace LehrerApp.Desktop.Tests; /// /// Deckt den Bug ab, der beim ersten echten Test der KI-Unterstützung auftrat: .NETs /// DateOnly/TimeOnly haben standardmäßig ein ISO-JSON-Format ("yyyy-MM-dd"/"HH:mm:ss"), der /// KI-Wire-Vertrag dokumentiert aber deutsches Format ("TT.MM.JJJJ"/"HH:mm") — jede KI-Antwort im /// dokumentierten Format scheiterte deshalb mit einer JsonException beim Deserialisieren. /// public sealed class GermanDateTimeJsonConverterTests { private static readonly JsonSerializerOptions Options = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, Converters = { new GermanDateOnlyJsonConverter(), new GermanTimeOnlyJsonConverter() }, }; [Fact] public void DateOnly_SerialisiertAlsDeutschesFormat() { Assert.Equal("\"24.12.2026\"", JsonSerializer.Serialize(new DateOnly(2026, 12, 24), Options)); } [Fact] public void DateOnly_ParstDeutschesFormat() { Assert.Equal(new DateOnly(2026, 12, 24), JsonSerializer.Deserialize("\"24.12.2026\"", Options)); } /// LLMs weichen erfahrungsgemäß gelegentlich vom im Prompt dokumentierten Format ab — /// ISO 8601 wird deshalb defensiv trotzdem akzeptiert statt hart zu scheitern. [Fact] public void DateOnly_FaelltBeiAbweichendemFormatAufAllgemeinesParsenZurueck() { Assert.Equal(new DateOnly(2026, 12, 24), JsonSerializer.Deserialize("\"2026-12-24\"", Options)); } [Fact] public void TimeOnly_SerialisiertAlsHHmm() { Assert.Equal("\"14:30\"", JsonSerializer.Serialize(new TimeOnly(14, 30), Options)); } [Fact] public void TimeOnly_ParstHHmm() { Assert.Equal(new TimeOnly(14, 30), JsonSerializer.Deserialize("\"14:30\"", Options)); } /// Der eigentliche Bug betraf DateOnly?/TimeOnly? (nullable) in AiLesson, nicht die /// nicht-nullable Basistypen — dieser Test deckt genau das ab, nicht nur die Converter isoliert. [Fact] public void AiLesson_MitDeutschemDatumUndUhrzeit_DeserialisiertKorrekt() { const string json = """ {"id":null,"date":"24.12.2026","lessonNumber":3,"topic":"Test","startTime":"14:30", "phases":[],"homework":null,"reflection":null} """; var lesson = JsonSerializer.Deserialize(json, Options); Assert.Equal(new DateOnly(2026, 12, 24), lesson!.Date); Assert.Equal(new TimeOnly(14, 30), lesson.StartTime); } [Fact] public void AiLesson_OhneDatumUndUhrzeit_BleibtNull() { const string json = """{"id":null,"topic":"Test","phases":[]}"""; var lesson = JsonSerializer.Deserialize(json, Options); Assert.Null(lesson!.Date); Assert.Null(lesson.StartTime); } }