Skip to content

Commit 020d9ae

Browse files
authored
Add support for cursor pagination in AlertListOptions (#2512)
Fixes: #2511.
1 parent 3bfe921 commit 020d9ae

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

github/code-scanning.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ type AlertListOptions struct {
121121
// Return code scanning alerts for a specific branch reference. The ref must be formatted as heads/<branch name>.
122122
Ref string `url:"ref,omitempty"`
123123

124+
ListCursorOptions
125+
126+
// Add ListOptions so offset pagination with integer type "page" query parameter is accepted
127+
// since ListCursorOptions accepts "page" as string only.
124128
ListOptions
125129
}
126130

github/code-scanning_test.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,132 @@ func TestCodeScanningService_ListAlertsForOrg(t *testing.T) {
293293
})
294294
}
295295

296+
func TestCodeScanningService_ListAlertsForOrgLisCursorOptions(t *testing.T) {
297+
client, mux, _, teardown := setup()
298+
defer teardown()
299+
300+
mux.HandleFunc("/orgs/o/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", "per_page": "1", "before": "deadbeefb", "after": "deadbeefa"})
303+
fmt.Fprint(w, `[{
304+
"repository": {
305+
"id": 1,
306+
"name": "n",
307+
"url": "url"
308+
},
309+
"rule_id":"js/trivial-conditional",
310+
"rule_severity":"warning",
311+
"rule_description":"Useless conditional",
312+
"tool": {
313+
"name": "CodeQL",
314+
"guid": null,
315+
"version": "1.4.0"
316+
},
317+
"rule": {
318+
"id": "js/trivial-conditional",
319+
"severity": "warning",
320+
"description": "Useless conditional",
321+
"name": "js/trivial-conditional",
322+
"full_description": "Expression has no effect",
323+
"help": "Expression has no effect"
324+
},
325+
"most_recent_instance": {
326+
"ref": "refs/heads/main",
327+
"state": "open",
328+
"commit_sha": "abcdefg12345",
329+
"message": {
330+
"text": "This path depends on a user-provided value."
331+
},
332+
"location": {
333+
"path": "spec-main/api-session-spec.ts",
334+
"start_line": 917,
335+
"end_line": 917,
336+
"start_column": 7,
337+
"end_column": 18
338+
},
339+
"classifications": [
340+
"test"
341+
]
342+
},
343+
"created_at":"2020-05-06T12:00:00Z",
344+
"state":"open",
345+
"closed_by":null,
346+
"closed_at":null,
347+
"url":"https://api.github.com/repos/o/r/code-scanning/alerts/25",
348+
"html_url":"https://github.com/o/r/security/code-scanning/25"
349+
}]`)
350+
})
351+
352+
opts := &AlertListOptions{State: "open", Ref: "heads/master", ListCursorOptions: ListCursorOptions{PerPage: 1, Before: "deadbeefb", After: "deadbeefa"}}
353+
ctx := context.Background()
354+
alerts, _, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts)
355+
if err != nil {
356+
t.Errorf("CodeScanning.ListAlertsForOrg returned error: %v", err)
357+
}
358+
359+
date := Timestamp{time.Date(2020, time.May, 06, 12, 00, 00, 0, time.UTC)}
360+
want := []*Alert{
361+
{
362+
Repository: &Repository{
363+
ID: Int64(1),
364+
URL: String("url"),
365+
Name: String("n"),
366+
},
367+
RuleID: String("js/trivial-conditional"),
368+
RuleSeverity: String("warning"),
369+
RuleDescription: String("Useless conditional"),
370+
Tool: &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
371+
Rule: &Rule{
372+
ID: String("js/trivial-conditional"),
373+
Severity: String("warning"),
374+
Description: String("Useless conditional"),
375+
Name: String("js/trivial-conditional"),
376+
FullDescription: String("Expression has no effect"),
377+
Help: String("Expression has no effect"),
378+
},
379+
CreatedAt: &date,
380+
State: String("open"),
381+
ClosedBy: nil,
382+
ClosedAt: nil,
383+
URL: String("https://api.github.com/repos/o/r/code-scanning/alerts/25"),
384+
HTMLURL: String("https://github.com/o/r/security/code-scanning/25"),
385+
MostRecentInstance: &MostRecentInstance{
386+
Ref: String("refs/heads/main"),
387+
State: String("open"),
388+
CommitSHA: String("abcdefg12345"),
389+
Message: &Message{
390+
Text: String("This path depends on a user-provided value."),
391+
},
392+
Location: &Location{
393+
Path: String("spec-main/api-session-spec.ts"),
394+
StartLine: Int(917),
395+
EndLine: Int(917),
396+
StartColumn: Int(7),
397+
EndColumn: Int(18),
398+
},
399+
Classifications: []string{"test"},
400+
},
401+
},
402+
}
403+
if !cmp.Equal(alerts, want) {
404+
t.Errorf("CodeScanning.ListAlertsForOrg returned %+v, want %+v", *&alerts, *&want)
405+
}
406+
407+
const methodName = "ListAlertsForOrg"
408+
testBadOptions(t, methodName, func() (err error) {
409+
_, _, err = client.CodeScanning.ListAlertsForOrg(ctx, "\n", opts)
410+
return err
411+
})
412+
413+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
414+
got, resp, err := client.CodeScanning.ListAlertsForOrg(ctx, "o", opts)
415+
if got != nil {
416+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
417+
}
418+
return resp, err
419+
})
420+
}
421+
296422
func TestCodeScanningService_ListAlertsForRepo(t *testing.T) {
297423
client, mux, _, teardown := setup()
298424
defer teardown()

0 commit comments

Comments
 (0)