1
2
3
4
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
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
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
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
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 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 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
87 _, resp, err := client.CodeScanning.UploadSarif(ctx, "o", "r", sarifAnalysis)
88 return resp, err
89 })
90 }
91
92 func TestCodeScanningService_ListAlertsForOrg(t *testing.T) {
93 client, mux, _, teardown := setup()
94 defer teardown()
95
96 mux.HandleFunc("/orgs/o/code-scanning/alerts", func(w http.ResponseWriter, r *http.Request) {
97 testMethod(t, r, "GET")
98 testFormValues(t, r, values{"state": "open", "ref": "heads/master"})
99 fmt.Fprint(w, `[{
100 "repository": {
101 "id": 1,
102 "name": "n",
103 "url": "url"
104 },
105 "rule_id":"js/trivial-conditional",
106 "rule_severity":"warning",
107 "rule_description":"Useless conditional",
108 "tool": {
109 "name": "CodeQL",
110 "guid": null,
111 "version": "1.4.0"
112 },
113 "rule": {
114 "id": "js/trivial-conditional",
115 "severity": "warning",
116 "description": "Useless conditional",
117 "name": "js/trivial-conditional",
118 "full_description": "Expression has no effect",
119 "help": "Expression has no effect"
120 },
121 "most_recent_instance": {
122 "ref": "refs/heads/main",
123 "state": "open",
124 "commit_sha": "abcdefg12345",
125 "message": {
126 "text": "This path depends on a user-provided value."
127 },
128 "location": {
129 "path": "spec-main/api-session-spec.ts",
130 "start_line": 917,
131 "end_line": 917,
132 "start_column": 7,
133 "end_column": 18
134 },
135 "classifications": [
136 "test"
137 ]
138 },
139 "created_at":"2020-05-06T12:00:00Z",
140 "state":"open",
141 "closed_by":null,
142 "closed_at":null,
143 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/25",
144 "html_url":"https://github.com/o/r/security/code-scanning/25"
145 },
146 {
147 "rule_id":"js/useless-expression",
148 "rule_severity":"warning",
149 "rule_description":"Expression has no effect",
150 "tool": {
151 "name": "CodeQL",
152 "guid": null,
153 "version": "1.4.0"
154 },
155 "rule": {
156 "id": "js/useless-expression",
157 "severity": "warning",
158 "description": "Expression has no effect",
159 "name": "js/useless-expression",
160 "full_description": "Expression has no effect",
161 "help": "Expression has no effect"
162 },
163 "most_recent_instance": {
164 "ref": "refs/heads/main",
165 "state": "open",
166 "commit_sha": "abcdefg12345",
167 "message": {
168 "text": "This path depends on a user-provided value."
169 },
170 "location": {
171 "path": "spec-main/api-session-spec.ts",
172 "start_line": 917,
173 "end_line": 917,
174 "start_column": 7,
175 "end_column": 18
176 },
177 "classifications": [
178 "test"
179 ]
180 },
181 "created_at":"2020-05-06T12:00:00Z",
182 "state":"open",
183 "closed_by":null,
184 "closed_at":null,
185 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88",
186 "html_url":"https://github.com/o/r/security/code-scanning/88"
187 }]`)
188 })
189
190 opts := &AlertListOptions{State: "open", Ref: "heads/master"}
191 ctx := context.Background()
192 alerts, _, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts)
193 if err != nil {
194 t.Errorf("CodeScanning.ListAlertsForOrg returned error: %v", err)
195 }
196
197 date := Timestamp{time.Date(2020, time.May, 06, 12, 00, 00, 0, time.UTC)}
198 want := []*Alert{
199 {
200 Repository: &Repository{
201 ID: Int64(1),
202 URL: String("url"),
203 Name: String("n"),
204 },
205 RuleID: String("js/trivial-conditional"),
206 RuleSeverity: String("warning"),
207 RuleDescription: String("Useless conditional"),
208 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
209 Rule: &Rule{
210 ID: String("js/trivial-conditional"),
211 Severity: String("warning"),
212 Description: String("Useless conditional"),
213 Name: String("js/trivial-conditional"),
214 FullDescription: String("Expression has no effect"),
215 Help: String("Expression has no effect"),
216 },
217 CreatedAt: &date,
218 State: String("open"),
219 ClosedBy: nil,
220 ClosedAt: nil,
221 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/25"),
222 HTMLURL: String("https://github.com/o/r/security/code-scanning/25"),
223 MostRecentInstance: &MostRecentInstance{
224 Ref: String("refs/heads/main"),
225 State: String("open"),
226 CommitSHA: String("abcdefg12345"),
227 Message: &Message{
228 Text: String("This path depends on a user-provided value."),
229 },
230 Location: &Location{
231 Path: String("spec-main/api-session-spec.ts"),
232 StartLine: Int(917),
233 EndLine: Int(917),
234 StartColumn: Int(7),
235 EndColumn: Int(18),
236 },
237 Classifications: []string{"test"},
238 },
239 },
240 {
241 RuleID: String("js/useless-expression"),
242 RuleSeverity: String("warning"),
243 RuleDescription: String("Expression has no effect"),
244 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
245 Rule: &Rule{
246 ID: String("js/useless-expression"),
247 Severity: String("warning"),
248 Description: String("Expression has no effect"),
249 Name: String("js/useless-expression"),
250 FullDescription: String("Expression has no effect"),
251 Help: String("Expression has no effect"),
252 },
253 CreatedAt: &date,
254 State: String("open"),
255 ClosedBy: nil,
256 ClosedAt: nil,
257 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"),
258 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"),
259 MostRecentInstance: &MostRecentInstance{
260 Ref: String("refs/heads/main"),
261 State: String("open"),
262 CommitSHA: String("abcdefg12345"),
263 Message: &Message{
264 Text: String("This path depends on a user-provided value."),
265 },
266 Location: &Location{
267 Path: String("spec-main/api-session-spec.ts"),
268 StartLine: Int(917),
269 EndLine: Int(917),
270 StartColumn: Int(7),
271 EndColumn: Int(18),
272 },
273 Classifications: []string{"test"},
274 },
275 },
276 }
277 if !cmp.Equal(alerts, want) {
278 t.Errorf("CodeScanning.ListAlertsForOrg returned %+v, want %+v", *&alerts, *&want)
279 }
280
281 const methodName = "ListAlertsForOrg"
282 testBadOptions(t, methodName, func() (err error) {
283 _, _, err = client.CodeScanning.ListAlertsForOrg(ctx, "\n", opts)
284 return err
285 })
286
287 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
288 got, resp, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts)
289 if got != nil {
290 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
291 }
292 return resp, err
293 })
294 }
295
296 func TestCodeScanningService_ListAlertsForRepo(t *testing.T) {
297 client, mux, _, teardown := setup()
298 defer teardown()
299
300 mux.HandleFunc("/repos/o/r/code-scanning/alerts", func(w http.ResponseWriter, r *http.Request) {
301 testMethod(t, r, "GET")
302 testFormValues(t, r, values{"state": "open", "ref": "heads/master"})
303 fmt.Fprint(w, `[{
304 "rule_id":"js/trivial-conditional",
305 "rule_severity":"warning",
306 "rule_description":"Useless conditional",
307 "tool": {
308 "name": "CodeQL",
309 "guid": null,
310 "version": "1.4.0"
311 },
312 "rule": {
313 "id": "js/trivial-conditional",
314 "severity": "warning",
315 "description": "Useless conditional",
316 "name": "js/trivial-conditional",
317 "full_description": "Expression has no effect",
318 "help": "Expression has no effect"
319 },
320 "most_recent_instance": {
321 "ref": "refs/heads/main",
322 "state": "open",
323 "commit_sha": "abcdefg12345",
324 "message": {
325 "text": "This path depends on a user-provided value."
326 },
327 "location": {
328 "path": "spec-main/api-session-spec.ts",
329 "start_line": 917,
330 "end_line": 917,
331 "start_column": 7,
332 "end_column": 18
333 },
334 "classifications": [
335 "test"
336 ]
337 },
338 "created_at":"2020-05-06T12:00:00Z",
339 "state":"open",
340 "closed_by":null,
341 "closed_at":null,
342 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/25",
343 "html_url":"https://github.com/o/r/security/code-scanning/25"
344 },
345 {
346 "rule_id":"js/useless-expression",
347 "rule_severity":"warning",
348 "rule_description":"Expression has no effect",
349 "tool": {
350 "name": "CodeQL",
351 "guid": null,
352 "version": "1.4.0"
353 },
354 "rule": {
355 "id": "js/useless-expression",
356 "severity": "warning",
357 "description": "Expression has no effect",
358 "name": "js/useless-expression",
359 "full_description": "Expression has no effect",
360 "help": "Expression has no effect"
361 },
362 "most_recent_instance": {
363 "ref": "refs/heads/main",
364 "state": "open",
365 "commit_sha": "abcdefg12345",
366 "message": {
367 "text": "This path depends on a user-provided value."
368 },
369 "location": {
370 "path": "spec-main/api-session-spec.ts",
371 "start_line": 917,
372 "end_line": 917,
373 "start_column": 7,
374 "end_column": 18
375 },
376 "classifications": [
377 "test"
378 ]
379 },
380 "created_at":"2020-05-06T12:00:00Z",
381 "state":"open",
382 "closed_by":null,
383 "closed_at":null,
384 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88",
385 "html_url":"https://github.com/o/r/security/code-scanning/88"
386 }]`)
387 })
388
389 opts := &AlertListOptions{State: "open", Ref: "heads/master"}
390 ctx := context.Background()
391 alerts, _, err := client.CodeScanning.ListAlertsForRepo(ctx, "o", "r", opts)
392 if err != nil {
393 t.Errorf("CodeScanning.ListAlertsForRepo returned error: %v", err)
394 }
395
396 date := Timestamp{time.Date(2020, time.May, 06, 12, 00, 00, 0, time.UTC)}
397 want := []*Alert{
398 {
399 RuleID: String("js/trivial-conditional"),
400 RuleSeverity: String("warning"),
401 RuleDescription: String("Useless conditional"),
402 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
403 Rule: &Rule{
404 ID: String("js/trivial-conditional"),
405 Severity: String("warning"),
406 Description: String("Useless conditional"),
407 Name: String("js/trivial-conditional"),
408 FullDescription: String("Expression has no effect"),
409 Help: String("Expression has no effect"),
410 },
411 CreatedAt: &date,
412 State: String("open"),
413 ClosedBy: nil,
414 ClosedAt: nil,
415 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/25"),
416 HTMLURL: String("https://github.com/o/r/security/code-scanning/25"),
417 MostRecentInstance: &MostRecentInstance{
418 Ref: String("refs/heads/main"),
419 State: String("open"),
420 CommitSHA: String("abcdefg12345"),
421 Message: &Message{
422 Text: String("This path depends on a user-provided value."),
423 },
424 Location: &Location{
425 Path: String("spec-main/api-session-spec.ts"),
426 StartLine: Int(917),
427 EndLine: Int(917),
428 StartColumn: Int(7),
429 EndColumn: Int(18),
430 },
431 Classifications: []string{"test"},
432 },
433 },
434 {
435 RuleID: String("js/useless-expression"),
436 RuleSeverity: String("warning"),
437 RuleDescription: String("Expression has no effect"),
438 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
439 Rule: &Rule{
440 ID: String("js/useless-expression"),
441 Severity: String("warning"),
442 Description: String("Expression has no effect"),
443 Name: String("js/useless-expression"),
444 FullDescription: String("Expression has no effect"),
445 Help: String("Expression has no effect"),
446 },
447 CreatedAt: &date,
448 State: String("open"),
449 ClosedBy: nil,
450 ClosedAt: nil,
451 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"),
452 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"),
453 MostRecentInstance: &MostRecentInstance{
454 Ref: String("refs/heads/main"),
455 State: String("open"),
456 CommitSHA: String("abcdefg12345"),
457 Message: &Message{
458 Text: String("This path depends on a user-provided value."),
459 },
460 Location: &Location{
461 Path: String("spec-main/api-session-spec.ts"),
462 StartLine: Int(917),
463 EndLine: Int(917),
464 StartColumn: Int(7),
465 EndColumn: Int(18),
466 },
467 Classifications: []string{"test"},
468 },
469 },
470 }
471 if !cmp.Equal(alerts, want) {
472 t.Errorf("CodeScanning.ListAlertsForRepo returned %+v, want %+v", alerts, want)
473 }
474
475 const methodName = "ListAlertsForRepo"
476 testBadOptions(t, methodName, func() (err error) {
477 _, _, err = client.CodeScanning.ListAlertsForRepo(ctx, "\n", "\n", opts)
478 return err
479 })
480
481 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
482 got, resp, err := client.CodeScanning.ListAlertsForRepo(ctx, "o", "r", opts)
483 if got != nil {
484 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
485 }
486 return resp, err
487 })
488 }
489
490 func TestCodeScanningService_GetAlert(t *testing.T) {
491 client, mux, _, teardown := setup()
492 defer teardown()
493
494 mux.HandleFunc("/repos/o/r/code-scanning/alerts/88", func(w http.ResponseWriter, r *http.Request) {
495 testMethod(t, r, "GET")
496 fmt.Fprint(w, `{"rule_id":"js/useless-expression",
497 "rule_severity":"warning",
498 "rule_description":"Expression has no effect",
499 "tool": {
500 "name": "CodeQL",
501 "guid": null,
502 "version": "1.4.0"
503 },
504 "rule": {
505 "id": "useless expression",
506 "severity": "warning",
507 "description": "Expression has no effect",
508 "name": "useless expression",
509 "full_description": "Expression has no effect",
510 "help": "Expression has no effect"
511 },
512 "most_recent_instance": {
513 "ref": "refs/heads/main",
514 "state": "open",
515 "commit_sha": "abcdefg12345",
516 "message": {
517 "text": "This path depends on a user-provided value."
518 },
519 "location": {
520 "path": "spec-main/api-session-spec.ts",
521 "start_line": 917,
522 "end_line": 917,
523 "start_column": 7,
524 "end_column": 18
525 },
526 "classifications": [
527 "test"
528 ]
529 },
530 "created_at":"2019-01-02T15:04:05Z",
531 "state":"open",
532 "closed_by":null,
533 "closed_at":null,
534 "url":"https://api.github.com/repos/o/r/code-scanning/alerts/88",
535 "html_url":"https://github.com/o/r/security/code-scanning/88"}`)
536 })
537
538 ctx := context.Background()
539 alert, _, err := client.CodeScanning.GetAlert(ctx, "o", "r", 88)
540 if err != nil {
541 t.Errorf("CodeScanning.GetAlert returned error: %v", err)
542 }
543
544 date := Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}
545 want := &Alert{
546 RuleID: String("js/useless-expression"),
547 RuleSeverity: String("warning"),
548 RuleDescription: String("Expression has no effect"),
549 Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
550 Rule: &Rule{
551 ID: String("useless expression"),
552 Severity: String("warning"),
553 Description: String("Expression has no effect"),
554 Name: String("useless expression"),
555 FullDescription: String("Expression has no effect"),
556 Help: String("Expression has no effect"),
557 },
558 CreatedAt: &date,
559 State: String("open"),
560 ClosedBy: nil,
561 ClosedAt: nil,
562 URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/88"),
563 HTMLURL: String("https://github.com/o/r/security/code-scanning/88"),
564 MostRecentInstance: &MostRecentInstance{
565 Ref: String("refs/heads/main"),
566 State: String("open"),
567 CommitSHA: String("abcdefg12345"),
568 Message: &Message{
569 Text: String("This path depends on a user-provided value."),
570 },
571 Location: &Location{
572 Path: String("spec-main/api-session-spec.ts"),
573 StartLine: Int(917),
574 EndLine: Int(917),
575 StartColumn: Int(7),
576 EndColumn: Int(18),
577 },
578 Classifications: []string{"test"},
579 },
580 }
581 if !cmp.Equal(alert, want) {
582 t.Errorf("CodeScanning.GetAlert returned %+v, want %+v", alert, want)
583 }
584
585 const methodName = "GetAlert"
586 testBadOptions(t, methodName, func() (err error) {
587 _, _, err = client.CodeScanning.GetAlert(ctx, "\n", "\n", -88)
588 return err
589 })
590
591 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
592 got, resp, err := client.CodeScanning.GetAlert(ctx, "o", "r", 88)
593 if got != nil {
594 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
595 }
596 return resp, err
597 })
598 }
599
600 func TestAlert_Marshal(t *testing.T) {
601 testJSONMarshal(t, &Alert{}, "{}")
602
603 u := &Alert{
604 RuleID: String("rid"),
605 RuleSeverity: String("rs"),
606 RuleDescription: String("rd"),
607 Tool: &Tool{
608 Name: String("n"),
609 GUID: String("g"),
610 Version: String("v"),
611 },
612 CreatedAt: &Timestamp{referenceTime},
613 State: String("fixed"),
614 ClosedBy: &User{
615 Login: String("l"),
616 ID: Int64(1),
617 NodeID: String("n"),
618 URL: String("u"),
619 ReposURL: String("r"),
620 EventsURL: String("e"),
621 AvatarURL: String("a"),
622 },
623 ClosedAt: &Timestamp{referenceTime},
624 URL: String("url"),
625 HTMLURL: String("hurl"),
626 }
627
628 want := `{
629 "rule_id": "rid",
630 "rule_severity": "rs",
631 "rule_description": "rd",
632 "tool": {
633 "name": "n",
634 "guid": "g",
635 "version": "v"
636 },
637 "created_at": ` + referenceTimeStr + `,
638 "state": "fixed",
639 "closed_by": {
640 "login": "l",
641 "id": 1,
642 "node_id": "n",
643 "avatar_url": "a",
644 "url": "u",
645 "events_url": "e",
646 "repos_url": "r"
647 },
648 "closed_at": ` + referenceTimeStr + `,
649 "url": "url",
650 "html_url": "hurl"
651 }`
652
653 testJSONMarshal(t, u, want)
654 }
655
656 func TestLocation_Marshal(t *testing.T) {
657 testJSONMarshal(t, &Location{}, "{}")
658
659 u := &Location{
660 Path: String("path"),
661 StartLine: Int(1),
662 EndLine: Int(2),
663 StartColumn: Int(3),
664 EndColumn: Int(4),
665 }
666
667 want := `{
668 "path": "path",
669 "start_line": 1,
670 "end_line": 2,
671 "start_column": 3,
672 "end_column": 4
673 }`
674
675 testJSONMarshal(t, u, want)
676 }
677
678 func TestRule_Marshal(t *testing.T) {
679 testJSONMarshal(t, &Rule{}, "{}")
680
681 u := &Rule{
682 ID: String("1"),
683 Severity: String("3"),
684 Description: String("description"),
685 Name: String("first"),
686 SecuritySeverityLevel: String("2"),
687 FullDescription: String("summary"),
688 Tags: []string{"tag1", "tag2"},
689 Help: String("Help Text"),
690 }
691
692 want := `{
693 "id": "1",
694 "severity": "3",
695 "description": "description",
696 "name": "first",
697 "security_severity_level": "2",
698 "full_description": "summary",
699 "tags": ["tag1", "tag2"],
700 "help": "Help Text"
701 }`
702
703 testJSONMarshal(t, u, want)
704 }
705
706 func TestTool_Marshal(t *testing.T) {
707 testJSONMarshal(t, &Tool{}, "{}")
708
709 u := &Tool{
710 Name: String("name"),
711 GUID: String("guid"),
712 Version: String("ver"),
713 }
714
715 want := `{
716 "name": "name",
717 "guid": "guid",
718 "version": "ver"
719 }`
720
721 testJSONMarshal(t, u, want)
722 }
723
724 func TestMessage_Marshal(t *testing.T) {
725 testJSONMarshal(t, &Message{}, "{}")
726
727 u := &Message{
728 Text: String("text"),
729 }
730
731 want := `{
732 "text": "text"
733 }`
734
735 testJSONMarshal(t, u, want)
736 }
737
738 func TestCodeScanningService_ListAnalysesForRepo(t *testing.T) {
739 client, mux, _, teardown := setup()
740 defer teardown()
741
742 mux.HandleFunc("/repos/o/r/code-scanning/analyses", func(w http.ResponseWriter, r *http.Request) {
743 testMethod(t, r, "GET")
744 testFormValues(t, r, values{"sarif_id": "8981cd8e-b078-4ac3-a3be-1dad7dbd0b582", "ref": "heads/master"})
745 fmt.Fprint(w, `[
746 {
747 "ref": "refs/heads/main",
748 "commit_sha": "d99612c3e1f2970085cfbaeadf8f010ef69bad83",
749 "analysis_key": ".github/workflows/codeql-analysis.yml:analyze",
750 "environment": "{\"language\":\"python\"}",
751 "error": "",
752 "category": ".github/workflows/codeql-analysis.yml:analyze/language:python",
753 "created_at": "2020-08-27T15:05:21Z",
754 "results_count": 17,
755 "rules_count": 49,
756 "id": 201,
757 "url": "https://api.github.com/repos/o/r/code-scanning/analyses/201",
758 "sarif_id": "8981cd8e-b078-4ac3-a3be-1dad7dbd0b582",
759 "tool": {
760 "name": "CodeQL",
761 "guid": null,
762 "version": "2.4.0"
763 },
764 "deletable": true,
765 "warning": ""
766 },
767 {
768 "ref": "refs/heads/my-branch",
769 "commit_sha": "c8cff6510d4d084fb1b4aa13b64b97ca12b07321",
770 "analysis_key": ".github/workflows/shiftleft.yml:build",
771 "environment": "{}",
772 "error": "",
773 "category": ".github/workflows/shiftleft.yml:build/",
774 "created_at": "2020-08-27T15:05:21Z",
775 "results_count": 17,
776 "rules_count": 32,
777 "id": 200,
778 "url": "https://api.github.com/repos/o/r/code-scanning/analyses/200",
779 "sarif_id": "8981cd8e-b078-4ac3-a3be-1dad7dbd0b582",
780 "tool": {
781 "name": "Python Security ScanningAnalysis",
782 "guid": null,
783 "version": "1.2.0"
784 },
785 "deletable": true,
786 "warning": ""
787 }
788 ]`)
789 })
790
791 opts := &AnalysesListOptions{SarifID: String("8981cd8e-b078-4ac3-a3be-1dad7dbd0b582"), Ref: String("heads/master")}
792 ctx := context.Background()
793 analyses, _, err := client.CodeScanning.ListAnalysesForRepo(ctx, "o", "r", opts)
794 if err != nil {
795 t.Errorf("CodeScanning.ListAnalysesForRepo returned error: %v", err)
796 }
797
798 date := &Timestamp{time.Date(2020, time.August, 27, 15, 05, 21, 0, time.UTC)}
799 want := []*ScanningAnalysis{
800 {
801 ID: Int64(201),
802 Ref: String("refs/heads/main"),
803 CommitSHA: String("d99612c3e1f2970085cfbaeadf8f010ef69bad83"),
804 AnalysisKey: String(".github/workflows/codeql-analysis.yml:analyze"),
805 Environment: String("{\"language\":\"python\"}"),
806 Error: String(""),
807 Category: String(".github/workflows/codeql-analysis.yml:analyze/language:python"),
808 CreatedAt: date,
809 ResultsCount: Int(17),
810 RulesCount: Int(49),
811 URL: String("https://api.github.com/repos/o/r/code-scanning/analyses/201"),
812 SarifID: String("8981cd8e-b078-4ac3-a3be-1dad7dbd0b582"),
813 Tool: &Tool{
814 Name: String("CodeQL"),
815 GUID: nil,
816 Version: String("2.4.0"),
817 },
818 Deletable: Bool(true),
819 Warning: String(""),
820 },
821 {
822 ID: Int64(200),
823 Ref: String("refs/heads/my-branch"),
824 CommitSHA: String("c8cff6510d4d084fb1b4aa13b64b97ca12b07321"),
825 AnalysisKey: String(".github/workflows/shiftleft.yml:build"),
826 Environment: String("{}"),
827 Error: String(""),
828 Category: String(".github/workflows/shiftleft.yml:build/"),
829 CreatedAt: date,
830 ResultsCount: Int(17),
831 RulesCount: Int(32),
832 URL: String("https://api.github.com/repos/o/r/code-scanning/analyses/200"),
833 SarifID: String("8981cd8e-b078-4ac3-a3be-1dad7dbd0b582"),
834 Tool: &Tool{
835 Name: String("Python Security ScanningAnalysis"),
836 GUID: nil,
837 Version: String("1.2.0"),
838 },
839 Deletable: Bool(true),
840 Warning: String(""),
841 },
842 }
843 if !cmp.Equal(analyses, want) {
844 t.Errorf("CodeScanning.ListAnalysesForRepo returned %+v, want %+v", analyses, want)
845 }
846
847 const methodName = "ListAnalysesForRepo"
848 testBadOptions(t, methodName, func() (err error) {
849 _, _, err = client.CodeScanning.ListAnalysesForRepo(ctx, "\n", "\n", opts)
850 return err
851 })
852
853 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
854 got, resp, err := client.CodeScanning.ListAnalysesForRepo(ctx, "o", "r", opts)
855 if got != nil {
856 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
857 }
858 return resp, err
859 })
860 }
861
862 func TestCodeScanningService_GetAnalysis(t *testing.T) {
863 client, mux, _, teardown := setup()
864 defer teardown()
865
866 mux.HandleFunc("/repos/o/r/code-scanning/analyses/3602840", func(w http.ResponseWriter, r *http.Request) {
867 testMethod(t, r, "GET")
868 fmt.Fprint(w, `{
869 "ref": "refs/heads/main",
870 "commit_sha": "c18c69115654ff0166991962832dc2bd7756e655",
871 "analysis_key": ".github/workflows/codeql-analysis.yml:analyze",
872 "environment": "{\"language\":\"javascript\"}",
873 "error": "",
874 "category": ".github/workflows/codeql-analysis.yml:analyze/language:javascript",
875 "created_at": "2021-01-13T11:55:49Z",
876 "results_count": 3,
877 "rules_count": 67,
878 "id": 3602840,
879 "url": "https://api.github.com/repos/o/r/code-scanning/analyses/201",
880 "sarif_id": "47177e22-5596-11eb-80a1-c1e54ef945c6",
881 "tool": {
882 "name": "CodeQL",
883 "guid": null,
884 "version": "2.4.0"
885 },
886 "deletable": true,
887 "warning": ""
888 }`)
889 })
890
891 ctx := context.Background()
892 analysis, _, err := client.CodeScanning.GetAnalysis(ctx, "o", "r", 3602840)
893 if err != nil {
894 t.Errorf("CodeScanning.GetAnalysis returned error: %v", err)
895 }
896
897 date := &Timestamp{time.Date(2021, time.January, 13, 11, 55, 49, 0, time.UTC)}
898 want := &ScanningAnalysis{
899 ID: Int64(3602840),
900 Ref: String("refs/heads/main"),
901 CommitSHA: String("c18c69115654ff0166991962832dc2bd7756e655"),
902 AnalysisKey: String(".github/workflows/codeql-analysis.yml:analyze"),
903 Environment: String("{\"language\":\"javascript\"}"),
904 Error: String(""),
905 Category: String(".github/workflows/codeql-analysis.yml:analyze/language:javascript"),
906 CreatedAt: date,
907 ResultsCount: Int(3),
908 RulesCount: Int(67),
909 URL: String("https://api.github.com/repos/o/r/code-scanning/analyses/201"),
910 SarifID: String("47177e22-5596-11eb-80a1-c1e54ef945c6"),
911 Tool: &Tool{
912 Name: String("CodeQL"),
913 GUID: nil,
914 Version: String("2.4.0"),
915 },
916 Deletable: Bool(true),
917 Warning: String(""),
918 }
919 if !cmp.Equal(analysis, want) {
920 t.Errorf("CodeScanning.GetAnalysis returned %+v, want %+v", analysis, want)
921 }
922
923 const methodName = "GetAnalysis"
924 testBadOptions(t, methodName, func() (err error) {
925 _, _, err = client.CodeScanning.GetAnalysis(ctx, "\n", "\n", -123)
926 return err
927 })
928
929 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
930 got, resp, err := client.CodeScanning.GetAnalysis(ctx, "o", "r", 3602840)
931 if got != nil {
932 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
933 }
934 return resp, err
935 })
936 }
937
View as plain text