github.com/google/go-github/v65@v65.0.0/github/apps_test.go (about) 1 // Copyright 2016 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 "time" 15 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestAppsService_Get_authenticatedApp(t *testing.T) { 20 client, mux, _, teardown := setup() 21 defer teardown() 22 23 mux.HandleFunc("/app", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "GET") 25 fmt.Fprint(w, `{"id":1}`) 26 }) 27 28 ctx := context.Background() 29 app, _, err := client.Apps.Get(ctx, "") 30 if err != nil { 31 t.Errorf("Apps.Get returned error: %v", err) 32 } 33 34 want := &App{ID: Int64(1)} 35 if !cmp.Equal(app, want) { 36 t.Errorf("Apps.Get returned %+v, want %+v", app, want) 37 } 38 39 const methodName = "Get" 40 testBadOptions(t, methodName, func() (err error) { 41 _, _, err = client.Apps.Get(ctx, "\n") 42 return err 43 }) 44 45 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 46 got, resp, err := client.Apps.Get(ctx, "") 47 if got != nil { 48 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 49 } 50 return resp, err 51 }) 52 } 53 54 func TestAppsService_Get_specifiedApp(t *testing.T) { 55 client, mux, _, teardown := setup() 56 defer teardown() 57 58 mux.HandleFunc("/apps/a", func(w http.ResponseWriter, r *http.Request) { 59 testMethod(t, r, "GET") 60 fmt.Fprint(w, `{"html_url":"https://github.com/apps/a"}`) 61 }) 62 63 ctx := context.Background() 64 app, _, err := client.Apps.Get(ctx, "a") 65 if err != nil { 66 t.Errorf("Apps.Get returned error: %v", err) 67 } 68 69 want := &App{HTMLURL: String("https://github.com/apps/a")} 70 if !cmp.Equal(app, want) { 71 t.Errorf("Apps.Get returned %+v, want %+v", *app.HTMLURL, *want.HTMLURL) 72 } 73 } 74 75 func TestAppsService_ListInstallationRequests(t *testing.T) { 76 client, mux, _, teardown := setup() 77 defer teardown() 78 79 mux.HandleFunc("/app/installation-requests", func(w http.ResponseWriter, r *http.Request) { 80 testMethod(t, r, "GET") 81 testFormValues(t, r, values{ 82 "page": "1", 83 "per_page": "2", 84 }) 85 fmt.Fprint(w, `[{ 86 "id": 1, 87 "account": { "id": 2 }, 88 "requester": { "id": 3 }, 89 "created_at": "2018-01-01T00:00:00Z" 90 }]`, 91 ) 92 }) 93 94 opt := &ListOptions{Page: 1, PerPage: 2} 95 ctx := context.Background() 96 installationRequests, _, err := client.Apps.ListInstallationRequests(ctx, opt) 97 if err != nil { 98 t.Errorf("Apps.ListInstallations returned error: %v", err) 99 } 100 101 date := Timestamp{Time: time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)} 102 want := []*InstallationRequest{{ 103 ID: Int64(1), 104 Account: &User{ID: Int64(2)}, 105 Requester: &User{ID: Int64(3)}, 106 CreatedAt: &date, 107 }} 108 if !cmp.Equal(installationRequests, want) { 109 t.Errorf("Apps.ListInstallationRequests returned %+v, want %+v", installationRequests, want) 110 } 111 112 const methodName = "ListInstallationRequests" 113 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 114 got, resp, err := client.Apps.ListInstallationRequests(ctx, opt) 115 if got != nil { 116 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 117 } 118 return resp, err 119 }) 120 } 121 122 func TestAppsService_ListInstallations(t *testing.T) { 123 client, mux, _, teardown := setup() 124 defer teardown() 125 126 mux.HandleFunc("/app/installations", func(w http.ResponseWriter, r *http.Request) { 127 testMethod(t, r, "GET") 128 testFormValues(t, r, values{ 129 "page": "1", 130 "per_page": "2", 131 }) 132 fmt.Fprint(w, `[{ 133 "id":1, 134 "app_id":1, 135 "target_id":1, 136 "target_type": "Organization", 137 "permissions": { 138 "actions": "read", 139 "administration": "read", 140 "checks": "read", 141 "contents": "read", 142 "content_references": "read", 143 "deployments": "read", 144 "environments": "read", 145 "issues": "write", 146 "metadata": "read", 147 "members": "read", 148 "organization_administration": "write", 149 "organization_custom_roles": "write", 150 "organization_hooks": "write", 151 "organization_packages": "write", 152 "organization_personal_access_tokens": "read", 153 "organization_personal_access_token_requests": "read", 154 "organization_plan": "read", 155 "organization_pre_receive_hooks": "write", 156 "organization_projects": "read", 157 "organization_secrets": "read", 158 "organization_self_hosted_runners": "read", 159 "organization_user_blocking": "write", 160 "packages": "read", 161 "pages": "read", 162 "pull_requests": "write", 163 "repository_hooks": "write", 164 "repository_projects": "read", 165 "repository_pre_receive_hooks": "read", 166 "secrets": "read", 167 "secret_scanning_alerts": "read", 168 "security_events": "read", 169 "single_file": "write", 170 "statuses": "write", 171 "team_discussions": "read", 172 "vulnerability_alerts": "read", 173 "workflows": "write" 174 }, 175 "events": [ 176 "push", 177 "pull_request" 178 ], 179 "single_file_name": "config.yml", 180 "repository_selection": "selected", 181 "created_at": "2018-01-01T00:00:00Z", 182 "updated_at": "2018-01-01T00:00:00Z"}]`, 183 ) 184 }) 185 186 opt := &ListOptions{Page: 1, PerPage: 2} 187 ctx := context.Background() 188 installations, _, err := client.Apps.ListInstallations(ctx, opt) 189 if err != nil { 190 t.Errorf("Apps.ListInstallations returned error: %v", err) 191 } 192 193 date := Timestamp{Time: time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)} 194 want := []*Installation{{ 195 ID: Int64(1), 196 AppID: Int64(1), 197 TargetID: Int64(1), 198 TargetType: String("Organization"), 199 SingleFileName: String("config.yml"), 200 RepositorySelection: String("selected"), 201 Permissions: &InstallationPermissions{ 202 Actions: String("read"), 203 Administration: String("read"), 204 Checks: String("read"), 205 Contents: String("read"), 206 ContentReferences: String("read"), 207 Deployments: String("read"), 208 Environments: String("read"), 209 Issues: String("write"), 210 Metadata: String("read"), 211 Members: String("read"), 212 OrganizationAdministration: String("write"), 213 OrganizationCustomRoles: String("write"), 214 OrganizationHooks: String("write"), 215 OrganizationPackages: String("write"), 216 OrganizationPersonalAccessTokens: String("read"), 217 OrganizationPersonalAccessTokenRequests: String("read"), 218 OrganizationPlan: String("read"), 219 OrganizationPreReceiveHooks: String("write"), 220 OrganizationProjects: String("read"), 221 OrganizationSecrets: String("read"), 222 OrganizationSelfHostedRunners: String("read"), 223 OrganizationUserBlocking: String("write"), 224 Packages: String("read"), 225 Pages: String("read"), 226 PullRequests: String("write"), 227 RepositoryHooks: String("write"), 228 RepositoryProjects: String("read"), 229 RepositoryPreReceiveHooks: String("read"), 230 Secrets: String("read"), 231 SecretScanningAlerts: String("read"), 232 SecurityEvents: String("read"), 233 SingleFile: String("write"), 234 Statuses: String("write"), 235 TeamDiscussions: String("read"), 236 VulnerabilityAlerts: String("read"), 237 Workflows: String("write")}, 238 Events: []string{"push", "pull_request"}, 239 CreatedAt: &date, 240 UpdatedAt: &date, 241 }} 242 if !cmp.Equal(installations, want) { 243 t.Errorf("Apps.ListInstallations returned %+v, want %+v", installations, want) 244 } 245 246 const methodName = "ListInstallations" 247 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 248 got, resp, err := client.Apps.ListInstallations(ctx, opt) 249 if got != nil { 250 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 251 } 252 return resp, err 253 }) 254 } 255 256 func TestAppsService_GetInstallation(t *testing.T) { 257 client, mux, _, teardown := setup() 258 defer teardown() 259 260 mux.HandleFunc("/app/installations/1", func(w http.ResponseWriter, r *http.Request) { 261 testMethod(t, r, "GET") 262 fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`) 263 }) 264 265 ctx := context.Background() 266 installation, _, err := client.Apps.GetInstallation(ctx, 1) 267 if err != nil { 268 t.Errorf("Apps.GetInstallation returned error: %v", err) 269 } 270 271 want := &Installation{ID: Int64(1), AppID: Int64(1), TargetID: Int64(1), TargetType: String("Organization")} 272 if !cmp.Equal(installation, want) { 273 t.Errorf("Apps.GetInstallation returned %+v, want %+v", installation, want) 274 } 275 276 const methodName = "GetInstallation" 277 testBadOptions(t, methodName, func() (err error) { 278 _, _, err = client.Apps.GetInstallation(ctx, -1) 279 return err 280 }) 281 282 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 283 got, resp, err := client.Apps.GetInstallation(ctx, 1) 284 if got != nil { 285 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 286 } 287 return resp, err 288 }) 289 } 290 291 func TestAppsService_ListUserInstallations(t *testing.T) { 292 client, mux, _, teardown := setup() 293 defer teardown() 294 295 mux.HandleFunc("/user/installations", func(w http.ResponseWriter, r *http.Request) { 296 testMethod(t, r, "GET") 297 testFormValues(t, r, values{ 298 "page": "1", 299 "per_page": "2", 300 }) 301 fmt.Fprint(w, `{"installations":[{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}]}`) 302 }) 303 304 opt := &ListOptions{Page: 1, PerPage: 2} 305 ctx := context.Background() 306 installations, _, err := client.Apps.ListUserInstallations(ctx, opt) 307 if err != nil { 308 t.Errorf("Apps.ListUserInstallations returned error: %v", err) 309 } 310 311 want := []*Installation{{ID: Int64(1), AppID: Int64(1), TargetID: Int64(1), TargetType: String("Organization")}} 312 if !cmp.Equal(installations, want) { 313 t.Errorf("Apps.ListUserInstallations returned %+v, want %+v", installations, want) 314 } 315 316 const methodName = "ListUserInstallations" 317 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 318 got, resp, err := client.Apps.ListUserInstallations(ctx, opt) 319 if got != nil { 320 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 321 } 322 return resp, err 323 }) 324 } 325 326 func TestAppsService_SuspendInstallation(t *testing.T) { 327 client, mux, _, teardown := setup() 328 defer teardown() 329 330 mux.HandleFunc("/app/installations/1/suspended", func(w http.ResponseWriter, r *http.Request) { 331 testMethod(t, r, "PUT") 332 333 w.WriteHeader(http.StatusNoContent) 334 }) 335 336 ctx := context.Background() 337 if _, err := client.Apps.SuspendInstallation(ctx, 1); err != nil { 338 t.Errorf("Apps.SuspendInstallation returned error: %v", err) 339 } 340 341 const methodName = "SuspendInstallation" 342 testBadOptions(t, methodName, func() (err error) { 343 _, err = client.Apps.SuspendInstallation(ctx, -1) 344 return err 345 }) 346 347 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 348 return client.Apps.SuspendInstallation(ctx, 1) 349 }) 350 } 351 352 func TestAppsService_UnsuspendInstallation(t *testing.T) { 353 client, mux, _, teardown := setup() 354 defer teardown() 355 356 mux.HandleFunc("/app/installations/1/suspended", func(w http.ResponseWriter, r *http.Request) { 357 testMethod(t, r, "DELETE") 358 359 w.WriteHeader(http.StatusNoContent) 360 }) 361 362 ctx := context.Background() 363 if _, err := client.Apps.UnsuspendInstallation(ctx, 1); err != nil { 364 t.Errorf("Apps.UnsuspendInstallation returned error: %v", err) 365 } 366 367 const methodName = "UnsuspendInstallation" 368 testBadOptions(t, methodName, func() (err error) { 369 _, err = client.Apps.UnsuspendInstallation(ctx, -1) 370 return err 371 }) 372 373 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 374 return client.Apps.UnsuspendInstallation(ctx, 1) 375 }) 376 } 377 378 func TestAppsService_DeleteInstallation(t *testing.T) { 379 client, mux, _, teardown := setup() 380 defer teardown() 381 382 mux.HandleFunc("/app/installations/1", func(w http.ResponseWriter, r *http.Request) { 383 testMethod(t, r, "DELETE") 384 w.WriteHeader(http.StatusNoContent) 385 }) 386 387 ctx := context.Background() 388 _, err := client.Apps.DeleteInstallation(ctx, 1) 389 if err != nil { 390 t.Errorf("Apps.DeleteInstallation returned error: %v", err) 391 } 392 393 const methodName = "DeleteInstallation" 394 testBadOptions(t, methodName, func() (err error) { 395 _, err = client.Apps.DeleteInstallation(ctx, -1) 396 return err 397 }) 398 399 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 400 return client.Apps.DeleteInstallation(ctx, 1) 401 }) 402 } 403 404 func TestAppsService_CreateInstallationToken(t *testing.T) { 405 client, mux, _, teardown := setup() 406 defer teardown() 407 408 mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) { 409 testMethod(t, r, "POST") 410 fmt.Fprint(w, `{"token":"t"}`) 411 }) 412 413 ctx := context.Background() 414 token, _, err := client.Apps.CreateInstallationToken(ctx, 1, nil) 415 if err != nil { 416 t.Errorf("Apps.CreateInstallationToken returned error: %v", err) 417 } 418 419 want := &InstallationToken{Token: String("t")} 420 if !cmp.Equal(token, want) { 421 t.Errorf("Apps.CreateInstallationToken returned %+v, want %+v", token, want) 422 } 423 424 const methodName = "CreateInstallationToken" 425 testBadOptions(t, methodName, func() (err error) { 426 _, _, err = client.Apps.CreateInstallationToken(ctx, -1, nil) 427 return err 428 }) 429 430 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 431 got, resp, err := client.Apps.CreateInstallationToken(ctx, 1, nil) 432 if got != nil { 433 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 434 } 435 return resp, err 436 }) 437 } 438 439 func TestAppsService_CreateInstallationTokenWithOptions(t *testing.T) { 440 client, mux, _, teardown := setup() 441 defer teardown() 442 443 installationTokenOptions := &InstallationTokenOptions{ 444 RepositoryIDs: []int64{1234}, 445 Repositories: []string{"foo"}, 446 Permissions: &InstallationPermissions{ 447 Contents: String("write"), 448 Issues: String("read"), 449 }, 450 } 451 452 mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) { 453 v := new(InstallationTokenOptions) 454 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 455 456 if !cmp.Equal(v, installationTokenOptions) { 457 t.Errorf("request sent %+v, want %+v", v, installationTokenOptions) 458 } 459 460 testMethod(t, r, "POST") 461 fmt.Fprint(w, `{"token":"t"}`) 462 }) 463 464 ctx := context.Background() 465 token, _, err := client.Apps.CreateInstallationToken(ctx, 1, installationTokenOptions) 466 if err != nil { 467 t.Errorf("Apps.CreateInstallationToken returned error: %v", err) 468 } 469 470 want := &InstallationToken{Token: String("t")} 471 if !cmp.Equal(token, want) { 472 t.Errorf("Apps.CreateInstallationToken returned %+v, want %+v", token, want) 473 } 474 } 475 476 func TestAppsService_CreateInstallationTokenListReposWithOptions(t *testing.T) { 477 client, mux, _, teardown := setup() 478 defer teardown() 479 480 installationTokenListRepoOptions := &InstallationTokenListRepoOptions{ 481 Repositories: []string{"foo"}, 482 Permissions: &InstallationPermissions{ 483 Contents: String("write"), 484 Issues: String("read"), 485 }, 486 } 487 488 mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) { 489 v := new(InstallationTokenListRepoOptions) 490 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 491 492 if !cmp.Equal(v, installationTokenListRepoOptions) { 493 t.Errorf("request sent %+v, want %+v", v, installationTokenListRepoOptions) 494 } 495 496 testMethod(t, r, "POST") 497 fmt.Fprint(w, `{"token":"t"}`) 498 }) 499 500 ctx := context.Background() 501 token, _, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, installationTokenListRepoOptions) 502 if err != nil { 503 t.Errorf("Apps.CreateInstallationTokenListRepos returned error: %v", err) 504 } 505 506 want := &InstallationToken{Token: String("t")} 507 if !cmp.Equal(token, want) { 508 t.Errorf("Apps.CreateInstallationTokenListRepos returned %+v, want %+v", token, want) 509 } 510 } 511 512 func TestAppsService_CreateInstallationTokenListReposWithNoOptions(t *testing.T) { 513 client, mux, _, teardown := setup() 514 defer teardown() 515 516 mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) { 517 testMethod(t, r, "POST") 518 fmt.Fprint(w, `{"token":"t"}`) 519 }) 520 521 ctx := context.Background() 522 token, _, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, nil) 523 if err != nil { 524 t.Errorf("Apps.CreateInstallationTokenListRepos returned error: %v", err) 525 } 526 527 want := &InstallationToken{Token: String("t")} 528 if !cmp.Equal(token, want) { 529 t.Errorf("Apps.CreateInstallationTokenListRepos returned %+v, want %+v", token, want) 530 } 531 532 const methodName = "CreateInstallationTokenListRepos" 533 testBadOptions(t, methodName, func() (err error) { 534 _, _, err = client.Apps.CreateInstallationTokenListRepos(ctx, -1, nil) 535 return err 536 }) 537 538 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 539 got, resp, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, nil) 540 if got != nil { 541 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 542 } 543 return resp, err 544 }) 545 } 546 547 func TestAppsService_CreateAttachement(t *testing.T) { 548 client, mux, _, teardown := setup() 549 defer teardown() 550 551 mux.HandleFunc("/content_references/11/attachments", func(w http.ResponseWriter, r *http.Request) { 552 testMethod(t, r, "POST") 553 testHeader(t, r, "Accept", mediaTypeContentAttachmentsPreview) 554 555 w.WriteHeader(http.StatusOK) 556 assertWrite(t, w, []byte(`{"id":1,"title":"title1","body":"body1"}`)) 557 }) 558 559 ctx := context.Background() 560 got, _, err := client.Apps.CreateAttachment(ctx, 11, "title1", "body1") 561 if err != nil { 562 t.Errorf("CreateAttachment returned error: %v", err) 563 } 564 565 want := &Attachment{ID: Int64(1), Title: String("title1"), Body: String("body1")} 566 if !cmp.Equal(got, want) { 567 t.Errorf("CreateAttachment = %+v, want %+v", got, want) 568 } 569 570 const methodName = "CreateAttachment" 571 testBadOptions(t, methodName, func() (err error) { 572 _, _, err = client.Apps.CreateAttachment(ctx, -11, "\n", "\n") 573 return err 574 }) 575 576 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 577 got, resp, err := client.Apps.CreateAttachment(ctx, 11, "title1", "body1") 578 if got != nil { 579 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 580 } 581 return resp, err 582 }) 583 } 584 585 func TestAppsService_FindOrganizationInstallation(t *testing.T) { 586 client, mux, _, teardown := setup() 587 defer teardown() 588 589 mux.HandleFunc("/orgs/o/installation", func(w http.ResponseWriter, r *http.Request) { 590 testMethod(t, r, "GET") 591 fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`) 592 }) 593 594 ctx := context.Background() 595 installation, _, err := client.Apps.FindOrganizationInstallation(ctx, "o") 596 if err != nil { 597 t.Errorf("Apps.FindOrganizationInstallation returned error: %v", err) 598 } 599 600 want := &Installation{ID: Int64(1), AppID: Int64(1), TargetID: Int64(1), TargetType: String("Organization")} 601 if !cmp.Equal(installation, want) { 602 t.Errorf("Apps.FindOrganizationInstallation returned %+v, want %+v", installation, want) 603 } 604 605 const methodName = "FindOrganizationInstallation" 606 testBadOptions(t, methodName, func() (err error) { 607 _, _, err = client.Apps.FindOrganizationInstallation(ctx, "\n") 608 return err 609 }) 610 611 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 612 got, resp, err := client.Apps.FindOrganizationInstallation(ctx, "o") 613 if got != nil { 614 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 615 } 616 return resp, err 617 }) 618 } 619 620 func TestAppsService_FindRepositoryInstallation(t *testing.T) { 621 client, mux, _, teardown := setup() 622 defer teardown() 623 624 mux.HandleFunc("/repos/o/r/installation", func(w http.ResponseWriter, r *http.Request) { 625 testMethod(t, r, "GET") 626 fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`) 627 }) 628 629 ctx := context.Background() 630 installation, _, err := client.Apps.FindRepositoryInstallation(ctx, "o", "r") 631 if err != nil { 632 t.Errorf("Apps.FindRepositoryInstallation returned error: %v", err) 633 } 634 635 want := &Installation{ID: Int64(1), AppID: Int64(1), TargetID: Int64(1), TargetType: String("Organization")} 636 if !cmp.Equal(installation, want) { 637 t.Errorf("Apps.FindRepositoryInstallation returned %+v, want %+v", installation, want) 638 } 639 640 const methodName = "FindRepositoryInstallation" 641 testBadOptions(t, methodName, func() (err error) { 642 _, _, err = client.Apps.FindRepositoryInstallation(ctx, "\n", "\n") 643 return err 644 }) 645 646 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 647 got, resp, err := client.Apps.FindRepositoryInstallation(ctx, "o", "r") 648 if got != nil { 649 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 650 } 651 return resp, err 652 }) 653 } 654 655 func TestAppsService_FindRepositoryInstallationByID(t *testing.T) { 656 client, mux, _, teardown := setup() 657 defer teardown() 658 659 mux.HandleFunc("/repositories/1/installation", func(w http.ResponseWriter, r *http.Request) { 660 testMethod(t, r, "GET") 661 fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`) 662 }) 663 664 ctx := context.Background() 665 installation, _, err := client.Apps.FindRepositoryInstallationByID(ctx, 1) 666 if err != nil { 667 t.Errorf("Apps.FindRepositoryInstallationByID returned error: %v", err) 668 } 669 670 want := &Installation{ID: Int64(1), AppID: Int64(1), TargetID: Int64(1), TargetType: String("Organization")} 671 if !cmp.Equal(installation, want) { 672 t.Errorf("Apps.FindRepositoryInstallationByID returned %+v, want %+v", installation, want) 673 } 674 675 const methodName = "FindRepositoryInstallationByID" 676 testBadOptions(t, methodName, func() (err error) { 677 _, _, err = client.Apps.FindRepositoryInstallationByID(ctx, -1) 678 return err 679 }) 680 681 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 682 got, resp, err := client.Apps.FindRepositoryInstallationByID(ctx, 1) 683 if got != nil { 684 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 685 } 686 return resp, err 687 }) 688 } 689 690 func TestAppsService_FindUserInstallation(t *testing.T) { 691 client, mux, _, teardown := setup() 692 defer teardown() 693 694 mux.HandleFunc("/users/u/installation", func(w http.ResponseWriter, r *http.Request) { 695 testMethod(t, r, "GET") 696 fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "User"}`) 697 }) 698 699 ctx := context.Background() 700 installation, _, err := client.Apps.FindUserInstallation(ctx, "u") 701 if err != nil { 702 t.Errorf("Apps.FindUserInstallation returned error: %v", err) 703 } 704 705 want := &Installation{ID: Int64(1), AppID: Int64(1), TargetID: Int64(1), TargetType: String("User")} 706 if !cmp.Equal(installation, want) { 707 t.Errorf("Apps.FindUserInstallation returned %+v, want %+v", installation, want) 708 } 709 710 const methodName = "FindUserInstallation" 711 testBadOptions(t, methodName, func() (err error) { 712 _, _, err = client.Apps.FindUserInstallation(ctx, "\n") 713 return err 714 }) 715 716 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 717 got, resp, err := client.Apps.FindUserInstallation(ctx, "u") 718 if got != nil { 719 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 720 } 721 return resp, err 722 }) 723 } 724 725 func TestContentReference_Marshal(t *testing.T) { 726 testJSONMarshal(t, &ContentReference{}, "{}") 727 728 u := &ContentReference{ 729 ID: Int64(1), 730 NodeID: String("nid"), 731 Reference: String("r"), 732 } 733 734 want := `{ 735 "id": 1, 736 "node_id": "nid", 737 "reference": "r" 738 }` 739 740 testJSONMarshal(t, u, want) 741 } 742 743 func TestAttachment_Marshal(t *testing.T) { 744 testJSONMarshal(t, &Attachment{}, "{}") 745 746 u := &Attachment{ 747 ID: Int64(1), 748 Title: String("t"), 749 Body: String("b"), 750 } 751 752 want := `{ 753 "id": 1, 754 "title": "t", 755 "body": "b" 756 }` 757 758 testJSONMarshal(t, u, want) 759 } 760 761 func TestInstallationPermissions_Marshal(t *testing.T) { 762 testJSONMarshal(t, &InstallationPermissions{}, "{}") 763 764 u := &InstallationPermissions{ 765 Actions: String("a"), 766 Administration: String("ad"), 767 Checks: String("c"), 768 Contents: String("co"), 769 ContentReferences: String("cr"), 770 Deployments: String("d"), 771 Environments: String("e"), 772 Issues: String("i"), 773 Metadata: String("md"), 774 Members: String("m"), 775 OrganizationAdministration: String("oa"), 776 OrganizationCustomOrgRoles: String("ocr"), 777 OrganizationHooks: String("oh"), 778 OrganizationPlan: String("op"), 779 OrganizationPreReceiveHooks: String("opr"), 780 OrganizationProjects: String("op"), 781 OrganizationSecrets: String("os"), 782 OrganizationSelfHostedRunners: String("osh"), 783 OrganizationUserBlocking: String("oub"), 784 Packages: String("pkg"), 785 Pages: String("pg"), 786 PullRequests: String("pr"), 787 RepositoryHooks: String("rh"), 788 RepositoryProjects: String("rp"), 789 RepositoryPreReceiveHooks: String("rprh"), 790 Secrets: String("s"), 791 SecretScanningAlerts: String("ssa"), 792 SecurityEvents: String("se"), 793 SingleFile: String("sf"), 794 Statuses: String("s"), 795 TeamDiscussions: String("td"), 796 VulnerabilityAlerts: String("va"), 797 Workflows: String("w"), 798 } 799 800 want := `{ 801 "actions": "a", 802 "administration": "ad", 803 "checks": "c", 804 "contents": "co", 805 "content_references": "cr", 806 "deployments": "d", 807 "environments": "e", 808 "issues": "i", 809 "metadata": "md", 810 "members": "m", 811 "organization_administration": "oa", 812 "organization_custom_org_roles": "ocr", 813 "organization_hooks": "oh", 814 "organization_plan": "op", 815 "organization_pre_receive_hooks": "opr", 816 "organization_projects": "op", 817 "organization_secrets": "os", 818 "organization_self_hosted_runners": "osh", 819 "organization_user_blocking": "oub", 820 "packages": "pkg", 821 "pages": "pg", 822 "pull_requests": "pr", 823 "repository_hooks": "rh", 824 "repository_projects": "rp", 825 "repository_pre_receive_hooks": "rprh", 826 "secrets": "s", 827 "secret_scanning_alerts": "ssa", 828 "security_events": "se", 829 "single_file": "sf", 830 "statuses": "s", 831 "team_discussions": "td", 832 "vulnerability_alerts":"va", 833 "workflows": "w" 834 }` 835 836 testJSONMarshal(t, u, want) 837 } 838 839 func TestInstallation_Marshal(t *testing.T) { 840 testJSONMarshal(t, &Installation{}, "{}") 841 842 u := &Installation{ 843 ID: Int64(1), 844 NodeID: String("nid"), 845 AppID: Int64(1), 846 AppSlug: String("as"), 847 TargetID: Int64(1), 848 Account: &User{ 849 Login: String("l"), 850 ID: Int64(1), 851 URL: String("u"), 852 AvatarURL: String("a"), 853 GravatarID: String("g"), 854 Name: String("n"), 855 Company: String("c"), 856 Blog: String("b"), 857 Location: String("l"), 858 Email: String("e"), 859 Hireable: Bool(true), 860 Bio: String("b"), 861 TwitterUsername: String("t"), 862 PublicRepos: Int(1), 863 Followers: Int(1), 864 Following: Int(1), 865 CreatedAt: &Timestamp{referenceTime}, 866 SuspendedAt: &Timestamp{referenceTime}, 867 }, 868 AccessTokensURL: String("atu"), 869 RepositoriesURL: String("ru"), 870 HTMLURL: String("hu"), 871 TargetType: String("tt"), 872 SingleFileName: String("sfn"), 873 RepositorySelection: String("rs"), 874 Events: []string{"e"}, 875 SingleFilePaths: []string{"s"}, 876 Permissions: &InstallationPermissions{ 877 Actions: String("a"), 878 ActionsVariables: String("ac"), 879 Administration: String("ad"), 880 Checks: String("c"), 881 Contents: String("co"), 882 ContentReferences: String("cr"), 883 Deployments: String("d"), 884 Environments: String("e"), 885 Issues: String("i"), 886 Metadata: String("md"), 887 Members: String("m"), 888 OrganizationAdministration: String("oa"), 889 OrganizationCustomOrgRoles: String("ocr"), 890 OrganizationHooks: String("oh"), 891 OrganizationPlan: String("op"), 892 OrganizationPreReceiveHooks: String("opr"), 893 OrganizationProjects: String("op"), 894 OrganizationSecrets: String("os"), 895 OrganizationSelfHostedRunners: String("osh"), 896 OrganizationUserBlocking: String("oub"), 897 Packages: String("pkg"), 898 Pages: String("pg"), 899 PullRequests: String("pr"), 900 RepositoryHooks: String("rh"), 901 RepositoryProjects: String("rp"), 902 RepositoryPreReceiveHooks: String("rprh"), 903 Secrets: String("s"), 904 SecretScanningAlerts: String("ssa"), 905 SecurityEvents: String("se"), 906 SingleFile: String("sf"), 907 Statuses: String("s"), 908 TeamDiscussions: String("td"), 909 VulnerabilityAlerts: String("va"), 910 Workflows: String("w"), 911 }, 912 CreatedAt: &Timestamp{referenceTime}, 913 UpdatedAt: &Timestamp{referenceTime}, 914 HasMultipleSingleFiles: Bool(false), 915 SuspendedBy: &User{ 916 Login: String("l"), 917 ID: Int64(1), 918 URL: String("u"), 919 AvatarURL: String("a"), 920 GravatarID: String("g"), 921 Name: String("n"), 922 Company: String("c"), 923 Blog: String("b"), 924 Location: String("l"), 925 Email: String("e"), 926 Hireable: Bool(true), 927 Bio: String("b"), 928 TwitterUsername: String("t"), 929 PublicRepos: Int(1), 930 Followers: Int(1), 931 Following: Int(1), 932 CreatedAt: &Timestamp{referenceTime}, 933 SuspendedAt: &Timestamp{referenceTime}, 934 }, 935 SuspendedAt: &Timestamp{referenceTime}, 936 } 937 938 want := `{ 939 "id": 1, 940 "node_id": "nid", 941 "app_id": 1, 942 "app_slug": "as", 943 "target_id": 1, 944 "account": { 945 "login": "l", 946 "id": 1, 947 "avatar_url": "a", 948 "gravatar_id": "g", 949 "name": "n", 950 "company": "c", 951 "blog": "b", 952 "location": "l", 953 "email": "e", 954 "hireable": true, 955 "bio": "b", 956 "twitter_username": "t", 957 "public_repos": 1, 958 "followers": 1, 959 "following": 1, 960 "created_at": ` + referenceTimeStr + `, 961 "suspended_at": ` + referenceTimeStr + `, 962 "url": "u" 963 }, 964 "access_tokens_url": "atu", 965 "repositories_url": "ru", 966 "html_url": "hu", 967 "target_type": "tt", 968 "single_file_name": "sfn", 969 "repository_selection": "rs", 970 "events": [ 971 "e" 972 ], 973 "single_file_paths": [ 974 "s" 975 ], 976 "permissions": { 977 "actions": "a", 978 "actions_variables": "ac", 979 "administration": "ad", 980 "checks": "c", 981 "contents": "co", 982 "content_references": "cr", 983 "deployments": "d", 984 "environments": "e", 985 "issues": "i", 986 "metadata": "md", 987 "members": "m", 988 "organization_administration": "oa", 989 "organization_custom_org_roles": "ocr", 990 "organization_hooks": "oh", 991 "organization_plan": "op", 992 "organization_pre_receive_hooks": "opr", 993 "organization_projects": "op", 994 "organization_secrets": "os", 995 "organization_self_hosted_runners": "osh", 996 "organization_user_blocking": "oub", 997 "packages": "pkg", 998 "pages": "pg", 999 "pull_requests": "pr", 1000 "repository_hooks": "rh", 1001 "repository_projects": "rp", 1002 "repository_pre_receive_hooks": "rprh", 1003 "secrets": "s", 1004 "secret_scanning_alerts": "ssa", 1005 "security_events": "se", 1006 "single_file": "sf", 1007 "statuses": "s", 1008 "team_discussions": "td", 1009 "vulnerability_alerts": "va", 1010 "workflows": "w" 1011 }, 1012 "created_at": ` + referenceTimeStr + `, 1013 "updated_at": ` + referenceTimeStr + `, 1014 "has_multiple_single_files": false, 1015 "suspended_by": { 1016 "login": "l", 1017 "id": 1, 1018 "avatar_url": "a", 1019 "gravatar_id": "g", 1020 "name": "n", 1021 "company": "c", 1022 "blog": "b", 1023 "location": "l", 1024 "email": "e", 1025 "hireable": true, 1026 "bio": "b", 1027 "twitter_username": "t", 1028 "public_repos": 1, 1029 "followers": 1, 1030 "following": 1, 1031 "created_at": ` + referenceTimeStr + `, 1032 "suspended_at": ` + referenceTimeStr + `, 1033 "url": "u" 1034 }, 1035 "suspended_at": ` + referenceTimeStr + ` 1036 }` 1037 1038 testJSONMarshal(t, u, want) 1039 } 1040 1041 func TestInstallationTokenOptions_Marshal(t *testing.T) { 1042 testJSONMarshal(t, &InstallationTokenOptions{}, "{}") 1043 1044 u := &InstallationTokenOptions{ 1045 RepositoryIDs: []int64{1}, 1046 Permissions: &InstallationPermissions{ 1047 Actions: String("a"), 1048 ActionsVariables: String("ac"), 1049 Administration: String("ad"), 1050 Checks: String("c"), 1051 Contents: String("co"), 1052 ContentReferences: String("cr"), 1053 Deployments: String("d"), 1054 Environments: String("e"), 1055 Issues: String("i"), 1056 Metadata: String("md"), 1057 Members: String("m"), 1058 OrganizationAdministration: String("oa"), 1059 OrganizationCustomOrgRoles: String("ocr"), 1060 OrganizationHooks: String("oh"), 1061 OrganizationPlan: String("op"), 1062 OrganizationPreReceiveHooks: String("opr"), 1063 OrganizationProjects: String("op"), 1064 OrganizationSecrets: String("os"), 1065 OrganizationSelfHostedRunners: String("osh"), 1066 OrganizationUserBlocking: String("oub"), 1067 Packages: String("pkg"), 1068 Pages: String("pg"), 1069 PullRequests: String("pr"), 1070 RepositoryHooks: String("rh"), 1071 RepositoryProjects: String("rp"), 1072 RepositoryPreReceiveHooks: String("rprh"), 1073 Secrets: String("s"), 1074 SecretScanningAlerts: String("ssa"), 1075 SecurityEvents: String("se"), 1076 SingleFile: String("sf"), 1077 Statuses: String("s"), 1078 TeamDiscussions: String("td"), 1079 VulnerabilityAlerts: String("va"), 1080 Workflows: String("w"), 1081 }, 1082 } 1083 1084 want := `{ 1085 "repository_ids": [1], 1086 "permissions": { 1087 "actions": "a", 1088 "actions_variables": "ac", 1089 "administration": "ad", 1090 "checks": "c", 1091 "contents": "co", 1092 "content_references": "cr", 1093 "deployments": "d", 1094 "environments": "e", 1095 "issues": "i", 1096 "metadata": "md", 1097 "members": "m", 1098 "organization_administration": "oa", 1099 "organization_custom_org_roles": "ocr", 1100 "organization_hooks": "oh", 1101 "organization_plan": "op", 1102 "organization_pre_receive_hooks": "opr", 1103 "organization_projects": "op", 1104 "organization_secrets": "os", 1105 "organization_self_hosted_runners": "osh", 1106 "organization_user_blocking": "oub", 1107 "packages": "pkg", 1108 "pages": "pg", 1109 "pull_requests": "pr", 1110 "repository_hooks": "rh", 1111 "repository_projects": "rp", 1112 "repository_pre_receive_hooks": "rprh", 1113 "secrets": "s", 1114 "secret_scanning_alerts": "ssa", 1115 "security_events": "se", 1116 "single_file": "sf", 1117 "statuses": "s", 1118 "team_discussions": "td", 1119 "vulnerability_alerts": "va", 1120 "workflows": "w" 1121 } 1122 }` 1123 1124 testJSONMarshal(t, u, want) 1125 } 1126 1127 func TestInstallationToken_Marshal(t *testing.T) { 1128 testJSONMarshal(t, &InstallationToken{}, "{}") 1129 1130 u := &InstallationToken{ 1131 Token: String("t"), 1132 ExpiresAt: &Timestamp{referenceTime}, 1133 Permissions: &InstallationPermissions{ 1134 Actions: String("a"), 1135 ActionsVariables: String("ac"), 1136 Administration: String("ad"), 1137 Checks: String("c"), 1138 Contents: String("co"), 1139 ContentReferences: String("cr"), 1140 Deployments: String("d"), 1141 Environments: String("e"), 1142 Issues: String("i"), 1143 Metadata: String("md"), 1144 Members: String("m"), 1145 OrganizationAdministration: String("oa"), 1146 OrganizationCustomOrgRoles: String("ocr"), 1147 OrganizationHooks: String("oh"), 1148 OrganizationPlan: String("op"), 1149 OrganizationPreReceiveHooks: String("opr"), 1150 OrganizationProjects: String("op"), 1151 OrganizationSecrets: String("os"), 1152 OrganizationSelfHostedRunners: String("osh"), 1153 OrganizationUserBlocking: String("oub"), 1154 Packages: String("pkg"), 1155 Pages: String("pg"), 1156 PullRequests: String("pr"), 1157 RepositoryHooks: String("rh"), 1158 RepositoryProjects: String("rp"), 1159 RepositoryPreReceiveHooks: String("rprh"), 1160 Secrets: String("s"), 1161 SecretScanningAlerts: String("ssa"), 1162 SecurityEvents: String("se"), 1163 SingleFile: String("sf"), 1164 Statuses: String("s"), 1165 TeamDiscussions: String("td"), 1166 VulnerabilityAlerts: String("va"), 1167 Workflows: String("w"), 1168 }, 1169 Repositories: []*Repository{ 1170 { 1171 ID: Int64(1), 1172 URL: String("u"), 1173 Name: String("n"), 1174 }, 1175 }, 1176 } 1177 1178 want := `{ 1179 "token": "t", 1180 "expires_at": ` + referenceTimeStr + `, 1181 "permissions": { 1182 "actions": "a", 1183 "actions_variables": "ac", 1184 "administration": "ad", 1185 "checks": "c", 1186 "contents": "co", 1187 "content_references": "cr", 1188 "deployments": "d", 1189 "environments": "e", 1190 "issues": "i", 1191 "metadata": "md", 1192 "members": "m", 1193 "organization_administration": "oa", 1194 "organization_custom_org_roles": "ocr", 1195 "organization_hooks": "oh", 1196 "organization_plan": "op", 1197 "organization_pre_receive_hooks": "opr", 1198 "organization_projects": "op", 1199 "organization_secrets": "os", 1200 "organization_self_hosted_runners": "osh", 1201 "organization_user_blocking": "oub", 1202 "packages": "pkg", 1203 "pages": "pg", 1204 "pull_requests": "pr", 1205 "repository_hooks": "rh", 1206 "repository_projects": "rp", 1207 "repository_pre_receive_hooks": "rprh", 1208 "secrets": "s", 1209 "secret_scanning_alerts": "ssa", 1210 "security_events": "se", 1211 "single_file": "sf", 1212 "statuses": "s", 1213 "team_discussions": "td", 1214 "vulnerability_alerts": "va", 1215 "workflows": "w" 1216 }, 1217 "repositories": [ 1218 { 1219 "id": 1, 1220 "url": "u", 1221 "name": "n" 1222 } 1223 ] 1224 }` 1225 1226 testJSONMarshal(t, u, want) 1227 } 1228 1229 func TestApp_Marshal(t *testing.T) { 1230 testJSONMarshal(t, &App{}, "{}") 1231 1232 u := &App{ 1233 ID: Int64(1), 1234 Slug: String("s"), 1235 NodeID: String("nid"), 1236 Owner: &User{ 1237 Login: String("l"), 1238 ID: Int64(1), 1239 URL: String("u"), 1240 AvatarURL: String("a"), 1241 GravatarID: String("g"), 1242 Name: String("n"), 1243 Company: String("c"), 1244 Blog: String("b"), 1245 Location: String("l"), 1246 Email: String("e"), 1247 Hireable: Bool(true), 1248 Bio: String("b"), 1249 TwitterUsername: String("t"), 1250 PublicRepos: Int(1), 1251 Followers: Int(1), 1252 Following: Int(1), 1253 CreatedAt: &Timestamp{referenceTime}, 1254 SuspendedAt: &Timestamp{referenceTime}, 1255 }, 1256 Name: String("n"), 1257 Description: String("d"), 1258 ExternalURL: String("eu"), 1259 HTMLURL: String("hu"), 1260 CreatedAt: &Timestamp{referenceTime}, 1261 UpdatedAt: &Timestamp{referenceTime}, 1262 Permissions: &InstallationPermissions{ 1263 Actions: String("a"), 1264 ActionsVariables: String("ac"), 1265 Administration: String("ad"), 1266 Checks: String("c"), 1267 Contents: String("co"), 1268 ContentReferences: String("cr"), 1269 Deployments: String("d"), 1270 Environments: String("e"), 1271 Issues: String("i"), 1272 Metadata: String("md"), 1273 Members: String("m"), 1274 OrganizationAdministration: String("oa"), 1275 OrganizationCustomOrgRoles: String("ocr"), 1276 OrganizationHooks: String("oh"), 1277 OrganizationPlan: String("op"), 1278 OrganizationPreReceiveHooks: String("opr"), 1279 OrganizationProjects: String("op"), 1280 OrganizationSecrets: String("os"), 1281 OrganizationSelfHostedRunners: String("osh"), 1282 OrganizationUserBlocking: String("oub"), 1283 Packages: String("pkg"), 1284 Pages: String("pg"), 1285 PullRequests: String("pr"), 1286 RepositoryHooks: String("rh"), 1287 RepositoryProjects: String("rp"), 1288 RepositoryPreReceiveHooks: String("rprh"), 1289 Secrets: String("s"), 1290 SecretScanningAlerts: String("ssa"), 1291 SecurityEvents: String("se"), 1292 SingleFile: String("sf"), 1293 Statuses: String("s"), 1294 TeamDiscussions: String("td"), 1295 VulnerabilityAlerts: String("va"), 1296 Workflows: String("w"), 1297 }, 1298 Events: []string{"s"}, 1299 } 1300 1301 want := `{ 1302 "id": 1, 1303 "slug": "s", 1304 "node_id": "nid", 1305 "owner": { 1306 "login": "l", 1307 "id": 1, 1308 "avatar_url": "a", 1309 "gravatar_id": "g", 1310 "name": "n", 1311 "company": "c", 1312 "blog": "b", 1313 "location": "l", 1314 "email": "e", 1315 "hireable": true, 1316 "bio": "b", 1317 "twitter_username": "t", 1318 "public_repos": 1, 1319 "followers": 1, 1320 "following": 1, 1321 "created_at": ` + referenceTimeStr + `, 1322 "suspended_at": ` + referenceTimeStr + `, 1323 "url": "u" 1324 }, 1325 "name": "n", 1326 "description": "d", 1327 "external_url": "eu", 1328 "html_url": "hu", 1329 "created_at": ` + referenceTimeStr + `, 1330 "updated_at": ` + referenceTimeStr + `, 1331 "permissions": { 1332 "actions": "a", 1333 "actions_variables": "ac", 1334 "administration": "ad", 1335 "checks": "c", 1336 "contents": "co", 1337 "content_references": "cr", 1338 "deployments": "d", 1339 "environments": "e", 1340 "issues": "i", 1341 "metadata": "md", 1342 "members": "m", 1343 "organization_administration": "oa", 1344 "organization_custom_org_roles": "ocr", 1345 "organization_hooks": "oh", 1346 "organization_plan": "op", 1347 "organization_pre_receive_hooks": "opr", 1348 "organization_projects": "op", 1349 "organization_secrets": "os", 1350 "organization_self_hosted_runners": "osh", 1351 "organization_user_blocking": "oub", 1352 "packages": "pkg", 1353 "pages": "pg", 1354 "pull_requests": "pr", 1355 "repository_hooks": "rh", 1356 "repository_projects": "rp", 1357 "repository_pre_receive_hooks": "rprh", 1358 "secrets": "s", 1359 "secret_scanning_alerts": "ssa", 1360 "security_events": "se", 1361 "single_file": "sf", 1362 "statuses": "s", 1363 "team_discussions": "td", 1364 "vulnerability_alerts": "va", 1365 "workflows": "w" 1366 }, 1367 "events": ["s"] 1368 }` 1369 1370 testJSONMarshal(t, u, want) 1371 }