github.com/google/go-github/v65@v65.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 client, mux, _, teardown := setup() 20 defer teardown() 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: 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 assertNilError(t, 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: &CommitAuthor{ 361 Login: String("rd@yahoo.com"), 362 }, 363 Repo: &PushEventRepository{ 364 ID: Int64(321), 365 NodeID: String("node_321"), 366 }, 367 Sender: &User{ 368 Login: String("st@gmail.com"), 369 ID: Int64(202), 370 }, 371 } 372 373 want := `{ 374 "action": "action", 375 "after": "after", 376 "before": "before", 377 "commits": [ 378 { 379 "added": ["1", "2", "3"], 380 "author":{ 381 "email": "abc@gmail.com", 382 "name": "abc", 383 "username": "abc_12" 384 }, 385 "committer": { 386 "email": "abc@gmail.com", 387 "name": "abc", 388 "username": "abc_12" 389 }, 390 "id": "1", 391 "message": "WebHookCommit", 392 "modified": ["abc", "efg", "erd"], 393 "removed": ["cmd", "rti", "duv"] 394 } 395 ], 396 "compare": "compare", 397 "created": true, 398 "forced": false, 399 "head_commit": { 400 "added": ["1", "2", "3"], 401 "author":{ 402 "email": "abc@gmail.com", 403 "name": "abc", 404 "username": "abc_12" 405 }, 406 "committer": { 407 "email": "abc@gmail.com", 408 "name": "abc", 409 "username": "abc_12" 410 }, 411 "id": "1", 412 "message": "WebHookCommit", 413 "modified": ["abc", "efg", "erd"], 414 "removed": ["cmd", "rti", "duv"] 415 }, 416 "installation": { 417 "id": 12 418 }, 419 "organization": { 420 "id" : 22 421 }, 422 "pusher":{ 423 "username": "rd@yahoo.com" 424 }, 425 "repository":{ 426 "id": 321, 427 "node_id": "node_321" 428 }, 429 "sender":{ 430 "login": "st@gmail.com", 431 "id": 202 432 } 433 }` 434 435 testJSONMarshal(t, v, want) 436 } 437 438 func TestBranchWebHookAuthor_Marshal(t *testing.T) { 439 testJSONMarshal(t, &WebHookAuthor{}, "{}") 440 441 v := &WebHookAuthor{ 442 Email: String("abc@gmail.com"), 443 Name: String("abc"), 444 Login: String("abc_12"), 445 } 446 447 want := `{ 448 "email": "abc@gmail.com", 449 "name": "abc", 450 "username": "abc_12" 451 }` 452 453 testJSONMarshal(t, v, want) 454 } 455 456 func TestBranchWebHookCommit_Marshal(t *testing.T) { 457 testJSONMarshal(t, &WebHookCommit{}, "{}") 458 459 v := &WebHookCommit{ 460 Added: []string{"1", "2", "3"}, 461 Author: &WebHookAuthor{ 462 Email: String("abc@gmail.com"), 463 Name: String("abc"), 464 Login: String("abc_12"), 465 }, 466 Committer: &WebHookAuthor{ 467 Email: String("abc@gmail.com"), 468 Name: String("abc"), 469 Login: String("abc_12"), 470 }, 471 ID: String("1"), 472 Message: String("WebHookCommit"), 473 Modified: []string{"abc", "efg", "erd"}, 474 Removed: []string{"cmd", "rti", "duv"}, 475 } 476 477 want := `{ 478 "added": ["1", "2", "3"], 479 "author":{ 480 "email": "abc@gmail.com", 481 "name": "abc", 482 "username": "abc_12" 483 }, 484 "committer": { 485 "email": "abc@gmail.com", 486 "name": "abc", 487 "username": "abc_12" 488 }, 489 "id": "1", 490 "message": "WebHookCommit", 491 "modified": ["abc", "efg", "erd"], 492 "removed": ["cmd", "rti", "duv"] 493 }` 494 495 testJSONMarshal(t, v, want) 496 } 497 498 func TestBranchCreateHookRequest_Marshal(t *testing.T) { 499 testJSONMarshal(t, &createHookRequest{}, "{}") 500 501 v := &createHookRequest{ 502 Name: "abc", 503 Events: []string{"1", "2", "3"}, 504 Active: Bool(true), 505 Config: &HookConfig{ContentType: String("json")}, 506 } 507 508 want := `{ 509 "name": "abc", 510 "active": true, 511 "events": ["1","2","3"], 512 "config":{ 513 "content_type": "json" 514 } 515 }` 516 517 testJSONMarshal(t, v, want) 518 } 519 520 func TestBranchHook_Marshal(t *testing.T) { 521 testJSONMarshal(t, &Hook{}, "{}") 522 523 v := &Hook{ 524 CreatedAt: &Timestamp{referenceTime}, 525 UpdatedAt: &Timestamp{referenceTime}, 526 URL: String("url"), 527 ID: Int64(1), 528 Type: String("type"), 529 Name: String("name"), 530 TestURL: String("testurl"), 531 PingURL: String("pingurl"), 532 LastResponse: map[string]interface{}{ 533 "item": "item", 534 }, 535 Config: &HookConfig{ContentType: String("json")}, 536 Events: []string{"1", "2", "3"}, 537 Active: Bool(true), 538 } 539 540 want := `{ 541 "created_at": ` + referenceTimeStr + `, 542 "updated_at": ` + referenceTimeStr + `, 543 "url": "url", 544 "id": 1, 545 "type": "type", 546 "name": "name", 547 "test_url": "testurl", 548 "ping_url": "pingurl", 549 "last_response":{ 550 "item": "item" 551 }, 552 "config":{ 553 "content_type": "json" 554 }, 555 "events": ["1","2","3"], 556 "active": true 557 }` 558 559 testJSONMarshal(t, v, want) 560 } 561 562 func TestRepositoriesService_Subscribe(t *testing.T) { 563 client, mux, _, teardown := setup() 564 defer teardown() 565 566 mux.HandleFunc("/hub", func(w http.ResponseWriter, r *http.Request) { 567 testMethod(t, r, http.MethodPost) 568 testHeader(t, r, "Content-Type", "application/x-www-form-urlencoded") 569 testFormValues(t, r, values{ 570 "hub.mode": "subscribe", 571 "hub.topic": "https://github.com/o/r/events/push", 572 "hub.callback": "http://postbin.org/123", 573 "hub.secret": "test secret", 574 }) 575 }) 576 577 ctx := context.Background() 578 _, err := client.Repositories.Subscribe( 579 ctx, 580 "o", 581 "r", 582 "push", 583 "http://postbin.org/123", 584 []byte("test secret"), 585 ) 586 if err != nil { 587 t.Errorf("Repositories.Subscribe returned error: %v", err) 588 } 589 590 testNewRequestAndDoFailure(t, "Subscribe", client, func() (*Response, error) { 591 return client.Repositories.Subscribe(ctx, "o", "r", "push", "http://postbin.org/123", nil) 592 }) 593 } 594 595 func TestRepositoriesService_Unsubscribe(t *testing.T) { 596 client, mux, _, teardown := setup() 597 defer teardown() 598 599 mux.HandleFunc("/hub", func(w http.ResponseWriter, r *http.Request) { 600 testMethod(t, r, http.MethodPost) 601 testHeader(t, r, "Content-Type", "application/x-www-form-urlencoded") 602 testFormValues(t, r, values{ 603 "hub.mode": "unsubscribe", 604 "hub.topic": "https://github.com/o/r/events/push", 605 "hub.callback": "http://postbin.org/123", 606 "hub.secret": "test secret", 607 }) 608 }) 609 610 ctx := context.Background() 611 _, err := client.Repositories.Unsubscribe( 612 ctx, 613 "o", 614 "r", 615 "push", 616 "http://postbin.org/123", 617 []byte("test secret"), 618 ) 619 if err != nil { 620 t.Errorf("Repositories.Unsubscribe returned error: %v", err) 621 } 622 623 testNewRequestAndDoFailure(t, "Unsubscribe", client, func() (*Response, error) { 624 return client.Repositories.Unsubscribe(ctx, "o", "r", "push", "http://postbin.org/123", nil) 625 }) 626 }