Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
89 lines
2.5 KiB
Go
89 lines
2.5 KiB
Go
package web
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func testRenderer(t *testing.T) *Renderer {
|
|
t.Helper()
|
|
rn, err := NewRenderer(Brand{Title: "VPN-Portal Firma GmbH", Version: "1.2.3",
|
|
SupportContact: "it@firma.de"})
|
|
if err != nil {
|
|
t.Fatalf("NewRenderer: %v", err)
|
|
}
|
|
return rn
|
|
}
|
|
|
|
func TestRenderLoginPage(t *testing.T) {
|
|
rn := testRenderer(t)
|
|
rec := httptest.NewRecorder()
|
|
rn.Render(rec, httptest.NewRequest(http.MethodGet, "/login", nil), http.StatusOK,
|
|
"login", PageData{Brand: rn.brand})
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("Code = %d", rec.Code)
|
|
}
|
|
body := rec.Body.String()
|
|
for _, want := range []string{
|
|
"<!DOCTYPE html>", `lang="de"`, "VPN-Portal Firma GmbH",
|
|
S["login_submit"], S["login_username_hint"], "1.2.3",
|
|
`name="password"`, `type="password"`,
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("Login-Seite enthält %q nicht", want)
|
|
}
|
|
}
|
|
if ct := rec.Header().Get("Content-Type"); !strings.HasPrefix(ct, "text/html") {
|
|
t.Errorf("Content-Type = %q", ct)
|
|
}
|
|
}
|
|
|
|
func TestRenderEscapesUserContent(t *testing.T) {
|
|
rn := testRenderer(t)
|
|
rec := httptest.NewRecorder()
|
|
rn.Render(rec, httptest.NewRequest(http.MethodGet, "/", nil), http.StatusOK,
|
|
"error", PageData{
|
|
Brand: rn.brand,
|
|
Flash: `<script>alert(1)</script>`,
|
|
Data: errorPageData{Title: "T", Message: `"><img src=x onerror=alert(1)>`},
|
|
})
|
|
body := rec.Body.String()
|
|
if strings.Contains(body, "<script>alert(1)</script>") {
|
|
t.Error("Flash-Text wurde nicht escapt")
|
|
}
|
|
if strings.Contains(body, "onerror=alert(1)>") {
|
|
t.Error("Fehlermeldung wurde nicht escapt")
|
|
}
|
|
}
|
|
|
|
func TestRenderSetsStatusCode(t *testing.T) {
|
|
rn := testRenderer(t)
|
|
rec := httptest.NewRecorder()
|
|
rn.Render(rec, httptest.NewRequest(http.MethodGet, "/", nil), http.StatusServiceUnavailable,
|
|
"error", PageData{Brand: rn.brand, Data: errorPageData{Title: "x", Message: "y"}})
|
|
if rec.Code != http.StatusServiceUnavailable {
|
|
t.Fatalf("Code = %d, want 503", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestAllTemplatesParse(t *testing.T) {
|
|
rn := testRenderer(t)
|
|
for _, page := range pageNames {
|
|
if rn.pages[page] == nil {
|
|
t.Errorf("Template %q wurde nicht geladen", page)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRenderUnknownPageDoesNotPanic(t *testing.T) {
|
|
rn := testRenderer(t)
|
|
rec := httptest.NewRecorder()
|
|
rn.Render(rec, httptest.NewRequest(http.MethodGet, "/", nil), http.StatusOK,
|
|
"gibtsnicht", PageData{Brand: rn.brand})
|
|
if rec.Code != http.StatusInternalServerError {
|
|
t.Fatalf("Code = %d, want 500", rec.Code)
|
|
}
|
|
}
|