# Teststrategie für TipTap Markdown-Migration ## Zusammenfassung der Analyse Die TipTap-Migration umfasst folgende Kernkomponenten: | Komponente | Beschreibung | Komplexität | |------------|--------------|-------------| | `lib/src/Components/TipTap/utils/preprocessMarkdown.ts` | 6-stufige Preprocessing-Pipeline | Hoch | | `lib/src/Components/TipTap/utils/simpleMarkdownToHtml.tsx` | Statische HTML-Konvertierung | Mittel | | `lib/src/Components/TipTap/extensions/Hashtag.tsx` | Custom Extension mit Tokenizer | Mittel | | `lib/src/Components/TipTap/extensions/ItemMention.tsx` | Custom Extension mit Tokenizer | Mittel | | `lib/src/Components/TipTap/extensions/VideoEmbed.tsx` | Block-Element für Videos | Mittel | | `lib/src/Components/Input/RichTextEditor.tsx` | Haupt-Editor-Komponente | Hoch | | `lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx` | Read-Only Editor | Mittel | | `lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextViewStatic.tsx` | Lightweight Static Renderer | Niedrig | --- ## Empfohlene Teststrategie: Testing Pyramid ``` ┌─────────────────┐ │ E2E Tests │ ← Wenige, kritische User Journeys │ (Cypress) │ └────────┬────────┘ │ ┌────────┴────────┐ │ Integration │ ← TipTap + Extensions zusammen │ Tests (Vitest) │ └────────┬────────┘ │ ┌───────────────────┴───────────────────┐ │ Unit Tests (Vitest) │ ← Utility-Funktionen isoliert │ preprocessMarkdown, simpleMarkdownToHtml │ └────────────────────────────────────────┘ ``` ### Begründung der Strategie 1. **Unit Tests für Utility-Funktionen (Hauptfokus)** - `preprocessMarkdown.ts` und `simpleMarkdownToHtml.tsx` sind **pure Funktionen** ohne Abhängigkeiten - Extrem schnelle Ausführung, hohe Coverage möglich - Einfach zu warten und zu debuggen - Hier liegt die meiste **Geschäftslogik** der Markdown-Verarbeitung 2. **Integration Tests für TipTap Extensions** - Extensions benötigen einen Editor-Kontext - Testen der Markdown ↔ JSON ↔ HTML Roundtrips - Mäßiger Aufwand, gute Fehlererkennung 3. **E2E Tests nur für kritische User Journeys** - Hoher Wartungsaufwand - Langsame Ausführung - Für Smoke Tests und Regressionsschutz --- ## Detaillierte Testfälle ### 1. Unit Tests für `preprocessMarkdown.ts` #### A) `convertNakedUrls` | Testfall | Input | Expected Output | |----------|-------|-----------------| | **Happy Path** | `Check https://example.com out` | `Check [example.com](https://example.com) out` | | **www entfernen** | `https://www.example.com` | `[example.com](https://example.com)` | | **URL in Markdown-Link (Skip)** | `[link](https://example.com)` | Unverändert | | **URL in Autolink (Skip)** | `` | Unverändert | | **Mehrere URLs** | `https://a.com and https://b.com` | Beide konvertiert | | **URL am Satzende mit Punkt** | `Visit https://example.com.` | Punkt nicht Teil der URL | | **URL mit Klammern** | `(https://example.com)` | Klammern korrekt behandelt | | **URL mit Query-Params** | `https://example.com?a=1&b=2` | Vollständig konvertiert | #### B) `preprocessVideoLinks` | Testfall | Input | Expected Output | |----------|-------|-----------------| | **YouTube Standard** | `` | `` | | **YouTube Short URL** | `` | Korrekt konvertiert | | **YouTube Markdown Link** | `[Video](https://youtube.com/watch?v=abc123)` | Korrekt konvertiert | | **Rumble Embed** | `` | `` | | **URL mit Extra-Params** | `` | Nur Video-ID extrahiert | | **Kein Video-Link** | `` | Unverändert | | **Gemischter Content** | `Text more` | Nur Video konvertiert | #### C) `preprocessHashtags` | Testfall | Input | Expected Output | |----------|-------|-----------------| | **Einfacher Hashtag** | `Hello #world` | `Hello #world` | | **Hashtag mit Umlauten** | `#München` | Korrekt erkannt | | **Hashtag mit Zahlen** | `#test123` | Korrekt erkannt | | **Hashtag in Link (Skip)** | `[#tag](#anchor)` | Unverändert | | **Hashtag nach Klammer (Skip)** | `(#section)` | Unverändert | | **Mehrere Hashtags** | `#one #two #three` | Alle konvertiert | | **Ungültiger Hashtag** | `#` | Unverändert (kein Text) | | **Hashtag mit Underscore** | `#my_tag` | Korrekt erkannt | #### D) `preprocessItemMentions` | Testfall | Input | Expected Output | |----------|-------|-----------------| | **Standard Format** | `[@Person](/item/uuid-123)` | `@Person` | | **Mit Layer (Legacy)** | `[@Name](/item/layer/uuid)` | Korrekt konvertiert | | **Relativer Pfad** | `[@Name](item/uuid)` | Korrekt konvertiert | | **Mehrere Mentions** | `[@A](/item/1) und [@B](/item/2)` | Beide konvertiert | | **Kein Item-Link** | `[@Name](/other/path)` | Unverändert | | **UUID Case-Insensitive** | `[@Name](/item/ABC-def-123)` | Korrekt erkannt | | **Label mit Sonderzeichen** | `[@Max Müller](/item/uuid)` | Korrekt konvertiert | #### E) `truncateMarkdown` | Testfall | Input | Limit | Expected | |----------|-------|-------|----------| | **Unter Limit** | `Short text` | 100 | Unverändert | | **Über Limit (Plain)** | `A very long text...` | 10 | `A very lo...` | | **Hashtag nicht schneiden** | `Text #verylonghashtag more` | 15 | Vollständiger Hashtag oder davor abschneiden | | **Mention nicht schneiden** | `Hi [@Person](/item/x) bye` | 10 | Vollständige Mention oder davor | | **Link nicht schneiden** | `See [link](url) more` | 8 | Vollständiger Link oder davor | | **Newlines nicht zählen** | `Line1\n\nLine2` | 10 | Newlines ignoriert bei Zählung | | **Gemischter Content** | `#tag [@m](/item/1) text` | 20 | Tokens atomar | #### F) `removeMarkdownSyntax` | Testfall | Input | Expected | |----------|-------|----------| | **Bold** | `**bold**` | `bold` | | **Italic** | `*italic*` | `italic` | | **Headers** | `# Heading` | `Heading` | | **Links** | `[text](url)` | `text` | | **Item Mentions erhalten** | `[@Name](/item/x)` | Erhalten | | **Bilder entfernen** | `![alt](img.png)` | Leer | | **Code** | `` `code` `` | `code` | --- ### 2. Unit Tests für `simpleMarkdownToHtml.tsx` | Testfall | Input | Expected HTML | |----------|-------|---------------| | **Bold** | `**bold**` | `bold` | | **Italic** | `*italic*` | `italic` | | **Link** | `[text](url)` | `text` | | **External Link** | `[text](https://ext.com)` | `` | | **Header H1** | `# Title` | `

Title

` | | **Header H2-H6** | `## ... ######` | Entsprechende h-Tags | | **Inline Code** | `` `code` `` | `code` | | **Blockquote** | `> quote` | `
quote
` | | **Video Embed** | `` | `