TC-COMM-006: Rich-Text Compose & Send-Test
🆕 New on stage — 2026-06-25 → 2026-06-29. This TC covers the broadcast-composer features shipped after the prior guide freeze: Send-Test (#433), merge-tag personalization + XSS escaping (#252/#449), rich-text editor + HTML-source toggle + sandboxed preview (#488), and tenant brand color in the email wrapper. These supersede the old "no test-send / no merge tags / raw-
<textarea> body" notes on the older TC pages. See the Test Plan banners and the Jun 25 / Jun 29 release notes.
Module: Communications — Broadcasts (composer)
Primary Test User: comms@demo.membervu.com / Comms123! (Communications Manager)
Priority: P1 (Send-Test + XSS escape are money/security-adjacent)
Objectives
- Author a broadcast body in the rich-text editor (bold / italic / link / bullet + numbered list) and confirm the stored value is sanitized HTML.
- Toggle Rich text ⇄ HTML source, edit raw markup, and confirm the lossy-conversion warning fires when switching back over tables/images/headings.
- Open Preview and confirm it renders the branded email inside a sandboxed iframe (no script execution) using the tenant's brand color in the header/footer.
- Send-Test: one
[TEST]email to the requesting admin only; the broadcast stays a DRAFT with its recipient ledger unchanged (still editable). - Merge tags:
{{firstName}}substitutes per-recipient; a value containing<script>is HTML-escaped (no injection); an unsupported{{token}}is stripped before the real send. - Segment-filter validation: an unknown/operator-shaped filter is rejected with
400(#449), not silently ignored.
Scenario summary
| ID | Scenario | Key data assertion |
|---|---|---|
| CM6-01 | Rich-text compose | Toolbar formats apply; saved bodyHtml contains <strong>/<a>/<ul>, never <script> or on*= handlers. |
| CM6-02 | HTML-source toggle + lossy warning | Toggle shows raw HTML; switching back with a <table>/<img> present raises a confirm dialog before conversion. |
| CM6-03 | Sandboxed branded preview | Preview iframe carries sandbox="allow-same-origin" (no allow-scripts); header/footer bar color == tenant OrgProfile.primaryColor. |
| CM6-04 | Send-Test | Exactly ONE email in webmail, To == the admin's own address, subject starts [TEST]; broadcast row still DRAFT, recipientCount/sentAt unchanged. |
| CM6-05 | Merge-tag substitution + XSS escape | Delivered email shows the real first name for {{firstName}}; a name of <script>alert(1)</script> appears as inert escaped text, NOT executed and NOT double-escaped for a normal name. |
| CM6-06 | Unsupported token stripped | Body {{unknownTag}} is left inert in preview and removed from the real send payload (not delivered literally). |
| CM6-07 | Segment-filter validation | POST a broadcast/segment with filter {"in":[...]} or an unknown key → 400, not a silent full-audience send. |
➡️ Full click-by-click steps: TC-COMM-006 (Detailed).