github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/webhook/webhook_test.go (about) 1 package webhook 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "net/http/httptest" 10 "testing" 11 12 "github.com/google/uuid" 13 "github.com/goreleaser/goreleaser/internal/testctx" 14 "github.com/goreleaser/goreleaser/internal/testlib" 15 "github.com/goreleaser/goreleaser/pkg/config" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestStringer(t *testing.T) { 20 require.Equal(t, "webhook", Pipe{}.String()) 21 } 22 23 func TestNoEndpoint(t *testing.T) { 24 ctx := testctx.NewWithCfg(config.Project{ 25 Announce: config.Announce{ 26 Webhook: config.Webhook{}, 27 }, 28 }) 29 require.EqualError(t, Pipe{}.Announce(ctx), `webhook: no endpoint url`) 30 } 31 32 func TestMalformedEndpoint(t *testing.T) { 33 ctx := testctx.NewWithCfg(config.Project{ 34 Announce: config.Announce{ 35 Webhook: config.Webhook{ 36 EndpointURL: "httxxx://example.com", 37 }, 38 }, 39 }) 40 require.EqualError(t, Pipe{}.Announce(ctx), `webhook: Post "httxxx://example.com": unsupported protocol scheme "httxxx"`) 41 } 42 43 func TestAnnounceInvalidMessageTemplate(t *testing.T) { 44 ctx := testctx.NewWithCfg(config.Project{ 45 Announce: config.Announce{ 46 Webhook: config.Webhook{ 47 EndpointURL: "https://example.com/webhook", 48 MessageTemplate: "{{ .Foo }", 49 }, 50 }, 51 }) 52 testlib.RequireTemplateError(t, Pipe{}.Announce(ctx)) 53 } 54 55 type WebHookServerMockMessage struct { 56 Response string `json:"response"` 57 UUID uuid.UUID `json:"uuid"` 58 } 59 60 func TestAnnounceWebhook(t *testing.T) { 61 responseServer := WebHookServerMockMessage{ 62 Response: "Thanks for the announcement!", 63 UUID: uuid.New(), 64 } 65 66 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 67 defer r.Body.Close() 68 69 body, err := io.ReadAll(r.Body) 70 require.NoError(t, err) 71 require.Equal(t, "webhook-test", string(body)) 72 73 w.WriteHeader(http.StatusCreated) 74 w.Header().Set("Content-Type", "application/json") 75 err = json.NewEncoder(w).Encode(responseServer) 76 require.NoError(t, err) 77 })) 78 defer srv.Close() 79 80 ctx := testctx.NewWithCfg(config.Project{ 81 ProjectName: "webhook-test", 82 Announce: config.Announce{ 83 Webhook: config.Webhook{ 84 EndpointURL: srv.URL, 85 MessageTemplate: "{{ .ProjectName }}", 86 }, 87 }, 88 }) 89 require.NoError(t, Pipe{}.Announce(ctx)) 90 } 91 92 func TestAnnounceTLSWebhook(t *testing.T) { 93 responseServer := WebHookServerMockMessage{ 94 Response: "Thanks for the announcement!", 95 UUID: uuid.New(), 96 } 97 98 srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 99 defer r.Body.Close() 100 body, err := io.ReadAll(r.Body) 101 require.NoError(t, err) 102 require.Equal(t, "webhook-test", string(body)) 103 w.WriteHeader(http.StatusCreated) 104 w.Header().Set("Content-Type", "application/json") 105 err = json.NewEncoder(w).Encode(responseServer) 106 require.NoError(t, err) 107 })) 108 defer srv.Close() 109 fmt.Println(srv.URL) 110 ctx := testctx.NewWithCfg(config.Project{ 111 ProjectName: "webhook-test", 112 Announce: config.Announce{ 113 Webhook: config.Webhook{ 114 EndpointURL: srv.URL, 115 MessageTemplate: "{{ .ProjectName }}", 116 SkipTLSVerify: true, 117 }, 118 }, 119 }) 120 require.NoError(t, Pipe{}.Announce(ctx)) 121 } 122 123 func TestAnnounceTLSCheckCertWebhook(t *testing.T) { 124 responseServer := WebHookServerMockMessage{ 125 Response: "Thanks for the announcement!", 126 UUID: uuid.New(), 127 } 128 129 srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 130 defer r.Body.Close() 131 w.WriteHeader(http.StatusCreated) 132 w.Header().Set("Content-Type", "application/json") 133 err := json.NewEncoder(w).Encode(responseServer) 134 require.NoError(t, err) 135 })) 136 defer srv.Close() 137 fmt.Println(srv.URL) 138 ctx := testctx.NewWithCfg(config.Project{ 139 ProjectName: "webhook-test", 140 Announce: config.Announce{ 141 Webhook: config.Webhook{ 142 EndpointURL: srv.URL, 143 SkipTLSVerify: false, 144 }, 145 }, 146 }) 147 require.Error(t, Pipe{}.Announce(ctx)) 148 } 149 150 func TestAnnounceBasicAuthWebhook(t *testing.T) { 151 responseServer := WebHookServerMockMessage{ 152 Response: "Thanks for the announcement!", 153 UUID: uuid.New(), 154 } 155 156 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 157 defer r.Body.Close() 158 159 body, err := io.ReadAll(r.Body) 160 require.NoError(t, err) 161 require.Equal(t, "webhook-test", string(body)) 162 163 auth := r.Header.Get("Authorization") 164 require.Equal(t, fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte("user:pass"))), auth) 165 166 w.WriteHeader(http.StatusCreated) 167 w.Header().Set("Content-Type", "application/json") 168 err = json.NewEncoder(w).Encode(responseServer) 169 require.NoError(t, err) 170 })) 171 172 defer srv.Close() 173 174 ctx := testctx.NewWithCfg(config.Project{ 175 ProjectName: "webhook-test", 176 Announce: config.Announce{ 177 Webhook: config.Webhook{ 178 EndpointURL: srv.URL, 179 MessageTemplate: "{{ .ProjectName }}", 180 }, 181 }, 182 }) 183 t.Setenv("BASIC_AUTH_HEADER_VALUE", fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte("user:pass")))) 184 require.NoError(t, Pipe{}.Announce(ctx)) 185 } 186 187 func TestAnnounceAdditionalHeadersWebhook(t *testing.T) { 188 responseServer := WebHookServerMockMessage{ 189 Response: "Thanks for the announcement!", 190 UUID: uuid.New(), 191 } 192 193 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 194 defer r.Body.Close() 195 196 body, err := io.ReadAll(r.Body) 197 require.NoError(t, err) 198 require.Equal(t, "webhook-test", string(body)) 199 200 customHeader := r.Header.Get("X-Custom-Header") 201 require.Equal(t, "custom-value", customHeader) 202 203 w.WriteHeader(http.StatusCreated) 204 w.Header().Set("Content-Type", "application/json") 205 err = json.NewEncoder(w).Encode(responseServer) 206 require.NoError(t, err) 207 })) 208 defer srv.Close() 209 210 ctx := testctx.NewWithCfg(config.Project{ 211 ProjectName: "webhook-test", 212 Announce: config.Announce{ 213 Webhook: config.Webhook{ 214 EndpointURL: srv.URL, 215 MessageTemplate: "{{ .ProjectName }}", 216 Headers: map[string]string{ 217 "X-Custom-Header": "custom-value", 218 }, 219 }, 220 }, 221 }) 222 require.NoError(t, Pipe{}.Announce(ctx)) 223 } 224 225 func TestSkip(t *testing.T) { 226 t.Run("skip", func(t *testing.T) { 227 require.True(t, Pipe{}.Skip(testctx.New())) 228 }) 229 230 t.Run("dont skip", func(t *testing.T) { 231 ctx := testctx.NewWithCfg(config.Project{ 232 Announce: config.Announce{ 233 Webhook: config.Webhook{ 234 Enabled: true, 235 }, 236 }, 237 }) 238 require.False(t, Pipe{}.Skip(ctx)) 239 }) 240 }