From 5eb36ad3e9d2a19cd1bd2dfea17179582ccabf9e Mon Sep 17 00:00:00 2001 From: tleininger Date: Thu, 1 Oct 2026 12:52:51 +0200 Subject: [PATCH] Style editor Markdown with .markdown-body and add ::: design blocks Co-Authored-By: Claude Opus 5.5 --- Elternbeirat.Web.Tests/MarkdownTests.cs | 81 ++++ Elternbeirat.Web.Tests/PocketBaseFixture.cs | 6 +- Elternbeirat.Web.Tests/RouteSmokeTests.cs | 17 +- .../Features/Events/EventList.razor | 2 +- Elternbeirat.Web/Features/Faqs/FaqList.razor | 6 +- .../Features/Pages/ContentPage.razor | 2 +- .../Features/Posts/PostDetail.razor | 2 +- .../Features/Posts/PostList.razor | 2 +- Elternbeirat.Web/Shared/Markdown.cs | 121 +++++- Elternbeirat.Web/wwwroot/app.css | 360 ++++++++++++++++++ docs/redaktion.md | 99 +++++ pb/pb_migrations/1727200000_dev_seed.js | 2 +- 12 files changed, 683 insertions(+), 17 deletions(-) create mode 100644 Elternbeirat.Web.Tests/MarkdownTests.cs diff --git a/Elternbeirat.Web.Tests/MarkdownTests.cs b/Elternbeirat.Web.Tests/MarkdownTests.cs new file mode 100644 index 0000000..038f9ca --- /dev/null +++ b/Elternbeirat.Web.Tests/MarkdownTests.cs @@ -0,0 +1,81 @@ +using Elternbeirat.Web.Shared; + +namespace Elternbeirat.Web.Tests; + +/// +/// Unit tests for the Markdown pipeline behind every editor-written body. Pure logic, +/// no PocketBase needed. +/// +public class MarkdownTests +{ + [Theory] + [InlineData(null)] + [InlineData("")] + public void Empty_input_renders_nothing(string? markdown) => + Markdown.ToHtml(markdown).ShouldBe(""); + + [Fact] + public void Custom_container_renders_a_div_with_its_name_as_class() + { + var html = Markdown.ToHtml("::: kennzahlen\n- **seit 1975** Gründung\n:::"); + + html.ShouldContain("
"); + html.ShouldContain("seit 1975"); + } + + [Fact] + public void Unknown_container_renders_its_content_as_normal_text() + { + // A typo in the block name must cost the styling, never the text. + var html = Markdown.ToHtml("::: gibtsnicht\nNormaler Text.\n:::"); + + html.ShouldContain("

Normaler Text.

"); + html.ShouldNotContain(":::"); + } + + [Fact] + public void Raw_html_is_escaped_not_passed_through() + { + // The body is rendered as a MarkupString; a passed-through \n\n
Box
"); + + html.ShouldNotContain("