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

  1. Author a broadcast body in the rich-text editor (bold / italic / link / bullet + numbered list) and confirm the stored value is sanitized HTML.
  2. Toggle Rich text ⇄ HTML source, edit raw markup, and confirm the lossy-conversion warning fires when switching back over tables/images/headings.
  3. 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.
  4. Send-Test: one [TEST] email to the requesting admin only; the broadcast stays a DRAFT with its recipient ledger unchanged (still editable).
  5. Merge tags: {{firstName}} substitutes per-recipient; a value containing <script> is HTML-escaped (no injection); an unsupported {{token}} is stripped before the real send.
  6. Segment-filter validation: an unknown/operator-shaped filter is rejected with 400 (#449), not silently ignored.

Scenario summary

IDScenarioKey data assertion
CM6-01Rich-text composeToolbar formats apply; saved bodyHtml contains <strong>/<a>/<ul>, never <script> or on*= handlers.
CM6-02HTML-source toggle + lossy warningToggle shows raw HTML; switching back with a <table>/<img> present raises a confirm dialog before conversion.
CM6-03Sandboxed branded previewPreview iframe carries sandbox="allow-same-origin" (no allow-scripts); header/footer bar color == tenant OrgProfile.primaryColor.
CM6-04Send-TestExactly ONE email in webmail, To == the admin's own address, subject starts [TEST]; broadcast row still DRAFT, recipientCount/sentAt unchanged.
CM6-05Merge-tag substitution + XSS escapeDelivered 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-06Unsupported token strippedBody {{unknownTag}} is left inert in preview and removed from the real send payload (not delivered literally).
CM6-07Segment-filter validationPOST 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).