Show each target's delivered and failed deliveries in the target list (closes #372)
check / check (push) Successful in 3m17s
check / check (push) Successful in 3m17s
Each row of the webhook page's target list now shows the target's delivered and failed deliveries, in total and in the last 24 hours. The totals are the target's running totals, so retention does not reduce them; the 24-hour figures are counted over that window of the deliveries' status index, in one query for all targets. Deliveries still pending or retrying count in neither. Model: opus-5-5
This commit is contained in:
@@ -3,6 +3,7 @@ package handlers_test
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
"sneak.berlin/go/webhooker/internal/database"
|
||||
"sneak.berlin/go/webhooker/internal/delivery"
|
||||
"sneak.berlin/go/webhooker/internal/handlers"
|
||||
"sneak.berlin/go/webhooker/internal/logger"
|
||||
"sneak.berlin/go/webhooker/internal/session"
|
||||
)
|
||||
|
||||
@@ -69,3 +71,104 @@ func TestHandleSourceDetail_ShowsArchiveFile(t *testing.T) {
|
||||
assert.Contains(t, body, "not created yet")
|
||||
assert.NotContains(t, body, "Archive Size:")
|
||||
}
|
||||
|
||||
// targetList returns the text of the targets section in a rendered
|
||||
// webhook page, from its heading to the next heading, with the markup
|
||||
// taken out and each run of space made one space. Each target's row
|
||||
// then reads as its name, type, state and buttons, followed by the
|
||||
// lines below them.
|
||||
func targetList(t *testing.T, page string) string {
|
||||
t.Helper()
|
||||
|
||||
_, list, found := strings.Cut(page, ">Targets</h2>")
|
||||
require.True(t, found, "the page has no targets section")
|
||||
|
||||
list, _, _ = strings.Cut(list, "<h2")
|
||||
list = regexp.MustCompile(`<[^>]*>`).ReplaceAllString(list, " ")
|
||||
|
||||
return strings.Join(strings.Fields(list), " ")
|
||||
}
|
||||
|
||||
// TestHandleSourceDetail_ShowsTargetDeliveries checks each target row's
|
||||
// delivered and failed deliveries, in total and in the last 24 hours,
|
||||
// for the history seedStatsHistory builds, before and after the real
|
||||
// retention reaper removes the oldest event. The http target has one
|
||||
// delivered, one of them in the last 24 hours, and three failed, one of
|
||||
// them in the last 24 hours and one of them the oldest event's, which
|
||||
// retention removes without changing the total. The active log target
|
||||
// has two failed, both in the last 24 hours, and its pending and
|
||||
// retrying deliveries count in neither. The four inactive log targets
|
||||
// have none.
|
||||
func TestHandleSourceDetail_ShowsTargetDeliveries(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
h *handlers.Handlers
|
||||
sess *session.Session
|
||||
db *database.Database
|
||||
dbMgr *database.WebhookDBManager
|
||||
log *logger.Logger
|
||||
)
|
||||
|
||||
app := newTestApp(t, &h, &sess, &db, &dbMgr, &log)
|
||||
app.RequireStart()
|
||||
|
||||
t.Cleanup(app.RequireStop)
|
||||
|
||||
hist := seedStatsHistory(t, h, sess, db, dbMgr)
|
||||
|
||||
const (
|
||||
httpRow = "Delivered: 1 in total, 1 in the last 24 hours " +
|
||||
"Failed: 3 in total, 1 in the last 24 hours"
|
||||
activeLogRow = "t-log log Active Edit Deactivate Delete " +
|
||||
"Delivered: 0 in total, 0 in the last 24 hours " +
|
||||
"Failed: 2 in total, 2 in the last 24 hours"
|
||||
inactiveLogRow = "t-log log Inactive Edit Activate Delete " +
|
||||
"Delivered: 0 in total, 0 in the last 24 hours " +
|
||||
"Failed: 0 in total, 0 in the last 24 hours"
|
||||
)
|
||||
|
||||
list := targetList(t, renderSourceDetailPage(t, h, sess, hist.webhook.ID))
|
||||
assert.Equal(t, 1, strings.Count(list, httpRow))
|
||||
assert.Equal(t, 1, strings.Count(list, activeLogRow))
|
||||
assert.Equal(t, 4, strings.Count(list, inactiveLogRow))
|
||||
|
||||
statsPrune(t, db, dbMgr, log, hist.webhookDB)
|
||||
|
||||
list = targetList(t, renderSourceDetailPage(t, h, sess, hist.webhook.ID))
|
||||
assert.Equal(t, 1, strings.Count(list, httpRow))
|
||||
assert.Equal(t, 1, strings.Count(list, activeLogRow))
|
||||
assert.Equal(t, 4, strings.Count(list, inactiveLogRow))
|
||||
}
|
||||
|
||||
// TestHandleSourceDetail_TargetDeliveriesUnreadable checks that when the
|
||||
// webhook's event database cannot be read, each target's row says so
|
||||
// instead of showing zeros.
|
||||
func TestHandleSourceDetail_TargetDeliveriesUnreadable(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)
|
||||
seedTarget(t, db, wh.ID, database.TargetTypeLog)
|
||||
|
||||
webhookDB, err := dbMgr.GetDB(wh.ID)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t,
|
||||
webhookDB.Migrator().DropTable(&database.TargetTotals{}))
|
||||
|
||||
list := targetList(t, renderSourceDetailPage(t, h, sess, wh.ID))
|
||||
assert.Contains(t, list, "t-log log Active Edit Deactivate Delete "+
|
||||
"The delivery counts could not be read.")
|
||||
assert.NotContains(t, list, "Delivered:")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user