package handlers_test import ( "net/http" "strconv" "strings" "testing" "time" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/gorm/clause" "sneak.berlin/go/webhooker/internal/database" "sneak.berlin/go/webhooker/internal/handlers" "sneak.berlin/go/webhooker/internal/session" ) // TestHandleSourceDetail_ShowsEntrypointEvents proves each entrypoint // on the webhook page shows its own figures: how many events arrived // through it within the webhook's retention period, leaving out one // older than that, and when the newest arrived, or "never" for an // entrypoint with none. func TestHandleSourceDetail_ShowsEntrypointEvents(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 := &database.Webhook{ UserID: deleteTestUserID, Name: "figures", RetentionDays: 7, } require.NoError(t, db.DB().Omit(clause.Associations).Create(wh).Error) webhookDB, err := dbMgr.GetDB(wh.ID) require.NoError(t, err) entrypoint := func() *database.Entrypoint { ep := &database.Entrypoint{ WebhookID: wh.ID, Path: uuid.New().String(), Active: true, } require.NoError(t, db.DB().Omit(clause.Associations).Create(ep).Error) return ep } event := func(ep *database.Entrypoint, age time.Duration) time.Time { e := &database.Event{ WebhookID: wh.ID, EntrypointID: ep.ID, Method: http.MethodPost, } e.CreatedAt = time.Now().Add(-age) require.NoError(t, webhookDB.Omit(clause.Associations).Create(e).Error) return e.CreatedAt } busy, quiet, unused := entrypoint(), entrypoint(), entrypoint() event(busy, 8*24*time.Hour) // older than the 7 days kept event(busy, 3*time.Hour) busyLast := event(busy, time.Hour) quietLast := event(quiet, 2*24*time.Hour) body := renderSourceDetailPage(t, h, sess, wh.ID) // rowOf returns the part of the page from an entrypoint's URL to // the next entrypoint's, which holds its figures. rowOf := func(ep *database.Entrypoint) string { _, row, found := strings.Cut(body, `id="entrypoint-url-`+ep.ID+`"`) require.True(t, found) row, _, _ = strings.Cut(row, `id="entrypoint-url-`) return row } lastEvent := func(at time.Time) string { return `Last Event:\s*[^<]+ ago` } count := func(n int) string { return `Events Within Retention:\s*` + strconv.Itoa(n) + `` } assert.Regexp(t, lastEvent(busyLast), rowOf(busy)) assert.Regexp(t, count(2), rowOf(busy)) assert.Regexp(t, lastEvent(quietLast), rowOf(quiet)) assert.Regexp(t, count(1), rowOf(quiet)) assert.Regexp(t, `Last Event:\s*never`, rowOf(unused)) assert.Regexp(t, count(0), rowOf(unused)) }