check / check (push) Waiting to run
Each entrypoint on the webhook page has an Edit button that shows its
description as a form, with Save and Cancel, in place. Edit hides while
the form is open, so the form always opens on the saved description.
Saving posts to /hook/{id}/entrypoints/{entrypointID}/edit, behind the
same login, CSRF and ownership checks as activate, deactivate and
delete, and writes only the description column, so the URL never
changes. An empty description shows as "Entrypoint". Activate and
deactivate now write only the active column, so they cannot write back
an older description over an edit.
Model: opus-5-5
96 lines
2.4 KiB
Go
96 lines
2.4 KiB
Go
package handlers_test
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/go-chi/chi"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/gorm"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
)
|
|
|
|
// TestHandleEntrypointToggle_DoesNotUndoAnEdit proves that a toggle
|
|
// which loaded the entrypoint before an edit of its description was
|
|
// saved does not write the old description back over the edit. The
|
|
// edit is submitted from a callback on the toggle's own read of the
|
|
// entrypoint, so it is saved after that read and before the toggle
|
|
// writes.
|
|
func TestHandleEntrypointToggle_DoesNotUndoAnEdit(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
env := setupSourceTest(t)
|
|
wh := seedWebhookWithRetention(t, env.db, 30)
|
|
ep := seedEntrypoint(t, env.db, wh.ID)
|
|
require.True(t, ep.Active)
|
|
|
|
router := chi.NewRouter()
|
|
router.Post(
|
|
"/hook/{sourceID}/entrypoints/{entrypointID}/edit",
|
|
env.handlers.HandleEntrypointEdit(),
|
|
)
|
|
router.Post(
|
|
"/hook/{sourceID}/entrypoints/{entrypointID}/toggle",
|
|
env.handlers.HandleEntrypointToggle(),
|
|
)
|
|
|
|
// post submits one of the entrypoint's forms as the test user and
|
|
// returns the response's status code.
|
|
post := func(action string, form url.Values) int {
|
|
req := httptest.NewRequestWithContext(
|
|
context.Background(), http.MethodPost,
|
|
"/hook/"+wh.ID+"/entrypoints/"+ep.ID+"/"+action,
|
|
strings.NewReader(form.Encode()),
|
|
)
|
|
req.Header.Set(
|
|
"Content-Type", "application/x-www-form-urlencoded",
|
|
)
|
|
|
|
for _, c := range env.cookies {
|
|
req.AddCookie(c)
|
|
}
|
|
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
return w.Code
|
|
}
|
|
|
|
var (
|
|
edited bool
|
|
editCode int
|
|
)
|
|
|
|
require.NoError(t, env.db.DB().Callback().Query().
|
|
After("gorm:query").
|
|
Register("test:edit_after_toggle_read", func(tx *gorm.DB) {
|
|
// Only the first read of an entrypoint, the toggle's,
|
|
// submits the edit.
|
|
if tx.Statement.Table != "entrypoints" || edited {
|
|
return
|
|
}
|
|
|
|
edited = true
|
|
editCode = post(
|
|
"edit", url.Values{"description": {"Billing sender"}},
|
|
)
|
|
}),
|
|
)
|
|
|
|
require.Equal(t, http.StatusSeeOther, post("toggle", nil))
|
|
require.Equal(t, http.StatusSeeOther, editCode)
|
|
|
|
var stored database.Entrypoint
|
|
|
|
require.NoError(
|
|
t, env.db.DB().First(&stored, "id = ?", ep.ID).Error,
|
|
)
|
|
assert.False(t, stored.Active)
|
|
assert.Equal(t, "Billing sender", stored.Description)
|
|
}
|