check / check (push) Waiting to run
The UI gave one thing several names. The `database` type is now Archive in the type list, on its badge and on the edit page, and its settings read "Archive expiry" and "Archive rotation" everywhere. The retry field is "Delivery attempts", with help text, errors and the target list saying it counts every attempt; a stored 0 shows as one attempt. The target list uses one capitalisation. The navbar says "Sign out", the sign-in page "Sign in", and the resubmit notice "webhook" instead of "source". The README follows. Stored values, their meaning, routes and form field names are unchanged. Model: opus-5-5
112 lines
2.9 KiB
Go
112 lines
2.9 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{}, "Sign in - 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,
|
|
dataKeyEvents: []handlers.EventLogView{},
|
|
"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>")
|
|
}
|