Files
summercms/postcard/mailer_test.go
Jakub Zych b4fd8339fe feat(04-03): render registered mail templates through memory
- Parse Winter INI + == Markdown templates and Goldmark HTML
- Memory driver stores rendered subject, text, and HTML
- Caller selects -en siblings by full dotted name

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 13:58:02 +02:00

105 lines
2.9 KiB
Go

package postcard
import (
"context"
"strings"
"testing"
"testing/fstest"
)
func TestMailRenderSmoke(t *testing.T) {
t.Parallel()
fsys := fstest.MapFS{
"views/mail/hello.htm": {Data: []byte(`subject = "Witaj {{ .Name }}"
description = "Hello greeting"
layout = "default"
==
Witaj **{{ .Name }}**.
[Strona]({{ .URL }})
`)},
"views/mail/hello-en.htm": {Data: []byte(`subject = "Hello {{ .Name }}"
description = "English hello greeting"
layout = "default"
==
Hello **{{ .Name }}**.
[Site]({{ .URL }})
`)},
}
cat := NewCatalog()
err := cat.Register("golem15.hello", fsys, []string{
"golem15.hello::mail.hello",
"golem15.hello::mail.hello-en",
}, nil)
if err != nil {
t.Fatalf("Register: %v", err)
}
drv := NewMemoryDriver()
mail := NewMailer(cat, drv, Options{})
ctx := context.Background()
vars := map[string]any{"Name": "Ada", "URL": "https://example.test"}
if err := mail.Send(ctx, Message{
Template: "golem15.hello::mail.hello",
To: []string{"ada@example.test"},
Vars: vars,
}); err != nil {
t.Fatalf("Send hello: %v", err)
}
if err := mail.Send(ctx, Message{
Template: "golem15.hello::mail.hello-en",
To: []string{"ada@example.test"},
Vars: vars,
}); err != nil {
t.Fatalf("Send hello-en: %v", err)
}
got := drv.Messages()
if len(got) != 2 {
t.Fatalf("stored %d messages, want 2", len(got))
}
pl, en := got[0], got[1]
if pl.Subject != "Witaj Ada" {
t.Fatalf("default locale subject = %q", pl.Subject)
}
if en.Subject != "Hello Ada" {
t.Fatalf("-en subject = %q", en.Subject)
}
if !strings.Contains(pl.Text, "Witaj **Ada**.") || strings.Contains(pl.Text, "Hello **Ada**.") {
t.Fatalf("default locale text = %q", pl.Text)
}
if !strings.Contains(en.Text, "Hello **Ada**.") || strings.Contains(en.Text, "Witaj **Ada**.") {
t.Fatalf("-en text = %q", en.Text)
}
if !strings.Contains(pl.HTML, "<strong>Ada</strong>") || !strings.Contains(pl.HTML, `href="https://example.test"`) {
t.Fatalf("default locale HTML = %q", pl.HTML)
}
if !strings.Contains(en.HTML, "<strong>Ada</strong>") || !strings.Contains(en.HTML, `href="https://example.test"`) {
t.Fatalf("-en HTML = %q", en.HTML)
}
if !strings.Contains(pl.HTML, `class="content-body"`) || !strings.Contains(en.HTML, `class="content-body"`) {
t.Fatalf("neutral default layout missing from HTML")
}
t.Run("unsafe vars stay out of HTML", func(t *testing.T) {
drv := NewMemoryDriver()
mail := NewMailer(cat, drv, Options{})
if err := mail.Send(ctx, Message{
Template: "golem15.hello::mail.hello-en",
To: []string{"ada@example.test"},
Vars: map[string]any{
"Name": `<script>alert(1)</script>`,
"URL": "javascript:alert(1)",
},
}); err != nil {
t.Fatalf("Send: %v", err)
}
html := drv.Messages()[0].HTML
if strings.Contains(strings.ToLower(html), "<script") || strings.Contains(strings.ToLower(html), "javascript:") {
t.Fatalf("unsafe HTML leaked: %s", html)
}
})
}