Toggle only a target's active state, so it cannot undo an edit (closes #431) #437
@@ -1911,9 +1911,13 @@ func (h *Handlers) HandleTargetToggle() http.HandlerFunc {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tgt.Active = !tgt.Active
|
// Only the active column: saving the whole row would
|
||||||
|
// write back the name and settings read above over an
|
||||||
|
// edit saved since.
|
||||||
|
active := !tgt.Active
|
||||||
|
|
||||||
return tgt.Active, h.db.DB().Save(&tgt).Error
|
return active, h.db.DB().Model(&tgt).
|
||||||
|
Update("active", active).Error
|
||||||
},
|
},
|
||||||
"failed to toggle target",
|
"failed to toggle target",
|
||||||
targetActivated, targetDeactivated,
|
targetActivated, targetDeactivated,
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package handlers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestHandleTargetToggle_DoesNotUndoAnEdit proves that a toggle which
|
||||||
|
// loaded the target before an edit of it was saved does not write the
|
||||||
|
// old name and settings back over the edit. The edit is submitted from
|
||||||
|
// a callback on the toggle's own read of the target, so it is saved
|
||||||
|
// after that read and before the toggle writes.
|
||||||
|
func TestHandleTargetToggle_DoesNotUndoAnEdit(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
env := setupSourceTest(t)
|
||||||
|
wh, tgt := seedHTTPTarget(t, env, "", "")
|
||||||
|
require.True(t, tgt.Active)
|
||||||
|
|
||||||
|
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) {
|
||||||
|
// The edit reads the target too; only the toggle's read,
|
||||||
|
// the first, submits it.
|
||||||
|
if tx.Statement.Table != "targets" || edited {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
edited = true
|
||||||
|
editCode = submitTargetEdit(
|
||||||
|
env, wh.ID, tgt.ID,
|
||||||
|
editForm(editReplacedURL, "", ""),
|
||||||
|
).Code
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
req := postRequest(
|
||||||
|
"/hook/"+wh.ID+"/targets/"+tgt.ID+"/toggle",
|
||||||
|
env.cookies,
|
||||||
|
map[string]string{paramSourceID: wh.ID, paramTargetID: tgt.ID},
|
||||||
|
)
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
env.handlers.HandleTargetToggle().ServeHTTP(w, req)
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusSeeOther, w.Code)
|
||||||
|
require.Equal(t, http.StatusSeeOther, editCode)
|
||||||
|
|
||||||
|
stored := storedTarget(t, env, tgt.ID)
|
||||||
|
assert.False(t, stored.Active)
|
||||||
|
assert.Equal(t, "edited-name", stored.Name)
|
||||||
|
assert.Equal(t, 5, stored.MaxRetries)
|
||||||
|
assert.Equal(
|
||||||
|
t, editReplacedURL, storedHTTPConfig(t, env, tgt.ID).URL,
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user