diff --git a/README.md b/README.md
index 044b612..0bff573 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,14 @@
Library webhooks
================
-
+
+
[](https://semaphoreci.com/joeybloggs/webhooks)
[](https://coveralls.io/github/go-playground/webhooks?branch=v1)
+[](https://goreportcard.com/report/go-playground/webhooks)
[](https://godoc.org/gopkg.in/go-playground/webhooks.v1)
+
-Library webhooks allows for easy recieving and parsing of GitHub Webhook Events; more services to come i.e. BitBucket...
+Library webhooks allows for easy recieving and parsing of GitHub & Bitbucket Webhook Events
Features:
diff --git a/bitbucket/bitbucket.go b/bitbucket/bitbucket.go
new file mode 100644
index 0000000..b43c154
--- /dev/null
+++ b/bitbucket/bitbucket.go
@@ -0,0 +1,179 @@
+package bitbucket
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "net/http"
+
+ "gopkg.in/go-playground/webhooks.v1"
+)
+
+// Webhook instance contains all methods needed to process events
+type Webhook struct {
+ provider webhooks.Provider
+ uuid string
+ eventFuncs map[Event]webhooks.ProcessPayloadFunc
+}
+
+// Config defines the configuration to create a new Bitbucket Webhook instance
+type Config struct {
+ UUID string
+}
+
+// Event defines a Bitbucket hook event type
+type Event string
+
+// Bitbucket hook types
+const (
+ RepoPushEvent Event = "repo:push"
+ RepoForkEvent Event = "repo:fork"
+ RepoCommitCommentCreatedEvent Event = "repo:commit_comment_created"
+ RepoCommitStatusCreatedEvent Event = "repo:commit_status_created"
+ RepoCommitStatusUpdatedEvent Event = "repo:commit_status_updated"
+ IssueCreatedEvent Event = "issue:created"
+ IssueUpdatedEvent Event = "issue:updated"
+ IssueCommentCreatedEvent Event = "issue:comment_created"
+ PullRequestCreatedEvent Event = "pullrequest:created"
+ PullRequestUpdatedEvent Event = "pullrequest:updated"
+ PullRequestApprovedEvent Event = "pullrequest:approved"
+ PullRequestApprovalRemovedEvent Event = "pullrequest:unapproved"
+ PullRequestMergedEvent Event = "pullrequest:fulfilled"
+ PullRequestDeclinedEvent Event = "pullrequest:rejected"
+ PullRequestCommentCreatedEvent Event = "pullrequest:comment_created"
+ PullRequestCommentUpdatedEvent Event = "pullrequest:comment_updated"
+ PullRequestCommentDeletedEvent Event = "pull_request:comment_deleted"
+)
+
+// New creates and returns a WebHook instance denoted by the Provider type
+func New(config *Config) *Webhook {
+ return &Webhook{
+ provider: webhooks.Bitbucket,
+ uuid: config.UUID,
+ eventFuncs: map[Event]webhooks.ProcessPayloadFunc{},
+ }
+}
+
+// Provider returns the current hooks provider ID
+func (hook Webhook) Provider() webhooks.Provider {
+ return hook.provider
+}
+
+// RegisterEvents registers the function to call when the specified event(s) are encountered
+func (hook Webhook) RegisterEvents(fn webhooks.ProcessPayloadFunc, events ...Event) {
+
+ for _, event := range events {
+ hook.eventFuncs[event] = fn
+ }
+}
+
+// ParsePayload parses and verifies the payload and fires off the mapped function, if it exists.
+func (hook Webhook) ParsePayload(w http.ResponseWriter, r *http.Request) {
+
+ uuid := r.Header.Get("X-Hook-UUID")
+ if uuid == "" {
+ http.Error(w, "400 Bad Request - Missing X-Hook-UUID Header", http.StatusBadRequest)
+ return
+ }
+
+ if uuid != hook.uuid {
+ http.Error(w, "403 Forbidden - Missing X-Hook-UUID does not match", http.StatusForbidden)
+ return
+ }
+
+ event := r.Header.Get("X-Event-Key")
+ if event == "" {
+ http.Error(w, "400 Bad Request - Missing X-Event-Key Header", http.StatusBadRequest)
+ return
+ }
+
+ bitbucketEvent := Event(event)
+
+ fn, ok := hook.eventFuncs[bitbucketEvent]
+ // if no event registered
+ if !ok {
+ return
+ }
+
+ payload, err := ioutil.ReadAll(r.Body)
+ if err != nil || len(payload) == 0 {
+ http.Error(w, "Error reading Body", http.StatusInternalServerError)
+ return
+ }
+
+ switch bitbucketEvent {
+ case RepoPushEvent:
+ var pl RepoPushPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case RepoForkEvent:
+ var pl RepoForkPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case RepoCommitCommentCreatedEvent:
+ var pl RepoCommitCommentCreatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case RepoCommitStatusCreatedEvent:
+ var pl RepoCommitStatusCreatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case RepoCommitStatusUpdatedEvent:
+ var pl RepoCommitStatusUpdatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case IssueCreatedEvent:
+ var pl IssueCreatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case IssueUpdatedEvent:
+ var pl IssueUpdatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case IssueCommentCreatedEvent:
+ var pl IssueCommentCreatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestCreatedEvent:
+ var pl PullRequestCreatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestUpdatedEvent:
+ var pl PullRequestUpdatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestApprovedEvent:
+ var pl PullRequestApprovedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestApprovalRemovedEvent:
+ var pl PullRequestApprovalRemovedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestMergedEvent:
+ var pl PullRequestMergedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestDeclinedEvent:
+ var pl PullRequestDeclinedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestCommentCreatedEvent:
+ var pl PullRequestCommentCreatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestCommentUpdatedEvent:
+ var pl PullRequestCommentUpdatedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ case PullRequestCommentDeletedEvent:
+ var pl PullRequestCommentDeletedPayload
+ json.Unmarshal([]byte(payload), &pl)
+ hook.runProcessPayloadFunc(fn, pl)
+ }
+}
+
+func (hook Webhook) runProcessPayloadFunc(fn webhooks.ProcessPayloadFunc, results interface{}) {
+ go func(fn webhooks.ProcessPayloadFunc, results interface{}) {
+ fn(results)
+ }(fn, results)
+}
diff --git a/bitbucket/bitbucket_test.go b/bitbucket/bitbucket_test.go
new file mode 100644
index 0000000..602e084
--- /dev/null
+++ b/bitbucket/bitbucket_test.go
@@ -0,0 +1,2881 @@
+package bitbucket
+
+import (
+ "bytes"
+ "net/http"
+ "os"
+ "strconv"
+ "testing"
+ "time"
+
+ . "gopkg.in/go-playground/assert.v1"
+ "gopkg.in/go-playground/webhooks.v1"
+)
+
+// 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 (
+ port = 3010
+ path = "/webhooks"
+)
+
+// HandlePayload handles GitHub event(s)
+func HandlePayload(payload interface{}) {
+
+}
+
+var hook *Webhook
+
+func TestMain(m *testing.M) {
+
+ // setup
+ hook = New(&Config{UUID: "MY_UUID"})
+ hook.RegisterEvents(HandlePayload, RepoPushEvent, RepoForkEvent, RepoCommitCommentCreatedEvent, RepoCommitStatusCreatedEvent, RepoCommitStatusUpdatedEvent, IssueCreatedEvent, IssueUpdatedEvent, IssueCommentCreatedEvent, PullRequestCreatedEvent, PullRequestUpdatedEvent, PullRequestApprovedEvent, PullRequestApprovalRemovedEvent, PullRequestMergedEvent, PullRequestDeclinedEvent, PullRequestCommentCreatedEvent, PullRequestCommentUpdatedEvent, PullRequestCommentDeletedEvent)
+
+ go webhooks.Run(hook, "127.0.0.1:"+strconv.Itoa(port), path)
+ time.Sleep(5000)
+
+ os.Exit(m.Run())
+
+ // teardown
+}
+
+func TestProvider(t *testing.T) {
+ Equal(t, hook.Provider(), webhooks.Bitbucket)
+}
+
+func TestUUIDMissingEvent(t *testing.T) {
+ payload := "{}"
+
+ req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload)))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("X-Event-Key", "noneexistant_event")
+
+ Equal(t, err, nil)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ Equal(t, err, nil)
+
+ defer resp.Body.Close()
+
+ Equal(t, resp.StatusCode, http.StatusBadRequest)
+}
+
+func TestUUIDDoesNotMatchEvent(t *testing.T) {
+ payload := "{}"
+
+ req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload)))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("X-Hook-UUID", "THIS_DOES_NOT_MATCH")
+
+ Equal(t, err, nil)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ Equal(t, err, nil)
+
+ defer resp.Body.Close()
+
+ Equal(t, resp.StatusCode, http.StatusForbidden)
+}
+
+func TestBadNoEventHeader(t *testing.T) {
+ payload := "{}"
+
+ req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload)))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("X-Hook-UUID", "MY_UUID")
+
+ Equal(t, err, nil)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ Equal(t, err, nil)
+
+ defer resp.Body.Close()
+
+ Equal(t, resp.StatusCode, http.StatusBadRequest)
+}
+
+func TestUnsubscribedEvent(t *testing.T) {
+ payload := "{}"
+
+ req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload)))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("X-Hook-UUID", "MY_UUID")
+ req.Header.Set("X-Event-Key", "noneexistant_event")
+
+ Equal(t, err, nil)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ Equal(t, err, nil)
+
+ defer resp.Body.Close()
+
+ Equal(t, resp.StatusCode, http.StatusOK)
+}
+
+func TestBadBody(t *testing.T) {
+ payload := ""
+
+ req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload)))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("X-Hook-UUID", "MY_UUID")
+ req.Header.Set("X-Event-Key", "repo:push")
+
+ Equal(t, err, nil)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ Equal(t, err, nil)
+
+ defer resp.Body.Close()
+
+ Equal(t, resp.StatusCode, http.StatusInternalServerError)
+}
+
+func TestRepoPush(t *testing.T) {
+
+ payload := `{
+ "actor":{
+ "username":"emmap1",
+ "display_name":"Emma",
+ "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/users/emmap1"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/emmap1"
+ },
+ "avatar":{
+ "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png"
+ }
+ }
+ },
+ "repository":{
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/bitbucket/bitbucket"
+ },
+ "avatar":{
+ "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png"
+ }
+ },
+ "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}",
+ "full_name":"team_name/repo_name",
+ "name":"repo_name",
+ "scm":"git",
+ "is_private":true
+ },
+ "push":{
+ "changes":[
+ {
+ "new":{
+ "type":"branch",
+ "name":"name-of-branch",
+ "target":{
+ "type":"commit",
+ "hash":"709d658dc5b6d6afcd46049c2f332ee3f515a67d",
+ "author":{
+ "username":"emmap1",
+ "display_name":"Emma",
+ "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/users/emmap1"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/emmap1"
+ },
+ "avatar":{
+ "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png"
+ }
+ }
+ },
+ "message":"new commit message\n",
+ "date":"2015-06-09T03:34:49+00:00",
+ "parents":[
+ {
+ "type":"commit",
+ "hash":"1e65c05c1d5171631d92438a13901ca7dae9618c",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/8cbbd65829c7ad834a97841e0defc965718036a0"
+ },
+ "html":{
+ "href":"https://bitbucket.org/user_name/repo_name/commits/8cbbd65829c7ad834a97841e0defc965718036a0"
+ }
+ }
+ }
+ ],
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/c4b2b7914156a878aa7c9da452a09fb50c2091f2"
+ },
+ "html":{
+ "href":"https://bitbucket.org/user_name/repo_name/commits/c4b2b7914156a878aa7c9da452a09fb50c2091f2"
+ }
+ }
+ },
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/refs/branches/master"
+ },
+ "commits":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commits/master"
+ },
+ "html":{
+ "href":"https://bitbucket.org/user_name/repo_name/branch/master"
+ }
+ }
+ },
+ "old":{
+ "type":"branch",
+ "name":"name-of-branch",
+ "target":{
+ "type":"commit",
+ "hash":"1e65c05c1d5171631d92438a13901ca7dae9618c",
+ "author":{
+ "username":"emmap1",
+ "display_name":"Emma",
+ "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/users/emmap1"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/emmap1"
+ },
+ "avatar":{
+ "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png"
+ }
+ }
+ },
+ "message":"old commit message\n",
+ "date":"2015-06-08T21:34:56+00:00",
+ "parents":[
+ {
+ "type":"commit",
+ "hash":"e0d0c2041e09746be5ce4b55067d5a8e3098c843",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/9c4a3452da3bc4f37af5a6bb9c784246f44406f7"
+ },
+ "html":{
+ "href":"https://bitbucket.org/user_name/repo_name/commits/9c4a3452da3bc4f37af5a6bb9c784246f44406f7"
+ }
+ }
+ }
+ ],
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/b99ea6dad8f416e57c5ca78c1ccef590600d841b"
+ },
+ "html":{
+ "href":"https://bitbucket.org/user_name/repo_name/commits/b99ea6dad8f416e57c5ca78c1ccef590600d841b"
+ }
+ }
+ },
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/refs/branches/master"
+ },
+ "commits":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commits/master"
+ },
+ "html":{
+ "href":"https://bitbucket.org/user_name/repo_name/branch/master"
+ }
+ }
+ },
+ "links":{
+ "html":{
+ "href":"https://bitbucket.org/user_name/repo_name/branches/compare/c4b2b7914156a878aa7c9da452a09fb50c2091f2..b99ea6dad8f416e57c5ca78c1ccef590600d841b"
+ },
+ "diff":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/diff/c4b2b7914156a878aa7c9da452a09fb50c2091f2..b99ea6dad8f416e57c5ca78c1ccef590600d841b"
+ },
+ "commits":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commits?include=c4b2b7914156a878aa7c9da452a09fb50c2091f2&exclude=b99ea6dad8f416e57c5ca78c1ccef590600d841b"
+ }
+ },
+ "created":false,
+ "forced":false,
+ "closed":false,
+ "commits":[
+ {
+ "hash":"03f4a7270240708834de475bcf21532d6134777e",
+ "type":"commit",
+ "message":"commit message\n",
+ "author":{
+ "username":"emmap1",
+ "display_name":"Emma",
+ "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/users/emmap1"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/emmap1"
+ },
+ "avatar":{
+ "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png"
+ }
+ }
+ },
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/2.0/repositories/user/repo/commit/03f4a7270240708834de475bcf21532d6134777e"
+ },
+ "html":{
+ "href":"https://bitbucket.org/user/repo/commits/03f4a7270240708834de475bcf21532d6134777e"
+ }
+ }
+ }
+ ],
+ "truncated":false
+ }
+ ]
+ }
+}
+`
+
+ req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload)))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("X-Hook-UUID", "MY_UUID")
+ req.Header.Set("X-Event-Key", "repo:push")
+
+ Equal(t, err, nil)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ Equal(t, err, nil)
+
+ defer resp.Body.Close()
+
+ Equal(t, resp.StatusCode, http.StatusOK)
+}
+
+func TestRepoFork(t *testing.T) {
+
+ payload := `{
+ "actor":{
+ "username":"emmap1",
+ "display_name":"Emma",
+ "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/users/emmap1"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/emmap1"
+ },
+ "avatar":{
+ "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png"
+ }
+ }
+ },
+ "repository":{
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/bitbucket/bitbucket"
+ },
+ "avatar":{
+ "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png"
+ }
+ },
+ "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}",
+ "full_name":"team_name/repo_name",
+ "name":"repo_name",
+ "scm":"git",
+ "is_private":true
+ },
+ "fork":{
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/bitbucket/bitbucket"
+ },
+ "avatar":{
+ "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png"
+ }
+ },
+ "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}",
+ "full_name":"team_name/repo_name",
+ "name":"repo_name",
+ "scm":"git",
+ "is_private":true
+ }
+}
+`
+
+ req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload)))
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("X-Hook-UUID", "MY_UUID")
+ req.Header.Set("X-Event-Key", "repo:fork")
+
+ Equal(t, err, nil)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ Equal(t, err, nil)
+
+ defer resp.Body.Close()
+
+ Equal(t, resp.StatusCode, http.StatusOK)
+}
+
+func TestRepoCommitCommentCreated(t *testing.T) {
+
+ payload := `{
+ "actor":{
+ "username":"emmap1",
+ "display_name":"Emma",
+ "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}",
+ "links":{
+ "self":{
+ "href":"https://api.bitbucket.org/api/2.0/users/emmap1"
+ },
+ "html":{
+ "href":"https://api.bitbucket.org/emmap1"
+ },
+ "avatar":{
+ "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png"
+ }
+ }
+ },
+ "comment":{
+ "id":17,
+ "parent":{
+ "id":16
+ },
+ "content":{
+ "raw":"Comment text",
+ "html":"
Comment text
", + "markup":"markdown" + }, + "inline":{ + "path":"path/to/file", + "from":null, + "to":10 + }, + "created_on":"2015-04-06T16:52:29.982346+00:00", + "updated_on":"2015-04-06T16:52:29.983730+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/comments/comment_id" + }, + "html":{ + "href":"https://api.bitbucket.org/comment_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "commit":{ + "hash":"d3022fc0ca3d65c7f6654eea129d6bf0cf0ee08e" + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "repo:commit_comment_created") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestRepoCommitStatusCreated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "commit_status":{ + "name":"Unit Tests (Python)", + "description":"Build started", + "state":"INPROGRESS", + "key":"mybuildtool", + "url":"https://my-build-tool.com/builds/MY-PROJECT/BUILD-777", + "type":"build", + "created_on":"2015-11-19T20:37:35.547563+00:00", + "updated_on":"2015-11-19T20:37:35.547563+00:00", + "links":{ + "commit":{ + "href":"http://api.bitbucket.org/2.0/repositories/tk/test/commit/9fec847784abb10b2fa567ee63b85bd238955d0e" + }, + "self":{ + "href":"http://api.bitbucket.org/2.0/repositories/tk/test/commit/9fec847784abb10b2fa567ee63b85bd238955d0e/statuses/build/mybuildtool" + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "repo:commit_status_created") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestRepoCommitStatusUpdated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "commit_status":{ + "name":"Unit Tests (Python)", + "description":"All tests passed", + "state":"SUCCESSFUL", + "key":"mybuildtool", + "url":"https://my-build-tool.com/builds/MY-PROJECT/BUILD-792", + "type":"build", + "created_on":"2015-11-19T20:37:35.547563+00:00", + "updated_on":"2015-11-20T08:01:16.433108+00:00", + "links":{ + "commit":{ + "href":"http://api.bitbucket.org/2.0/repositories/tk/test/commit/9fec847784abb10b2fa567ee63b85bd238955d0e" + }, + "self":{ + "href":"http://api.bitbucket.org/2.0/repositories/tk/test/commit/9fec847784abb10b2fa567ee63b85bd238955d0e/statuses/build/mybuildtool" + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "repo:commit_status_updated") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestIssueCreated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "issue":{ + "id":1, + "component":"component", + "title":"Issue title", + "content":{ + "raw":"Issue description", + "html":"Issue description
", + "markup":"markdown" + }, + "priority":"trivial|minor|major|critical|blocker", + "state":"new|open|on hold|resolved|duplicate|invalid|wontfix|closed", + "type":"bug|enhancement|proposal|task", + "milestone":{ + "name":"milestone 1" + }, + "version":{ + "name":"version 1" + }, + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.179678+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/issues/issue_id" + }, + "html":{ + "href":"https://api.bitbucket.org/issue_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "issue:created") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestIssueUpdated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "issue":{ + "id":1, + "component":"component", + "title":"Issue title", + "content":{ + "raw":"Issue description", + "html":"Issue description
", + "markup":"markdown" + }, + "priority":"trivial|minor|major|critical|blocker", + "state":"new|open|on hold|resolved|duplicate|invalid|wontfix|closed", + "type":"bug|enhancement|proposal|task", + "milestone":{ + "name":"milestone 1" + }, + "version":{ + "name":"version 1" + }, + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.179678+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/issues/issue_id" + }, + "html":{ + "href":"https://api.bitbucket.org/issue_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "comment":{ + "id":17, + "parent":{ + "id":16 + }, + "content":{ + "raw":"Comment text", + "html":"Comment text
", + "markup":"markdown" + }, + "inline":{ + "path":"path/to/file", + "from":null, + "to":10 + }, + "created_on":"2015-04-06T16:52:29.982346+00:00", + "updated_on":"2015-04-06T16:52:29.983730+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/comments/comment_id" + }, + "html":{ + "href":"https://api.bitbucket.org/comment_id" + } + } + }, + "changes":{ + "status":{ + "old":"open", + "new":"on hold" + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "issue:updated") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestIssueCommentCreated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "issue":{ + "id":1, + "component":"component", + "title":"Issue title", + "content":{ + "raw":"Issue description", + "html":"Issue description
", + "markup":"markdown" + }, + "priority":"trivial|minor|major|critical|blocker", + "state":"new|open|on hold|resolved|duplicate|invalid|wontfix|closed", + "type":"bug|enhancement|proposal|task", + "milestone":{ + "name":"milestone 1" + }, + "version":{ + "name":"version 1" + }, + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.179678+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/issues/issue_id" + }, + "html":{ + "href":"https://api.bitbucket.org/issue_id" + } + } + }, + "comment":{ + "id":17, + "parent":{ + "id":16 + }, + "content":{ + "raw":"Comment text", + "html":"Comment text
", + "markup":"markdown" + }, + "inline":{ + "path":"path/to/file", + "from":null, + "to":10 + }, + "created_on":"2015-04-06T16:52:29.982346+00:00", + "updated_on":"2015-04-06T16:52:29.983730+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/comments/comment_id" + }, + "html":{ + "href":"https://api.bitbucket.org/comment_id" + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "issue:comment_created") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestCreated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:created") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestUpdated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:updated") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestApproved(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "approval":{ + "date":"2015-04-06T16:34:59.195330+00:00", + "user":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:approved") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestApprovalRemoved(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "approval":{ + "date":"2015-04-06T16:34:59.195330+00:00", + "user":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:unapproved") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestMerged(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:fulfilled") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestDeclined(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:rejected") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestCommentCreated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "comment":{ + "id":17, + "parent":{ + "id":16 + }, + "content":{ + "raw":"Comment text", + "html":"Comment text
", + "markup":"markdown" + }, + "inline":{ + "path":"path/to/file", + "from":null, + "to":10 + }, + "created_on":"2015-04-06T16:52:29.982346+00:00", + "updated_on":"2015-04-06T16:52:29.983730+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/comments/comment_id" + }, + "html":{ + "href":"https://api.bitbucket.org/comment_id" + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:comment_created") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestCommentUpdated(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "comment":{ + "id":17, + "parent":{ + "id":16 + }, + "content":{ + "raw":"Comment text", + "html":"Comment text
", + "markup":"markdown" + }, + "inline":{ + "path":"path/to/file", + "from":null, + "to":10 + }, + "created_on":"2015-04-06T16:52:29.982346+00:00", + "updated_on":"2015-04-06T16:52:29.983730+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/comments/comment_id" + }, + "html":{ + "href":"https://api.bitbucket.org/comment_id" + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pullrequest:comment_updated") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestPullRequestCommentDeleted(t *testing.T) { + + payload := `{ + "actor":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + }, + "pullrequest":{ + "id":1, + "title":"Title of pull request", + "description":"Description of pull request", + "state":"OPEN|MERGED|DECLINED", + "author":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "source":{ + "branch":{ + "name":"branch2" + }, + "commit":{ + "hash":"d3022fc0ca3d" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "destination":{ + "branch":{ + "name":"master" + }, + "commit":{ + "hash":"ce5965ddd289" + }, + "repository":{ + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/repositories/bitbucket/bitbucket" + }, + "html":{ + "href":"https://api.bitbucket.org/bitbucket/bitbucket" + }, + "avatar":{ + "href":"https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid":"{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name":"team_name/repo_name", + "name":"repo_name", + "scm":"git", + "is_private":true + } + }, + "merge_commit":{ + "hash":"764413d85e29" + }, + "participants":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "reviewers":[ + { + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + } + ], + "close_source_branch":true, + "closed_by":{ + "username":"emmap1", + "display_name":"Emma", + "uuid":"{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html":{ + "href":"https://api.bitbucket.org/emmap1" + }, + "avatar":{ + "href":"https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "reason":"reason for declining the PR (if applicable)", + "created_on":"2015-04-06T15:23:38.179678+00:00", + "updated_on":"2015-04-06T15:23:38.205705+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/pullrequests/pullrequest_id" + }, + "html":{ + "href":"https://api.bitbucket.org/pullrequest_id" + } + } + }, + "comment":{ + "id":17, + "parent":{ + "id":16 + }, + "content":{ + "raw":"Comment text", + "html":"Comment text
", + "markup":"markdown" + }, + "inline":{ + "path":"path/to/file", + "from":null, + "to":10 + }, + "created_on":"2015-04-06T16:52:29.982346+00:00", + "updated_on":"2015-04-06T16:52:29.983730+00:00", + "links":{ + "self":{ + "href":"https://api.bitbucket.org/api/2.0/comments/comment_id" + }, + "html":{ + "href":"https://api.bitbucket.org/comment_id" + } + } + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hook-UUID", "MY_UUID") + req.Header.Set("X-Event-Key", "pull_request:comment_deleted") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} diff --git a/bitbucket/payload.go b/bitbucket/payload.go new file mode 100644 index 0000000..aac6a8a --- /dev/null +++ b/bitbucket/payload.go @@ -0,0 +1,389 @@ +package bitbucket + +import "time" + +// PullRequestCommentDeletedPayload is the Bitbucket pull_request:comment_deleted payload +type PullRequestCommentDeletedPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + PullRequest PullRequest `json:"pullrequest"` + Comment Comment `json:"comment"` +} + +// PullRequestCommentUpdatedPayload is the Bitbucket pullrequest:comment_updated payload +type PullRequestCommentUpdatedPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + PullRequest PullRequest `json:"pullrequest"` + Comment Comment `json:"comment"` +} + +// PullRequestCommentCreatedPayload is the Bitbucket pullrequest:comment_created payload +type PullRequestCommentCreatedPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + PullRequest PullRequest `json:"pullrequest"` + Comment Comment `json:"comment"` +} + +// PullRequestDeclinedPayload is the Bitbucket pullrequest:rejected payload +type PullRequestDeclinedPayload struct { + Actor User `json:"actor"` + PullRequest PullRequest `json:"pullrequest"` + Repository Repository `json:"repository"` +} + +// PullRequestMergedPayload is the Bitbucket pullrequest:fulfilled payload +type PullRequestMergedPayload struct { + Actor User `json:"actor"` + PullRequest PullRequest `json:"pullrequest"` + Repository Repository `json:"repository"` +} + +// PullRequestApprovalRemovedPayload is the Bitbucket pullrequest:unapproved payload +type PullRequestApprovalRemovedPayload struct { + Actor User `json:"actor"` + PullRequest PullRequest `json:"pullrequest"` + Repository Repository `json:"repository"` + Approval Approval `json:"approval"` +} + +// PullRequestApprovedPayload is the Bitbucket pullrequest:approved payload +type PullRequestApprovedPayload struct { + Actor User `json:"actor"` + PullRequest PullRequest `json:"pullrequest"` + Repository Repository `json:"repository"` + Approval Approval `json:"approval"` +} + +// PullRequestUpdatedPayload is the Bitbucket pullrequest:updated payload +type PullRequestUpdatedPayload struct { + Actor User `json:"actor"` + PullRequest PullRequest `json:"pullrequest"` + Repository Repository `json:"repository"` +} + +// PullRequestCreatedPayload is the Bitbucket pullrequest:created payload +type PullRequestCreatedPayload struct { + Actor User `json:"actor"` + PullRequest PullRequest `json:"pullrequest"` + Repository Repository `json:"repository"` +} + +// IssueCommentCreatedPayload is the Bitbucket issue:comment_created payload +type IssueCommentCreatedPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + Issue Issue `json:"issue"` + Comment Comment `json:"comment"` +} + +// IssueUpdatedPayload is the Bitbucket issue:updated payload +type IssueUpdatedPayload struct { + Actor User `json:"actor"` + Issue Issue `json:"issue"` + Repository Repository `json:"repository"` + Comment Comment `json:"comment"` + Changes IssueChanges `json:"changes"` +} + +// IssueCreatedPayload is the Bitbucket issue:created payload +type IssueCreatedPayload struct { + Actor User `json:"actor"` + Issue Issue `json:"issue"` + Repository Repository `json:"repository"` +} + +// RepoCommitStatusUpdatedPayload is the Bitbucket repo:commit_status_updated payload +type RepoCommitStatusUpdatedPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + CommitStatus CommitStatus `json:"commit_status"` +} + +// RepoCommitStatusCreatedPayload is the Bitbucket repo:commit_status_created payload +type RepoCommitStatusCreatedPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + CommitStatus CommitStatus `json:"commit_status"` +} + +// RepoCommitCommentCreatedPayload is the Bitbucket repo:commit_comment_created payload +type RepoCommitCommentCreatedPayload struct { + Actor User `json:"actor"` + Comment Comment `json:"comment"` + Repository Repository `json:"repository"` + Commit CommitHash `json:"commit"` +} + +// RepoForkPayload is the Bitbucket repo:fork payload +type RepoForkPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + Fork Repository `json:"fork"` +} + +// RepoPushPayload is the Bitbucket repo:push payload +type RepoPushPayload struct { + Actor User `json:"actor"` + Repository Repository `json:"repository"` + Push Push `json:"push"` +} + +// Approval is the common Bitbucket Issue Approval Sub Entity +type Approval struct { + Date time.Time `json:"date"` + User User `json:"user"` +} + +// IssueChanges is the common Bitbucket Issue Changes Sub Entity +type IssueChanges struct { + Status IssueChangeStatus `json:"status"` +} + +// IssueChangeStatus is the common Bitbucket Issue Change Status Sub Entity +type IssueChangeStatus struct { + Old string `json:"old"` + New string `json:"new"` +} + +// CommitStatus is the common Bitbucket CommitStatus Sub Entity +type CommitStatus struct { + Name string `json:"name"` + Description string `json:"description"` + State string `json:"state"` + Key string `json:"key"` + URL string `json:"url"` + Type string `json:"type"` + CreatedOn time.Time `json:"created_on"` + UpdatedOn time.Time `json:"updated_on"` + Links LinksSelfCommit `json:"links"` +} + +// Push is the common Bitbucket Push Sub Entity +type Push struct { + Changes []Change `json:"changes"` +} + +// Change is the common Bitbucket Change Sub Entity +type Change struct { + New ChangeData `json:"new"` + Old ChangeData `json:"old"` + Links LinksHTMLDiffCommits `json:"links"` + Created bool `json:"created"` + Forced bool `json:"forced"` + Closed bool `json:"closed"` + Commits []Commit `json:"commits"` + Truncated bool `json:"truncated"` +} + +// ChangeData is the common Bitbucket ChangeData Sub Entity +type ChangeData struct { + Type string `json:"type"` + Name string `json:"name"` + Target Target `json:"target"` + Links LinksHTMLSelfCommits `json:"links"` +} + +// Target is the common Bitbucket Target Sub Entity +type Target struct { + Type string `json:"type"` + Hash string `json:"hash"` + Author User `json:"author"` + Message string `json:"message"` + Date time.Time `json:"date"` + Parents []Parent `json:"parents"` + Links LinksHTMLSelf `json:"links"` +} + +// Parent is the common Bitbucket Parent Sub Entity +type Parent struct { + Type string `json:"type"` + Hash string `json:"hash"` + Links LinksHTMLSelf `json:"links"` +} + +// Commit is the common Bitbucket Commit Sub Entity +type Commit struct { + Hash string `json:"hash"` + Type string `json:"type"` + Message string `json:"message"` + Author User `json:"author"` + Links LinksHTMLSelf `json:"links"` +} + +// User is the common Bitbucket User Entity +type User struct { + Username string `json:"username"` + DisplayName string `json:"display_name"` + UUID string `json:"uuid"` + Links Links `json:"links"` +} + +// Repository is the common Bitbucket Repository Entity +type Repository struct { + Links Links `json:"links"` + UUID string `json:"uuid"` + FullName string `json:"full_name"` + Name string `json:"name"` + Scm string `json:"scm"` + IsPrivate bool `json:"is_private"` +} + +// Issue is the common Bitbucket Issue Entity +type Issue struct { + ID int64 `json:"id"` + Component string `json:"component"` + Title string `json:"title"` + Content Content `json:"content"` + Priority string `json:"priority"` + State string `json:"state"` + Type string `json:"type"` + Milestone Milestone `json:"milestone"` + Version Version `json:"version"` + CreatedOn time.Time `json:"created_on"` + UpdatedOn time.Time `json:"updated_on"` + Links LinksHTMLSelf `json:"links"` +} + +// Comment is the common Bitbucket Comment Entity +type Comment struct { + ID int64 `json:"id"` + Parent ParentID `json:"parent"` + Content Content `json:"content"` + Inline Inline `json:"inline"` + CreatedOn time.Time `json:"created_on"` + UpdatedOn time.Time `json:"updated_on"` + Links LinksHTMLSelf `json:"links"` +} + +// PullRequest is the common Bitbucket PullRequest Entity +type PullRequest struct { + ID int64 `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + State string `json:"state"` + Author User `json:"author"` + Source Source `json:"source"` + Destination Destination `json:"destination"` + MergeCommit CommitHash `json:"merge_commit"` + Participants []User `json:"participants"` + Reviewers []User `json:"reviewers"` + CloseSourceBranch bool `json:"close_source_branch"` + ClosedBy User `json:"closed_by"` + Reason string `json:"reason"` + CreatedOn time.Time `json:"created_on"` + UpdatedOn time.Time `json:"updated_on"` + Links LinksHTMLSelf `json:"links"` +} + +// Destination is the common Bitbucket Destination Sub Entity +type Destination struct { + Branch Branch `json:"branch"` + Commit CommitHash `json:"commit"` + Repository Repository `json:"repository"` +} + +// Source is the common Bitbucket Source Sub Entity +type Source struct { + Branch Branch `json:"branch"` + Commit CommitHash `json:"commit"` + Repository Repository `json:"repository"` +} + +// Branch is the common Bitbucket Branch Sub Entity +type Branch struct { + Name string `json:"name"` +} + +// CommitHash is the common Bitbucket CommitHash Sub Entity +type CommitHash struct { + Hash string `json:"hash"` +} + +// Inline is the common Bitbucket Inline Sub Entity +type Inline struct { + Path string `json:"path"` + From *int64 `json:"from"` + To int64 `json:"to"` +} + +// ParentID is the common Bitbucket ParentID Sub Entity +type ParentID struct { + ID int64 `json:"id"` +} + +// Avatar is the common Bitbucket Avatar Sub Entity +type Avatar struct { + HREF string `json:"href"` +} + +// HTML is the common Bitbucket HTML Sub Entity +type HTML struct { + HREF string `json:"href"` +} + +// Self is the common Bitbucket Self Sub Entity +type Self struct { + HREF string `json:"href"` +} + +// Diff is the common Bitbucket Diff Sub Entity +type Diff struct { + HREF string `json:"href"` +} + +// Commits is the common Bitbucket Commits Sub Entity +type Commits struct { + HREF string `json:"href"` +} + +// LinksSelfCommit is the common Bitbucket LinksSelfCommit Sub Entity +type LinksSelfCommit struct { + Self Self `json:"self"` + Commit Commits `json:"commit"` +} + +// LinksHTMLSelfCommits is the common Bitbucket LinksHTMLSelfCommits Sub Entity +type LinksHTMLSelfCommits struct { + Self Self `json:"self"` + Commits Commits `json:"commits"` + HTML HTML `json:"html"` +} + +// LinksHTMLDiffCommits is the common Bitbucket LinksHTMLDiffCommits Sub Entity +type LinksHTMLDiffCommits struct { + HTML HTML `json:"html"` + Diff Diff `json:"diff"` + Commits Commits `json:"commits"` +} + +// Links is the common Bitbucket Links Sub Entity +type Links struct { + Avatar Avatar `json:"avatar"` + HTML HTML `json:"html"` + Self Self `json:"self"` +} + +// LinksHTMLSelf is the common Bitbucket LinksHTMLSelf Sub Entity +type LinksHTMLSelf struct { + HTML HTML `json:"html"` + Self Self `json:"self"` +} + +// Content is the common Bitbucket Content Sub Entity +type Content struct { + HTML string `json:"html"` + Markup string `json:"markup"` + Raw string `json:"raw"` +} + +// Milestone is the common Bitbucket Milestone Sub Entity +type Milestone struct { + Name string `json:"name"` +} + +// Version is the common Bitbucket Version Sub Entity +type Version struct { + Name string `json:"name"` +} diff --git a/github/github.go b/github/github.go index 1709473..efced88 100644 --- a/github/github.go +++ b/github/github.go @@ -18,7 +18,7 @@ type Webhook struct { eventFuncs map[Event]webhooks.ProcessPayloadFunc } -// Config defines the configuration to create a new GitHubWebhook instance +// Config defines the configuration to create a new GitHub Webhook instance type Config struct { Secret string } diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..1a16078 Binary files /dev/null and b/logo.png differ diff --git a/webhooks.go b/webhooks.go index d95c7c8..6dcd6f1 100644 --- a/webhooks.go +++ b/webhooks.go @@ -9,6 +9,8 @@ func (p Provider) String() string { switch p { case GitHub: return "GitHub" + case Bitbucket: + return "Bitbucket" default: return "Unknown" } @@ -17,6 +19,7 @@ func (p Provider) String() string { // webhooks available providers const ( GitHub Provider = iota + Bitbucket ) // Webhook interface defines a webhook to recieve events diff --git a/webhooks_test.go b/webhooks_test.go index 049a345..9ade530 100644 --- a/webhooks_test.go +++ b/webhooks_test.go @@ -235,5 +235,6 @@ D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g== func TestProviderString(t *testing.T) { Equal(t, GitHub.String(), "GitHub") + Equal(t, Bitbucket.String(), "Bitbucket") Equal(t, Provider(999999).String(), "Unknown") }