Seed from go-template-repo, renamed to simplexcalc

The template's files at a77fd30, without its history or LICENSE, after
script/rename simplexcalc.

Model: opus-5-5
This commit is contained in:
clawbot
2026-09-26 21:38:57 +00:00
parent e336f46e34
commit f8ce8cef83
79 changed files with 7131 additions and 0 deletions
+197
View File
@@ -0,0 +1,197 @@
package render_test
import (
"bytes"
"html/template"
"net/http/httptest"
"strings"
"testing"
"time"
"sneak.berlin/go/simplexcalc/internal/database"
"sneak.berlin/go/simplexcalc/internal/globals"
"sneak.berlin/go/simplexcalc/internal/render"
"sneak.berlin/go/simplexcalc/templates"
)
func newRenderer(t *testing.T) *render.Renderer {
t.Helper()
r, err := render.New(nil, render.Params{
Globals: &globals.Globals{
Appname: "simplexcalc", Version: "test", Buildarch: "amd64",
},
})
if err != nil {
t.Fatalf("compiling templates: %v", err)
}
return r
}
// TestEveryEmbeddedPageCompiles is the reason New parses everything at
// startup: a template that does not compile must be a process that does
// not start, and this is what proves the set is complete rather than
// just non-empty.
func TestEveryEmbeddedPageCompiles(t *testing.T) {
t.Parallel()
r := newRenderer(t)
embedded, err := templates.FS.ReadDir(".")
if err != nil {
t.Fatalf("reading embedded templates: %v", err)
}
want := 0
for _, e := range embedded {
if !e.IsDir() && strings.HasSuffix(e.Name(), ".html") && e.Name() != "base.html" {
want++
}
}
if want == 0 {
t.Fatal("no page templates were embedded, so this test proves nothing")
}
if got := len(r.Names()); got != want {
t.Errorf("compiled %d pages (%v), embedded %d", got, r.Names(), want)
}
}
// TestIndexRendersEmbeddedContent renders the page the service serves
// at /, with real data, and checks that the base document, both
// partials and the page body all made it into one response.
func TestIndexRendersEmbeddedContent(t *testing.T) {
t.Parallel()
r := newRenderer(t)
data := render.IndexPage{
Page: r.NewPage(template.HTML(`<input type="hidden" name="csrf" />`)),
WidgetCount: 1,
Widgets: []database.Widget{
{
ID: "abc", Name: "a widget", SizeBytes: 4096,
CreatedAt: time.Now().Add(-time.Hour),
},
},
}
var buf bytes.Buffer
err := r.Execute(&buf, "index.html", data)
if err != nil {
t.Fatalf("rendering index: %v", err)
}
out := buf.String()
for _, want := range []string{
"<!doctype html>", // base document
`href="/static/css/style.css"`, // base document links the embedded asset
"<nav>", // navbar partial
"<footer>", // footer partial
"a widget", // page data
"4.0 KiB", // the bytes template func
"ago", // the since template func
`name="csrf"`, // the CSRF field was placed
} {
if !strings.Contains(out, want) {
t.Errorf("rendered page is missing %q\n---\n%s", want, out)
}
}
}
// TestHTMLEscapesUserData: the name comes from a form, and html/template
// is only a defence if the data actually goes through it.
func TestHTMLEscapesUserData(t *testing.T) {
t.Parallel()
r := newRenderer(t)
data := render.IndexPage{
Page: r.NewPage(""),
WidgetCount: 1,
Widgets: []database.Widget{
{ID: "x", Name: `<script>alert(1)</script>`, CreatedAt: time.Now()},
},
}
var buf bytes.Buffer
err := r.Execute(&buf, "index.html", data)
if err != nil {
t.Fatalf("rendering: %v", err)
}
if strings.Contains(buf.String(), "<script>alert(1)</script>") {
t.Error("a widget name was rendered as live markup")
}
}
// TestPagesDoNotShareBlocks: index.html and error.html both define
// "title" and "content". Parsed into one set, the last one parsed would
// define both for everybody, and every page would render as whichever
// that was.
func TestPagesDoNotShareBlocks(t *testing.T) {
t.Parallel()
r := newRenderer(t)
var buf bytes.Buffer
err := r.Execute(&buf, "error.html", render.ErrorPage{
Page: r.NewPage(""), Status: 404, Message: "gone fishing",
})
if err != nil {
t.Fatalf("rendering error page: %v", err)
}
out := buf.String()
if !strings.Contains(out, "gone fishing") {
t.Errorf("error page did not render its own content:\n%s", out)
}
if strings.Contains(out, "widgets (") {
t.Error("the error page rendered the index's content block")
}
}
// TestUnknownTemplateIsAnError, rather than an empty 200.
func TestUnknownTemplateIsAnError(t *testing.T) {
t.Parallel()
r := newRenderer(t)
err := r.Execute(&bytes.Buffer{}, "nope.html", nil)
if err == nil {
t.Fatal("rendering a template that does not exist must fail")
}
}
// TestHTMLWritesStatusAndType checks the response contract, since the
// handlers rely on it for every page they serve.
func TestHTMLWritesStatusAndType(t *testing.T) {
t.Parallel()
r := newRenderer(t)
w := httptest.NewRecorder()
err := r.HTML(w, 404, "error.html", render.ErrorPage{
Page: r.NewPage(""), Status: 404, Message: "no",
})
if err != nil {
t.Fatalf("rendering: %v", err)
}
if w.Code != 404 {
t.Errorf("status = %d, want 404", w.Code)
}
if ct := w.Header().Get("Content-Type"); !strings.HasPrefix(ct, "text/html") {
t.Errorf("Content-Type = %q", ct)
}
}