using MeetingAssistant.MeetingNotes; using MeetingAssistant.Summary; using Microsoft.Extensions.Options; namespace MeetingAssistant.Tests; public sealed class MeetingSummaryFailureWriterTests { [Fact] public async Task WriterOverwritesSummaryWithFailureDetails() { var root = Path.Combine(Path.GetTempPath(), "meeting-assistant-tests", Guid.NewGuid().ToString("N")); var artifacts = new MeetingSessionArtifacts( Path.Combine(root, "Notes", "meeting.md"), Path.Combine(root, "Transcripts", "transcript.md"), Path.Combine(root, "Assistant Context", "context.md"), Path.Combine(root, "Summaries", "summary.md")); Directory.CreateDirectory(Path.GetDirectoryName(artifacts.SummaryPath)!); Directory.CreateDirectory(Path.GetDirectoryName(artifacts.MeetingNotePath)!); await File.WriteAllTextAsync( artifacts.MeetingNotePath, """ --- title: Failure Meeting start_time: "2026-05-20T10:00:00.0000000+02:00" end_time: "2026-05-20T10:30:00.0000000+02:00" attendees: - Ada projects: - Current Project transcript: "[[../Transcripts/transcript|Transcript]]" assistant_context: "[[../Assistant Context/context|Assistant Context]]" summary: "[[../Summaries/summary|Summary]]" --- """); await File.WriteAllTextAsync( artifacts.SummaryPath, """ --- attendees: - Preserved projects: - Stale Project --- # Old Summary """); var writer = new MeetingSummaryFailureWriter( Options.Create(new MeetingAssistantOptions { Api = new ApiOptions { PublicBaseUrl = "http://localhost:5090" } }), new MarkdownMeetingNoteStore( Options.Create(new MeetingAssistantOptions { Vault = new VaultOptions { MeetingNotesFolder = Path.GetDirectoryName(artifacts.MeetingNotePath)! } }), Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance)); var result = await writer.WriteAsync( artifacts, new InvalidOperationException("LiteLLM Responses request failed with 500"), CancellationToken.None); var content = await File.ReadAllTextAsync(artifacts.SummaryPath); Assert.False(result.Succeeded); Assert.Equal(artifacts.SummaryPath, result.SummaryPath); Assert.Contains("Summary Generation Failed", content); Assert.Contains("title: Failure Meeting", content); Assert.Contains("attendees:", content); Assert.Contains("- Preserved", content); Assert.DoesNotContain("- Ada", content); Assert.Contains("projects:", content); Assert.Contains("- Current Project", content); Assert.DoesNotContain("- Stale Project", content); Assert.Contains("meeting: \"[[../Notes/meeting|Meeting Note]]\"", content); Assert.Contains("transcript: \"[[../Transcripts/transcript|Transcript]]\"", content); Assert.Contains("assistant_context: \"[[../Assistant Context/context|Assistant Context]]\"", content); Assert.DoesNotContain("summary:", content); Assert.Contains( "[Retry summary generation](http://localhost:5090/meetings/summary/retry?summaryPath=summary.md)", content); Assert.Contains("LiteLLM Responses request failed with 500", content); Assert.Contains(artifacts.TranscriptPath, content); Assert.DoesNotContain("# Old Summary", content); } }