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