From 8e5c6a0907f5b7e9582a630eab63baaac4c576e2 Mon Sep 17 00:00:00 2001
From: mahula
Date: Thu, 15 Jan 2026 18:33:05 +0100
Subject: [PATCH] Revert "docs: add TipTap migration testing strategy"
This reverts commit 64b6e60951dbefee64a54e688396099f370ee150.
---
TESTING_STRATEGY.md | 376 +++++++++++++++++++++
docs/Test_Strategy.md | 752 ------------------------------------------
2 files changed, 376 insertions(+), 752 deletions(-)
create mode 100644 TESTING_STRATEGY.md
delete mode 100644 docs/Test_Strategy.md
diff --git a/TESTING_STRATEGY.md b/TESTING_STRATEGY.md
new file mode 100644
index 00000000..ec11704a
--- /dev/null
+++ b/TESTING_STRATEGY.md
@@ -0,0 +1,376 @@
+# 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** | `` | 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** | `` | `
` Trennung |
+
+---
+
+### 3. Integration Tests für TipTap Extensions
+
+Diese Tests benötigen einen TipTap Editor-Kontext. Setup via `@tiptap/core`:
+
+```typescript
+// Test-Setup Beispiel
+import { Editor } from '@tiptap/core'
+import StarterKit from '@tiptap/starter-kit'
+import { Markdown } from '@tiptap/markdown'
+import { Hashtag } from './Hashtag'
+```
+
+#### A) Hashtag Extension
+
+| Testfall | Beschreibung |
+|----------|--------------|
+| **Markdown → JSON** | `#tag` wird zu `{ type: 'hashtag', attrs: { label: 'tag' } }` |
+| **JSON → Markdown** | Hashtag-Node wird zu `#tag` serialisiert |
+| **HTML Parse** | `#x` wird erkannt |
+| **HTML Render** | Node rendert korrekte HTML-Struktur |
+| **Tokenizer Start** | `/(? {
+ it('should create and save content with hashtags and mentions', () => {
+ // 1. Neues Item erstellen
+ // 2. Text eingeben mit #tag und @mention
+ // 3. Speichern
+ // 4. Popup öffnen und Rendering prüfen
+ })
+
+ it('should handle video embeds', () => {
+ // YouTube URL einfügen → Video-Embed sichtbar
+ })
+})
+```
+
+#### B) Display Flow
+
+```typescript
+describe('Text Display', () => {
+ it('should render hashtags clickable in popup', () => {
+ // Item mit Hashtag öffnen
+ // Hashtag klicken
+ // Filter wird aktiviert
+ })
+
+ it('should navigate to mentioned items', () => {
+ // Item mit @mention öffnen
+ // Mention klicken
+ // Navigation zum verlinkten Item
+ })
+})
+```
+
+---
+
+## Priorisierung der Implementierung
+
+### Phase 1: Unit Tests (Höchste Priorität)
+
+| Datei | Geschätzte Tests | Grund |
+|-------|------------------|-------|
+| `preprocessMarkdown.spec.ts` | ~40 Tests | Pure Functions, schnell, hohe Coverage |
+| `simpleMarkdownToHtml.spec.ts` | ~25 Tests | Pure Function, XSS-kritisch |
+
+### Phase 2: Integration Tests
+
+| Datei | Geschätzte Tests | Grund |
+|-------|------------------|-------|
+| `Hashtag.spec.ts` | ~15 Tests | Custom Extension mit Tokenizer |
+| `ItemMention.spec.ts` | ~15 Tests | Custom Extension mit Tokenizer |
+| `VideoEmbed.spec.ts` | ~10 Tests | Block-Element |
+
+### Phase 3: Component Tests
+
+| Datei | Geschätzte Tests | Grund |
+|-------|------------------|-------|
+| `RichTextEditor.spec.tsx` | ~15 Tests | Haupt-Editor |
+| `TextView.spec.tsx` | ~10 Tests | Read-Only Variante |
+| `TextViewStatic.spec.tsx` | ~8 Tests | Lightweight Renderer |
+
+### Phase 4: E2E Tests (Niedrigste Priorität)
+
+| Datei | Geschätzte Tests | Grund |
+|-------|------------------|-------|
+| `editor-flow.cy.ts` | 3-5 Tests | Kritische User Journey |
+
+---
+
+## Edge Cases und Error Handling
+
+### Besonders wichtige Grenzfälle
+
+1. **Leerer Input** - Alle Funktionen sollten mit `''`, `null`, `undefined` umgehen
+2. **Sehr langer Text** - Performance bei >10.000 Zeichen
+3. **Verschachtelte Syntax** - `**#bold-hashtag**`, `[[@mention](/item/x)](url)`
+4. **Unicode** - Emojis, RTL-Text, Sonderzeichen
+5. **Malformed Markdown** - Ungeschlossene Tags: `**bold`, `[link(`
+6. **XSS Vectors** - `"` | `<script>` escaped |
-| **Security** | XSS event handler | `"
"` | Escaped |
-| **Security** | Already escaped | `"&"` | Preserved correctly |
-
----
-
-### 3. Unit Tests: Dependency Functions (`ReplaceURLs.ts`)
-
-The preprocessing pipeline depends on `fixUrls` and `mailRegex` from `lib/src/Utils/ReplaceURLs.ts`. These must be tested:
-
-#### A) `fixUrls`
-
-| Category | Test Case | Input | Expected Output |
-|----------|-----------|-------|-----------------|
-| **Happy Path** | Add https to naked domain | `"Visit example.com today"` | `"Visit https://example.com today"` |
-| **Happy Path** | Preserve existing https | `"https://example.com"` | Unchanged |
-| **Happy Path** | Preserve existing http | `"http://example.com"` | Unchanged |
-| **Happy Path** | Multiple domains | `"a.com and b.org"` | Both get https:// |
-| **Edge** | Domain with path | `"example.com/page"` | `"https://example.com/page"` |
-| **Edge** | Domain with subdomain | `"sub.example.com"` | `"https://sub.example.com"` |
-| **Skip** | Inside markdown link | `"[link](example.com)"` | Behavior depends on implementation |
-
-#### B) `mailRegex`
-
-| Category | Test Case | Input | Should Match |
-|----------|-----------|-------|--------------|
-| **Happy Path** | Simple email | `"test@example.com"` | ✓ |
-| **Happy Path** | With subdomain | `"user@mail.example.com"` | ✓ |
-| **Happy Path** | With plus | `"user+tag@example.com"` | ✓ |
-| **Happy Path** | With dots | `"first.last@example.com"` | ✓ |
-| **Happy Path** | Country TLD | `"user@example.co.uk"` | ✓ |
-| **Edge** | Invalid - no @ | `"not-an-email"` | ✗ |
-| **Edge** | Invalid - no domain | `"user@"` | ✗ |
-| **Edge** | Invalid - no local | `"@example.com"` | ✗ |
-
----
-
-### 4. Unit Tests: XSS Security (`xss.spec.ts`)
-
-**Critical:** The `simpleMarkdownToHtml` function uses a tag restoration pattern that could be vulnerable to XSS. A dedicated security test suite is required.
-
-#### XSS Attack Vectors
-
-```typescript
-const XSS_VECTORS = [
- // Basic XSS
- '',
- '
',
- '