A target's settings move from the per-type JSON string in targets.config to columns: url, headers, timeout_seconds, forward_query, archive_expiry and archive_rotation. A column a type does not use stays empty. headers holds the header map as JSON text through GORM's JSON serializer, and archive_expiry holds a time.Duration, 0 meaning never. The forms check each setting once, with the same refusals and messages, and the edit form is filled from the columns, so the per-type config structs, their parsers and the "could not be read" branches are gone. A delivery task carries the six settings in place of the JSON string; tests check that each copy into a task, and back out of one, keeps all six. Model: opus-5-5
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"net/netip"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/google/uuid"
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
"gorm.io/gorm/clause"
|
||||
"sneak.berlin/go/webhooker/internal/config"
|
||||
"sneak.berlin/go/webhooker/internal/database"
|
||||
"sneak.berlin/go/webhooker/internal/delivery"
|
||||
"sneak.berlin/go/webhooker/internal/handlers"
|
||||
"sneak.berlin/go/webhooker/internal/middleware"
|
||||
"sneak.berlin/go/webhooker/internal/middleware/middlewaretest"
|
||||
@@ -206,3 +208,71 @@ func receivedLine(t *testing.T, buf *bytes.Buffer) map[string]any {
|
||||
|
||||
return found[0]
|
||||
}
|
||||
|
||||
// targetWithEverySetting returns target settings with all six set, the
|
||||
// archive ones included, so a task that drops one of them differs from
|
||||
// the target.
|
||||
func targetWithEverySetting() database.Target {
|
||||
return database.Target{
|
||||
URL: replayTargetURL,
|
||||
Headers: map[string]string{"X-Api-Key": "k"},
|
||||
TimeoutSeconds: 7,
|
||||
ForwardQuery: true,
|
||||
ArchiveExpiry: time.Hour,
|
||||
ArchiveRotation: "daily",
|
||||
}
|
||||
}
|
||||
|
||||
// assertTaskCarriesTargetSettings proves a delivery task carries every
|
||||
// one of the target's settings. They are copied into the task one field
|
||||
// at a time, and a field left out is sent empty without any error.
|
||||
func assertTaskCarriesTargetSettings(
|
||||
t *testing.T, task delivery.Task, target *database.Target,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
assert.Equal(t, target.ID, task.TargetID)
|
||||
assert.Equal(t, target.URL, task.TargetURL)
|
||||
assert.Equal(t, target.Headers, task.TargetHeaders)
|
||||
assert.Equal(t, target.TimeoutSeconds, task.TimeoutSeconds)
|
||||
assert.Equal(t, target.ForwardQuery, task.ForwardQuery)
|
||||
assert.Equal(t, target.ArchiveExpiry, task.ArchiveExpiry)
|
||||
assert.Equal(t, target.ArchiveRotation, task.ArchiveRotation)
|
||||
}
|
||||
|
||||
// TestHandleWebhook_TaskCarriesEveryTargetSetting proves the task a
|
||||
// received event hands the delivery engine carries every one of the
|
||||
// target's settings.
|
||||
func TestHandleWebhook_TaskCarriesEveryTargetSetting(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
h *handlers.Handlers
|
||||
db *database.Database
|
||||
notif *recordingNotifier
|
||||
)
|
||||
|
||||
app := newTestApp(t, &h, &db, ¬if)
|
||||
app.RequireStart()
|
||||
|
||||
t.Cleanup(app.RequireStop)
|
||||
|
||||
webhook := seedWebhook(t, db)
|
||||
entrypoint := seedEntrypoint(t, db, webhook.ID)
|
||||
target := seedConfiguredTarget(
|
||||
t, db, webhook.ID, database.TargetTypeHTTP,
|
||||
targetWithEverySetting(),
|
||||
)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
h.HandleWebhook().ServeHTTP(w, postRequest(
|
||||
"/h/"+entrypoint.Path, nil,
|
||||
map[string]string{"uuid": entrypoint.Path},
|
||||
))
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
tasks := notif.Tasks()
|
||||
require.Len(t, tasks, 1)
|
||||
assertTaskCarriesTargetSettings(t, tasks[0], target)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user