check / check (push) Waiting to run
The http and slack targets sent the fixed User-Agent webhooker/1.0. The delivery engine now takes the version from Globals, the value the web UI footer shows, and one method builds webhooker/<version> for both targets. The http target still sets it after the configured headers, so a configured or inbound User-Agent never reaches the wire. A test builds the engine through its real constructor with a known version and checks the header each target sends. Model: opus-5-5
92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
package delivery_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/netip"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/fx/fxtest"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
"sneak.berlin/go/webhooker/internal/delivery"
|
|
"sneak.berlin/go/webhooker/internal/globals"
|
|
"sneak.berlin/go/webhooker/internal/logger"
|
|
"sneak.berlin/go/webhooker/internal/metrics"
|
|
)
|
|
|
|
// Both the http and the slack target send webhooker/ and the version
|
|
// in Globals, the value the web UI footer shows. A User-Agent
|
|
// configured on the target or carried in by the sender does not
|
|
// replace it.
|
|
func TestUserAgent_IsTheBuildVersion(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const want = "webhooker/1.2.3-test"
|
|
|
|
userAgents := make(chan string, 1)
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
userAgents <- r.Header.Get("User-Agent")
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
},
|
|
))
|
|
defer ts.Close()
|
|
|
|
g := &globals.Globals{Version: "1.2.3-test"}
|
|
lc := fxtest.NewLifecycle(t)
|
|
|
|
log, err := logger.New(lc, logger.LoggerParams{Globals: g})
|
|
require.NoError(t, err)
|
|
|
|
e := delivery.New(lc, delivery.EngineParams{
|
|
Globals: g,
|
|
Logger: log,
|
|
// httptest listens on loopback, which the default guard
|
|
// refuses.
|
|
SSRFGuard: delivery.NewTestGuard(
|
|
netip.MustParsePrefix("127.0.0.0/8"),
|
|
),
|
|
Metrics: metrics.New(prometheus.NewRegistry()),
|
|
})
|
|
|
|
statusCode, _, _, err := e.ExportDoHTTPRequest(
|
|
context.Background(),
|
|
&delivery.HTTPTargetConfig{
|
|
URL: ts.URL,
|
|
Headers: map[string]string{"User-Agent": "configured/1"},
|
|
},
|
|
&database.Event{Headers: `{"User-Agent":["curl/8"]}`},
|
|
)
|
|
require.NoError(t, err)
|
|
require.Equal(t, http.StatusOK, statusCode)
|
|
require.Len(t, userAgents, 1, "the http target sent no request")
|
|
assert.Equal(t, want, <-userAgents, "http target")
|
|
|
|
db := testWebhookDB(t)
|
|
targetID := uuid.New().String()
|
|
|
|
slackCfg, err := json.Marshal(
|
|
delivery.SlackTargetConfig{WebhookURL: ts.URL},
|
|
)
|
|
require.NoError(t, err)
|
|
|
|
event := seedEvent(t, db, `{"action":"test"}`)
|
|
dlv := seedDelivery(
|
|
t, db, event.ID, targetID, database.DeliveryStatusPending,
|
|
)
|
|
|
|
e.ExportDeliverSlack(context.Background(), db, buildSlackDelivery(
|
|
dlv, event, targetID, "test-slack", string(slackCfg),
|
|
))
|
|
require.Len(t, userAgents, 1, "the slack target sent no request")
|
|
assert.Equal(t, want, <-userAgents, "slack target")
|
|
}
|