361 lines
9.5 KiB
Go
361 lines
9.5 KiB
Go
package bitbucket
|
|
|
|
import (
|
|
"bytes"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"io"
|
|
|
|
"reflect"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// NOTES:
|
|
// - Run "go test" to run tests
|
|
// - Run "gocov test | gocov report" to report on test converage by file
|
|
// - Run "gocov test | gocov annotate -" to report on all code and functions, those ,marked with "MISS" were never called
|
|
//
|
|
// or
|
|
//
|
|
// -- may be a good idea to change to output path to somewherelike /tmp
|
|
// go test -coverprofile cover.out && go tool cover -html=cover.out -o cover.html
|
|
//
|
|
//
|
|
const (
|
|
path = "/webhooks"
|
|
)
|
|
|
|
var hook *Webhook
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
// setup
|
|
var err error
|
|
hook, err = New(Options.UUID("MY_UUID"))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
os.Exit(m.Run())
|
|
|
|
// teardown
|
|
}
|
|
|
|
func newServer(handler http.HandlerFunc) *httptest.Server {
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc(path, handler)
|
|
return httptest.NewServer(mux)
|
|
}
|
|
|
|
func TestBadRequests(t *testing.T) {
|
|
assert := require.New(t)
|
|
tests := []struct {
|
|
name string
|
|
event Event
|
|
payload io.Reader
|
|
headers http.Header
|
|
}{
|
|
{
|
|
name: "UUIDMissingEvent",
|
|
event: RepoPushEvent,
|
|
payload: bytes.NewBuffer([]byte("{}")),
|
|
headers: http.Header{
|
|
"X-Event-Key": []string{"noneexistant_event"},
|
|
},
|
|
},
|
|
{
|
|
name: "UUIDDoesNotMatchEvent",
|
|
event: RepoPushEvent,
|
|
payload: bytes.NewBuffer([]byte("{}")),
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"THIS_DOES_NOT_MATCH"},
|
|
"X-Event-Key": []string{"repo:push"},
|
|
},
|
|
},
|
|
{
|
|
name: "BadNoEventHeader",
|
|
event: RepoPushEvent,
|
|
payload: bytes.NewBuffer([]byte("{}")),
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
},
|
|
},
|
|
{
|
|
name: "BadBody",
|
|
event: RepoPushEvent,
|
|
payload: bytes.NewBuffer([]byte("")),
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"repo:push"},
|
|
},
|
|
},
|
|
{
|
|
name: "UnsubscribedEvent",
|
|
event: RepoPushEvent,
|
|
payload: bytes.NewBuffer([]byte("")),
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"noneexistant_event"},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tc := tt
|
|
client := &http.Client{}
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
var parseError error
|
|
server := newServer(func(w http.ResponseWriter, r *http.Request) {
|
|
_, parseError = hook.Parse(r, tc.event)
|
|
})
|
|
defer server.Close()
|
|
req, err := http.NewRequest(http.MethodPost, server.URL+path, tc.payload)
|
|
assert.NoError(err)
|
|
req.Header = tc.headers
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := client.Do(req)
|
|
assert.NoError(err)
|
|
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
assert.Error(parseError)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWebhooks(t *testing.T) {
|
|
assert := require.New(t)
|
|
tests := []struct {
|
|
name string
|
|
event Event
|
|
typ interface{}
|
|
filename string
|
|
headers http.Header
|
|
}{
|
|
{
|
|
name: "RepoPush",
|
|
event: RepoPushEvent,
|
|
typ: RepoPushPayload{},
|
|
filename: "../testdata/bitbucket/repo-push.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"repo:push"},
|
|
},
|
|
},
|
|
{
|
|
name: "RepoFork",
|
|
event: RepoForkEvent,
|
|
typ: RepoForkPayload{},
|
|
filename: "../testdata/bitbucket/repo-fork.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"repo:fork"},
|
|
},
|
|
},
|
|
{
|
|
name: "RepoUpdated",
|
|
event: RepoUpdatedEvent,
|
|
typ: RepoUpdatedPayload{},
|
|
filename: "../testdata/bitbucket/repo-updated.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"repo:updated"},
|
|
},
|
|
},
|
|
{
|
|
name: "RepoCommitCommentCreated",
|
|
event: RepoCommitCommentCreatedEvent,
|
|
typ: RepoCommitCommentCreatedPayload{},
|
|
filename: "../testdata/bitbucket/commit-comment-created.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"repo:commit_comment_created"},
|
|
},
|
|
},
|
|
{
|
|
name: "RepoCommitStatusCreated",
|
|
event: RepoCommitStatusCreatedEvent,
|
|
typ: RepoCommitStatusCreatedPayload{},
|
|
filename: "../testdata/bitbucket/repo-commit-status-created.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"repo:commit_status_created"},
|
|
},
|
|
},
|
|
{
|
|
name: "RepoCommitStatusUpdated",
|
|
event: RepoCommitStatusUpdatedEvent,
|
|
typ: RepoCommitStatusUpdatedPayload{},
|
|
filename: "../testdata/bitbucket/repo-commit-status-updated.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"repo:commit_status_updated"},
|
|
},
|
|
},
|
|
{
|
|
name: "IssueCreated",
|
|
event: IssueCreatedEvent,
|
|
typ: IssueCreatedPayload{},
|
|
filename: "../testdata/bitbucket/issue-created.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"issue:created"},
|
|
},
|
|
},
|
|
{
|
|
name: "IssueUpdated",
|
|
event: IssueUpdatedEvent,
|
|
typ: IssueUpdatedPayload{},
|
|
filename: "../testdata/bitbucket/issue-updated.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"issue:updated"},
|
|
},
|
|
},
|
|
{
|
|
name: "IssueUpdated",
|
|
event: IssueUpdatedEvent,
|
|
typ: IssueUpdatedPayload{},
|
|
filename: "../testdata/bitbucket/issue-updated.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"issue:updated"},
|
|
},
|
|
},
|
|
{
|
|
name: "IssueCommentCreated",
|
|
event: IssueCommentCreatedEvent,
|
|
typ: IssueCommentCreatedPayload{},
|
|
filename: "../testdata/bitbucket/issue-comment-created.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"issue:comment_created"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestCreated",
|
|
event: PullRequestCreatedEvent,
|
|
typ: PullRequestCreatedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-created.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:created"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestUpdated",
|
|
event: PullRequestUpdatedEvent,
|
|
typ: PullRequestUpdatedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-updated.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:updated"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestApproved",
|
|
event: PullRequestApprovedEvent,
|
|
typ: PullRequestApprovedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-approved.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:approved"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestApprovalRemoved",
|
|
event: PullRequestUnapprovedEvent,
|
|
typ: PullRequestUnapprovedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-approval-removed.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:unapproved"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestMerged",
|
|
event: PullRequestMergedEvent,
|
|
typ: PullRequestMergedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-merged.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:fulfilled"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestDeclined",
|
|
event: PullRequestDeclinedEvent,
|
|
typ: PullRequestDeclinedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-declined.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:rejected"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestCommentCreated",
|
|
event: PullRequestCommentCreatedEvent,
|
|
typ: PullRequestCommentCreatedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-comment-created.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:comment_created"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestCommentUpdated",
|
|
event: PullRequestCommentUpdatedEvent,
|
|
typ: PullRequestCommentUpdatedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-comment-updated.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:comment_updated"},
|
|
},
|
|
},
|
|
{
|
|
name: "PullRequestCommentDeleted",
|
|
event: PullRequestCommentDeletedEvent,
|
|
typ: PullRequestCommentDeletedPayload{},
|
|
filename: "../testdata/bitbucket/pull-request-comment-deleted.json",
|
|
headers: http.Header{
|
|
"X-Hook-UUID": []string{"MY_UUID"},
|
|
"X-Event-Key": []string{"pullrequest:comment_deleted"},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tc := tt
|
|
client := &http.Client{}
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
payload, err := os.Open(tc.filename)
|
|
assert.NoError(err)
|
|
defer func() {
|
|
_ = payload.Close()
|
|
}()
|
|
|
|
var parseError error
|
|
var results interface{}
|
|
server := newServer(func(w http.ResponseWriter, r *http.Request) {
|
|
results, parseError = hook.Parse(r, tc.event)
|
|
})
|
|
defer server.Close()
|
|
req, err := http.NewRequest(http.MethodPost, server.URL+path, payload)
|
|
assert.NoError(err)
|
|
req.Header = tc.headers
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := client.Do(req)
|
|
assert.NoError(err)
|
|
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
assert.NoError(parseError)
|
|
assert.Equal(reflect.TypeOf(tc.typ), reflect.TypeOf(results))
|
|
})
|
|
}
|
|
}
|