Give each event its own page and show bodies the same everywhere (closes #369)
check / check (push) Successful in 3m15s

Each row of the recent events on the webhook page links to the
event's own page, /hook/{id}/events/{eventID}, and expands to show its
body; only the newest starts expanded. The event's page shows its
details, its whole body and every delivery with its attempts.

One renderer, newBodyView with templates/event_body.html, shows a body
in all three places: whole up to 32 KiB, cut there in the lists with a
link to the event's page, JSON pretty-printed, a body of more than 200
lines or 32 KiB in a scrolling box, and a body that is not text left
out beside its download link. A resubmitted copy links to its
original's page.

Model: opus-5-5
This commit is contained in:
clawbot
2026-10-02 17:10:02 +00:00
committed by sneak
parent 40f59ec4d2
commit f346b69999
22 changed files with 959 additions and 170 deletions
+43
View File
@@ -364,6 +364,7 @@ func (e *testEnv) seedEvent(
WebhookID: webhookID,
Method: http.MethodPost,
Body: body,
BodyBytes: int64(len(body)),
ContentType: "application/octet-stream",
}
@@ -1247,6 +1248,48 @@ func TestHook_LinksBetweenPages(t *testing.T) {
}
}
// TestEventPage_OpenedFromRecentEvents follows the Open link of a
// row in the recent events on the webhook page through the
// production router to the event's own page, which shows the body
// and links back. Another user gets a 404 at the same URL, and a
// logged-out request is sent to log in.
func TestEventPage_OpenedFromRecentEvents(t *testing.T) {
t.Parallel()
env := newTestEnv(t)
ownerID, _ := env.seedUser(t, "owner", "somepassword")
cookies := env.authCookies(t, ownerID, "owner")
wh := env.seedWebhook(t, ownerID)
evt := env.seedEvent(t, wh.ID, "OWNERS-PAYLOAD-3e9d")
page := "/hook/" + wh.ID
path := env.urlFrom(t, page, `href="([^"]+)"[^>]*>Open<`, cookies)
require.Equal(t, page+"/events/"+evt.ID, path)
w := env.get(path, cookies)
require.Equal(t, http.StatusOK, w.Code)
assert.Contains(t, w.Body.String(), "OWNERS-PAYLOAD-3e9d")
assert.Equal(
t, page,
env.urlFrom(t, path, `href="([^"]+)"[^>]*>&larr; Back to `, cookies),
)
intruderID, _ := env.seedUser(t, "intruder", "somepassword")
w = env.get(path, env.authCookies(t, intruderID, "intruder"))
assert.Equal(t, http.StatusNotFound, w.Code)
assert.NotContains(t, w.Body.String(), "OWNERS-PAYLOAD-3e9d")
anon := env.get(path, nil)
assert.Equal(t, http.StatusSeeOther, anon.Code)
assert.Equal(
t, "/pages/login?next="+url.QueryEscape(path),
anon.Header().Get("Location"),
)
}
// TestSourceLogs_TruncationLinkDownloadsTheBody walks the whole
// feature the way a user does: render the event log page through
// the production router, take the download URL out of the markup