diff --git a/github/secret_scanning.go b/github/secret_scanning.go index ec64950a67..d512560d9f 100644 --- a/github/secret_scanning.go +++ b/github/secret_scanning.go @@ -61,6 +61,14 @@ type SecretScanningAlertListOptions struct { Resolution string `url:"resolution,omitempty"` ListCursorOptions + + // List options can vary on the Enterprise type. + // On Enterprise Cloud, Secret Scan alerts support requesting by page number + // along with providing a cursor for an "after" param. + // See: https://docs.github.com/en/enterprise-cloud@latest/rest/secret-scanning#list-secret-scanning-alerts-for-an-organization + // Whereas on Enterprise Server, pagination is by index. + // See: https://docs.github.com/en/enterprise-server@3.6/rest/secret-scanning#list-secret-scanning-alerts-for-an-organization + ListOptions } // SecretScanningAlertUpdateOptions specifies optional parameters to the SecretScanningService.UpdateAlert method. diff --git a/github/secret_scanning_test.go b/github/secret_scanning_test.go index afe6144e7c..af70fc8087 100644 --- a/github/secret_scanning_test.go +++ b/github/secret_scanning_test.go @@ -146,6 +146,73 @@ func TestSecretScanningService_ListAlertsForOrg(t *testing.T) { }) } +func TestSecretScanningService_ListAlertsForOrgListOptions(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/secret-scanning/alerts", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"state": "open", "secret_type": "mailchimp_api_key", "per_page": "1", "page": "1"}) + + fmt.Fprint(w, `[{ + "number": 1, + "created_at": "1996-06-20T00:00:00Z", + "url": "https://api.github.com/repos/o/r/secret-scanning/alerts/1", + "html_url": "https://github.com/o/r/security/secret-scanning/1", + "locations_url": "https://api.github.com/repos/o/r/secret-scanning/alerts/1/locations", + "state": "open", + "resolution": null, + "resolved_at": null, + "resolved_by": null, + "secret_type": "mailchimp_api_key", + "secret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us2" + }]`) + }) + + ctx := context.Background() + + // Testing pagination by index + opts := &SecretScanningAlertListOptions{State: "open", SecretType: "mailchimp_api_key", ListOptions: ListOptions{Page: 1, PerPage: 1}} + + alerts, _, err := client.SecretScanning.ListAlertsForOrg(ctx, "o", opts) + if err != nil { + t.Errorf("SecretScanning.ListAlertsForOrg returned error: %v", err) + } + + date := Timestamp{time.Date(1996, time.June, 20, 00, 00, 00, 0, time.UTC)} + want := []*SecretScanningAlert{ + { + Number: Int(1), + CreatedAt: &date, + URL: String("https://api.github.com/repos/o/r/secret-scanning/alerts/1"), + HTMLURL: String("https://github.com/o/r/security/secret-scanning/1"), + LocationsURL: String("https://api.github.com/repos/o/r/secret-scanning/alerts/1/locations"), + State: String("open"), + Resolution: nil, + ResolvedAt: nil, + ResolvedBy: nil, + SecretType: String("mailchimp_api_key"), + Secret: String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us2"), + }, + } + + if !cmp.Equal(alerts, want) { + t.Errorf("SecretScanning.ListAlertsForOrg returned %+v, want %+v", alerts, want) + } + + const methodName = "ListAlertsForOrg" + + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.SecretScanning.ListAlertsForOrg(ctx, "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.SecretScanning.ListAlertsForOrg(ctx, "o", opts) + return resp, err + }) +} + func TestSecretScanningService_ListAlertsForRepo(t *testing.T) { client, mux, _, teardown := setup() defer teardown()