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