Files
webhooker/internal/handlers/source_logs_deleted_target_test.go
clawbot 5fda446c71
All checks were successful
check / check (push) Successful in 3m13s
Name a deleted target on its historical deliveries (closes #211)
2026-08-24 02:03:23 +02:00

145 lines
3.9 KiB
Go

package handlers_test
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sneak.berlin/go/webhooker/internal/database"
"sneak.berlin/go/webhooker/internal/handlers"
"sneak.berlin/go/webhooker/internal/session"
)
// deletedMarker is the suffix the event log appends to the name
// of a target that no longer exists.
const deletedMarker = " (deleted)"
// deleteTargetThroughHandler removes a target through the real
// deletion handler, so the test soft-deletes exactly the way the
// UI does rather than by writing the timestamp itself.
func deleteTargetThroughHandler(
t *testing.T,
h *handlers.Handlers,
sess *session.Session,
webhookID, targetID string,
) {
t.Helper()
req := postRequest(
"/source/"+webhookID+"/targets/"+targetID+"/delete",
authenticatedCookies(
t, sess, deleteTestUserID, deleteTestUsername,
),
map[string]string{
paramSourceID: webhookID,
paramTargetID: targetID,
},
)
w := httptest.NewRecorder()
h.HandleTargetDelete().ServeHTTP(w, req)
require.Equal(t, http.StatusSeeOther, w.Code)
}
// TestHandleSourceLogs_NamesDeletedTarget proves a delivery
// produced by a since-deleted target still names it on the event
// log, marked as deleted.
//
// Deletes are soft and deliveries carry no foreign key to the
// target row, so the history outlives the target. Against a
// scoped lookup the delivery resolves to a zero view and the page
// renders ": delivered" with nothing saying what it was delivered
// to.
func TestHandleSourceLogs_NamesDeletedTarget(t *testing.T) {
t.Parallel()
var (
h *handlers.Handlers
sess *session.Session
db *database.Database
dbMgr *database.WebhookDBManager
)
app := newTestApp(t, &h, &sess, &db, &dbMgr)
app.RequireStart()
t.Cleanup(app.RequireStop)
wh := seedWebhook(t, db)
tgt := seedTarget(t, db, wh.ID, database.TargetTypeLog)
seedDeliveredEvent(t, dbMgr, wh.ID, tgt.ID)
// The control: the name is on the page while the target
// lives, and is not yet marked as deleted.
before := renderSourceLogsPage(t, h, sess, wh.ID)
assert.Contains(t, before, tgt.Name)
assert.NotContains(t, before, tgt.Name+deletedMarker)
deleteTargetThroughHandler(t, h, sess, wh.ID, tgt.ID)
after := renderSourceLogsPage(t, h, sess, wh.ID)
assert.Contains(
t, after, tgt.Name+deletedMarker,
"a delivery from a deleted target must keep its name, "+
"marked as no longer existing",
)
assert.Contains(
t, after, "delivered",
"the delivery history itself must survive the delete",
)
}
// TestHandleSourceLogs_MasksDeletedTargetConfig proves that
// naming a deleted target does not widen what the page shows of
// it: its stored configuration stays masked by exactly the rules
// a live target's is.
//
// The lookup behind the name reads soft-deleted rows, so it
// carries a full target row — credential blob included — into the
// place a zero value used to sit. The projection to TargetView is
// what keeps that blob away from the template, and it must hold
// for a deleted row too.
func TestHandleSourceLogs_MasksDeletedTargetConfig(t *testing.T) {
t.Parallel()
var (
h *handlers.Handlers
sess *session.Session
db *database.Database
dbMgr *database.WebhookDBManager
)
app := newTestApp(t, &h, &sess, &db, &dbMgr)
app.RequireStart()
t.Cleanup(app.RequireStop)
wh := seedWebhook(t, db)
tgt := seedConfiguredTarget(
t, db, wh.ID,
database.TargetTypeSlack,
`{"webhookUrl":"`+slackWebhookURL+`"}`,
)
seedDeliveredEvent(t, dbMgr, wh.ID, tgt.ID)
deleteTargetThroughHandler(t, h, sess, wh.ID, tgt.ID)
body := renderSourceLogsPage(t, h, sess, wh.ID)
assert.NotContains(t, body, slackSecretPath)
assert.NotContains(t, body, "T00000000")
assert.NotContains(t, body, "B00000000")
assert.NotContains(
t, body, "XXXXXXXXXXXXXXXXXXXXXXXX",
)
assert.NotContains(t, body, "webhookUrl")
// The name is there; only the credential is not.
assert.Contains(t, body, tgt.Name+deletedMarker)
}