github.com/google/go-github/v70@v70.0.0/github/repos_hooks_test.go (about) 1 // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "encoding/json" 11 "fmt" 12 "net/http" 13 "testing" 14 15 "github.com/google/go-cmp/cmp" 16 ) 17 18 func TestRepositoriesService_CreateHook(t *testing.T) { 19 t.Parallel() 20 client, mux, _ := setup(t) 21 22 input := &Hook{CreatedAt: &Timestamp{referenceTime}} 23 24 mux.HandleFunc("/repos/o/r/hooks", func(w http.ResponseWriter, r *http.Request) { 25 v := new(createHookRequest) 26 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 27 28 testMethod(t, r, "POST") 29 want := &createHookRequest{Name: "web"} 30 if !cmp.Equal(v, want) { 31 t.Errorf("Request body = %+v, want %+v", v, want) 32 } 33 34 fmt.Fprint(w, `{"id":1}`) 35 }) 36 37 ctx := context.Background() 38 hook, _, err := client.Repositories.CreateHook(ctx, "o", "r", input) 39 if err != nil { 40 t.Errorf("Repositories.CreateHook returned error: %v", err) 41 } 42 43 want := &Hook{ID: Ptr(int64(1))} 44 if !cmp.Equal(hook, want) { 45 t.Errorf("Repositories.CreateHook returned %+v, want %+v", hook, want) 46 } 47 48 const methodName = "CreateHook" 49 testBadOptions(t, methodName, func() (err error) { 50 _, _, err = client.Repositories.CreateHook(ctx, "\n", "\n", input) 51 return err 52 }) 53 54 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 55 got, resp, err := client.Repositories.CreateHook(ctx, "o", "r", input) 56 if got != nil { 57 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 58 } 59 return resp, err 60 }) 61 } 62 63 func TestRepositoriesService_ListHooks(t *testing.T) { 64 t.Parallel() 65 client, mux, _ := setup(t) 66 67 mux.HandleFunc("/repos/o/r/hooks", func(w http.ResponseWriter, r *http.Request) { 68 testMethod(t, r, "GET") 69 testFormValues(t, r, values{"page": "2"}) 70 fmt.Fprint(w, `[{"id":1}, {"id":2}]`) 71 }) 72 73 opt := &ListOptions{Page: 2} 74 75 ctx := context.Background() 76 hooks, _, err := client.Repositories.ListHooks(ctx, "o", "r", opt) 77 if err != nil { 78 t.Errorf("Repositories.ListHooks returned error: %v", err) 79 } 80 81 want := []*Hook{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}} 82 if !cmp.Equal(hooks, want) { 83 t.Errorf("Repositories.ListHooks returned %+v, want %+v", hooks, want) 84 } 85 86 const methodName = "ListHooks" 87 testBadOptions(t, methodName, func() (err error) { 88 _, _, err = client.Repositories.ListHooks(ctx, "\n", "\n", opt) 89 return err 90 }) 91 92 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 93 got, resp, err := client.Repositories.ListHooks(ctx, "o", "r", opt) 94 if got != nil { 95 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 96 } 97 return resp, err 98 }) 99 } 100 101 func TestRepositoriesService_ListHooks_invalidOwner(t *testing.T) { 102 t.Parallel() 103 client, _, _ := setup(t) 104 105 ctx := context.Background() 106 _, _, err := client.Repositories.ListHooks(ctx, "%", "%", nil) 107 testURLParseError(t, err) 108 } 109 110 func TestRepositoriesService_ListHooks_403_code_no_rate_limit(t *testing.T) { 111 t.Parallel() 112 testErrorResponseForStatusCode(t, http.StatusForbidden) 113 } 114 115 func TestRepositoriesService_ListHooks_404_code(t *testing.T) { 116 t.Parallel() 117 testErrorResponseForStatusCode(t, http.StatusNotFound) 118 } 119 120 func TestRepositoriesService_GetHook(t *testing.T) { 121 t.Parallel() 122 client, mux, _ := setup(t) 123 124 mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) { 125 testMethod(t, r, "GET") 126 fmt.Fprint(w, `{"id":1}`) 127 }) 128 129 ctx := context.Background() 130 hook, _, err := client.Repositories.GetHook(ctx, "o", "r", 1) 131 if err != nil { 132 t.Errorf("Repositories.GetHook returned error: %v", err) 133 } 134 135 want := &Hook{ID: Ptr(int64(1))} 136 if !cmp.Equal(hook, want) { 137 t.Errorf("Repositories.GetHook returned %+v, want %+v", hook, want) 138 } 139 140 const methodName = "GetHook" 141 testBadOptions(t, methodName, func() (err error) { 142 _, _, err = client.Repositories.GetHook(ctx, "\n", "\n", -1) 143 return err 144 }) 145 146 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 147 got, resp, err := client.Repositories.GetHook(ctx, "o", "r", 1) 148 if got != nil { 149 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 150 } 151 return resp, err 152 }) 153 } 154 155 func TestRepositoriesService_GetHook_invalidOwner(t *testing.T) { 156 t.Parallel() 157 client, _, _ := setup(t) 158 159 ctx := context.Background() 160 _, _, err := client.Repositories.GetHook(ctx, "%", "%", 1) 161 testURLParseError(t, err) 162 } 163 164 func TestRepositoriesService_EditHook(t *testing.T) { 165 t.Parallel() 166 client, mux, _ := setup(t) 167 168 input := &Hook{} 169 170 mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) { 171 v := new(Hook) 172 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 173 174 testMethod(t, r, "PATCH") 175 if !cmp.Equal(v, input) { 176 t.Errorf("Request body = %+v, want %+v", v, input) 177 } 178 179 fmt.Fprint(w, `{"id":1}`) 180 }) 181 182 ctx := context.Background() 183 hook, _, err := client.Repositories.EditHook(ctx, "o", "r", 1, input) 184 if err != nil { 185 t.Errorf("Repositories.EditHook returned error: %v", err) 186 } 187 188 want := &Hook{ID: Ptr(int64(1))} 189 if !cmp.Equal(hook, want) { 190 t.Errorf("Repositories.EditHook returned %+v, want %+v", hook, want) 191 } 192 193 const methodName = "EditHook" 194 testBadOptions(t, methodName, func() (err error) { 195 _, _, err = client.Repositories.EditHook(ctx, "\n", "\n", -1, input) 196 return err 197 }) 198 199 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 200 got, resp, err := client.Repositories.EditHook(ctx, "o", "r", 1, input) 201 if got != nil { 202 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 203 } 204 return resp, err 205 }) 206 } 207 208 func TestRepositoriesService_EditHook_invalidOwner(t *testing.T) { 209 t.Parallel() 210 client, _, _ := setup(t) 211 212 ctx := context.Background() 213 _, _, err := client.Repositories.EditHook(ctx, "%", "%", 1, nil) 214 testURLParseError(t, err) 215 } 216 217 func TestRepositoriesService_DeleteHook(t *testing.T) { 218 t.Parallel() 219 client, mux, _ := setup(t) 220 221 mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) { 222 testMethod(t, r, "DELETE") 223 }) 224 225 ctx := context.Background() 226 _, err := client.Repositories.DeleteHook(ctx, "o", "r", 1) 227 if err != nil { 228 t.Errorf("Repositories.DeleteHook returned error: %v", err) 229 } 230 231 const methodName = "DeleteHook" 232 testBadOptions(t, methodName, func() (err error) { 233 _, err = client.Repositories.DeleteHook(ctx, "\n", "\n", -1) 234 return err 235 }) 236 237 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 238 return client.Repositories.DeleteHook(ctx, "o", "r", 1) 239 }) 240 } 241 242 func TestRepositoriesService_DeleteHook_invalidOwner(t *testing.T) { 243 t.Parallel() 244 client, _, _ := setup(t) 245 246 ctx := context.Background() 247 _, err := client.Repositories.DeleteHook(ctx, "%", "%", 1) 248 testURLParseError(t, err) 249 } 250 251 func TestRepositoriesService_PingHook(t *testing.T) { 252 t.Parallel() 253 client, mux, _ := setup(t) 254 255 mux.HandleFunc("/repos/o/r/hooks/1/pings", func(w http.ResponseWriter, r *http.Request) { 256 testMethod(t, r, "POST") 257 }) 258 259 ctx := context.Background() 260 _, err := client.Repositories.PingHook(ctx, "o", "r", 1) 261 if err != nil { 262 t.Errorf("Repositories.PingHook returned error: %v", err) 263 } 264 265 const methodName = "PingHook" 266 testBadOptions(t, methodName, func() (err error) { 267 _, err = client.Repositories.PingHook(ctx, "\n", "\n", -1) 268 return err 269 }) 270 271 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 272 return client.Repositories.PingHook(ctx, "o", "r", 1) 273 }) 274 } 275 276 func TestRepositoriesService_TestHook(t *testing.T) { 277 t.Parallel() 278 client, mux, _ := setup(t) 279 280 mux.HandleFunc("/repos/o/r/hooks/1/tests", func(w http.ResponseWriter, r *http.Request) { 281 testMethod(t, r, "POST") 282 }) 283 284 ctx := context.Background() 285 _, err := client.Repositories.TestHook(ctx, "o", "r", 1) 286 if err != nil { 287 t.Errorf("Repositories.TestHook returned error: %v", err) 288 } 289 290 const methodName = "TestHook" 291 testBadOptions(t, methodName, func() (err error) { 292 _, err = client.Repositories.TestHook(ctx, "\n", "\n", -1) 293 return err 294 }) 295 296 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 297 return client.Repositories.TestHook(ctx, "o", "r", 1) 298 }) 299 } 300 301 func TestRepositoriesService_TestHook_invalidOwner(t *testing.T) { 302 t.Parallel() 303 client, _, _ := setup(t) 304 305 ctx := context.Background() 306 _, err := client.Repositories.TestHook(ctx, "%", "%", 1) 307 testURLParseError(t, err) 308 } 309 310 func TestBranchWebHookPayload_Marshal(t *testing.T) { 311 t.Parallel() 312 testJSONMarshal(t, &WebHookPayload{}, "{}") 313 314 v := &WebHookPayload{ 315 Action: Ptr("action"), 316 After: Ptr("after"), 317 Before: Ptr("before"), 318 Commits: []*WebHookCommit{ 319 { 320 Added: []string{"1", "2", "3"}, 321 Author: &WebHookAuthor{ 322 Email: Ptr("abc@gmail.com"), 323 Name: Ptr("abc"), 324 Login: Ptr("abc_12"), 325 }, 326 Committer: &WebHookAuthor{ 327 Email: Ptr("abc@gmail.com"), 328 Name: Ptr("abc"), 329 Login: Ptr("abc_12"), 330 }, 331 ID: Ptr("1"), 332 Message: Ptr("WebHookCommit"), 333 Modified: []string{"abc", "efg", "erd"}, 334 Removed: []string{"cmd", "rti", "duv"}, 335 }, 336 }, 337 Compare: Ptr("compare"), 338 Created: Ptr(true), 339 Forced: Ptr(false), 340 HeadCommit: &WebHookCommit{ 341 Added: []string{"1", "2", "3"}, 342 Author: &WebHookAuthor{ 343 Email: Ptr("abc@gmail.com"), 344 Name: Ptr("abc"), 345 Login: Ptr("abc_12"), 346 }, 347 Committer: &WebHookAuthor{ 348 Email: Ptr("abc@gmail.com"), 349 Name: Ptr("abc"), 350 Login: Ptr("abc_12"), 351 }, 352 ID: Ptr("1"), 353 Message: Ptr("WebHookCommit"), 354 Modified: []string{"abc", "efg", "erd"}, 355 Removed: []string{"cmd", "rti", "duv"}, 356 }, 357 Installation: &Installation{ 358 ID: Ptr(int64(12)), 359 }, 360 Organization: &Organization{ 361 ID: Ptr(int64(22)), 362 }, 363 Pusher: &CommitAuthor{ 364 Login: Ptr("rd@yahoo.com"), 365 }, 366 Repo: &PushEventRepository{ 367 ID: Ptr(int64(321)), 368 NodeID: Ptr("node_321"), 369 }, 370 Sender: &User{ 371 Login: Ptr("st@gmail.com"), 372 ID: Ptr(int64(202)), 373 }, 374 } 375 376 want := `{ 377 "action": "action", 378 "after": "after", 379 "before": "before", 380 "commits": [ 381 { 382 "added": ["1", "2", "3"], 383 "author":{ 384 "email": "abc@gmail.com", 385 "name": "abc", 386 "username": "abc_12" 387 }, 388 "committer": { 389 "email": "abc@gmail.com", 390 "name": "abc", 391 "username": "abc_12" 392 }, 393 "id": "1", 394 "message": "WebHookCommit", 395 "modified": ["abc", "efg", "erd"], 396 "removed": ["cmd", "rti", "duv"] 397 } 398 ], 399 "compare": "compare", 400 "created": true, 401 "forced": false, 402 "head_commit": { 403 "added": ["1", "2", "3"], 404 "author":{ 405 "email": "abc@gmail.com", 406 "name": "abc", 407 "username": "abc_12" 408 }, 409 "committer": { 410 "email": "abc@gmail.com", 411 "name": "abc", 412 "username": "abc_12" 413 }, 414 "id": "1", 415 "message": "WebHookCommit", 416 "modified": ["abc", "efg", "erd"], 417 "removed": ["cmd", "rti", "duv"] 418 }, 419 "installation": { 420 "id": 12 421 }, 422 "organization": { 423 "id" : 22 424 }, 425 "pusher":{ 426 "username": "rd@yahoo.com" 427 }, 428 "repository":{ 429 "id": 321, 430 "node_id": "node_321" 431 }, 432 "sender":{ 433 "login": "st@gmail.com", 434 "id": 202 435 } 436 }` 437 438 testJSONMarshal(t, v, want) 439 } 440 441 func TestBranchWebHookAuthor_Marshal(t *testing.T) { 442 t.Parallel() 443 testJSONMarshal(t, &WebHookAuthor{}, "{}") 444 445 v := &WebHookAuthor{ 446 Email: Ptr("abc@gmail.com"), 447 Name: Ptr("abc"), 448 Login: Ptr("abc_12"), 449 } 450 451 want := `{ 452 "email": "abc@gmail.com", 453 "name": "abc", 454 "username": "abc_12" 455 }` 456 457 testJSONMarshal(t, v, want) 458 } 459 460 func TestBranchWebHookCommit_Marshal(t *testing.T) { 461 t.Parallel() 462 testJSONMarshal(t, &WebHookCommit{}, "{}") 463 464 v := &WebHookCommit{ 465 Added: []string{"1", "2", "3"}, 466 Author: &WebHookAuthor{ 467 Email: Ptr("abc@gmail.com"), 468 Name: Ptr("abc"), 469 Login: Ptr("abc_12"), 470 }, 471 Committer: &WebHookAuthor{ 472 Email: Ptr("abc@gmail.com"), 473 Name: Ptr("abc"), 474 Login: Ptr("abc_12"), 475 }, 476 ID: Ptr("1"), 477 Message: Ptr("WebHookCommit"), 478 Modified: []string{"abc", "efg", "erd"}, 479 Removed: []string{"cmd", "rti", "duv"}, 480 } 481 482 want := `{ 483 "added": ["1", "2", "3"], 484 "author":{ 485 "email": "abc@gmail.com", 486 "name": "abc", 487 "username": "abc_12" 488 }, 489 "committer": { 490 "email": "abc@gmail.com", 491 "name": "abc", 492 "username": "abc_12" 493 }, 494 "id": "1", 495 "message": "WebHookCommit", 496 "modified": ["abc", "efg", "erd"], 497 "removed": ["cmd", "rti", "duv"] 498 }` 499 500 testJSONMarshal(t, v, want) 501 } 502 503 func TestBranchCreateHookRequest_Marshal(t *testing.T) { 504 t.Parallel() 505 testJSONMarshal(t, &createHookRequest{}, "{}") 506 507 v := &createHookRequest{ 508 Name: "abc", 509 Events: []string{"1", "2", "3"}, 510 Active: Ptr(true), 511 Config: &HookConfig{ContentType: Ptr("json")}, 512 } 513 514 want := `{ 515 "name": "abc", 516 "active": true, 517 "events": ["1","2","3"], 518 "config":{ 519 "content_type": "json" 520 } 521 }` 522 523 testJSONMarshal(t, v, want) 524 } 525 526 func TestBranchHook_Marshal(t *testing.T) { 527 t.Parallel() 528 testJSONMarshal(t, &Hook{}, "{}") 529 530 v := &Hook{ 531 CreatedAt: &Timestamp{referenceTime}, 532 UpdatedAt: &Timestamp{referenceTime}, 533 URL: Ptr("url"), 534 ID: Ptr(int64(1)), 535 Type: Ptr("type"), 536 Name: Ptr("name"), 537 TestURL: Ptr("testurl"), 538 PingURL: Ptr("pingurl"), 539 LastResponse: map[string]interface{}{ 540 "item": "item", 541 }, 542 Config: &HookConfig{ContentType: Ptr("json")}, 543 Events: []string{"1", "2", "3"}, 544 Active: Ptr(true), 545 } 546 547 want := `{ 548 "created_at": ` + referenceTimeStr + `, 549 "updated_at": ` + referenceTimeStr + `, 550 "url": "url", 551 "id": 1, 552 "type": "type", 553 "name": "name", 554 "test_url": "testurl", 555 "ping_url": "pingurl", 556 "last_response":{ 557 "item": "item" 558 }, 559 "config":{ 560 "content_type": "json" 561 }, 562 "events": ["1","2","3"], 563 "active": true 564 }` 565 566 testJSONMarshal(t, v, want) 567 } 568 569 func TestRepositoriesService_Subscribe(t *testing.T) { 570 t.Parallel() 571 client, mux, _ := setup(t) 572 573 mux.HandleFunc("/hub", func(w http.ResponseWriter, r *http.Request) { 574 testMethod(t, r, http.MethodPost) 575 testHeader(t, r, "Content-Type", "application/x-www-form-urlencoded") 576 testFormValues(t, r, values{ 577 "hub.mode": "subscribe", 578 "hub.topic": "https://github.com/o/r/events/push", 579 "hub.callback": "http://postbin.org/123", 580 "hub.secret": "test secret", 581 }) 582 }) 583 584 ctx := context.Background() 585 _, err := client.Repositories.Subscribe( 586 ctx, 587 "o", 588 "r", 589 "push", 590 "http://postbin.org/123", 591 []byte("test secret"), 592 ) 593 if err != nil { 594 t.Errorf("Repositories.Subscribe returned error: %v", err) 595 } 596 597 testNewRequestAndDoFailure(t, "Subscribe", client, func() (*Response, error) { 598 return client.Repositories.Subscribe(ctx, "o", "r", "push", "http://postbin.org/123", nil) 599 }) 600 } 601 602 func TestRepositoriesService_Unsubscribe(t *testing.T) { 603 t.Parallel() 604 client, mux, _ := setup(t) 605 606 mux.HandleFunc("/hub", func(w http.ResponseWriter, r *http.Request) { 607 testMethod(t, r, http.MethodPost) 608 testHeader(t, r, "Content-Type", "application/x-www-form-urlencoded") 609 testFormValues(t, r, values{ 610 "hub.mode": "unsubscribe", 611 "hub.topic": "https://github.com/o/r/events/push", 612 "hub.callback": "http://postbin.org/123", 613 "hub.secret": "test secret", 614 }) 615 }) 616 617 ctx := context.Background() 618 _, err := client.Repositories.Unsubscribe( 619 ctx, 620 "o", 621 "r", 622 "push", 623 "http://postbin.org/123", 624 []byte("test secret"), 625 ) 626 if err != nil { 627 t.Errorf("Repositories.Unsubscribe returned error: %v", err) 628 } 629 630 testNewRequestAndDoFailure(t, "Unsubscribe", client, func() (*Response, error) { 631 return client.Repositories.Unsubscribe(ctx, "o", "r", "push", "http://postbin.org/123", nil) 632 }) 633 }