github.com/go-playground/webhooks/v6@v6.3.0/bitbucket/bitbucket_test.go (about)

     1  package bitbucket
     2  
     3  import (
     4  	"bytes"
     5  	"log"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"testing"
    10  
    11  	"io"
    12  
    13  	"reflect"
    14  
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  // NOTES:
    19  // - Run "go test" to run tests
    20  // - Run "gocov test | gocov report" to report on test converage by file
    21  // - Run "gocov test | gocov annotate -" to report on all code and functions, those ,marked with "MISS" were never called
    22  //
    23  // or
    24  //
    25  // -- may be a good idea to change to output path to somewherelike /tmp
    26  // go test -coverprofile cover.out && go tool cover -html=cover.out -o cover.html
    27  //
    28  //
    29  const (
    30  	path = "/webhooks"
    31  )
    32  
    33  var hook *Webhook
    34  
    35  func TestMain(m *testing.M) {
    36  
    37  	// setup
    38  	var err error
    39  	hook, err = New(Options.UUID("MY_UUID"))
    40  	if err != nil {
    41  		log.Fatal(err)
    42  	}
    43  	os.Exit(m.Run())
    44  
    45  	// teardown
    46  }
    47  
    48  func newServer(handler http.HandlerFunc) *httptest.Server {
    49  	mux := http.NewServeMux()
    50  	mux.HandleFunc(path, handler)
    51  	return httptest.NewServer(mux)
    52  }
    53  
    54  func TestBadRequests(t *testing.T) {
    55  	assert := require.New(t)
    56  	tests := []struct {
    57  		name    string
    58  		event   Event
    59  		payload io.Reader
    60  		headers http.Header
    61  	}{
    62  		{
    63  			name:    "UUIDMissingEvent",
    64  			event:   RepoPushEvent,
    65  			payload: bytes.NewBuffer([]byte("{}")),
    66  			headers: http.Header{
    67  				"X-Event-Key": []string{"noneexistant_event"},
    68  			},
    69  		},
    70  		{
    71  			name:    "UUIDDoesNotMatchEvent",
    72  			event:   RepoPushEvent,
    73  			payload: bytes.NewBuffer([]byte("{}")),
    74  			headers: http.Header{
    75  				"X-Hook-UUID": []string{"THIS_DOES_NOT_MATCH"},
    76  				"X-Event-Key": []string{"repo:push"},
    77  			},
    78  		},
    79  		{
    80  			name:    "BadNoEventHeader",
    81  			event:   RepoPushEvent,
    82  			payload: bytes.NewBuffer([]byte("{}")),
    83  			headers: http.Header{
    84  				"X-Hook-UUID": []string{"MY_UUID"},
    85  			},
    86  		},
    87  		{
    88  			name:    "BadBody",
    89  			event:   RepoPushEvent,
    90  			payload: bytes.NewBuffer([]byte("")),
    91  			headers: http.Header{
    92  				"X-Hook-UUID": []string{"MY_UUID"},
    93  				"X-Event-Key": []string{"repo:push"},
    94  			},
    95  		},
    96  		{
    97  			name:    "UnsubscribedEvent",
    98  			event:   RepoPushEvent,
    99  			payload: bytes.NewBuffer([]byte("")),
   100  			headers: http.Header{
   101  				"X-Hook-UUID": []string{"MY_UUID"},
   102  				"X-Event-Key": []string{"noneexistant_event"},
   103  			},
   104  		},
   105  	}
   106  
   107  	for _, tt := range tests {
   108  		tc := tt
   109  		client := &http.Client{}
   110  		t.Run(tt.name, func(t *testing.T) {
   111  			t.Parallel()
   112  			var parseError error
   113  			server := newServer(func(w http.ResponseWriter, r *http.Request) {
   114  				_, parseError = hook.Parse(r, tc.event)
   115  			})
   116  			defer server.Close()
   117  			req, err := http.NewRequest(http.MethodPost, server.URL+path, tc.payload)
   118  			assert.NoError(err)
   119  			req.Header = tc.headers
   120  			req.Header.Set("Content-Type", "application/json")
   121  
   122  			resp, err := client.Do(req)
   123  			assert.NoError(err)
   124  			assert.Equal(http.StatusOK, resp.StatusCode)
   125  			assert.Error(parseError)
   126  		})
   127  	}
   128  }
   129  
   130  func TestWebhooks(t *testing.T) {
   131  	assert := require.New(t)
   132  	tests := []struct {
   133  		name     string
   134  		event    Event
   135  		typ      interface{}
   136  		filename string
   137  		headers  http.Header
   138  	}{
   139  		{
   140  			name:     "RepoPush",
   141  			event:    RepoPushEvent,
   142  			typ:      RepoPushPayload{},
   143  			filename: "../testdata/bitbucket/repo-push.json",
   144  			headers: http.Header{
   145  				"X-Hook-UUID": []string{"MY_UUID"},
   146  				"X-Event-Key": []string{"repo:push"},
   147  			},
   148  		},
   149  		{
   150  			name:     "RepoFork",
   151  			event:    RepoForkEvent,
   152  			typ:      RepoForkPayload{},
   153  			filename: "../testdata/bitbucket/repo-fork.json",
   154  			headers: http.Header{
   155  				"X-Hook-UUID": []string{"MY_UUID"},
   156  				"X-Event-Key": []string{"repo:fork"},
   157  			},
   158  		},
   159  		{
   160  			name:     "RepoUpdated",
   161  			event:    RepoUpdatedEvent,
   162  			typ:      RepoUpdatedPayload{},
   163  			filename: "../testdata/bitbucket/repo-updated.json",
   164  			headers: http.Header{
   165  				"X-Hook-UUID": []string{"MY_UUID"},
   166  				"X-Event-Key": []string{"repo:updated"},
   167  			},
   168  		},
   169  		{
   170  			name:     "RepoCommitCommentCreated",
   171  			event:    RepoCommitCommentCreatedEvent,
   172  			typ:      RepoCommitCommentCreatedPayload{},
   173  			filename: "../testdata/bitbucket/commit-comment-created.json",
   174  			headers: http.Header{
   175  				"X-Hook-UUID": []string{"MY_UUID"},
   176  				"X-Event-Key": []string{"repo:commit_comment_created"},
   177  			},
   178  		},
   179  		{
   180  			name:     "RepoCommitStatusCreated",
   181  			event:    RepoCommitStatusCreatedEvent,
   182  			typ:      RepoCommitStatusCreatedPayload{},
   183  			filename: "../testdata/bitbucket/repo-commit-status-created.json",
   184  			headers: http.Header{
   185  				"X-Hook-UUID": []string{"MY_UUID"},
   186  				"X-Event-Key": []string{"repo:commit_status_created"},
   187  			},
   188  		},
   189  		{
   190  			name:     "RepoCommitStatusUpdated",
   191  			event:    RepoCommitStatusUpdatedEvent,
   192  			typ:      RepoCommitStatusUpdatedPayload{},
   193  			filename: "../testdata/bitbucket/repo-commit-status-updated.json",
   194  			headers: http.Header{
   195  				"X-Hook-UUID": []string{"MY_UUID"},
   196  				"X-Event-Key": []string{"repo:commit_status_updated"},
   197  			},
   198  		},
   199  		{
   200  			name:     "IssueCreated",
   201  			event:    IssueCreatedEvent,
   202  			typ:      IssueCreatedPayload{},
   203  			filename: "../testdata/bitbucket/issue-created.json",
   204  			headers: http.Header{
   205  				"X-Hook-UUID": []string{"MY_UUID"},
   206  				"X-Event-Key": []string{"issue:created"},
   207  			},
   208  		},
   209  		{
   210  			name:     "IssueUpdated",
   211  			event:    IssueUpdatedEvent,
   212  			typ:      IssueUpdatedPayload{},
   213  			filename: "../testdata/bitbucket/issue-updated.json",
   214  			headers: http.Header{
   215  				"X-Hook-UUID": []string{"MY_UUID"},
   216  				"X-Event-Key": []string{"issue:updated"},
   217  			},
   218  		},
   219  		{
   220  			name:     "IssueUpdated",
   221  			event:    IssueUpdatedEvent,
   222  			typ:      IssueUpdatedPayload{},
   223  			filename: "../testdata/bitbucket/issue-updated.json",
   224  			headers: http.Header{
   225  				"X-Hook-UUID": []string{"MY_UUID"},
   226  				"X-Event-Key": []string{"issue:updated"},
   227  			},
   228  		},
   229  		{
   230  			name:     "IssueCommentCreated",
   231  			event:    IssueCommentCreatedEvent,
   232  			typ:      IssueCommentCreatedPayload{},
   233  			filename: "../testdata/bitbucket/issue-comment-created.json",
   234  			headers: http.Header{
   235  				"X-Hook-UUID": []string{"MY_UUID"},
   236  				"X-Event-Key": []string{"issue:comment_created"},
   237  			},
   238  		},
   239  		{
   240  			name:     "PullRequestCreated",
   241  			event:    PullRequestCreatedEvent,
   242  			typ:      PullRequestCreatedPayload{},
   243  			filename: "../testdata/bitbucket/pull-request-created.json",
   244  			headers: http.Header{
   245  				"X-Hook-UUID": []string{"MY_UUID"},
   246  				"X-Event-Key": []string{"pullrequest:created"},
   247  			},
   248  		},
   249  		{
   250  			name:     "PullRequestUpdated",
   251  			event:    PullRequestUpdatedEvent,
   252  			typ:      PullRequestUpdatedPayload{},
   253  			filename: "../testdata/bitbucket/pull-request-updated.json",
   254  			headers: http.Header{
   255  				"X-Hook-UUID": []string{"MY_UUID"},
   256  				"X-Event-Key": []string{"pullrequest:updated"},
   257  			},
   258  		},
   259  		{
   260  			name:     "PullRequestApproved",
   261  			event:    PullRequestApprovedEvent,
   262  			typ:      PullRequestApprovedPayload{},
   263  			filename: "../testdata/bitbucket/pull-request-approved.json",
   264  			headers: http.Header{
   265  				"X-Hook-UUID": []string{"MY_UUID"},
   266  				"X-Event-Key": []string{"pullrequest:approved"},
   267  			},
   268  		},
   269  		{
   270  			name:     "PullRequestApprovalRemoved",
   271  			event:    PullRequestUnapprovedEvent,
   272  			typ:      PullRequestUnapprovedPayload{},
   273  			filename: "../testdata/bitbucket/pull-request-approval-removed.json",
   274  			headers: http.Header{
   275  				"X-Hook-UUID": []string{"MY_UUID"},
   276  				"X-Event-Key": []string{"pullrequest:unapproved"},
   277  			},
   278  		},
   279  		{
   280  			name:     "PullRequestMerged",
   281  			event:    PullRequestMergedEvent,
   282  			typ:      PullRequestMergedPayload{},
   283  			filename: "../testdata/bitbucket/pull-request-merged.json",
   284  			headers: http.Header{
   285  				"X-Hook-UUID": []string{"MY_UUID"},
   286  				"X-Event-Key": []string{"pullrequest:fulfilled"},
   287  			},
   288  		},
   289  		{
   290  			name:     "PullRequestDeclined",
   291  			event:    PullRequestDeclinedEvent,
   292  			typ:      PullRequestDeclinedPayload{},
   293  			filename: "../testdata/bitbucket/pull-request-declined.json",
   294  			headers: http.Header{
   295  				"X-Hook-UUID": []string{"MY_UUID"},
   296  				"X-Event-Key": []string{"pullrequest:rejected"},
   297  			},
   298  		},
   299  		{
   300  			name:     "PullRequestCommentCreated",
   301  			event:    PullRequestCommentCreatedEvent,
   302  			typ:      PullRequestCommentCreatedPayload{},
   303  			filename: "../testdata/bitbucket/pull-request-comment-created.json",
   304  			headers: http.Header{
   305  				"X-Hook-UUID": []string{"MY_UUID"},
   306  				"X-Event-Key": []string{"pullrequest:comment_created"},
   307  			},
   308  		},
   309  		{
   310  			name:     "PullRequestCommentUpdated",
   311  			event:    PullRequestCommentUpdatedEvent,
   312  			typ:      PullRequestCommentUpdatedPayload{},
   313  			filename: "../testdata/bitbucket/pull-request-comment-updated.json",
   314  			headers: http.Header{
   315  				"X-Hook-UUID": []string{"MY_UUID"},
   316  				"X-Event-Key": []string{"pullrequest:comment_updated"},
   317  			},
   318  		},
   319  		{
   320  			name:     "PullRequestCommentDeleted",
   321  			event:    PullRequestCommentDeletedEvent,
   322  			typ:      PullRequestCommentDeletedPayload{},
   323  			filename: "../testdata/bitbucket/pull-request-comment-deleted.json",
   324  			headers: http.Header{
   325  				"X-Hook-UUID": []string{"MY_UUID"},
   326  				"X-Event-Key": []string{"pullrequest:comment_deleted"},
   327  			},
   328  		},
   329  	}
   330  
   331  	for _, tt := range tests {
   332  		tc := tt
   333  		client := &http.Client{}
   334  		t.Run(tt.name, func(t *testing.T) {
   335  			t.Parallel()
   336  			payload, err := os.Open(tc.filename)
   337  			assert.NoError(err)
   338  			defer func() {
   339  				_ = payload.Close()
   340  			}()
   341  
   342  			var parseError error
   343  			var results interface{}
   344  			server := newServer(func(w http.ResponseWriter, r *http.Request) {
   345  				results, parseError = hook.Parse(r, tc.event)
   346  			})
   347  			defer server.Close()
   348  			req, err := http.NewRequest(http.MethodPost, server.URL+path, payload)
   349  			assert.NoError(err)
   350  			req.Header = tc.headers
   351  			req.Header.Set("Content-Type", "application/json")
   352  
   353  			resp, err := client.Do(req)
   354  			assert.NoError(err)
   355  			assert.Equal(http.StatusOK, resp.StatusCode)
   356  			assert.NoError(parseError)
   357  			assert.Equal(reflect.TypeOf(tc.typ), reflect.TypeOf(results))
   358  		})
   359  	}
   360  }