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