github.com/google/go-github/v60@v60.0.0/github/code-scanning_test.go (about) 1 // Copyright 2020 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 TestCodeScanningService_Alert_ID(t *testing.T) { 20 // Test: nil Alert ID == 0 21 var a *Alert 22 id := a.ID() 23 var want int64 24 if id != want { 25 t.Errorf("Alert.ID error returned %+v, want %+v", id, want) 26 } 27 28 // Test: Valid HTMLURL 29 a = &Alert{ 30 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), 31 } 32 id = a.ID() 33 want = 88 34 if !cmp.Equal(id, want) { 35 t.Errorf("Alert.ID error returned %+v, want %+v", id, want) 36 } 37 38 // Test: HTMLURL is nil 39 a = &Alert{} 40 id = a.ID() 41 want = 0 42 if !cmp.Equal(id, want) { 43 t.Errorf("Alert.ID error returned %+v, want %+v", id, want) 44 } 45 46 // Test: ID can't be parsed as an int 47 a = &Alert{ 48 HTMLURL: String("https://github.com/o/r/security/code-scanning/bad88"), 49 } 50 id = a.ID() 51 want = 0 52 if !cmp.Equal(id, want) { 53 t.Errorf("Alert.ID error returned %+v, want %+v", id, want) 54 } 55 } 56 57 func TestCodeScanningService_UploadSarif(t *testing.T) { 58 client, mux, _, teardown := setup() 59 defer teardown() 60 61 expectedSarifID := &SarifID{ 62 ID: String("testid"), 63 URL: String("https://example.com/testurl"), 64 } 65 66 mux.HandleFunc("/repos/o/r/code-scanning/sarifs", func(w http.ResponseWriter, r *http.Request) { 67 v := new(SarifAnalysis) 68 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 69 testMethod(t, r, "POST") 70 want := &SarifAnalysis{CommitSHA: String("abc"), Ref: String("ref/head/main"), Sarif: String("abc"), CheckoutURI: String("uri"), StartedAt: &Timestamp{time.Date(2006, time.January, 02, 15, 04, 05, 0, time.UTC)}, ToolName: String("codeql-cli")} 71 if !cmp.Equal(v, want) { 72 t.Errorf("Request body = %+v, want %+v", v, want) 73 } 74 75 w.WriteHeader(http.StatusAccepted) 76 respBody, _ := json.Marshal(expectedSarifID) 77 _, _ = w.Write(respBody) 78 }) 79 80 ctx := context.Background() 81 sarifAnalysis := &SarifAnalysis{CommitSHA: String("abc"), Ref: String("ref/head/main"), Sarif: String("abc"), CheckoutURI: String("uri"), StartedAt: &Timestamp{time.Date(2006, time.January, 02, 15, 04, 05, 0, time.UTC)}, ToolName: String("codeql-cli")} 82 respSarifID, _, err := client.CodeScanning.UploadSarif(ctx, "o", "r", sarifAnalysis) 83 if err != nil { 84 t.Errorf("CodeScanning.UploadSarif returned error: %v", err) 85 } 86 if !cmp.Equal(expectedSarifID, respSarifID) { 87 t.Errorf("Sarif response = %+v, want %+v", respSarifID, expectedSarifID) 88 } 89 90 const methodName = "UploadSarif" 91 testBadOptions(t, methodName, func() (err error) { 92 _, _, err = client.CodeScanning.UploadSarif(ctx, "\n", "\n", sarifAnalysis) 93 return err 94 }) 95 96 testNewRequestAndDoFailureCategory(t, methodName, client, codeScanningUploadCategory, func() (*Response, error) { 97 _, resp, err := client.CodeScanning.UploadSarif(ctx, "o", "r", sarifAnalysis) 98 return resp, err 99 }) 100 } 101 102 func TestCodeScanningService_GetSARIF(t *testing.T) { 103 client, mux, _, teardown := setup() 104 defer teardown() 105 106 mux.HandleFunc("/repos/o/r/code-scanning/sarifs/abc", func(w http.ResponseWriter, r *http.Request) { 107 testMethod(t, r, "GET") 108 fmt.Fprint(w, `{ 109 "processing_status": "s", 110 "analyses_url": "u" 111 }`) 112 }) 113 114 ctx := context.Background() 115 sarifUpload, _, err := client.CodeScanning.GetSARIF(ctx, "o", "r", "abc") 116 if err != nil { 117 t.Errorf("CodeScanning.GetSARIF returned error: %v", err) 118 } 119 120 want := &SARIFUpload{ 121 ProcessingStatus: String("s"), 122 AnalysesURL: String("u"), 123 } 124 if !cmp.Equal(sarifUpload, want) { 125 t.Errorf("CodeScanning.GetSARIF returned %+v, want %+v", sarifUpload, want) 126 } 127 128 const methodName = "GetSARIF" 129 testBadOptions(t, methodName, func() (err error) { 130 _, _, err = client.CodeScanning.GetSARIF(ctx, "\n", "\n", "\n") 131 return err 132 }) 133 134 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 135 got, resp, err := client.CodeScanning.GetSARIF(ctx, "o", "r", "abc") 136 if got != nil { 137 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 138 } 139 return resp, err 140 }) 141 } 142 143 func TestCodeScanningService_ListAlertsForOrg(t *testing.T) { 144 client, mux, _, teardown := setup() 145 defer teardown() 146 147 mux.HandleFunc("/orgs/o/code-scanning/alerts", func(w http.ResponseWriter, r *http.Request) { 148 testMethod(t, r, "GET") 149 testFormValues(t, r, values{"state": "open", "ref": "heads/master", "severity": "warning", "tool_name": "CodeQL"}) 150 fmt.Fprint(w, `[{ 151 "repository": { 152 "id": 1, 153 "name": "n", 154 "url": "url" 155 }, 156 "rule_id":"js/trivial-conditional", 157 "rule_severity":"warning", 158 "rule_description":"Useless conditional", 159 "tool": { 160 "name": "CodeQL", 161 "guid": null, 162 "version": "1.4.0" 163 }, 164 "rule": { 165 "id": "js/trivial-conditional", 166 "severity": "warning", 167 "description": "Useless conditional", 168 "name": "js/trivial-conditional", 169 "full_description": "Expression has no effect", 170 "help": "Expression has no effect" 171 }, 172 "most_recent_instance": { 173 "ref": "refs/heads/main", 174 "state": "open", 175 "commit_sha": "abcdefg12345", 176 "message": { 177 "text": "This path depends on a user-provided value." 178 }, 179 "location": { 180 "path": "spec-main/api-session-spec.ts", 181 "start_line": 917, 182 "end_line": 917, 183 "start_column": 7, 184 "end_column": 18 185 }, 186 "classifications": [ 187 "test" 188 ] 189 }, 190 "created_at":"2020-05-06T12:00:00Z", 191 "state":"open", 192 "closed_by":null, 193 "closed_at":null, 194 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/25", 195 "html_url":"https://github.com/o/r/security/code-scanning/25" 196 }, 197 { 198 "rule_id":"js/useless-expression", 199 "rule_severity":"warning", 200 "rule_description":"Expression has no effect", 201 "tool": { 202 "name": "CodeQL", 203 "guid": null, 204 "version": "1.4.0" 205 }, 206 "rule": { 207 "id": "js/useless-expression", 208 "severity": "warning", 209 "description": "Expression has no effect", 210 "name": "js/useless-expression", 211 "full_description": "Expression has no effect", 212 "help": "Expression has no effect" 213 }, 214 "most_recent_instance": { 215 "ref": "refs/heads/main", 216 "state": "open", 217 "commit_sha": "abcdefg12345", 218 "message": { 219 "text": "This path depends on a user-provided value." 220 }, 221 "location": { 222 "path": "spec-main/api-session-spec.ts", 223 "start_line": 917, 224 "end_line": 917, 225 "start_column": 7, 226 "end_column": 18 227 }, 228 "classifications": [ 229 "test" 230 ] 231 }, 232 "created_at":"2020-05-06T12:00:00Z", 233 "state":"open", 234 "closed_by":null, 235 "closed_at":null, 236 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88", 237 "html_url":"https://github.com/o/r/security/code-scanning/88" 238 }]`) 239 }) 240 241 opts := &AlertListOptions{State: "open", Ref: "heads/master", Severity: "warning", ToolName: "CodeQL"} 242 ctx := context.Background() 243 alerts, _, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts) 244 if err != nil { 245 t.Errorf("CodeScanning.ListAlertsForOrg returned error: %v", err) 246 } 247 248 date := Timestamp{time.Date(2020, time.May, 06, 12, 00, 00, 0, time.UTC)} 249 want := []*Alert{ 250 { 251 Repository: &Repository{ 252 ID: Int64(1), 253 URL: String("url"), 254 Name: String("n"), 255 }, 256 RuleID: String("js/trivial-conditional"), 257 RuleSeverity: String("warning"), 258 RuleDescription: String("Useless conditional"), 259 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")}, 260 Rule: &Rule{ 261 ID: String("js/trivial-conditional"), 262 Severity: String("warning"), 263 Description: String("Useless conditional"), 264 Name: String("js/trivial-conditional"), 265 FullDescription: String("Expression has no effect"), 266 Help: String("Expression has no effect"), 267 }, 268 CreatedAt: &date, 269 State: String("open"), 270 ClosedBy: nil, 271 ClosedAt: nil, 272 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/25"), 273 HTMLURL: String("https://github.com/o/r/security/code-scanning/25"), 274 MostRecentInstance: &MostRecentInstance{ 275 Ref: String("refs/heads/main"), 276 State: String("open"), 277 CommitSHA: String("abcdefg12345"), 278 Message: &Message{ 279 Text: String("This path depends on a user-provided value."), 280 }, 281 Location: &Location{ 282 Path: String("spec-main/api-session-spec.ts"), 283 StartLine: Int(917), 284 EndLine: Int(917), 285 StartColumn: Int(7), 286 EndColumn: Int(18), 287 }, 288 Classifications: []string{"test"}, 289 }, 290 }, 291 { 292 RuleID: String("js/useless-expression"), 293 RuleSeverity: String("warning"), 294 RuleDescription: String("Expression has no effect"), 295 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")}, 296 Rule: &Rule{ 297 ID: String("js/useless-expression"), 298 Severity: String("warning"), 299 Description: String("Expression has no effect"), 300 Name: String("js/useless-expression"), 301 FullDescription: String("Expression has no effect"), 302 Help: String("Expression has no effect"), 303 }, 304 CreatedAt: &date, 305 State: String("open"), 306 ClosedBy: nil, 307 ClosedAt: nil, 308 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"), 309 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), 310 MostRecentInstance: &MostRecentInstance{ 311 Ref: String("refs/heads/main"), 312 State: String("open"), 313 CommitSHA: String("abcdefg12345"), 314 Message: &Message{ 315 Text: String("This path depends on a user-provided value."), 316 }, 317 Location: &Location{ 318 Path: String("spec-main/api-session-spec.ts"), 319 StartLine: Int(917), 320 EndLine: Int(917), 321 StartColumn: Int(7), 322 EndColumn: Int(18), 323 }, 324 Classifications: []string{"test"}, 325 }, 326 }, 327 } 328 if !cmp.Equal(alerts, want) { 329 t.Errorf("CodeScanning.ListAlertsForOrg returned %+v, want %+v", alerts, want) 330 } 331 332 const methodName = "ListAlertsForOrg" 333 testBadOptions(t, methodName, func() (err error) { 334 _, _, err = client.CodeScanning.ListAlertsForOrg(ctx, "\n", opts) 335 return err 336 }) 337 338 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 339 got, resp, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts) 340 if got != nil { 341 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 342 } 343 return resp, err 344 }) 345 } 346 347 func TestCodeScanningService_ListAlertsForOrgLisCursorOptions(t *testing.T) { 348 client, mux, _, teardown := setup() 349 defer teardown() 350 351 mux.HandleFunc("/orgs/o/code-scanning/alerts", func(w http.ResponseWriter, r *http.Request) { 352 testMethod(t, r, "GET") 353 testFormValues(t, r, values{"state": "open", "ref": "heads/master", "severity": "warning", "tool_name": "CodeQL", "per_page": "1", "before": "deadbeefb", "after": "deadbeefa"}) 354 fmt.Fprint(w, `[{ 355 "repository": { 356 "id": 1, 357 "name": "n", 358 "url": "url" 359 }, 360 "rule_id":"js/trivial-conditional", 361 "rule_severity":"warning", 362 "rule_description":"Useless conditional", 363 "tool": { 364 "name": "CodeQL", 365 "guid": null, 366 "version": "1.4.0" 367 }, 368 "rule": { 369 "id": "js/trivial-conditional", 370 "severity": "warning", 371 "description": "Useless conditional", 372 "name": "js/trivial-conditional", 373 "full_description": "Expression has no effect", 374 "help": "Expression has no effect" 375 }, 376 "most_recent_instance": { 377 "ref": "refs/heads/main", 378 "state": "open", 379 "commit_sha": "abcdefg12345", 380 "message": { 381 "text": "This path depends on a user-provided value." 382 }, 383 "location": { 384 "path": "spec-main/api-session-spec.ts", 385 "start_line": 917, 386 "end_line": 917, 387 "start_column": 7, 388 "end_column": 18 389 }, 390 "classifications": [ 391 "test" 392 ] 393 }, 394 "created_at":"2020-05-06T12:00:00Z", 395 "state":"open", 396 "closed_by":null, 397 "closed_at":null, 398 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/25", 399 "html_url":"https://github.com/o/r/security/code-scanning/25" 400 }]`) 401 }) 402 403 opts := &AlertListOptions{State: "open", Ref: "heads/master", Severity: "warning", ToolName: "CodeQL", ListCursorOptions: ListCursorOptions{PerPage: 1, Before: "deadbeefb", After: "deadbeefa"}} 404 ctx := context.Background() 405 alerts, _, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts) 406 if err != nil { 407 t.Errorf("CodeScanning.ListAlertsForOrg returned error: %v", err) 408 } 409 410 date := Timestamp{time.Date(2020, time.May, 06, 12, 00, 00, 0, time.UTC)} 411 want := []*Alert{ 412 { 413 Repository: &Repository{ 414 ID: Int64(1), 415 URL: String("url"), 416 Name: String("n"), 417 }, 418 RuleID: String("js/trivial-conditional"), 419 RuleSeverity: String("warning"), 420 RuleDescription: String("Useless conditional"), 421 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")}, 422 Rule: &Rule{ 423 ID: String("js/trivial-conditional"), 424 Severity: String("warning"), 425 Description: String("Useless conditional"), 426 Name: String("js/trivial-conditional"), 427 FullDescription: String("Expression has no effect"), 428 Help: String("Expression has no effect"), 429 }, 430 CreatedAt: &date, 431 State: String("open"), 432 ClosedBy: nil, 433 ClosedAt: nil, 434 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/25"), 435 HTMLURL: String("https://github.com/o/r/security/code-scanning/25"), 436 MostRecentInstance: &MostRecentInstance{ 437 Ref: String("refs/heads/main"), 438 State: String("open"), 439 CommitSHA: String("abcdefg12345"), 440 Message: &Message{ 441 Text: String("This path depends on a user-provided value."), 442 }, 443 Location: &Location{ 444 Path: String("spec-main/api-session-spec.ts"), 445 StartLine: Int(917), 446 EndLine: Int(917), 447 StartColumn: Int(7), 448 EndColumn: Int(18), 449 }, 450 Classifications: []string{"test"}, 451 }, 452 }, 453 } 454 if !cmp.Equal(alerts, want) { 455 t.Errorf("CodeScanning.ListAlertsForOrg returned %+v, want %+v", alerts, want) 456 } 457 458 const methodName = "ListAlertsForOrg" 459 testBadOptions(t, methodName, func() (err error) { 460 _, _, err = client.CodeScanning.ListAlertsForOrg(ctx, "\n", opts) 461 return err 462 }) 463 464 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 465 got, resp, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts) 466 if got != nil { 467 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 468 } 469 return resp, err 470 }) 471 } 472 473 func TestCodeScanningService_ListAlertsForRepo(t *testing.T) { 474 client, mux, _, teardown := setup() 475 defer teardown() 476 477 mux.HandleFunc("/repos/o/r/code-scanning/alerts", func(w http.ResponseWriter, r *http.Request) { 478 testMethod(t, r, "GET") 479 testFormValues(t, r, values{"state": "open", "ref": "heads/master", "severity": "warning", "tool_name": "CodeQL"}) 480 fmt.Fprint(w, `[{ 481 "rule_id":"js/trivial-conditional", 482 "rule_severity":"warning", 483 "rule_description":"Useless conditional", 484 "tool": { 485 "name": "CodeQL", 486 "guid": null, 487 "version": "1.4.0" 488 }, 489 "rule": { 490 "id": "js/trivial-conditional", 491 "severity": "warning", 492 "description": "Useless conditional", 493 "name": "js/trivial-conditional", 494 "full_description": "Expression has no effect", 495 "help": "Expression has no effect" 496 }, 497 "most_recent_instance": { 498 "ref": "refs/heads/main", 499 "state": "open", 500 "commit_sha": "abcdefg12345", 501 "message": { 502 "text": "This path depends on a user-provided value." 503 }, 504 "location": { 505 "path": "spec-main/api-session-spec.ts", 506 "start_line": 917, 507 "end_line": 917, 508 "start_column": 7, 509 "end_column": 18 510 }, 511 "classifications": [ 512 "test" 513 ] 514 }, 515 "created_at":"2020-05-06T12:00:00Z", 516 "state":"open", 517 "closed_by":null, 518 "closed_at":null, 519 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/25", 520 "html_url":"https://github.com/o/r/security/code-scanning/25" 521 }, 522 { 523 "rule_id":"js/useless-expression", 524 "rule_severity":"warning", 525 "rule_description":"Expression has no effect", 526 "tool": { 527 "name": "CodeQL", 528 "guid": null, 529 "version": "1.4.0" 530 }, 531 "rule": { 532 "id": "js/useless-expression", 533 "severity": "warning", 534 "description": "Expression has no effect", 535 "name": "js/useless-expression", 536 "full_description": "Expression has no effect", 537 "help": "Expression has no effect" 538 }, 539 "most_recent_instance": { 540 "ref": "refs/heads/main", 541 "state": "open", 542 "commit_sha": "abcdefg12345", 543 "message": { 544 "text": "This path depends on a user-provided value." 545 }, 546 "location": { 547 "path": "spec-main/api-session-spec.ts", 548 "start_line": 917, 549 "end_line": 917, 550 "start_column": 7, 551 "end_column": 18 552 }, 553 "classifications": [ 554 "test" 555 ] 556 }, 557 "created_at":"2020-05-06T12:00:00Z", 558 "state":"open", 559 "closed_by":null, 560 "closed_at":null, 561 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88", 562 "html_url":"https://github.com/o/r/security/code-scanning/88" 563 }]`) 564 }) 565 566 opts := &AlertListOptions{State: "open", Ref: "heads/master", Severity: "warning", ToolName: "CodeQL"} 567 ctx := context.Background() 568 alerts, _, err := client.CodeScanning.ListAlertsForRepo(ctx, "o", "r", opts) 569 if err != nil { 570 t.Errorf("CodeScanning.ListAlertsForRepo returned error: %v", err) 571 } 572 573 date := Timestamp{time.Date(2020, time.May, 06, 12, 00, 00, 0, time.UTC)} 574 want := []*Alert{ 575 { 576 RuleID: String("js/trivial-conditional"), 577 RuleSeverity: String("warning"), 578 RuleDescription: String("Useless conditional"), 579 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")}, 580 Rule: &Rule{ 581 ID: String("js/trivial-conditional"), 582 Severity: String("warning"), 583 Description: String("Useless conditional"), 584 Name: String("js/trivial-conditional"), 585 FullDescription: String("Expression has no effect"), 586 Help: String("Expression has no effect"), 587 }, 588 CreatedAt: &date, 589 State: String("open"), 590 ClosedBy: nil, 591 ClosedAt: nil, 592 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/25"), 593 HTMLURL: String("https://github.com/o/r/security/code-scanning/25"), 594 MostRecentInstance: &MostRecentInstance{ 595 Ref: String("refs/heads/main"), 596 State: String("open"), 597 CommitSHA: String("abcdefg12345"), 598 Message: &Message{ 599 Text: String("This path depends on a user-provided value."), 600 }, 601 Location: &Location{ 602 Path: String("spec-main/api-session-spec.ts"), 603 StartLine: Int(917), 604 EndLine: Int(917), 605 StartColumn: Int(7), 606 EndColumn: Int(18), 607 }, 608 Classifications: []string{"test"}, 609 }, 610 }, 611 { 612 RuleID: String("js/useless-expression"), 613 RuleSeverity: String("warning"), 614 RuleDescription: String("Expression has no effect"), 615 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")}, 616 Rule: &Rule{ 617 ID: String("js/useless-expression"), 618 Severity: String("warning"), 619 Description: String("Expression has no effect"), 620 Name: String("js/useless-expression"), 621 FullDescription: String("Expression has no effect"), 622 Help: String("Expression has no effect"), 623 }, 624 CreatedAt: &date, 625 State: String("open"), 626 ClosedBy: nil, 627 ClosedAt: nil, 628 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"), 629 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), 630 MostRecentInstance: &MostRecentInstance{ 631 Ref: String("refs/heads/main"), 632 State: String("open"), 633 CommitSHA: String("abcdefg12345"), 634 Message: &Message{ 635 Text: String("This path depends on a user-provided value."), 636 }, 637 Location: &Location{ 638 Path: String("spec-main/api-session-spec.ts"), 639 StartLine: Int(917), 640 EndLine: Int(917), 641 StartColumn: Int(7), 642 EndColumn: Int(18), 643 }, 644 Classifications: []string{"test"}, 645 }, 646 }, 647 } 648 if !cmp.Equal(alerts, want) { 649 t.Errorf("CodeScanning.ListAlertsForRepo returned %+v, want %+v", alerts, want) 650 } 651 652 const methodName = "ListAlertsForRepo" 653 testBadOptions(t, methodName, func() (err error) { 654 _, _, err = client.CodeScanning.ListAlertsForRepo(ctx, "\n", "\n", opts) 655 return err 656 }) 657 658 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 659 got, resp, err := client.CodeScanning.ListAlertsForRepo(ctx, "o", "r", opts) 660 if got != nil { 661 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 662 } 663 return resp, err 664 }) 665 } 666 667 func TestCodeScanningService_UpdateAlert(t *testing.T) { 668 client, mux, _, teardown := setup() 669 defer teardown() 670 mux.HandleFunc("/repos/o/r/code-scanning/alerts/88", func(w http.ResponseWriter, r *http.Request) { 671 testMethod(t, r, "PATCH") 672 fmt.Fprint(w, `{"rule_id":"js/useless-expression", 673 "rule_severity":"warning", 674 "rule_description":"Expression has no effect", 675 "tool": { 676 "name": "CodeQL", 677 "guid": null, 678 "version": "1.4.0" 679 }, 680 "rule": { 681 "id": "useless expression", 682 "severity": "warning", 683 "description": "Expression has no effect", 684 "name": "useless expression", 685 "full_description": "Expression has no effect", 686 "help": "Expression has no effect" 687 }, 688 "most_recent_instance": { 689 "ref": "refs/heads/main", 690 "state": "dismissed", 691 "commit_sha": "abcdefg12345", 692 "message": { 693 "text": "This path depends on a user-provided value." 694 }, 695 "location": { 696 "path": "spec-main/api-session-spec.ts", 697 "start_line": 917, 698 "end_line": 917, 699 "start_column": 7, 700 "end_column": 18 701 }, 702 "classifications": [ 703 "test" 704 ] 705 }, 706 "created_at":"2019-01-02T15:04:05Z", 707 "state":"dismissed", 708 "dismissed_reason": "false positive", 709 "dismissed_comment": "This alert is not actually correct as sanitizer is used", 710 "closed_by":null, 711 "closed_at":null, 712 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88", 713 "html_url":"https://github.com/o/r/security/code-scanning/88"}`) 714 }) 715 716 ctx := context.Background() 717 dismissedComment := String("This alert is not actually correct as sanitizer is used") 718 dismissedReason := String("false positive") 719 state := String("dismissed") 720 stateInfo := &CodeScanningAlertState{State: *state, DismissedReason: dismissedReason, DismissedComment: dismissedComment} 721 alert, _, err := client.CodeScanning.UpdateAlert(ctx, "o", "r", 88, stateInfo) 722 if err != nil { 723 t.Errorf("CodeScanning.UpdateAlert returned error: %v", err) 724 } 725 726 date := Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)} 727 want := &Alert{ 728 RuleID: String("js/useless-expression"), 729 RuleSeverity: String("warning"), 730 RuleDescription: String("Expression has no effect"), 731 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")}, 732 Rule: &Rule{ 733 ID: String("useless expression"), 734 Severity: String("warning"), 735 Description: String("Expression has no effect"), 736 Name: String("useless expression"), 737 FullDescription: String("Expression has no effect"), 738 Help: String("Expression has no effect"), 739 }, 740 CreatedAt: &date, 741 State: state, 742 DismissedReason: dismissedReason, 743 DismissedComment: dismissedComment, 744 ClosedBy: nil, 745 ClosedAt: nil, 746 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"), 747 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), 748 MostRecentInstance: &MostRecentInstance{ 749 Ref: String("refs/heads/main"), 750 State: String("dismissed"), 751 CommitSHA: String("abcdefg12345"), 752 Message: &Message{ 753 Text: String("This path depends on a user-provided value."), 754 }, 755 Location: &Location{ 756 Path: String("spec-main/api-session-spec.ts"), 757 StartLine: Int(917), 758 EndLine: Int(917), 759 StartColumn: Int(7), 760 EndColumn: Int(18), 761 }, 762 Classifications: []string{"test"}, 763 }, 764 } 765 if !cmp.Equal(alert, want) { 766 t.Errorf("CodeScanning.UpdateAlert returned %+v, want %+v", alert, want) 767 } 768 769 const methodName = "UpdateAlert" 770 testBadOptions(t, methodName, func() (err error) { 771 _, _, err = client.CodeScanning.UpdateAlert(ctx, "\n", "\n", -88, stateInfo) 772 return err 773 }) 774 775 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 776 got, resp, err := client.CodeScanning.UpdateAlert(ctx, "o", "r", 88, stateInfo) 777 if got != nil { 778 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 779 } 780 return resp, err 781 }) 782 } 783 784 func TestCodeScanningService_ListAlertInstances(t *testing.T) { 785 client, mux, _, teardown := setup() 786 defer teardown() 787 788 mux.HandleFunc("/repos/o/r/code-scanning/alerts/88/instances", func(w http.ResponseWriter, r *http.Request) { 789 testMethod(t, r, "GET") 790 fmt.Fprint(w, `[ 791 { 792 "ref": "refs/heads/main", 793 "analysis_key": ".github/workflows/codeql-analysis.yml:analyze", 794 "environment": "", 795 "category": ".github/workflows/codeql-analysis.yml:analyze", 796 "state": "open", 797 "fixed_at": null, 798 "commit_sha": "abcdefg12345", 799 "message": { 800 "text": "This path depends on a user-provided value." 801 }, 802 "location": { 803 "path": "spec-main/api-session-spec.ts", 804 "start_line": 917, 805 "end_line": 917, 806 "start_column": 7, 807 "end_column": 18 808 }, 809 "classifications": [ 810 "test" 811 ] 812 } 813 ]`) 814 }) 815 816 opts := &AlertInstancesListOptions{Ref: "heads/main", ListOptions: ListOptions{Page: 1}} 817 ctx := context.Background() 818 instances, _, err := client.CodeScanning.ListAlertInstances(ctx, "o", "r", 88, opts) 819 if err != nil { 820 t.Errorf("CodeScanning.ListAlertInstances returned error: %v", err) 821 } 822 823 want := []*MostRecentInstance{ 824 { 825 Ref: String("refs/heads/main"), 826 AnalysisKey: String(".github/workflows/codeql-analysis.yml:analyze"), 827 Category: String(".github/workflows/codeql-analysis.yml:analyze"), 828 Environment: String(""), 829 State: String("open"), 830 CommitSHA: String("abcdefg12345"), 831 Message: &Message{ 832 Text: String("This path depends on a user-provided value."), 833 }, 834 Location: &Location{ 835 Path: String("spec-main/api-session-spec.ts"), 836 StartLine: Int(917), 837 EndLine: Int(917), 838 StartColumn: Int(7), 839 EndColumn: Int(18), 840 }, 841 Classifications: []string{"test"}, 842 }, 843 } 844 if !cmp.Equal(instances, want) { 845 t.Errorf("CodeScanning.ListAlertInstances returned %+v, want %+v", instances, want) 846 } 847 848 const methodName = "ListAlertInstances" 849 testBadOptions(t, methodName, func() (err error) { 850 _, _, err = client.CodeScanning.ListAlertInstances(ctx, "\n", "\n", -1, opts) 851 return err 852 }) 853 854 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 855 got, resp, err := client.CodeScanning.ListAlertInstances(ctx, "o", "r", 88, opts) 856 if got != nil { 857 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 858 } 859 return resp, err 860 }) 861 } 862 863 func TestCodeScanningService_GetAlert(t *testing.T) { 864 client, mux, _, teardown := setup() 865 defer teardown() 866 867 mux.HandleFunc("/repos/o/r/code-scanning/alerts/88", func(w http.ResponseWriter, r *http.Request) { 868 testMethod(t, r, "GET") 869 fmt.Fprint(w, `{ 870 "rule_id":"js/useless-expression", 871 "rule_severity":"warning", 872 "rule_description":"Expression has no effect", 873 "tool": { 874 "name": "CodeQL", 875 "guid": null, 876 "version": "1.4.0" 877 }, 878 "rule": { 879 "id": "useless expression", 880 "severity": "warning", 881 "description": "Expression has no effect", 882 "name": "useless expression", 883 "full_description": "Expression has no effect", 884 "help": "Expression has no effect" 885 }, 886 "most_recent_instance": { 887 "ref": "refs/heads/main", 888 "state": "open", 889 "commit_sha": "abcdefg12345", 890 "message": { 891 "text": "This path depends on a user-provided value." 892 }, 893 "location": { 894 "path": "spec-main/api-session-spec.ts", 895 "start_line": 917, 896 "end_line": 917, 897 "start_column": 7, 898 "end_column": 18 899 }, 900 "classifications": [ 901 "test" 902 ] 903 }, 904 "created_at":"2019-01-02T15:04:05Z", 905 "state":"open", 906 "closed_by":null, 907 "closed_at":null, 908 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88", 909 "html_url":"https://github.com/o/r/security/code-scanning/88" 910 }`) 911 }) 912 913 ctx := context.Background() 914 alert, _, err := client.CodeScanning.GetAlert(ctx, "o", "r", 88) 915 if err != nil { 916 t.Errorf("CodeScanning.GetAlert returned error: %v", err) 917 } 918 919 date := Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)} 920 want := &Alert{ 921 RuleID: String("js/useless-expression"), 922 RuleSeverity: String("warning"), 923 RuleDescription: String("Expression has no effect"), 924 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")}, 925 Rule: &Rule{ 926 ID: String("useless expression"), 927 Severity: String("warning"), 928 Description: String("Expression has no effect"), 929 Name: String("useless expression"), 930 FullDescription: String("Expression has no effect"), 931 Help: String("Expression has no effect"), 932 }, 933 CreatedAt: &date, 934 State: String("open"), 935 ClosedBy: nil, 936 ClosedAt: nil, 937 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"), 938 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"), 939 MostRecentInstance: &MostRecentInstance{ 940 Ref: String("refs/heads/main"), 941 State: String("open"), 942 CommitSHA: String("abcdefg12345"), 943 Message: &Message{ 944 Text: String("This path depends on a user-provided value."), 945 }, 946 Location: &Location{ 947 Path: String("spec-main/api-session-spec.ts"), 948 StartLine: Int(917), 949 EndLine: Int(917), 950 StartColumn: Int(7), 951 EndColumn: Int(18), 952 }, 953 Classifications: []string{"test"}, 954 }, 955 } 956 if !cmp.Equal(alert, want) { 957 t.Errorf("CodeScanning.GetAlert returned %+v, want %+v", alert, want) 958 } 959 960 const methodName = "GetAlert" 961 testBadOptions(t, methodName, func() (err error) { 962 _, _, err = client.CodeScanning.GetAlert(ctx, "\n", "\n", -88) 963 return err 964 }) 965 966 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 967 got, resp, err := client.CodeScanning.GetAlert(ctx, "o", "r", 88) 968 if got != nil { 969 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 970 } 971 return resp, err 972 }) 973 } 974 975 func TestAlert_Marshal(t *testing.T) { 976 testJSONMarshal(t, &Alert{}, "{}") 977 978 u := &Alert{ 979 RuleID: String("rid"), 980 RuleSeverity: String("rs"), 981 RuleDescription: String("rd"), 982 Tool: &Tool{ 983 Name: String("n"), 984 GUID: String("g"), 985 Version: String("v"), 986 }, 987 CreatedAt: &Timestamp{referenceTime}, 988 State: String("fixed"), 989 ClosedBy: &User{ 990 Login: String("l"), 991 ID: Int64(1), 992 NodeID: String("n"), 993 URL: String("u"), 994 ReposURL: String("r"), 995 EventsURL: String("e"), 996 AvatarURL: String("a"), 997 }, 998 ClosedAt: &Timestamp{referenceTime}, 999 URL: String("url"), 1000 HTMLURL: String("hurl"), 1001 } 1002 1003 want := `{ 1004 "rule_id": "rid", 1005 "rule_severity": "rs", 1006 "rule_description": "rd", 1007 "tool": { 1008 "name": "n", 1009 "guid": "g", 1010 "version": "v" 1011 }, 1012 "created_at": ` + referenceTimeStr + `, 1013 "state": "fixed", 1014 "closed_by": { 1015 "login": "l", 1016 "id": 1, 1017 "node_id": "n", 1018 "avatar_url": "a", 1019 "url": "u", 1020 "events_url": "e", 1021 "repos_url": "r" 1022 }, 1023 "closed_at": ` + referenceTimeStr + `, 1024 "url": "url", 1025 "html_url": "hurl" 1026 }` 1027 1028 testJSONMarshal(t, u, want) 1029 } 1030 1031 func TestLocation_Marshal(t *testing.T) { 1032 testJSONMarshal(t, &Location{}, "{}") 1033 1034 u := &Location{ 1035 Path: String("path"), 1036 StartLine: Int(1), 1037 EndLine: Int(2), 1038 StartColumn: Int(3), 1039 EndColumn: Int(4), 1040 } 1041 1042 want := `{ 1043 "path": "path", 1044 "start_line": 1, 1045 "end_line": 2, 1046 "start_column": 3, 1047 "end_column": 4 1048 }` 1049 1050 testJSONMarshal(t, u, want) 1051 } 1052 1053 func TestRule_Marshal(t *testing.T) { 1054 testJSONMarshal(t, &Rule{}, "{}") 1055 1056 u := &Rule{ 1057 ID: String("1"), 1058 Severity: String("3"), 1059 Description: String("description"), 1060 Name: String("first"), 1061 SecuritySeverityLevel: String("2"), 1062 FullDescription: String("summary"), 1063 Tags: []string{"tag1", "tag2"}, 1064 Help: String("Help Text"), 1065 } 1066 1067 want := `{ 1068 "id": "1", 1069 "severity": "3", 1070 "description": "description", 1071 "name": "first", 1072 "security_severity_level": "2", 1073 "full_description": "summary", 1074 "tags": ["tag1", "tag2"], 1075 "help": "Help Text" 1076 }` 1077 1078 testJSONMarshal(t, u, want) 1079 } 1080 1081 func TestTool_Marshal(t *testing.T) { 1082 testJSONMarshal(t, &Tool{}, "{}") 1083 1084 u := &Tool{ 1085 Name: String("name"), 1086 GUID: String("guid"), 1087 Version: String("ver"), 1088 } 1089 1090 want := `{ 1091 "name": "name", 1092 "guid": "guid", 1093 "version": "ver" 1094 }` 1095 1096 testJSONMarshal(t, u, want) 1097 } 1098 1099 func TestMessage_Marshal(t *testing.T) { 1100 testJSONMarshal(t, &Message{}, "{}") 1101 1102 u := &Message{ 1103 Text: String("text"), 1104 } 1105 1106 want := `{ 1107 "text": "text" 1108 }` 1109 1110 testJSONMarshal(t, u, want) 1111 } 1112 1113 func TestCodeScanningService_ListAnalysesForRepo(t *testing.T) { 1114 client, mux, _, teardown := setup() 1115 defer teardown() 1116 1117 mux.HandleFunc("/repos/o/r/code-scanning/analyses", func(w http.ResponseWriter, r *http.Request) { 1118 testMethod(t, r, "GET") 1119 testFormValues(t, r, values{"sarif_id": "8981cd8e-b078-4ac3-a3be-1dad7dbd0b582", "ref": "heads/master"}) 1120 fmt.Fprint(w, `[ 1121 { 1122 "ref": "refs/heads/main", 1123 "commit_sha": "d99612c3e1f2970085cfbaeadf8f010ef69bad83", 1124 "analysis_key": ".github/workflows/codeql-analysis.yml:analyze", 1125 "environment": "{\"language\":\"python\"}", 1126 "error": "", 1127 "category": ".github/workflows/codeql-analysis.yml:analyze/language:python", 1128 "created_at": "2020-08-27T15:05:21Z", 1129 "results_count": 17, 1130 "rules_count": 49, 1131 "id": 201, 1132 "url": "https://api.github.com/repos/o/r/code-scanning/analyses/201", 1133 "sarif_id": "8981cd8e-b078-4ac3-a3be-1dad7dbd0b582", 1134 "tool": { 1135 "name": "CodeQL", 1136 "guid": null, 1137 "version": "2.4.0" 1138 }, 1139 "deletable": true, 1140 "warning": "" 1141 }, 1142 { 1143 "ref": "refs/heads/my-branch", 1144 "commit_sha": "c8cff6510d4d084fb1b4aa13b64b97ca12b07321", 1145 "analysis_key": ".github/workflows/shiftleft.yml:build", 1146 "environment": "{}", 1147 "error": "", 1148 "category": ".github/workflows/shiftleft.yml:build/", 1149 "created_at": "2020-08-27T15:05:21Z", 1150 "results_count": 17, 1151 "rules_count": 32, 1152 "id": 200, 1153 "url": "https://api.github.com/repos/o/r/code-scanning/analyses/200", 1154 "sarif_id": "8981cd8e-b078-4ac3-a3be-1dad7dbd0b582", 1155 "tool": { 1156 "name": "Python Security ScanningAnalysis", 1157 "guid": null, 1158 "version": "1.2.0" 1159 }, 1160 "deletable": true, 1161 "warning": "" 1162 } 1163 ]`) 1164 }) 1165 1166 opts := &AnalysesListOptions{SarifID: String("8981cd8e-b078-4ac3-a3be-1dad7dbd0b582"), Ref: String("heads/master")} 1167 ctx := context.Background() 1168 analyses, _, err := client.CodeScanning.ListAnalysesForRepo(ctx, "o", "r", opts) 1169 if err != nil { 1170 t.Errorf("CodeScanning.ListAnalysesForRepo returned error: %v", err) 1171 } 1172 1173 date := &Timestamp{time.Date(2020, time.August, 27, 15, 05, 21, 0, time.UTC)} 1174 want := []*ScanningAnalysis{ 1175 { 1176 ID: Int64(201), 1177 Ref: String("refs/heads/main"), 1178 CommitSHA: String("d99612c3e1f2970085cfbaeadf8f010ef69bad83"), 1179 AnalysisKey: String(".github/workflows/codeql-analysis.yml:analyze"), 1180 Environment: String("{\"language\":\"python\"}"), 1181 Error: String(""), 1182 Category: String(".github/workflows/codeql-analysis.yml:analyze/language:python"), 1183 CreatedAt: date, 1184 ResultsCount: Int(17), 1185 RulesCount: Int(49), 1186 URL: String("https://api.github.com/repos/o/r/code-scanning/analyses/201"), 1187 SarifID: String("8981cd8e-b078-4ac3-a3be-1dad7dbd0b582"), 1188 Tool: &Tool{ 1189 Name: String("CodeQL"), 1190 GUID: nil, 1191 Version: String("2.4.0"), 1192 }, 1193 Deletable: Bool(true), 1194 Warning: String(""), 1195 }, 1196 { 1197 ID: Int64(200), 1198 Ref: String("refs/heads/my-branch"), 1199 CommitSHA: String("c8cff6510d4d084fb1b4aa13b64b97ca12b07321"), 1200 AnalysisKey: String(".github/workflows/shiftleft.yml:build"), 1201 Environment: String("{}"), 1202 Error: String(""), 1203 Category: String(".github/workflows/shiftleft.yml:build/"), 1204 CreatedAt: date, 1205 ResultsCount: Int(17), 1206 RulesCount: Int(32), 1207 URL: String("https://api.github.com/repos/o/r/code-scanning/analyses/200"), 1208 SarifID: String("8981cd8e-b078-4ac3-a3be-1dad7dbd0b582"), 1209 Tool: &Tool{ 1210 Name: String("Python Security ScanningAnalysis"), 1211 GUID: nil, 1212 Version: String("1.2.0"), 1213 }, 1214 Deletable: Bool(true), 1215 Warning: String(""), 1216 }, 1217 } 1218 if !cmp.Equal(analyses, want) { 1219 t.Errorf("CodeScanning.ListAnalysesForRepo returned %+v, want %+v", analyses, want) 1220 } 1221 1222 const methodName = "ListAnalysesForRepo" 1223 testBadOptions(t, methodName, func() (err error) { 1224 _, _, err = client.CodeScanning.ListAnalysesForRepo(ctx, "\n", "\n", opts) 1225 return err 1226 }) 1227 1228 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1229 got, resp, err := client.CodeScanning.ListAnalysesForRepo(ctx, "o", "r", opts) 1230 if got != nil { 1231 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1232 } 1233 return resp, err 1234 }) 1235 } 1236 1237 func TestCodeScanningService_GetAnalysis(t *testing.T) { 1238 client, mux, _, teardown := setup() 1239 defer teardown() 1240 1241 mux.HandleFunc("/repos/o/r/code-scanning/analyses/3602840", func(w http.ResponseWriter, r *http.Request) { 1242 testMethod(t, r, "GET") 1243 fmt.Fprint(w, `{ 1244 "ref": "refs/heads/main", 1245 "commit_sha": "c18c69115654ff0166991962832dc2bd7756e655", 1246 "analysis_key": ".github/workflows/codeql-analysis.yml:analyze", 1247 "environment": "{\"language\":\"javascript\"}", 1248 "error": "", 1249 "category": ".github/workflows/codeql-analysis.yml:analyze/language:javascript", 1250 "created_at": "2021-01-13T11:55:49Z", 1251 "results_count": 3, 1252 "rules_count": 67, 1253 "id": 3602840, 1254 "url": "https://api.github.com/repos/o/r/code-scanning/analyses/201", 1255 "sarif_id": "47177e22-5596-11eb-80a1-c1e54ef945c6", 1256 "tool": { 1257 "name": "CodeQL", 1258 "guid": null, 1259 "version": "2.4.0" 1260 }, 1261 "deletable": true, 1262 "warning": "" 1263 }`) 1264 }) 1265 1266 ctx := context.Background() 1267 analysis, _, err := client.CodeScanning.GetAnalysis(ctx, "o", "r", 3602840) 1268 if err != nil { 1269 t.Errorf("CodeScanning.GetAnalysis returned error: %v", err) 1270 } 1271 1272 date := &Timestamp{time.Date(2021, time.January, 13, 11, 55, 49, 0, time.UTC)} 1273 want := &ScanningAnalysis{ 1274 ID: Int64(3602840), 1275 Ref: String("refs/heads/main"), 1276 CommitSHA: String("c18c69115654ff0166991962832dc2bd7756e655"), 1277 AnalysisKey: String(".github/workflows/codeql-analysis.yml:analyze"), 1278 Environment: String("{\"language\":\"javascript\"}"), 1279 Error: String(""), 1280 Category: String(".github/workflows/codeql-analysis.yml:analyze/language:javascript"), 1281 CreatedAt: date, 1282 ResultsCount: Int(3), 1283 RulesCount: Int(67), 1284 URL: String("https://api.github.com/repos/o/r/code-scanning/analyses/201"), 1285 SarifID: String("47177e22-5596-11eb-80a1-c1e54ef945c6"), 1286 Tool: &Tool{ 1287 Name: String("CodeQL"), 1288 GUID: nil, 1289 Version: String("2.4.0"), 1290 }, 1291 Deletable: Bool(true), 1292 Warning: String(""), 1293 } 1294 if !cmp.Equal(analysis, want) { 1295 t.Errorf("CodeScanning.GetAnalysis returned %+v, want %+v", analysis, want) 1296 } 1297 1298 const methodName = "GetAnalysis" 1299 testBadOptions(t, methodName, func() (err error) { 1300 _, _, err = client.CodeScanning.GetAnalysis(ctx, "\n", "\n", -123) 1301 return err 1302 }) 1303 1304 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1305 got, resp, err := client.CodeScanning.GetAnalysis(ctx, "o", "r", 3602840) 1306 if got != nil { 1307 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1308 } 1309 return resp, err 1310 }) 1311 } 1312 1313 func TestCodeScanningService_DeleteAnalysis(t *testing.T) { 1314 client, mux, _, teardown := setup() 1315 defer teardown() 1316 1317 mux.HandleFunc("/repos/o/r/code-scanning/analyses/40", func(w http.ResponseWriter, r *http.Request) { 1318 testMethod(t, r, "DELETE") 1319 fmt.Fprint(w, `{ 1320 "next_analysis_url": "a", 1321 "confirm_delete_url": "b" 1322 }`) 1323 }) 1324 1325 ctx := context.Background() 1326 analysis, _, err := client.CodeScanning.DeleteAnalysis(ctx, "o", "r", 40) 1327 if err != nil { 1328 t.Errorf("CodeScanning.DeleteAnalysis returned error: %v", err) 1329 } 1330 1331 want := &DeleteAnalysis{ 1332 NextAnalysisURL: String("a"), 1333 ConfirmDeleteURL: String("b"), 1334 } 1335 if !cmp.Equal(analysis, want) { 1336 t.Errorf("CodeScanning.DeleteAnalysis returned %+v, want %+v", analysis, want) 1337 } 1338 1339 const methodName = "DeleteAnalysis" 1340 testBadOptions(t, methodName, func() (err error) { 1341 _, _, err = client.CodeScanning.DeleteAnalysis(ctx, "\n", "\n", -123) 1342 return err 1343 }) 1344 1345 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1346 got, resp, err := client.CodeScanning.DeleteAnalysis(ctx, "o", "r", 40) 1347 if got != nil { 1348 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1349 } 1350 return resp, err 1351 }) 1352 } 1353 1354 func TestCodeScanningService_ListCodeQLDatabases(t *testing.T) { 1355 client, mux, _, teardown := setup() 1356 defer teardown() 1357 1358 mux.HandleFunc("/repos/o/r/code-scanning/codeql/databases", func(w http.ResponseWriter, r *http.Request) { 1359 testMethod(t, r, "GET") 1360 fmt.Fprint(w, `[ 1361 { 1362 "id": 1, 1363 "name": "name", 1364 "language": "language", 1365 "uploader": { 1366 "login": "a", 1367 "id": 1, 1368 "node_id": "b", 1369 "avatar_url": "c", 1370 "gravatar_id": "d", 1371 "url": "e", 1372 "html_url": "f", 1373 "followers_url": "g", 1374 "following_url": "h", 1375 "gists_url": "i", 1376 "starred_url": "j", 1377 "subscriptions_url": "k", 1378 "organizations_url": "l", 1379 "repos_url": "m", 1380 "events_url": "n", 1381 "received_events_url": "o", 1382 "type": "p", 1383 "site_admin": false 1384 }, 1385 "content_type": "r", 1386 "size": 1024, 1387 "created_at": "2021-01-13T11:55:49Z", 1388 "updated_at": "2021-01-13T11:55:49Z", 1389 "url": "s" 1390 } 1391 ]`) 1392 }) 1393 1394 ctx := context.Background() 1395 databases, _, err := client.CodeScanning.ListCodeQLDatabases(ctx, "o", "r") 1396 if err != nil { 1397 t.Errorf("CodeScanning.ListCodeQLDatabases returned error: %v", err) 1398 } 1399 1400 date := &Timestamp{time.Date(2021, time.January, 13, 11, 55, 49, 0, time.UTC)} 1401 want := []*CodeQLDatabase{ 1402 { 1403 ID: Int64(1), 1404 Name: String("name"), 1405 Language: String("language"), 1406 Uploader: &User{ 1407 Login: String("a"), 1408 ID: Int64(1), 1409 NodeID: String("b"), 1410 AvatarURL: String("c"), 1411 GravatarID: String("d"), 1412 URL: String("e"), 1413 HTMLURL: String("f"), 1414 FollowersURL: String("g"), 1415 FollowingURL: String("h"), 1416 GistsURL: String("i"), 1417 StarredURL: String("j"), 1418 SubscriptionsURL: String("k"), 1419 OrganizationsURL: String("l"), 1420 ReposURL: String("m"), 1421 EventsURL: String("n"), 1422 ReceivedEventsURL: String("o"), 1423 Type: String("p"), 1424 SiteAdmin: Bool(false), 1425 }, 1426 ContentType: String("r"), 1427 Size: Int64(1024), 1428 CreatedAt: date, 1429 UpdatedAt: date, 1430 URL: String("s"), 1431 }, 1432 } 1433 1434 if !cmp.Equal(databases, want) { 1435 t.Errorf("CodeScanning.ListCodeQLDatabases returned %+v, want %+v", databases, want) 1436 } 1437 1438 const methodName = "ListCodeQLDatabases" 1439 testBadOptions(t, methodName, func() (err error) { 1440 _, _, err = client.CodeScanning.ListCodeQLDatabases(ctx, "\n", "\n") 1441 return err 1442 }) 1443 1444 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1445 got, resp, err := client.CodeScanning.ListCodeQLDatabases(ctx, "o", "r") 1446 if got != nil { 1447 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1448 } 1449 return resp, err 1450 }) 1451 } 1452 1453 func TestCodeScanningService_GetCodeQLDatabase(t *testing.T) { 1454 client, mux, _, teardown := setup() 1455 defer teardown() 1456 1457 mux.HandleFunc("/repos/o/r/code-scanning/codeql/databases/lang", func(w http.ResponseWriter, r *http.Request) { 1458 testMethod(t, r, "GET") 1459 fmt.Fprint(w, `{ 1460 "id": 1, 1461 "name": "name", 1462 "language": "language", 1463 "uploader": { 1464 "login": "a", 1465 "id": 1, 1466 "node_id": "b", 1467 "avatar_url": "c", 1468 "gravatar_id": "d", 1469 "url": "e", 1470 "html_url": "f", 1471 "followers_url": "g", 1472 "following_url": "h", 1473 "gists_url": "i", 1474 "starred_url": "j", 1475 "subscriptions_url": "k", 1476 "organizations_url": "l", 1477 "repos_url": "m", 1478 "events_url": "n", 1479 "received_events_url": "o", 1480 "type": "p", 1481 "site_admin": false 1482 }, 1483 "content_type": "r", 1484 "size": 1024, 1485 "created_at": "2021-01-13T11:55:49Z", 1486 "updated_at": "2021-01-13T11:55:49Z", 1487 "url": "s" 1488 }`) 1489 }) 1490 1491 ctx := context.Background() 1492 database, _, err := client.CodeScanning.GetCodeQLDatabase(ctx, "o", "r", "lang") 1493 if err != nil { 1494 t.Errorf("CodeScanning.GetCodeQLDatabase returned error: %v", err) 1495 } 1496 1497 date := &Timestamp{time.Date(2021, time.January, 13, 11, 55, 49, 0, time.UTC)} 1498 want := &CodeQLDatabase{ 1499 ID: Int64(1), 1500 Name: String("name"), 1501 Language: String("language"), 1502 Uploader: &User{ 1503 Login: String("a"), 1504 ID: Int64(1), 1505 NodeID: String("b"), 1506 AvatarURL: String("c"), 1507 GravatarID: String("d"), 1508 URL: String("e"), 1509 HTMLURL: String("f"), 1510 FollowersURL: String("g"), 1511 FollowingURL: String("h"), 1512 GistsURL: String("i"), 1513 StarredURL: String("j"), 1514 SubscriptionsURL: String("k"), 1515 OrganizationsURL: String("l"), 1516 ReposURL: String("m"), 1517 EventsURL: String("n"), 1518 ReceivedEventsURL: String("o"), 1519 Type: String("p"), 1520 SiteAdmin: Bool(false), 1521 }, 1522 ContentType: String("r"), 1523 Size: Int64(1024), 1524 CreatedAt: date, 1525 UpdatedAt: date, 1526 URL: String("s"), 1527 } 1528 1529 if !cmp.Equal(database, want) { 1530 t.Errorf("CodeScanning.GetCodeQLDatabase returned %+v, want %+v", database, want) 1531 } 1532 1533 const methodName = "GetCodeQLDatabase" 1534 testBadOptions(t, methodName, func() (err error) { 1535 _, _, err = client.CodeScanning.GetCodeQLDatabase(ctx, "\n", "\n", "\n") 1536 return err 1537 }) 1538 1539 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1540 got, resp, err := client.CodeScanning.GetCodeQLDatabase(ctx, "o", "r", "lang") 1541 if got != nil { 1542 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1543 } 1544 return resp, err 1545 }) 1546 } 1547 1548 func TestCodeScanningService_GetDefaultSetupConfiguration(t *testing.T) { 1549 client, mux, _, teardown := setup() 1550 defer teardown() 1551 1552 mux.HandleFunc("/repos/o/r/code-scanning/default-setup", func(w http.ResponseWriter, r *http.Request) { 1553 testMethod(t, r, "GET") 1554 _, err := fmt.Fprint(w, `{ 1555 "state": "configured", 1556 "languages": [ 1557 "javascript", 1558 "javascript-typescript", 1559 "typescript" 1560 ], 1561 "query_suite": "default", 1562 "updated_at": "2006-01-02T15:04:05Z" 1563 }`) 1564 if err != nil { 1565 t.Fatal(err) 1566 } 1567 }) 1568 1569 ctx := context.Background() 1570 cfg, _, err := client.CodeScanning.GetDefaultSetupConfiguration(ctx, "o", "r") 1571 if err != nil { 1572 t.Errorf("CodeScanning.GetDefaultSetupConfiguration returned error: %v", err) 1573 } 1574 1575 date := &Timestamp{time.Date(2006, time.January, 02, 15, 04, 05, 0, time.UTC)} 1576 want := &DefaultSetupConfiguration{ 1577 State: String("configured"), 1578 Languages: []string{"javascript", "javascript-typescript", "typescript"}, 1579 QuerySuite: String("default"), 1580 UpdatedAt: date, 1581 } 1582 if !cmp.Equal(cfg, want) { 1583 t.Errorf("CodeScanning.GetDefaultSetupConfiguration returned %+v, want %+v", cfg, want) 1584 } 1585 1586 const methodName = "GetDefaultSetupConfiguration" 1587 testBadOptions(t, methodName, func() (err error) { 1588 _, _, err = client.CodeScanning.GetDefaultSetupConfiguration(ctx, "\n", "\n") 1589 return err 1590 }) 1591 1592 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1593 got, resp, err := client.CodeScanning.GetDefaultSetupConfiguration(ctx, "o", "r") 1594 if got != nil { 1595 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1596 } 1597 return resp, err 1598 }) 1599 } 1600 1601 func TestCodeScanningService_UpdateDefaultSetupConfiguration(t *testing.T) { 1602 client, mux, _, teardown := setup() 1603 defer teardown() 1604 1605 mux.HandleFunc("/repos/o/r/code-scanning/default-setup", func(w http.ResponseWriter, r *http.Request) { 1606 testMethod(t, r, "PATCH") 1607 _, err := fmt.Fprint(w, `{ 1608 "run_id": 5301214200, 1609 "run_url": "https://api.github.com/repos/o/r/actions/runs/5301214200" 1610 }`) 1611 if err != nil { 1612 t.Fatal(err) 1613 } 1614 }) 1615 1616 ctx := context.Background() 1617 options := &UpdateDefaultSetupConfigurationOptions{ 1618 State: "configured", 1619 Languages: []string{"go"}, 1620 QuerySuite: String("default"), 1621 } 1622 got, _, err := client.CodeScanning.UpdateDefaultSetupConfiguration(ctx, "o", "r", options) 1623 if err != nil { 1624 t.Errorf("CodeScanning.UpdateDefaultSetupConfiguration returned error: %v", err) 1625 } 1626 1627 want := &UpdateDefaultSetupConfigurationResponse{ 1628 RunID: Int64(5301214200), 1629 RunURL: String("https://api.github.com/repos/o/r/actions/runs/5301214200"), 1630 } 1631 if !cmp.Equal(got, want) { 1632 t.Errorf("CodeScanning.UpdateDefaultSetupConfiguration returned %+v, want %+v", got, want) 1633 } 1634 1635 const methodName = "UpdateDefaultSetupConfiguration" 1636 testBadOptions(t, methodName, func() (err error) { 1637 _, _, err = client.CodeScanning.UpdateDefaultSetupConfiguration(ctx, "\n", "\n", nil) 1638 return err 1639 }) 1640 1641 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1642 got, resp, err := client.CodeScanning.UpdateDefaultSetupConfiguration(ctx, "o", "r", nil) 1643 if got != nil { 1644 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1645 } 1646 return resp, err 1647 }) 1648 }