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  }