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") }