check / check (push) Successful in 3m12s
parsePageTemplate parsed the page file before htmlheader.html. A later
definition of a template name replaces an earlier one (an empty one
never does), so htmlheader.html's {{block "title"}} replaced every
page's {{define "title"}} and every tab read "Webhooker". The page file
is now parsed last, into a set named after it, so it stays the entry
point.
A new test renders every page template and checks its title; the
"Webhooker" fallback is checked on htmlheader.html alone, since every
page declares a title.
Model: opus-5-5
108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
package handlers_test
|
|
|
|
import (
|
|
"html/template"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
"sneak.berlin/go/webhooker/internal/handlers"
|
|
"sneak.berlin/go/webhooker/internal/session"
|
|
"sneak.berlin/go/webhooker/templates"
|
|
)
|
|
|
|
// TestEveryPageRendersItsOwnTitle renders each page template and checks
|
|
// the browser tab title is the one the page declares, not the
|
|
// "Webhooker" fallback in htmlheader.html. A page that fails to render
|
|
// shows the error page's title instead, and fails here too.
|
|
func TestEveryPageRendersItsOwnTitle(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var h *handlers.Handlers
|
|
|
|
var sess *session.Session
|
|
|
|
app := newTestApp(t, &h, &sess)
|
|
app.RequireStart()
|
|
|
|
t.Cleanup(app.RequireStop)
|
|
|
|
// A pointer, as in the handlers: some pages call
|
|
// Webhook.RetentionLabel, a pointer method.
|
|
webhook := &database.Webhook{Name: "orders", RetentionDays: 14}
|
|
webhook.ID = testWebhookID
|
|
|
|
pages := []struct {
|
|
page string
|
|
data map[string]any
|
|
title string
|
|
}{
|
|
{"login.html", map[string]any{}, "Login - Webhooker"},
|
|
{"profile.html", map[string]any{}, "Profile - Webhooker"},
|
|
{"settings.html", map[string]any{}, "Settings - Webhooker"},
|
|
{"sources_list.html", map[string]any{}, "Webhooks - Webhooker"},
|
|
{"sources_new.html", map[string]any{}, "New Webhook - Webhooker"},
|
|
{
|
|
"source_detail.html",
|
|
map[string]any{dataKeyWebhook: webhook},
|
|
"orders - Webhooker",
|
|
},
|
|
{
|
|
"source_edit.html",
|
|
map[string]any{dataKeyWebhook: webhook},
|
|
"Edit orders - Webhooker",
|
|
},
|
|
{
|
|
"source_logs.html",
|
|
map[string]any{dataKeyWebhook: webhook, "TotalEvents": int64(0)},
|
|
"Full Event Log - orders - Webhooker",
|
|
},
|
|
{
|
|
"event_detail.html",
|
|
map[string]any{dataKeyWebhook: webhook},
|
|
"Event - orders - Webhooker",
|
|
},
|
|
{
|
|
"target_edit.html",
|
|
map[string]any{
|
|
dataKeyWebhook: webhook,
|
|
"Target": map[string]any{"Name": "alerts", "Type": "slack"},
|
|
},
|
|
"Edit alerts - Webhooker",
|
|
},
|
|
{
|
|
"error.html",
|
|
map[string]any{"StatusText": http.StatusText(http.StatusNotFound)},
|
|
"Not Found - Webhooker",
|
|
},
|
|
}
|
|
|
|
for _, p := range pages {
|
|
body := renderPage(t, h, sess, p.page, p.data)
|
|
|
|
_, afterOpen, _ := strings.Cut(body, "<title>")
|
|
title, _, _ := strings.Cut(afterOpen, "</title>")
|
|
|
|
assert.Equal(t, p.title, title, p.page)
|
|
}
|
|
}
|
|
|
|
// TestTitleFallbackIsWebhooker checks the title htmlheader.html gives a
|
|
// page that declares none. Every page declares one, so it is checked on
|
|
// htmlheader.html alone.
|
|
func TestTitleFallbackIsWebhooker(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
header := template.Must(
|
|
template.ParseFS(templates.Templates, "htmlheader.html"),
|
|
)
|
|
|
|
var buf strings.Builder
|
|
|
|
require.NoError(t, header.ExecuteTemplate(&buf, "htmlheader", nil))
|
|
assert.Contains(t, buf.String(), "<title>Webhooker</title>")
|
|
}
|