github.com/google/go-github/v74@v74.0.0/github/repos_hooks_deliveries_test.go (about) 1 // Copyright 2021 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 "reflect" 14 "testing" 15 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestRepositoriesService_ListHookDeliveries(t *testing.T) { 20 t.Parallel() 21 client, mux, _ := setup(t) 22 23 mux.HandleFunc("/repos/o/r/hooks/1/deliveries", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "GET") 25 testFormValues(t, r, values{"cursor": "v1_12077215967"}) 26 fmt.Fprint(w, `[{"id":1}, {"id":2}]`) 27 }) 28 29 opt := &ListCursorOptions{Cursor: "v1_12077215967"} 30 31 ctx := context.Background() 32 hooks, _, err := client.Repositories.ListHookDeliveries(ctx, "o", "r", 1, opt) 33 if err != nil { 34 t.Errorf("Repositories.ListHookDeliveries returned error: %v", err) 35 } 36 37 want := []*HookDelivery{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}} 38 if d := cmp.Diff(hooks, want); d != "" { 39 t.Errorf("Repositories.ListHooks want (-), got (+):\n%s", d) 40 } 41 42 const methodName = "ListHookDeliveries" 43 testBadOptions(t, methodName, func() (err error) { 44 _, _, err = client.Repositories.ListHookDeliveries(ctx, "\n", "\n", -1, opt) 45 return err 46 }) 47 48 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 49 got, resp, err := client.Repositories.ListHookDeliveries(ctx, "o", "r", 1, opt) 50 if got != nil { 51 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 52 } 53 return resp, err 54 }) 55 } 56 57 func TestRepositoriesService_ListHookDeliveries_invalidOwner(t *testing.T) { 58 t.Parallel() 59 client, _, _ := setup(t) 60 61 ctx := context.Background() 62 _, _, err := client.Repositories.ListHookDeliveries(ctx, "%", "%", 1, nil) 63 testURLParseError(t, err) 64 } 65 66 func TestRepositoriesService_GetHookDelivery(t *testing.T) { 67 t.Parallel() 68 client, mux, _ := setup(t) 69 70 mux.HandleFunc("/repos/o/r/hooks/1/deliveries/1", func(w http.ResponseWriter, r *http.Request) { 71 testMethod(t, r, "GET") 72 fmt.Fprint(w, `{"id":1}`) 73 }) 74 75 ctx := context.Background() 76 hook, _, err := client.Repositories.GetHookDelivery(ctx, "o", "r", 1, 1) 77 if err != nil { 78 t.Errorf("Repositories.GetHookDelivery returned error: %v", err) 79 } 80 81 want := &HookDelivery{ID: Ptr(int64(1))} 82 if !cmp.Equal(hook, want) { 83 t.Errorf("Repositories.GetHookDelivery returned %+v, want %+v", hook, want) 84 } 85 86 const methodName = "GetHookDelivery" 87 testBadOptions(t, methodName, func() (err error) { 88 _, _, err = client.Repositories.GetHookDelivery(ctx, "\n", "\n", -1, -1) 89 return err 90 }) 91 92 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 93 got, resp, err := client.Repositories.GetHookDelivery(ctx, "o", "r", 1, 1) 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_GetHookDelivery_invalidOwner(t *testing.T) { 102 t.Parallel() 103 client, _, _ := setup(t) 104 105 ctx := context.Background() 106 _, _, err := client.Repositories.GetHookDelivery(ctx, "%", "%", 1, 1) 107 testURLParseError(t, err) 108 } 109 110 func TestRepositoriesService_RedeliverHookDelivery(t *testing.T) { 111 t.Parallel() 112 client, mux, _ := setup(t) 113 114 mux.HandleFunc("/repos/o/r/hooks/1/deliveries/1/attempts", func(w http.ResponseWriter, r *http.Request) { 115 testMethod(t, r, "POST") 116 fmt.Fprint(w, `{"id":1}`) 117 }) 118 119 ctx := context.Background() 120 hook, _, err := client.Repositories.RedeliverHookDelivery(ctx, "o", "r", 1, 1) 121 if err != nil { 122 t.Errorf("Repositories.RedeliverHookDelivery returned error: %v", err) 123 } 124 125 want := &HookDelivery{ID: Ptr(int64(1))} 126 if !cmp.Equal(hook, want) { 127 t.Errorf("Repositories.RedeliverHookDelivery returned %+v, want %+v", hook, want) 128 } 129 130 const methodName = "RedeliverHookDelivery" 131 testBadOptions(t, methodName, func() (err error) { 132 _, _, err = client.Repositories.RedeliverHookDelivery(ctx, "\n", "\n", -1, -1) 133 return err 134 }) 135 136 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 137 got, resp, err := client.Repositories.RedeliverHookDelivery(ctx, "o", "r", 1, 1) 138 if got != nil { 139 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 140 } 141 return resp, err 142 }) 143 } 144 145 var hookDeliveryPayloadTypeToStruct = map[string]any{ 146 "check_run": &CheckRunEvent{}, 147 "check_suite": &CheckSuiteEvent{}, 148 "code_scanning_alert": &CodeScanningAlertEvent{}, 149 "commit_comment": &CommitCommentEvent{}, 150 "content_reference": &ContentReferenceEvent{}, 151 "create": &CreateEvent{}, 152 "delete": &DeleteEvent{}, 153 "dependabot_alert": &DependabotAlertEvent{}, 154 "deploy_key": &DeployKeyEvent{}, 155 "deployment": &DeploymentEvent{}, 156 "deployment_status": &DeploymentStatusEvent{}, 157 "discussion_comment": &DiscussionCommentEvent{}, 158 "discussion": &DiscussionEvent{}, 159 "fork": &ForkEvent{}, 160 "github_app_authorization": &GitHubAppAuthorizationEvent{}, 161 "gollum": &GollumEvent{}, 162 "installation": &InstallationEvent{}, 163 "installation_repositories": &InstallationRepositoriesEvent{}, 164 "issue_comment": &IssueCommentEvent{}, 165 "issues": &IssuesEvent{}, 166 "label": &LabelEvent{}, 167 "marketplace_purchase": &MarketplacePurchaseEvent{}, 168 "member": &MemberEvent{}, 169 "membership": &MembershipEvent{}, 170 "meta": &MetaEvent{}, 171 "milestone": &MilestoneEvent{}, 172 "organization": &OrganizationEvent{}, 173 "org_block": &OrgBlockEvent{}, 174 "package": &PackageEvent{}, 175 "page_build": &PageBuildEvent{}, 176 "ping": &PingEvent{}, 177 "projects_v2": &ProjectV2Event{}, 178 "projects_v2_item": &ProjectV2ItemEvent{}, 179 "public": &PublicEvent{}, 180 "pull_request": &PullRequestEvent{}, 181 "pull_request_review": &PullRequestReviewEvent{}, 182 "pull_request_review_comment": &PullRequestReviewCommentEvent{}, 183 "pull_request_review_thread": &PullRequestReviewThreadEvent{}, 184 "pull_request_target": &PullRequestTargetEvent{}, 185 "push": &PushEvent{}, 186 "registry_package": &RegistryPackageEvent{}, 187 "release": &ReleaseEvent{}, 188 "repository": &RepositoryEvent{}, 189 "repository_dispatch": &RepositoryDispatchEvent{}, 190 "repository_import": &RepositoryImportEvent{}, 191 "repository_vulnerability_alert": &RepositoryVulnerabilityAlertEvent{}, 192 "secret_scanning_alert": &SecretScanningAlertEvent{}, 193 "security_advisory": &SecurityAdvisoryEvent{}, 194 "security_and_analysis": &SecurityAndAnalysisEvent{}, 195 "star": &StarEvent{}, 196 "status": &StatusEvent{}, 197 "team": &TeamEvent{}, 198 "team_add": &TeamAddEvent{}, 199 "user": &UserEvent{}, 200 "watch": &WatchEvent{}, 201 "workflow_dispatch": &WorkflowDispatchEvent{}, 202 "workflow_job": &WorkflowJobEvent{}, 203 "workflow_run": &WorkflowRunEvent{}, 204 } 205 206 func TestHookDelivery_ParsePayload(t *testing.T) { 207 t.Parallel() 208 for evt, obj := range hookDeliveryPayloadTypeToStruct { 209 t.Run(evt, func(t *testing.T) { 210 t.Parallel() 211 bs, err := json.Marshal(obj) 212 if err != nil { 213 t.Fatal(err) 214 } 215 216 p := json.RawMessage(bs) 217 218 d := &HookDelivery{ 219 Event: Ptr(evt), 220 Request: &HookRequest{ 221 RawPayload: &p, 222 }, 223 } 224 225 got, err := d.ParseRequestPayload() 226 if err != nil { 227 t.Error(err) 228 } 229 230 if !reflect.DeepEqual(obj, got) { 231 t.Errorf("want %T %v, got %T %v", obj, obj, got, got) 232 } 233 }) 234 } 235 } 236 237 func TestHookDelivery_ParsePayload_invalidEvent(t *testing.T) { 238 t.Parallel() 239 p := json.RawMessage(nil) 240 241 d := &HookDelivery{ 242 Event: Ptr("some_invalid_event"), 243 Request: &HookRequest{ 244 RawPayload: &p, 245 }, 246 } 247 248 _, err := d.ParseRequestPayload() 249 if err == nil || err.Error() != `unsupported event type "some_invalid_event"` { 250 t.Errorf("unexpected error: %v", err) 251 } 252 } 253 254 func TestHookDelivery_ParsePayload_invalidPayload(t *testing.T) { 255 t.Parallel() 256 p := json.RawMessage([]byte(`{"check_run":{"id":"invalid"}}`)) 257 258 d := &HookDelivery{ 259 Event: Ptr("check_run"), 260 Request: &HookRequest{ 261 RawPayload: &p, 262 }, 263 } 264 265 _, err := d.ParseRequestPayload() 266 if err == nil || err.Error() != "json: cannot unmarshal string into Go struct field CheckRun.check_run.id of type int64" { 267 t.Errorf("unexpected error: %v", err) 268 } 269 } 270 271 func TestHookRequest_Marshal(t *testing.T) { 272 t.Parallel() 273 testJSONMarshal(t, &HookRequest{}, "{}") 274 275 header := make(map[string]string) 276 header["key"] = "value" 277 278 jsonMsg, _ := json.Marshal(&header) 279 280 r := &HookRequest{ 281 Headers: header, 282 RawPayload: (*json.RawMessage)(&jsonMsg), 283 } 284 285 want := `{ 286 "headers": { 287 "key": "value" 288 }, 289 "payload": { 290 "key": "value" 291 } 292 }` 293 294 testJSONMarshal(t, r, want) 295 } 296 297 func TestHookRequest_GetHeader(t *testing.T) { 298 t.Parallel() 299 300 header := make(map[string]string) 301 header["key1"] = "value1" 302 header["Key+2"] = "value2" 303 header["kEy-3"] = "value3" 304 header["KEY_4"] = "value4" 305 306 r := &HookRequest{ 307 Headers: header, 308 } 309 310 // Checking positive cases 311 testPrefixes := []string{"key", "Key", "kEy", "KEY"} 312 for hdrKey, hdrValue := range header { 313 for _, prefix := range testPrefixes { 314 key := prefix + hdrKey[3:] 315 if val := r.GetHeader(key); val != hdrValue { 316 t.Errorf("GetHeader(%q) is not working: %q != %q", key, val, hdrValue) 317 } 318 } 319 } 320 321 // Checking negative case 322 key := "asd" 323 if val := r.GetHeader(key); val != "" { 324 t.Errorf("GetHeader(%q) should return empty value: %q != %q", key, val, "") 325 } 326 key = "kay1" 327 if val := r.GetHeader(key); val != "" { 328 t.Errorf("GetHeader(%q) should return empty value: %q != %q", key, val, "") 329 } 330 } 331 332 func TestHookResponse_Marshal(t *testing.T) { 333 t.Parallel() 334 testJSONMarshal(t, &HookResponse{}, "{}") 335 336 header := make(map[string]string) 337 header["key"] = "value" 338 339 jsonMsg, _ := json.Marshal(&header) 340 341 r := &HookResponse{ 342 Headers: header, 343 RawPayload: (*json.RawMessage)(&jsonMsg), 344 } 345 346 want := `{ 347 "headers": { 348 "key": "value" 349 }, 350 "payload": { 351 "key": "value" 352 } 353 }` 354 355 testJSONMarshal(t, r, want) 356 } 357 358 func TestHookResponse_GetHeader(t *testing.T) { 359 t.Parallel() 360 361 header := make(map[string]string) 362 header["key1"] = "value1" 363 header["Key+2"] = "value2" 364 header["kEy-3"] = "value3" 365 header["KEY_4"] = "value4" 366 367 r := &HookResponse{ 368 Headers: header, 369 } 370 371 // Checking positive cases 372 testPrefixes := []string{"key", "Key", "kEy", "KEY"} 373 for hdrKey, hdrValue := range header { 374 for _, prefix := range testPrefixes { 375 key := prefix + hdrKey[3:] 376 if val := r.GetHeader(key); val != hdrValue { 377 t.Errorf("GetHeader(%q) is not working: %q != %q", key, val, hdrValue) 378 } 379 } 380 } 381 382 // Checking negative case 383 key := "asd" 384 if val := r.GetHeader(key); val != "" { 385 t.Errorf("GetHeader(%q) should return empty value: %q != %q", key, val, "") 386 } 387 key = "kay1" 388 if val := r.GetHeader(key); val != "" { 389 t.Errorf("GetHeader(%q) should return empty value: %q != %q", key, val, "") 390 } 391 } 392 393 func TestHookDelivery_Marshal(t *testing.T) { 394 t.Parallel() 395 testJSONMarshal(t, &HookDelivery{}, "{}") 396 397 header := make(map[string]string) 398 header["key"] = "value" 399 400 jsonMsg, _ := json.Marshal(&header) 401 402 r := &HookDelivery{ 403 ID: Ptr(int64(1)), 404 GUID: Ptr("guid"), 405 DeliveredAt: &Timestamp{referenceTime}, 406 Redelivery: Ptr(true), 407 Duration: Ptr(1.0), 408 Status: Ptr("guid"), 409 StatusCode: Ptr(1), 410 Event: Ptr("guid"), 411 Action: Ptr("guid"), 412 InstallationID: Ptr(int64(1)), 413 RepositoryID: Ptr(int64(1)), 414 Request: &HookRequest{ 415 Headers: header, 416 RawPayload: (*json.RawMessage)(&jsonMsg), 417 }, 418 Response: &HookResponse{ 419 Headers: header, 420 RawPayload: (*json.RawMessage)(&jsonMsg), 421 }, 422 } 423 424 want := `{ 425 "id": 1, 426 "guid": "guid", 427 "delivered_at": ` + referenceTimeStr + `, 428 "redelivery": true, 429 "duration": 1, 430 "status": "guid", 431 "status_code": 1, 432 "event": "guid", 433 "action": "guid", 434 "installation_id": 1, 435 "repository_id": 1, 436 "request": { 437 "headers": { 438 "key": "value" 439 }, 440 "payload": { 441 "key": "value" 442 } 443 }, 444 "response": { 445 "headers": { 446 "key": "value" 447 }, 448 "payload": { 449 "key": "value" 450 } 451 } 452 }` 453 454 testJSONMarshal(t, r, want) 455 }