check / check (push) Successful in 3m15s
The database target type is called an archive on its badge, in the add target form's type list and on its edit page, and its settings read "Archive expiry" and "Archive rotation" everywhere, the new webhook page included. The retry field is labelled "Delivery attempts", with its help text and error messages to match, on both target forms and in the target list. The navbar says "Sign out" and the sign-in page "Sign in". The resubmit notice says "webhook". The stored values (`database`, `max_retries`) and their meaning 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>")
|
|
}
|