github.com/go-playground/webhooks/v6@v6.3.0/github/github_test.go (about) 1 package github 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.Secret("IsWishesWereHorsesWedAllBeEatingSteak!")) 40 if err != nil { 41 log.Fatal(err) 42 } 43 os.Exit(m.Run()) 44 // teardown 45 } 46 47 func newServer(handler http.HandlerFunc) *httptest.Server { 48 mux := http.NewServeMux() 49 mux.HandleFunc(path, handler) 50 return httptest.NewServer(mux) 51 } 52 53 func TestBadRequests(t *testing.T) { 54 assert := require.New(t) 55 tests := []struct { 56 name string 57 event Event 58 payload io.Reader 59 headers http.Header 60 }{ 61 { 62 name: "BadNoEventHeader", 63 event: CreateEvent, 64 payload: bytes.NewBuffer([]byte("{}")), 65 headers: http.Header{}, 66 }, 67 { 68 name: "UnsubscribedEvent", 69 event: CreateEvent, 70 payload: bytes.NewBuffer([]byte("{}")), 71 headers: http.Header{ 72 "X-Github-Event": []string{"noneexistant_event"}, 73 }, 74 }, 75 { 76 name: "BadBody", 77 event: CommitCommentEvent, 78 payload: bytes.NewBuffer([]byte("")), 79 headers: http.Header{ 80 "X-Github-Event": []string{"commit_comment"}, 81 "X-Hub-Signature": []string{"sha1=156404ad5f721c53151147f3d3d302329f95a3ab"}, 82 }, 83 }, 84 { 85 name: "BadSignatureLength", 86 event: CommitCommentEvent, 87 payload: bytes.NewBuffer([]byte("{}")), 88 headers: http.Header{ 89 "X-Github-Event": []string{"commit_comment"}, 90 "X-Hub-Signature": []string{""}, 91 }, 92 }, 93 { 94 name: "BadSignatureMatch", 95 event: CommitCommentEvent, 96 payload: bytes.NewBuffer([]byte("{}")), 97 headers: http.Header{ 98 "X-Github-Event": []string{"commit_comment"}, 99 "X-Hub-Signature": []string{"sha1=111"}, 100 }, 101 }, 102 } 103 104 for _, tt := range tests { 105 tc := tt 106 client := &http.Client{} 107 t.Run(tt.name, func(t *testing.T) { 108 t.Parallel() 109 var parseError error 110 server := newServer(func(w http.ResponseWriter, r *http.Request) { 111 _, parseError = hook.Parse(r, tc.event) 112 }) 113 defer server.Close() 114 req, err := http.NewRequest(http.MethodPost, server.URL+path, tc.payload) 115 assert.NoError(err) 116 req.Header = tc.headers 117 req.Header.Set("Content-Type", "application/json") 118 119 resp, err := client.Do(req) 120 assert.NoError(err) 121 assert.Equal(http.StatusOK, resp.StatusCode) 122 assert.Error(parseError) 123 }) 124 } 125 } 126 127 func TestWebhooks(t *testing.T) { 128 assert := require.New(t) 129 tests := []struct { 130 name string 131 event Event 132 typ interface{} 133 filename string 134 headers http.Header 135 }{ 136 { 137 name: "CheckRunEvent", 138 event: CheckRunEvent, 139 typ: CheckRunPayload{}, 140 filename: "../testdata/github/check-run.json", 141 headers: http.Header{ 142 "X-Github-Event": []string{"check_run"}, 143 "X-Hub-Signature": []string{"sha1=229f4920493b455398168cd86dc6b366064bdf3f"}, 144 }, 145 }, 146 { 147 name: "CheckSuiteEvent", 148 event: CheckSuiteEvent, 149 typ: CheckSuitePayload{}, 150 filename: "../testdata/github/check-suite.json", 151 headers: http.Header{ 152 "X-Github-Event": []string{"check_suite"}, 153 "X-Hub-Signature": []string{"sha1=250ad5a340f8d91e67dc5682342f3190fd2006a1"}, 154 }, 155 }, 156 { 157 name: "CommitCommentEvent", 158 event: CommitCommentEvent, 159 typ: CommitCommentPayload{}, 160 filename: "../testdata/github/commit-comment.json", 161 headers: http.Header{ 162 "X-Github-Event": []string{"commit_comment"}, 163 "X-Hub-Signature": []string{"sha1=156404ad5f721c53151147f3d3d302329f95a3ab"}, 164 }, 165 }, 166 { 167 name: "CreateEvent", 168 event: CreateEvent, 169 typ: CreatePayload{}, 170 filename: "../testdata/github/create.json", 171 headers: http.Header{ 172 "X-Github-Event": []string{"create"}, 173 "X-Hub-Signature": []string{"sha1=77ff16ca116034bbeed77ebfce83b36572a9cbaf"}, 174 }, 175 }, 176 { 177 name: "DeleteEvent", 178 event: DeleteEvent, 179 typ: DeletePayload{}, 180 filename: "../testdata/github/delete.json", 181 headers: http.Header{ 182 "X-Github-Event": []string{"delete"}, 183 "X-Hub-Signature": []string{"sha1=4ddef04fd05b504c7041e294fca3ad1804bc7be1"}, 184 }, 185 }, 186 { 187 name: "DependabotAlertEvent", 188 event: DependabotAlertEvent, 189 typ: DependabotAlertPayload{}, 190 filename: "../testdata/github/dependabot_alert.json", 191 headers: http.Header{ 192 "X-Github-Event": []string{"dependabot_alert"}, 193 "X-Hub-Signature": []string{"sha1=ce6a2bc876463a8b3b492399302bf316e1af7a21"}, 194 }, 195 }, 196 { 197 name: "DeployKeyEvent", 198 event: DeployKeyEvent, 199 typ: DeployKeyPayload{}, 200 filename: "../testdata/github/deploy_key.json", 201 headers: http.Header{ 202 "X-Github-Event": []string{"deploy_key"}, 203 "X-Hub-Signature": []string{"sha1=dc9eea5621f5942542c94443cd2b71c8d7526168"}, 204 }, 205 }, 206 { 207 name: "DeploymentEvent", 208 event: DeploymentEvent, 209 typ: DeploymentPayload{}, 210 filename: "../testdata/github/deployment.json", 211 headers: http.Header{ 212 "X-Github-Event": []string{"deployment"}, 213 "X-Hub-Signature": []string{"sha1=bb47dc63ceb764a6b1f14fe123e299e5b814c67c"}, 214 }, 215 }, 216 { 217 name: "DeploymentStatusEvent", 218 event: DeploymentStatusEvent, 219 typ: DeploymentStatusPayload{}, 220 filename: "../testdata/github/deployment-status.json", 221 headers: http.Header{ 222 "X-Github-Event": []string{"deployment_status"}, 223 "X-Hub-Signature": []string{"sha1=1b2ce08e0c3487fdf22bed12c63dc734cf6dc8a4"}, 224 }, 225 }, 226 { 227 name: "ForkEvent", 228 event: ForkEvent, 229 typ: ForkPayload{}, 230 filename: "../testdata/github/fork.json", 231 headers: http.Header{ 232 "X-Github-Event": []string{"fork"}, 233 "X-Hub-Signature": []string{"sha1=cec5f8fb7c383514c622d3eb9e121891dfcca848"}, 234 }, 235 }, 236 { 237 name: "GollumEvent", 238 event: GollumEvent, 239 typ: GollumPayload{}, 240 filename: "../testdata/github/gollum.json", 241 headers: http.Header{ 242 "X-Github-Event": []string{"gollum"}, 243 "X-Hub-Signature": []string{"sha1=a375a6dc8ceac7231ee022211f8eb85e2a84a5b9"}, 244 }, 245 }, 246 { 247 name: "InstallationEvent", 248 event: InstallationEvent, 249 typ: InstallationPayload{}, 250 filename: "../testdata/github/installation.json", 251 headers: http.Header{ 252 "X-Github-Event": []string{"installation"}, 253 "X-Hub-Signature": []string{"sha1=2bcb4ad96133ce2dd6d140fad7a80a2b14407f7f"}, 254 }, 255 }, 256 { 257 name: "InstallationRepositoriesEvent", 258 event: InstallationRepositoriesEvent, 259 typ: InstallationRepositoriesPayload{}, 260 filename: "../testdata/github/installation-repositories.json", 261 headers: http.Header{ 262 "X-Github-Event": []string{"installation_repositories"}, 263 "X-Hub-Signature": []string{"sha1=997680ef1e6f4a6b6595f5fa70b82989f505137f"}, 264 }, 265 }, 266 { 267 name: "IntegrationInstallationEvent", 268 event: IntegrationInstallationEvent, 269 typ: InstallationPayload{}, 270 filename: "../testdata/github/integration-installation.json", 271 headers: http.Header{ 272 "X-Github-Event": []string{"integration_installation"}, 273 "X-Hub-Signature": []string{"sha1=1172601d35bdebac5f3aa7618c9e58eafb404c6f"}, 274 }, 275 }, 276 { 277 name: "IntegrationInstallationRepositoriesEvent", 278 event: IntegrationInstallationRepositoriesEvent, 279 typ: InstallationRepositoriesPayload{}, 280 filename: "../testdata/github/integration-installation-repositories.json", 281 headers: http.Header{ 282 "X-Github-Event": []string{"integration_installation_repositories"}, 283 "X-Hub-Signature": []string{"sha1=7c38ba703a3c89d00823920a47cd8863df8121d2"}, 284 }, 285 }, 286 { 287 name: "IssueCommentEvent", 288 event: IssueCommentEvent, 289 typ: IssueCommentPayload{}, 290 filename: "../testdata/github/issue-comment.json", 291 headers: http.Header{ 292 "X-Github-Event": []string{"issue_comment"}, 293 "X-Hub-Signature": []string{"sha1=e724c9f811fcf5f511aac32e4251b08ab1a0fd87"}, 294 }, 295 }, 296 { 297 name: "PullRequestIssueCommentEvent", 298 event: IssueCommentEvent, 299 typ: IssueCommentPayload{}, 300 filename: "../testdata/github/pull-request-issue-comment.json", 301 headers: http.Header{ 302 "X-Github-Event": []string{"issue_comment"}, 303 "X-Hub-Signature": []string{"sha1=6c969b99ef881b5c98b2dbfc66a34465fcf0e7d4"}, 304 }, 305 }, 306 { 307 name: "IssuesEvent", 308 event: IssuesEvent, 309 typ: IssuesPayload{}, 310 filename: "../testdata/github/issues.json", 311 headers: http.Header{ 312 "X-Github-Event": []string{"issues"}, 313 "X-Hub-Signature": []string{"sha1=dfc9a3428f3df86e4ecd78e34b41c55bba5d0b21"}, 314 }, 315 }, 316 { 317 name: "LabelEvent", 318 event: LabelEvent, 319 typ: LabelPayload{}, 320 filename: "../testdata/github/label.json", 321 headers: http.Header{ 322 "X-Github-Event": []string{"label"}, 323 "X-Hub-Signature": []string{"sha1=efc13e7ad816235222e4a6b3f96d3fd1e162dbd4"}, 324 }, 325 }, 326 { 327 name: "MemberEvent", 328 event: MemberEvent, 329 typ: MemberPayload{}, 330 filename: "../testdata/github/member.json", 331 headers: http.Header{ 332 "X-Github-Event": []string{"member"}, 333 "X-Hub-Signature": []string{"sha1=597e7d6627a6636d4c3283e36631983fbd57bdd0"}, 334 }, 335 }, 336 { 337 name: "MembershipEvent", 338 event: MembershipEvent, 339 typ: MembershipPayload{}, 340 filename: "../testdata/github/membership.json", 341 headers: http.Header{ 342 "X-Github-Event": []string{"membership"}, 343 "X-Hub-Signature": []string{"sha1=16928c947b3707b0efcf8ceb074a5d5dedc9c76e"}, 344 }, 345 }, 346 { 347 name: "MilestoneEvent", 348 event: MilestoneEvent, 349 typ: MilestonePayload{}, 350 filename: "../testdata/github/milestone.json", 351 headers: http.Header{ 352 "X-Github-Event": []string{"milestone"}, 353 "X-Hub-Signature": []string{"sha1=8b63f58ea58e6a59dcfc5ecbaea0d1741a6bf9ec"}, 354 }, 355 }, 356 { 357 name: "OrganizationEvent", 358 event: OrganizationEvent, 359 typ: OrganizationPayload{}, 360 filename: "../testdata/github/organization.json", 361 headers: http.Header{ 362 "X-Github-Event": []string{"organization"}, 363 "X-Hub-Signature": []string{"sha1=7e5ad88557be0a05fb89e86c7893d987386aa0d5"}, 364 }, 365 }, 366 { 367 name: "OrgBlockEvent", 368 event: OrgBlockEvent, 369 typ: OrgBlockPayload{}, 370 filename: "../testdata/github/org-block.json", 371 headers: http.Header{ 372 "X-Github-Event": []string{"org_block"}, 373 "X-Hub-Signature": []string{"sha1=21fe61da3f014c011edb60b0b9dfc9aa7059a24b"}, 374 }, 375 }, 376 { 377 name: "PageBuildEvent", 378 event: PageBuildEvent, 379 typ: PageBuildPayload{}, 380 filename: "../testdata/github/page-build.json", 381 headers: http.Header{ 382 "X-Github-Event": []string{"page_build"}, 383 "X-Hub-Signature": []string{"sha1=b3abad8f9c1b3fc0b01c4eb107447800bb5000f9"}, 384 }, 385 }, 386 { 387 name: "PingEvent", 388 event: PingEvent, 389 typ: PingPayload{}, 390 filename: "../testdata/github/ping.json", 391 headers: http.Header{ 392 "X-Github-Event": []string{"ping"}, 393 "X-Hub-Signature": []string{"sha1=f80e1cfc04245b65228b86612119ab5c894133c2"}, 394 }, 395 }, 396 { 397 name: "ProjectCardEvent", 398 event: ProjectCardEvent, 399 typ: ProjectCardPayload{}, 400 filename: "../testdata/github/project-card.json", 401 headers: http.Header{ 402 "X-Github-Event": []string{"project_card"}, 403 "X-Hub-Signature": []string{"sha1=f5ed1572b04f0e03c8d5f5e3f7fa63737bef76d7"}, 404 }, 405 }, 406 { 407 name: "ProjectColumnEvent", 408 event: ProjectColumnEvent, 409 typ: ProjectColumnPayload{}, 410 filename: "../testdata/github/project-column.json", 411 headers: http.Header{ 412 "X-Github-Event": []string{"project_column"}, 413 "X-Hub-Signature": []string{"sha1=7d5dd49d9863e982a4f577170717ea8350a69db0"}, 414 }, 415 }, 416 { 417 name: "ProjectEvent", 418 event: ProjectEvent, 419 typ: ProjectPayload{}, 420 filename: "../testdata/github/project.json", 421 headers: http.Header{ 422 "X-Github-Event": []string{"project"}, 423 "X-Hub-Signature": []string{"sha1=7295ab4f205434208f1b86edf2b55adae34c6c92"}, 424 }, 425 }, 426 { 427 name: "PublicEvent", 428 event: PublicEvent, 429 typ: PublicPayload{}, 430 filename: "../testdata/github/public.json", 431 headers: http.Header{ 432 "X-Github-Event": []string{"public"}, 433 "X-Hub-Signature": []string{"sha1=73edb2a8c69c1ac35efb797ede3dc2cde618c10c"}, 434 }, 435 }, 436 { 437 name: "PullRequestEvent", 438 event: PullRequestEvent, 439 typ: PullRequestPayload{}, 440 filename: "../testdata/github/pull-request.json", 441 headers: http.Header{ 442 "X-Github-Event": []string{"pull_request"}, 443 "X-Hub-Signature": []string{"sha1=88972f972db301178aa13dafaf112d26416a15e6"}, 444 }, 445 }, 446 { 447 name: "PullRequestReviewEvent", 448 event: PullRequestReviewEvent, 449 typ: PullRequestReviewPayload{}, 450 filename: "../testdata/github/pull-request-review.json", 451 headers: http.Header{ 452 "X-Github-Event": []string{"pull_request_review"}, 453 "X-Hub-Signature": []string{"sha1=55345ce92be7849f97d39b9426b95261d4bd4465"}, 454 }, 455 }, 456 { 457 name: "PullRequestReviewCommentEvent", 458 event: PullRequestReviewCommentEvent, 459 typ: PullRequestReviewCommentPayload{}, 460 filename: "../testdata/github/pull-request-review-comment.json", 461 headers: http.Header{ 462 "X-Github-Event": []string{"pull_request_review_comment"}, 463 "X-Hub-Signature": []string{"sha1=a9ece15dbcbb85fa5f00a0bf409494af2cbc5b60"}, 464 }, 465 }, 466 { 467 name: "PushEvent", 468 event: PushEvent, 469 typ: PushPayload{}, 470 filename: "../testdata/github/push.json", 471 headers: http.Header{ 472 "X-Github-Event": []string{"push"}, 473 "X-Hub-Signature": []string{"sha1=0534736f52c2fc5896ef1bd5a043127b20d233ba"}, 474 }, 475 }, 476 { 477 name: "ReleaseEvent", 478 event: ReleaseEvent, 479 typ: ReleasePayload{}, 480 filename: "../testdata/github/release.json", 481 headers: http.Header{ 482 "X-Github-Event": []string{"release"}, 483 "X-Hub-Signature": []string{"sha1=e62bb4c51bc7dde195b9525971c2e3aecb394390"}, 484 }, 485 }, 486 { 487 name: "RepositoryEvent", 488 event: RepositoryEvent, 489 typ: RepositoryPayload{}, 490 filename: "../testdata/github/repository.json", 491 headers: http.Header{ 492 "X-Github-Event": []string{"repository"}, 493 "X-Hub-Signature": []string{"sha1=df442a8af41edd2d42ccdd997938d1d111b0f94e"}, 494 }, 495 }, 496 { 497 name: "RepositoryEditedEvent", 498 event: RepositoryEvent, 499 typ: RepositoryPayload{}, 500 filename: "../testdata/github/repository-edited.json", 501 headers: http.Header{ 502 "X-Github-Event": []string{"repository"}, 503 "X-Hub-Signature": []string{"sha1=4edb36f8c0a8e3905e340c7af4b3af9a21d93acc"}, 504 }, 505 }, 506 { 507 name: "RepositoryVulnerabilityAlertEvent", 508 event: RepositoryVulnerabilityAlertEvent, 509 typ: RepositoryVulnerabilityAlertPayload{}, 510 filename: "../testdata/github/repository-vulnerability-alert.json", 511 headers: http.Header{ 512 "X-Github-Event": []string{"repository_vulnerability_alert"}, 513 "X-Hub-Signature": []string{"sha1=c42c0649e7e06413bcd756763edbab48dff400db"}, 514 }, 515 }, 516 { 517 name: "SecurityAdvisoryEvent", 518 event: SecurityAdvisoryEvent, 519 typ: SecurityAdvisoryPayload{}, 520 filename: "../testdata/github/security-advisory.json", 521 headers: http.Header{ 522 "X-Github-Event": []string{"security_advisory"}, 523 "X-Hub-Signature": []string{"sha1=6a71f24fa69f55469843a91dc3a5c3e29714a565"}, 524 }, 525 }, 526 { 527 name: "StatusEvent", 528 event: StatusEvent, 529 typ: StatusPayload{}, 530 filename: "../testdata/github/status.json", 531 headers: http.Header{ 532 "X-Github-Event": []string{"status"}, 533 "X-Hub-Signature": []string{"sha1=3caa5f062a2deb7cce1482314bb9b4c99bf0ab45"}, 534 }, 535 }, 536 { 537 name: "TeamEvent", 538 event: TeamEvent, 539 typ: TeamPayload{}, 540 filename: "../testdata/github/team.json", 541 headers: http.Header{ 542 "X-Github-Event": []string{"team"}, 543 "X-Hub-Signature": []string{"sha1=ff5b5d58faec10bd40fc96834148df408e7a4608"}, 544 }, 545 }, 546 { 547 name: "TeamAddEvent", 548 event: TeamAddEvent, 549 typ: TeamAddPayload{}, 550 filename: "../testdata/github/team-add.json", 551 headers: http.Header{ 552 "X-Github-Event": []string{"team_add"}, 553 "X-Hub-Signature": []string{"sha1=5f3953476e270b79cc6763780346110da880609a"}, 554 }, 555 }, 556 { 557 name: "WatchEvent", 558 event: WatchEvent, 559 typ: WatchPayload{}, 560 filename: "../testdata/github/watch.json", 561 headers: http.Header{ 562 "X-Github-Event": []string{"watch"}, 563 "X-Hub-Signature": []string{"sha1=a317bcfe69ccb8bece74c20c7378e5413c4772f1"}, 564 }, 565 }, 566 { 567 name: "WorkflowDispatchEvent", 568 event: WorkflowDispatchEvent, 569 typ: WorkflowDispatchPayload{}, 570 filename: "../testdata/github/workflow_dispatch.json", 571 headers: http.Header{ 572 "X-Github-Event": []string{"workflow_dispatch"}, 573 "X-Hub-Signature": []string{"sha1=58db5b3c7e2391b34275d42256e0eda67e4997b9"}, 574 }, 575 }, 576 { 577 name: "WorkflowJobEvent", 578 event: WorkflowJobEvent, 579 typ: WorkflowJobPayload{}, 580 filename: "../testdata/github/workflow_job.json", 581 headers: http.Header{ 582 "X-Github-Event": []string{"workflow_job"}, 583 "X-Hub-Signature": []string{"sha1=2f22091ecf169313c9991f5f98ef3dffb069841b"}, 584 }, 585 }, 586 { 587 name: "WorkflowRunEvent", 588 event: WorkflowRunEvent, 589 typ: WorkflowRunPayload{}, 590 filename: "../testdata/github/workflow_run.json", 591 headers: http.Header{ 592 "X-Github-Event": []string{"workflow_run"}, 593 "X-Hub-Signature": []string{"sha1=c54d046b1ce440bc3434c8de5ad73e0a630d7cbe"}, 594 }, 595 }, 596 { 597 name: "GitHubAppAuthorizationEvent", 598 event: GitHubAppAuthorizationEvent, 599 typ: GitHubAppAuthorizationPayload{}, 600 filename: "../testdata/github/github-app-authorization.json", 601 headers: http.Header{ 602 "X-Github-Event": []string{"github_app_authorization"}, 603 "X-Hub-Signature": []string{"sha1=4f18624a7fe3a9c525b51bdbd0e3da8230d753d6"}, 604 }, 605 }, 606 } 607 608 for _, tt := range tests { 609 tc := tt 610 client := &http.Client{} 611 t.Run(tt.name, func(t *testing.T) { 612 t.Parallel() 613 payload, err := os.Open(tc.filename) 614 assert.NoError(err) 615 defer func() { 616 _ = payload.Close() 617 }() 618 619 var parseError error 620 var results interface{} 621 server := newServer(func(w http.ResponseWriter, r *http.Request) { 622 results, parseError = hook.Parse(r, tc.event) 623 }) 624 defer server.Close() 625 req, err := http.NewRequest(http.MethodPost, server.URL+path, payload) 626 assert.NoError(err) 627 req.Header = tc.headers 628 req.Header.Set("Content-Type", "application/json") 629 630 resp, err := client.Do(req) 631 assert.NoError(err) 632 assert.Equal(http.StatusOK, resp.StatusCode) 633 assert.NoError(parseError) 634 assert.Equal(reflect.TypeOf(tc.typ), reflect.TypeOf(results)) 635 }) 636 } 637 }