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) }