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