package renderer
import (
"bytes"
"context"
"io"
"strings"
"testing"
)
func TestGenericHTMLHeaderFooter(t *testing.T) {
d := &genericHTMLDriver{}
pl := &driverPayload{
Template: bytes.NewBufferString(`{{template "pp" .}}`),
Header: bytes.NewBufferString(`{{.name}} {{template "pp" .}}`),
Footer: bytes.NewBufferString(``),
Variables: map[string]interface{}{"name": "Human"},
Partials: map[string]io.Reader{
"pp": bytes.NewBufferString(`{{define "pp"}}partial:{{.name}}{{end}}`),
},
}
out, err := d.Render(context.Background(), pl)
if err != nil {
t.Fatal(err)
}
bb, _ := io.ReadAll(out)
got := string(bb)
want := `partial:Human`
if got != want {
t.Fatalf("got %q, want %q", got, want)
}
// no header/footer keeps the single-pass path working
pl2 := &driverPayload{
Template: bytes.NewBufferString(`ok`),
Variables: map[string]interface{}{},
}
out2, err := d.Render(context.Background(), pl2)
if err != nil {
t.Fatal(err)
}
bb2, _ := io.ReadAll(out2)
if !strings.Contains(string(bb2), "ok") {
t.Fatalf("plain render broken: %q", string(bb2))
}
}
func TestGenericHTMLSafeHTML(t *testing.T) {
d := &genericHTMLDriver{}
rte := `
Title 1
`
pl := &driverPayload{
Template: bytes.NewBufferString(`{{.body}}
{{.body | safeHTML}}
`),
Variables: map[string]interface{}{"body": rte},
}
out, err := d.Render(context.Background(), pl)
if err != nil {
t.Fatal(err)
}
bb, _ := io.ReadAll(out)
got := string(bb)
want := `<h1>Title 1</h1>
Title 1
`
if got != want {
t.Fatalf("got %q, want %q", got, want)
}
// the case the partial workaround could not cover: rich text in a list
pl2 := &driverPayload{
Template: bytes.NewBufferString(`{{range .items}}{{.desc | safeHTML}} | {{end}}`),
Variables: map[string]interface{}{"items": []map[string]any{{"desc": rte}, {"desc": rte}}},
}
out2, err := d.Render(context.Background(), pl2)
if err != nil {
t.Fatal(err)
}
bb2, _ := io.ReadAll(out2)
if got, want := string(bb2), `Title 1 | Title 1 | `; got != want {
t.Fatalf("got %q, want %q", got, want)
}
// an unset or empty value must not break the render of the whole document
pl3 := &driverPayload{
Template: bytes.NewBufferString(`{{.unset | safeHTML}} | {{.blank | safeHTML}} | {{.count | safeHTML}} | `),
Variables: map[string]interface{}{"blank": nil, "count": 3},
}
out3, err := d.Render(context.Background(), pl3)
if err != nil {
t.Fatal(err)
}
bb3, _ := io.ReadAll(out3)
if got, want := string(bb3), ` | | 3 | `; got != want {
t.Fatalf("got %q, want %q", got, want)
}
}