Let an entrypoint's description be edited in place (closes #392)
check / check (push) Successful in 3m19s

An entrypoint's description was set when it was added and could never change, so renaming one meant deleting it and adding a new one with a new URL every sender had to be given again. Each entrypoint on the webhook page now has an Edit button, in the shared secondary style, that opens its description in place with Save and Cancel and keeps its URL. The save goes through the same login, CSRF and ownership checks as the other entrypoint actions; an empty description shows as "Entrypoint". Activate and deactivate now write only the active column, so they cannot undo an edit. Tests cover each, through the router and the browser.

Model: opus-5-5
This commit was merged in pull request #464.
This commit is contained in:
2026-10-02 21:32:43 +02:00
parent 820d9391ff
commit 0f5f6ba6bf
10 changed files with 442 additions and 15 deletions
+84
View File
@@ -86,6 +86,7 @@ func TestAlpineRunsUnderTheSecurityPolicy(t *testing.T) {
checkAddForms(ctx, t, page)
checkTargetType(ctx, t, page+"/events")
checkCopy(ctx, t, page)
checkEntrypointEdit(ctx, t, page, page+"/events")
checkEventLog(ctx, t, page+"/events", event.ID, target.Name)
checkMobileMenu(ctx, t, page)
@@ -363,6 +364,89 @@ func checkCopy(ctx context.Context, t *testing.T, url string) {
`clicking Copy does not show "Copied"`)
}
// checkEntrypointEdit loads a webhook page whose entrypoint has no
// description, and checks that Edit shows the edit form in place of
// the description and hides until the form closes, so the form always
// opens on the saved description; that Cancel hides it and drops what
// was typed; that after typing, opening the page at elsewhere and going
// back, Edit again opens the form on the saved description; and that
// Save changes the description the page shows.
func checkEntrypointEdit(
ctx context.Context, t *testing.T, url, elsewhere string,
) {
t.Helper()
const (
editForm = `form[action$="/edit"]`
input = editForm + ` input[name="description"]`
description = `//span[text()="Entrypoint"]`
edit = `//button[text()="Edit"]`
)
require.NoError(t, chromedp.Run(ctx, loadPage(url)))
assert.True(t, hidden(ctx, editForm),
"the edit form shows before Edit is clicked")
click(ctx, t, edit)
assert.True(t, shown(ctx, editForm),
"clicking Edit does not show the edit form")
assert.True(t, hidden(ctx, description),
"the description stays shown beside the edit form")
assert.True(t, hidden(ctx, edit),
"Edit stays shown while the edit form is open")
require.NoError(t, chromedp.Run(
ctx, chromedp.SendKeys(input, "draft", chromedp.ByQuery),
))
click(ctx, t, `//button[text()="Cancel"]`)
assert.True(t, hidden(ctx, editForm),
"clicking Cancel does not hide the edit form")
assert.True(t, shown(ctx, description),
"clicking Cancel does not show the description again")
assert.True(t, shown(ctx, edit),
"clicking Cancel does not show Edit again")
var typed string
click(ctx, t, edit)
require.NoError(t, chromedp.Run(
ctx, chromedp.Value(input, &typed, chromedp.ByQuery),
))
assert.Empty(t, typed, "Cancel keeps what was typed")
var loaded string
require.NoError(t, chromedp.Run(
ctx,
chromedp.SendKeys(input, "draft", chromedp.ByQuery),
loadPage(elsewhere),
chromedp.NavigateBack(),
chromedp.WaitNotPresent("[x-cloak]", chromedp.ByQuery),
chromedp.Evaluate(
`performance.getEntriesByType("navigation")[0].type`, &loaded,
),
))
require.Equal(
t, "back_forward", loaded,
"going back, the browser did not load the page again",
)
click(ctx, t, edit)
require.NoError(t, chromedp.Run(
ctx, chromedp.Value(input, &typed, chromedp.ByQuery),
))
assert.Empty(t, typed, "going back puts what was typed back in the form")
require.NoError(t, chromedp.Run(
ctx, chromedp.SendKeys(input, "Billing sender", chromedp.ByQuery),
))
click(ctx, t, `//button[text()="Save"]`)
assert.True(t, shown(ctx, `//span[text()="Billing sender"]`),
"saving the edit form does not change the description")
}
// checkEventLog loads the event log and checks that clicking an event's
// row expands it, that in there clicking its delivery shows the
// delivery's attempts and clicking again hides them, and that clicking