Replace the bare-bones inline HTML in notification, verification, and admin test emails with a shared branded layout in internal/mail, matching the web UI's Midnight Cinema theme (dark card shell, wordmark, mono episode-code badges, white primary CTA). The shell is built for email clients: tables + inline styles, explicit dark color-scheme, Outlook-safe button, and a width:100%/max-width pattern so the card shrinks correctly on phones. Plain-text bodies, subjects, and the link-free-when-unconfigured guarantee are unchanged; the admin test email gains an HTML body so the SMTP test doubles as a design preview. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
53 lines
1.7 KiB
Go
53 lines
1.7 KiB
Go
package mail
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestRenderLayoutEscapesAndPlacesContent(t *testing.T) {
|
|
out := RenderLayout(LayoutOptions{
|
|
Preheader: `sneak <script>alert(1)</script>`,
|
|
Title: `Title & <b>bold</b>`,
|
|
BodyHTML: `<p id="body-marker">trusted</p>`,
|
|
FooterHTML: `<span id="footer-marker">fine print</span>`,
|
|
})
|
|
if strings.Contains(out, "<script>") || strings.Contains(out, "<b>bold</b>") {
|
|
t.Fatalf("preheader/title not escaped:\n%s", out)
|
|
}
|
|
if !strings.Contains(out, "Title & <b>bold</b>") {
|
|
t.Fatalf("escaped title missing:\n%s", out)
|
|
}
|
|
if !strings.Contains(out, `<p id="body-marker">trusted</p>`) {
|
|
t.Fatalf("body HTML not passed through:\n%s", out)
|
|
}
|
|
if !strings.Contains(out, `<span id="footer-marker">fine print</span>`) {
|
|
t.Fatalf("footer HTML not passed through:\n%s", out)
|
|
}
|
|
if !strings.Contains(out, "SILO") {
|
|
t.Fatalf("wordmark missing:\n%s", out)
|
|
}
|
|
}
|
|
|
|
// Some emails must render fully link-free when no external URL is configured;
|
|
// the shell itself must therefore never contribute one.
|
|
func TestRenderLayoutAddsNoLinks(t *testing.T) {
|
|
out := RenderLayout(LayoutOptions{Title: "Hello", BodyHTML: "<p>hi</p>"})
|
|
if strings.Contains(out, "href=") {
|
|
t.Fatalf("layout shell added a link:\n%s", out)
|
|
}
|
|
if strings.Contains(out, "<h1") && strings.Contains(RenderLayout(LayoutOptions{BodyHTML: "x"}), "<h1") {
|
|
t.Fatalf("empty title should not render an <h1>")
|
|
}
|
|
}
|
|
|
|
func TestEmailButtonEscapes(t *testing.T) {
|
|
out := EmailButton(`Click "here" <now>`, `https://example.com/?a=1&b=<2>`)
|
|
if !strings.Contains(out, `href="https://example.com/?a=1&b=<2>"`) {
|
|
t.Fatalf("href not escaped: %s", out)
|
|
}
|
|
if strings.Contains(out, "<now>") {
|
|
t.Fatalf("label not escaped: %s", out)
|
|
}
|
|
}
|