package handlers_test import ( "html" "net/http" "net/url" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "sneak.berlin/go/webhooker/internal/database" ) // TestHandleTargetCreate_EveryType adds a target of each type. Each // submission carries a url: only the http and slack types store one. func TestHandleTargetCreate_EveryType(t *testing.T) { t.Parallel() env := setupSourceTest(t) cases := []struct { targetType database.TargetType fields map[string]string wantConfig string wantRetries int }{ { database.TargetTypeHTTP, map[string]string{"timeout": "12", "max_retries": "3"}, `{"url":"` + editOriginalURL + `","timeout":12}`, 3, }, { database.TargetTypeSlack, map[string]string{"max_retries": "4"}, `{"webhookUrl":"` + editOriginalURL + `"}`, 4, }, { database.TargetTypeDatabase, map[string]string{"expiry": "720h"}, `{"expiry":"720h"}`, 0, }, {database.TargetTypeLog, nil, "", 0}, } for _, tc := range cases { t.Run(string(tc.targetType), func(t *testing.T) { t.Parallel() webhook := seedWebhookWithRetention(t, env.db, 30) form := url.Values{} form.Set("name", "every-type") form.Set("type", string(tc.targetType)) form.Set("url", editOriginalURL) for field, value := range tc.fields { form.Set(field, value) } w := serveTarget( env, http.MethodPost, "/hook/"+webhook.ID+"/targets", form, ) require.Equal(t, http.StatusSeeOther, w.Code, w.Body.String()) targets := targetsForWebhook(t, env.db, webhook.ID) require.Len(t, targets, 1) assert.Equal(t, tc.targetType, targets[0].Type) assert.Equal(t, tc.wantRetries, targets[0].MaxRetries) if tc.wantConfig == "" { assert.Empty(t, targets[0].Config) } else { assert.JSONEq(t, tc.wantConfig, targets[0].Config) } }) } } // TestHandleTargetCreate_RefusedFormComesBack refuses a target of each // type and checks that the webhook page comes back with the add target // form open on that type, the values entered, and the reason. func TestHandleTargetCreate_RefusedFormComesBack(t *testing.T) { t.Parallel() env := setupSourceTest(t) cases := []struct { targetType database.TargetType fields map[string]string reason string }{ { database.TargetTypeHTTP, map[string]string{ "name": "private", "url": editBlockedURL, "timeout": "12", "max_retries": "3", }, "Invalid target URL", }, { database.TargetTypeSlack, map[string]string{"name": "no-url", "max_retries": "4"}, "Webhook URL is required for Slack targets", }, { database.TargetTypeDatabase, map[string]string{"name": "archive", "expiry": "7d"}, "Invalid archive expiry", }, { database.TargetTypeLog, map[string]string{"name": ""}, "Name is required", }, } for _, tc := range cases { t.Run(string(tc.targetType), func(t *testing.T) { t.Parallel() webhook := seedWebhookWithRetention(t, env.db, 30) form := url.Values{} form.Set("type", string(tc.targetType)) for field, value := range tc.fields { form.Set(field, value) } w := serveTarget( env, http.MethodPost, "/hook/"+webhook.ID+"/targets", form, ) assert.Equal(t, http.StatusBadRequest, w.Code) page := w.Body.String() assert.Contains( t, page, `data-type="`+string(tc.targetType)+`"`, ) assert.Contains(t, page, html.EscapeString(tc.reason)) for field, value := range tc.fields { assert.Contains( t, page, `name="`+field+`" value="`+html.EscapeString(value)+`"`, ) } assert.Empty(t, targetsForWebhook(t, env.db, webhook.ID)) }) } }