github.com/google/go-github/v69@v69.2.0/github/security_advisories_test.go (about) 1 // Copyright 2023 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 "fmt" 11 "net/http" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestSecurityAdvisoriesService_RequestCVE(t *testing.T) { 20 t.Parallel() 21 client, mux, _ := setup(t) 22 23 mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id_ok/cve", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "POST") 25 w.WriteHeader(http.StatusOK) 26 }) 27 28 mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id_accepted/cve", func(w http.ResponseWriter, r *http.Request) { 29 testMethod(t, r, "POST") 30 w.WriteHeader(http.StatusAccepted) 31 }) 32 33 ctx := context.Background() 34 _, err := client.SecurityAdvisories.RequestCVE(ctx, "o", "r", "ghsa_id_ok") 35 if err != nil { 36 t.Errorf("SecurityAdvisoriesService.RequestCVE returned error: %v", err) 37 } 38 39 _, err = client.SecurityAdvisories.RequestCVE(ctx, "o", "r", "ghsa_id_accepted") 40 if err != nil { 41 t.Errorf("SecurityAdvisoriesService.RequestCVE returned error: %v", err) 42 } 43 44 const methodName = "RequestCVE" 45 testBadOptions(t, methodName, func() (err error) { 46 _, err = client.SecurityAdvisories.RequestCVE(ctx, "\n", "\n", "\n") 47 return err 48 }) 49 50 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 51 resp, err := client.SecurityAdvisories.RequestCVE(ctx, "o", "r", "ghsa_id") 52 if err == nil { 53 t.Errorf("testNewRequestAndDoFailure %v should have return err", methodName) 54 } 55 return resp, err 56 }) 57 } 58 59 func TestSecurityAdvisoriesService_CreateTemporaryPrivateFork(t *testing.T) { 60 t.Parallel() 61 client, mux, _ := setup(t) 62 63 mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id/forks", func(w http.ResponseWriter, r *http.Request) { 64 testMethod(t, r, "POST") 65 fmt.Fprint(w, `{ 66 "id": 1, 67 "node_id": "R_kgDPP3c6pQ", 68 "owner": { 69 "login": "owner", 70 "id": 2, 71 "node_id": "MDQ6VXFGcjYyMjcyMTQw", 72 "avatar_url": "https://avatars.githubusercontent.com/u/111111?v=4", 73 "html_url": "https://github.com/xxxxx", 74 "gravatar_id": "", 75 "type": "User", 76 "site_admin": false, 77 "url": "https://api.github.com/users/owner", 78 "events_url": "https://api.github.com/users/owner/events{/privacy}", 79 "following_url": "https://api.github.com/users/owner/following{/other_user}", 80 "followers_url": "https://api.github.com/users/owner/followers", 81 "gists_url": "https://api.github.com/users/owner/gists{/gist_id}", 82 "organizations_url": "https://api.github.com/users/owner/orgs", 83 "received_events_url": "https://api.github.com/users/owner/received_events", 84 "repos_url": "https://api.github.com/users/owner/repos", 85 "starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}", 86 "subscriptions_url": "https://api.github.com/users/owner/subscriptions" 87 }, 88 "name": "repo-ghsa-xxxx-xxxx-xxxx", 89 "full_name": "owner/repo-ghsa-xxxx-xxxx-xxxx", 90 "default_branch": "master", 91 "created_at": "2023-12-08T17:22:41Z", 92 "pushed_at": "2023-12-03T11:27:08Z", 93 "updated_at": "2023-12-08T17:22:42Z", 94 "html_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", 95 "clone_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", 96 "git_url": "git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", 97 "ssh_url": "git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git", 98 "svn_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", 99 "fork": false, 100 "forks_count": 0, 101 "network_count": 0, 102 "open_issues_count": 0, 103 "open_issues": 0, 104 "stargazers_count": 0, 105 "subscribers_count": 0, 106 "watchers_count": 0, 107 "watchers": 0, 108 "size": 0, 109 "permissions": { 110 "admin": true, 111 "maintain": true, 112 "pull": true, 113 "push": true, 114 "triage": true 115 }, 116 "allow_forking": true, 117 "web_commit_signoff_required": false, 118 "archived": false, 119 "disabled": false, 120 "private": true, 121 "has_issues": false, 122 "has_wiki": false, 123 "has_pages": false, 124 "has_projects": false, 125 "has_downloads": false, 126 "has_discussions": false, 127 "is_template": false, 128 "url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx", 129 "archive_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}", 130 "assignees_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}", 131 "blobs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}", 132 "branches_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}", 133 "collaborators_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}", 134 "comments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}", 135 "commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}", 136 "compare_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}", 137 "contents_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}", 138 "contributors_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors", 139 "deployments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments", 140 "downloads_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads", 141 "events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events", 142 "forks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks", 143 "git_commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}", 144 "git_refs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}", 145 "git_tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}", 146 "hooks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks", 147 "issue_comment_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}", 148 "issue_events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}", 149 "issues_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}", 150 "keys_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}", 151 "labels_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}", 152 "languages_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages", 153 "merges_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges", 154 "milestones_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}", 155 "notifications_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}", 156 "pulls_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}", 157 "releases_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}", 158 "stargazers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers", 159 "statuses_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}", 160 "subscribers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers", 161 "subscription_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription", 162 "tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags", 163 "teams_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams", 164 "visibility": "private" 165 }`) 166 }) 167 168 ctx := context.Background() 169 fork, _, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "o", "r", "ghsa_id") 170 if err != nil { 171 t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned error: %v", err) 172 } 173 174 want := &Repository{ 175 ID: Ptr(int64(1)), 176 NodeID: Ptr("R_kgDPP3c6pQ"), 177 Owner: &User{ 178 Login: Ptr("owner"), 179 ID: Ptr(int64(2)), 180 NodeID: Ptr("MDQ6VXFGcjYyMjcyMTQw"), 181 AvatarURL: Ptr("https://avatars.githubusercontent.com/u/111111?v=4"), 182 HTMLURL: Ptr("https://github.com/xxxxx"), 183 GravatarID: Ptr(""), 184 Type: Ptr("User"), 185 SiteAdmin: Ptr(false), 186 URL: Ptr("https://api.github.com/users/owner"), 187 EventsURL: Ptr("https://api.github.com/users/owner/events{/privacy}"), 188 FollowingURL: Ptr("https://api.github.com/users/owner/following{/other_user}"), 189 FollowersURL: Ptr("https://api.github.com/users/owner/followers"), 190 GistsURL: Ptr("https://api.github.com/users/owner/gists{/gist_id}"), 191 OrganizationsURL: Ptr("https://api.github.com/users/owner/orgs"), 192 ReceivedEventsURL: Ptr("https://api.github.com/users/owner/received_events"), 193 ReposURL: Ptr("https://api.github.com/users/owner/repos"), 194 StarredURL: Ptr("https://api.github.com/users/owner/starred{/owner}{/repo}"), 195 SubscriptionsURL: Ptr("https://api.github.com/users/owner/subscriptions"), 196 }, 197 Name: Ptr("repo-ghsa-xxxx-xxxx-xxxx"), 198 FullName: Ptr("owner/repo-ghsa-xxxx-xxxx-xxxx"), 199 DefaultBranch: Ptr("master"), 200 CreatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 41, 0, time.UTC)}, 201 PushedAt: &Timestamp{time.Date(2023, time.December, 3, 11, 27, 8, 0, time.UTC)}, 202 UpdatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 42, 0, time.UTC)}, 203 HTMLURL: Ptr("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 204 CloneURL: Ptr("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 205 GitURL: Ptr("git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 206 SSHURL: Ptr("git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 207 SVNURL: Ptr("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 208 Fork: Ptr(false), 209 ForksCount: Ptr(0), 210 NetworkCount: Ptr(0), 211 OpenIssuesCount: Ptr(0), 212 OpenIssues: Ptr(0), 213 StargazersCount: Ptr(0), 214 SubscribersCount: Ptr(0), 215 WatchersCount: Ptr(0), 216 Watchers: Ptr(0), 217 Size: Ptr(0), 218 Permissions: map[string]bool{ 219 "admin": true, 220 "maintain": true, 221 "pull": true, 222 "push": true, 223 "triage": true, 224 }, 225 AllowForking: Ptr(true), 226 WebCommitSignoffRequired: Ptr(false), 227 Archived: Ptr(false), 228 Disabled: Ptr(false), 229 Private: Ptr(true), 230 HasIssues: Ptr(false), 231 HasWiki: Ptr(false), 232 HasPages: Ptr(false), 233 HasProjects: Ptr(false), 234 HasDownloads: Ptr(false), 235 HasDiscussions: Ptr(false), 236 IsTemplate: Ptr(false), 237 URL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx"), 238 ArchiveURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}"), 239 AssigneesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}"), 240 BlobsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}"), 241 BranchesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}"), 242 CollaboratorsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}"), 243 CommentsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}"), 244 CommitsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}"), 245 CompareURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}"), 246 ContentsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}"), 247 ContributorsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors"), 248 DeploymentsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments"), 249 DownloadsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads"), 250 EventsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events"), 251 ForksURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks"), 252 GitCommitsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}"), 253 GitRefsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}"), 254 GitTagsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}"), 255 HooksURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks"), 256 IssueCommentURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}"), 257 IssueEventsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}"), 258 IssuesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}"), 259 KeysURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}"), 260 LabelsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}"), 261 LanguagesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages"), 262 MergesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges"), 263 MilestonesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}"), 264 NotificationsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}"), 265 PullsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}"), 266 ReleasesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}"), 267 StargazersURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers"), 268 StatusesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}"), 269 SubscribersURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers"), 270 SubscriptionURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription"), 271 TagsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags"), 272 TeamsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams"), 273 Visibility: Ptr("private"), 274 } 275 if !cmp.Equal(fork, want) { 276 t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned %+v, want %+v", fork, want) 277 } 278 279 const methodName = "CreateTemporaryPrivateFork" 280 testBadOptions(t, methodName, func() (err error) { 281 _, _, err = client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "\n", "\n", "\n") 282 return err 283 }) 284 285 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 286 got, resp, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "o", "r", "ghsa_id") 287 if got != nil { 288 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 289 } 290 return resp, err 291 }) 292 } 293 294 func TestSecurityAdvisoriesService_CreateTemporaryPrivateFork_deferred(t *testing.T) { 295 t.Parallel() 296 client, mux, _ := setup(t) 297 298 mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id/forks", func(w http.ResponseWriter, r *http.Request) { 299 testMethod(t, r, "POST") 300 w.WriteHeader(http.StatusAccepted) 301 fmt.Fprint(w, `{ 302 "id": 1, 303 "node_id": "R_kgDPP3c6pQ", 304 "owner": { 305 "login": "owner", 306 "id": 2, 307 "node_id": "MDQ6VXFGcjYyMjcyMTQw", 308 "avatar_url": "https://avatars.githubusercontent.com/u/111111?v=4", 309 "html_url": "https://github.com/xxxxx", 310 "gravatar_id": "", 311 "type": "User", 312 "site_admin": false, 313 "url": "https://api.github.com/users/owner", 314 "events_url": "https://api.github.com/users/owner/events{/privacy}", 315 "following_url": "https://api.github.com/users/owner/following{/other_user}", 316 "followers_url": "https://api.github.com/users/owner/followers", 317 "gists_url": "https://api.github.com/users/owner/gists{/gist_id}", 318 "organizations_url": "https://api.github.com/users/owner/orgs", 319 "received_events_url": "https://api.github.com/users/owner/received_events", 320 "repos_url": "https://api.github.com/users/owner/repos", 321 "starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}", 322 "subscriptions_url": "https://api.github.com/users/owner/subscriptions" 323 }, 324 "name": "repo-ghsa-xxxx-xxxx-xxxx", 325 "full_name": "owner/repo-ghsa-xxxx-xxxx-xxxx", 326 "default_branch": "master", 327 "created_at": "2023-12-08T17:22:41Z", 328 "pushed_at": "2023-12-03T11:27:08Z", 329 "updated_at": "2023-12-08T17:22:42Z", 330 "html_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", 331 "clone_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", 332 "git_url": "git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", 333 "ssh_url": "git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git", 334 "svn_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", 335 "fork": false, 336 "forks_count": 0, 337 "network_count": 0, 338 "open_issues_count": 0, 339 "open_issues": 0, 340 "stargazers_count": 0, 341 "subscribers_count": 0, 342 "watchers_count": 0, 343 "watchers": 0, 344 "size": 0, 345 "permissions": { 346 "admin": true, 347 "maintain": true, 348 "pull": true, 349 "push": true, 350 "triage": true 351 }, 352 "allow_forking": true, 353 "web_commit_signoff_required": false, 354 "archived": false, 355 "disabled": false, 356 "private": true, 357 "has_issues": false, 358 "has_wiki": false, 359 "has_pages": false, 360 "has_projects": false, 361 "has_downloads": false, 362 "has_discussions": false, 363 "is_template": false, 364 "url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx", 365 "archive_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}", 366 "assignees_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}", 367 "blobs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}", 368 "branches_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}", 369 "collaborators_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}", 370 "comments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}", 371 "commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}", 372 "compare_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}", 373 "contents_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}", 374 "contributors_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors", 375 "deployments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments", 376 "downloads_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads", 377 "events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events", 378 "forks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks", 379 "git_commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}", 380 "git_refs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}", 381 "git_tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}", 382 "hooks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks", 383 "issue_comment_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}", 384 "issue_events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}", 385 "issues_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}", 386 "keys_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}", 387 "labels_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}", 388 "languages_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages", 389 "merges_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges", 390 "milestones_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}", 391 "notifications_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}", 392 "pulls_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}", 393 "releases_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}", 394 "stargazers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers", 395 "statuses_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}", 396 "subscribers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers", 397 "subscription_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription", 398 "tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags", 399 "teams_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams", 400 "visibility": "private" 401 }`) 402 }) 403 404 ctx := context.Background() 405 fork, _, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "o", "r", "ghsa_id") 406 if _, ok := err.(*AcceptedError); !ok { 407 t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned error: %v (want AcceptedError)", err) 408 } 409 410 want := &Repository{ 411 ID: Ptr(int64(1)), 412 NodeID: Ptr("R_kgDPP3c6pQ"), 413 Owner: &User{ 414 Login: Ptr("owner"), 415 ID: Ptr(int64(2)), 416 NodeID: Ptr("MDQ6VXFGcjYyMjcyMTQw"), 417 AvatarURL: Ptr("https://avatars.githubusercontent.com/u/111111?v=4"), 418 HTMLURL: Ptr("https://github.com/xxxxx"), 419 GravatarID: Ptr(""), 420 Type: Ptr("User"), 421 SiteAdmin: Ptr(false), 422 URL: Ptr("https://api.github.com/users/owner"), 423 EventsURL: Ptr("https://api.github.com/users/owner/events{/privacy}"), 424 FollowingURL: Ptr("https://api.github.com/users/owner/following{/other_user}"), 425 FollowersURL: Ptr("https://api.github.com/users/owner/followers"), 426 GistsURL: Ptr("https://api.github.com/users/owner/gists{/gist_id}"), 427 OrganizationsURL: Ptr("https://api.github.com/users/owner/orgs"), 428 ReceivedEventsURL: Ptr("https://api.github.com/users/owner/received_events"), 429 ReposURL: Ptr("https://api.github.com/users/owner/repos"), 430 StarredURL: Ptr("https://api.github.com/users/owner/starred{/owner}{/repo}"), 431 SubscriptionsURL: Ptr("https://api.github.com/users/owner/subscriptions"), 432 }, 433 Name: Ptr("repo-ghsa-xxxx-xxxx-xxxx"), 434 FullName: Ptr("owner/repo-ghsa-xxxx-xxxx-xxxx"), 435 DefaultBranch: Ptr("master"), 436 CreatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 41, 0, time.UTC)}, 437 PushedAt: &Timestamp{time.Date(2023, time.December, 3, 11, 27, 8, 0, time.UTC)}, 438 UpdatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 42, 0, time.UTC)}, 439 HTMLURL: Ptr("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 440 CloneURL: Ptr("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 441 GitURL: Ptr("git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 442 SSHURL: Ptr("git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 443 SVNURL: Ptr("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 444 Fork: Ptr(false), 445 ForksCount: Ptr(0), 446 NetworkCount: Ptr(0), 447 OpenIssuesCount: Ptr(0), 448 OpenIssues: Ptr(0), 449 StargazersCount: Ptr(0), 450 SubscribersCount: Ptr(0), 451 WatchersCount: Ptr(0), 452 Watchers: Ptr(0), 453 Size: Ptr(0), 454 Permissions: map[string]bool{ 455 "admin": true, 456 "maintain": true, 457 "pull": true, 458 "push": true, 459 "triage": true, 460 }, 461 AllowForking: Ptr(true), 462 WebCommitSignoffRequired: Ptr(false), 463 Archived: Ptr(false), 464 Disabled: Ptr(false), 465 Private: Ptr(true), 466 HasIssues: Ptr(false), 467 HasWiki: Ptr(false), 468 HasPages: Ptr(false), 469 HasProjects: Ptr(false), 470 HasDownloads: Ptr(false), 471 HasDiscussions: Ptr(false), 472 IsTemplate: Ptr(false), 473 URL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx"), 474 ArchiveURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}"), 475 AssigneesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}"), 476 BlobsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}"), 477 BranchesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}"), 478 CollaboratorsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}"), 479 CommentsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}"), 480 CommitsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}"), 481 CompareURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}"), 482 ContentsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}"), 483 ContributorsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors"), 484 DeploymentsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments"), 485 DownloadsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads"), 486 EventsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events"), 487 ForksURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks"), 488 GitCommitsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}"), 489 GitRefsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}"), 490 GitTagsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}"), 491 HooksURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks"), 492 IssueCommentURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}"), 493 IssueEventsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}"), 494 IssuesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}"), 495 KeysURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}"), 496 LabelsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}"), 497 LanguagesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages"), 498 MergesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges"), 499 MilestonesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}"), 500 NotificationsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}"), 501 PullsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}"), 502 ReleasesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}"), 503 StargazersURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers"), 504 StatusesURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}"), 505 SubscribersURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers"), 506 SubscriptionURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription"), 507 TagsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags"), 508 TeamsURL: Ptr("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams"), 509 Visibility: Ptr("private"), 510 } 511 if !cmp.Equal(fork, want) { 512 t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned %+v, want %+v", fork, want) 513 } 514 } 515 516 func TestSecurityAdvisoriesService_CreateTemporaryPrivateFork_invalidOwner(t *testing.T) { 517 t.Parallel() 518 client, _, _ := setup(t) 519 520 ctx := context.Background() 521 _, _, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "%", "r", "ghsa_id") 522 testURLParseError(t, err) 523 } 524 525 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_BadRequest(t *testing.T) { 526 t.Parallel() 527 client, mux, _ := setup(t) 528 529 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 530 testMethod(t, r, "GET") 531 532 http.Error(w, "Bad Request", 400) 533 }) 534 535 ctx := context.Background() 536 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 537 if err == nil { 538 t.Errorf("Expected HTTP 400 response") 539 } 540 if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want { 541 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 542 } 543 if advisories != nil { 544 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return %+v, want nil", advisories) 545 } 546 } 547 548 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_NotFound(t *testing.T) { 549 t.Parallel() 550 client, mux, _ := setup(t) 551 552 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 553 testMethod(t, r, "GET") 554 555 query := r.URL.Query() 556 if query.Get("state") != "draft" { 557 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned %+v, want %+v", query.Get("state"), "draft") 558 } 559 560 http.NotFound(w, r) 561 }) 562 563 ctx := context.Background() 564 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", &ListRepositorySecurityAdvisoriesOptions{ 565 State: "draft", 566 }) 567 if err == nil { 568 t.Errorf("Expected HTTP 404 response") 569 } 570 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 571 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 572 } 573 if advisories != nil { 574 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return %+v, want nil", advisories) 575 } 576 } 577 578 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_UnmarshalError(t *testing.T) { 579 t.Parallel() 580 client, mux, _ := setup(t) 581 582 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 583 testMethod(t, r, "GET") 584 585 w.WriteHeader(http.StatusOK) 586 assertWrite(t, w, []byte(`[{"ghsa_id": 12334354}]`)) 587 }) 588 589 ctx := context.Background() 590 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 591 if err == nil { 592 t.Errorf("Expected unmarshal error") 593 } else if !strings.Contains(err.Error(), "json: cannot unmarshal number into Go struct field SecurityAdvisory.ghsa_id of type string") { 594 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned unexpected error: %v", err) 595 } 596 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 597 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 598 } 599 if advisories != nil { 600 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return %+v, want nil", advisories) 601 } 602 } 603 604 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg(t *testing.T) { 605 t.Parallel() 606 client, mux, _ := setup(t) 607 608 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 609 testMethod(t, r, "GET") 610 611 w.WriteHeader(http.StatusOK) 612 assertWrite(t, w, []byte(`[ 613 { 614 "ghsa_id": "GHSA-abcd-1234-efgh", 615 "cve_id": "CVE-2050-00000" 616 } 617 ]`)) 618 }) 619 620 ctx := context.Background() 621 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 622 if err != nil { 623 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned error: %v, want nil", err) 624 } 625 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 626 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 627 } 628 629 want := []*SecurityAdvisory{ 630 { 631 GHSAID: Ptr("GHSA-abcd-1234-efgh"), 632 CVEID: Ptr("CVE-2050-00000"), 633 }, 634 } 635 if !cmp.Equal(advisories, want) { 636 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned %+v, want %+v", advisories, want) 637 } 638 639 methodName := "ListRepositorySecurityAdvisoriesForOrg" 640 testBadOptions(t, methodName, func() (err error) { 641 _, _, err = client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "\n", &ListRepositorySecurityAdvisoriesOptions{ 642 Sort: "\n", 643 }) 644 return err 645 }) 646 647 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 648 got, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 649 if got != nil { 650 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 651 } 652 return resp, err 653 }) 654 } 655 656 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_BadRequest(t *testing.T) { 657 t.Parallel() 658 client, mux, _ := setup(t) 659 660 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 661 testMethod(t, r, "GET") 662 663 http.Error(w, "Bad Request", 400) 664 }) 665 666 ctx := context.Background() 667 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 668 if err == nil { 669 t.Errorf("Expected HTTP 400 response") 670 } 671 if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want { 672 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 673 } 674 if advisories != nil { 675 t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories) 676 } 677 } 678 679 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_NotFound(t *testing.T) { 680 t.Parallel() 681 client, mux, _ := setup(t) 682 683 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 684 testMethod(t, r, "GET") 685 686 query := r.URL.Query() 687 if query.Get("state") != "draft" { 688 t.Errorf("ListRepositorySecurityAdvisories returned %+v, want %+v", query.Get("state"), "draft") 689 } 690 691 http.NotFound(w, r) 692 }) 693 694 ctx := context.Background() 695 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", &ListRepositorySecurityAdvisoriesOptions{ 696 State: "draft", 697 }) 698 if err == nil { 699 t.Errorf("Expected HTTP 404 response") 700 } 701 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 702 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 703 } 704 if advisories != nil { 705 t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories) 706 } 707 } 708 709 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_UnmarshalError(t *testing.T) { 710 t.Parallel() 711 client, mux, _ := setup(t) 712 713 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 714 testMethod(t, r, "GET") 715 716 w.WriteHeader(http.StatusOK) 717 assertWrite(t, w, []byte(`[{"ghsa_id": 12334354}]`)) 718 }) 719 720 ctx := context.Background() 721 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 722 if err == nil { 723 t.Errorf("Expected unmarshal error") 724 } else if !strings.Contains(err.Error(), "json: cannot unmarshal number into Go struct field SecurityAdvisory.ghsa_id of type string") { 725 t.Errorf("ListRepositorySecurityAdvisories returned unexpected error: %v", err) 726 } 727 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 728 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 729 } 730 if advisories != nil { 731 t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories) 732 } 733 } 734 735 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories(t *testing.T) { 736 t.Parallel() 737 client, mux, _ := setup(t) 738 739 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 740 testMethod(t, r, "GET") 741 742 w.WriteHeader(http.StatusOK) 743 assertWrite(t, w, []byte(`[ 744 { 745 "ghsa_id": "GHSA-abcd-1234-efgh", 746 "cve_id": "CVE-2050-00000" 747 } 748 ]`)) 749 }) 750 751 ctx := context.Background() 752 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 753 if err != nil { 754 t.Errorf("ListRepositorySecurityAdvisories returned error: %v, want nil", err) 755 } 756 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 757 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 758 } 759 760 want := []*SecurityAdvisory{ 761 { 762 GHSAID: Ptr("GHSA-abcd-1234-efgh"), 763 CVEID: Ptr("CVE-2050-00000"), 764 }, 765 } 766 if !cmp.Equal(advisories, want) { 767 t.Errorf("ListRepositorySecurityAdvisories returned %+v, want %+v", advisories, want) 768 } 769 770 methodName := "ListRepositorySecurityAdvisories" 771 testBadOptions(t, methodName, func() (err error) { 772 _, _, err = client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "\n", "\n", &ListRepositorySecurityAdvisoriesOptions{ 773 Sort: "\n", 774 }) 775 return err 776 }) 777 778 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 779 got, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 780 if got != nil { 781 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 782 } 783 return resp, err 784 }) 785 } 786 787 func TestListGlobalSecurityAdvisories(t *testing.T) { 788 t.Parallel() 789 client, mux, _ := setup(t) 790 791 mux.HandleFunc("/advisories", func(w http.ResponseWriter, r *http.Request) { 792 testMethod(t, r, "GET") 793 testFormValues(t, r, values{"cve_id": "CVE-xoxo-1234"}) 794 795 fmt.Fprint(w, `[{ 796 "id": 1, 797 "ghsa_id": "GHSA-xoxo-1234-xoxo", 798 "cve_id": "CVE-xoxo-1234", 799 "url": "https://api.github.com/advisories/GHSA-xoxo-1234-xoxo", 800 "html_url": "https://github.com/advisories/GHSA-xoxo-1234-xoxo", 801 "repository_advisory_url": "https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo", 802 "summary": "Heartbleed security advisory", 803 "description": "This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information.", 804 "type": "reviewed", 805 "severity": "high", 806 "source_code_location": "https://github.com/project/a-package", 807 "identifiers": [ 808 { 809 "type": "GHSA", 810 "value": "GHSA-xoxo-1234-xoxo" 811 }, 812 { 813 "type": "CVE", 814 "value": "CVE-xoxo-1234" 815 } 816 ], 817 "references": ["https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"], 818 "published_at": "1996-06-20T00:00:00Z", 819 "updated_at": "1996-06-20T00:00:00Z", 820 "github_reviewed_at": "1996-06-20T00:00:00Z", 821 "nvd_published_at": "1996-06-20T00:00:00Z", 822 "withdrawn_at": null, 823 "vulnerabilities": [ 824 { 825 "package": { 826 "ecosystem": "npm", 827 "name": "a-package" 828 }, 829 "first_patched_version": "1.0.3", 830 "vulnerable_version_range": "<=1.0.2", 831 "vulnerable_functions": ["a_function"] 832 } 833 ], 834 "cvss": { 835 "vector_string": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H", 836 "score": 7.6 837 }, 838 "cwes": [ 839 { 840 "cwe_id": "CWE-400", 841 "name": "Uncontrolled Resource Consumption" 842 } 843 ], 844 "credits": [ 845 { 846 "user": { 847 "login": "user", 848 "id": 1, 849 "node_id": "12=", 850 "avatar_url": "a", 851 "gravatar_id": "", 852 "url": "a", 853 "html_url": "b", 854 "followers_url": "b", 855 "following_url": "c", 856 "gists_url": "d", 857 "starred_url": "e", 858 "subscriptions_url": "f", 859 "organizations_url": "g", 860 "repos_url": "h", 861 "events_url": "i", 862 "received_events_url": "j", 863 "type": "User", 864 "site_admin": false 865 }, 866 "type": "analyst" 867 } 868 ] 869 } 870 ]`) 871 }) 872 873 ctx := context.Background() 874 opts := &ListGlobalSecurityAdvisoriesOptions{CVEID: Ptr("CVE-xoxo-1234")} 875 876 advisories, _, err := client.SecurityAdvisories.ListGlobalSecurityAdvisories(ctx, opts) 877 if err != nil { 878 t.Errorf("SecurityAdvisories.ListGlobalSecurityAdvisories returned error: %v", err) 879 } 880 881 date := Timestamp{time.Date(1996, time.June, 20, 00, 00, 00, 0, time.UTC)} 882 want := []*GlobalSecurityAdvisory{ 883 { 884 ID: Ptr(int64(1)), 885 SecurityAdvisory: SecurityAdvisory{ 886 GHSAID: Ptr("GHSA-xoxo-1234-xoxo"), 887 CVEID: Ptr("CVE-xoxo-1234"), 888 URL: Ptr("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 889 HTMLURL: Ptr("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 890 Severity: Ptr("high"), 891 Summary: Ptr("Heartbleed security advisory"), 892 Description: Ptr("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 893 Identifiers: []*AdvisoryIdentifier{ 894 { 895 Type: Ptr("GHSA"), 896 Value: Ptr("GHSA-xoxo-1234-xoxo"), 897 }, 898 { 899 Type: Ptr("CVE"), 900 Value: Ptr("CVE-xoxo-1234"), 901 }, 902 }, 903 PublishedAt: &date, 904 UpdatedAt: &date, 905 WithdrawnAt: nil, 906 CVSS: &AdvisoryCVSS{ 907 VectorString: Ptr("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 908 Score: Ptr(7.6), 909 }, 910 CWEs: []*AdvisoryCWEs{ 911 { 912 CWEID: Ptr("CWE-400"), 913 Name: Ptr("Uncontrolled Resource Consumption"), 914 }, 915 }, 916 }, 917 References: []string{"https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"}, 918 Vulnerabilities: []*GlobalSecurityVulnerability{ 919 { 920 Package: &VulnerabilityPackage{ 921 Ecosystem: Ptr("npm"), 922 Name: Ptr("a-package"), 923 }, 924 FirstPatchedVersion: Ptr("1.0.3"), 925 VulnerableVersionRange: Ptr("<=1.0.2"), 926 VulnerableFunctions: []string{"a_function"}, 927 }, 928 }, 929 RepositoryAdvisoryURL: Ptr("https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo"), 930 Type: Ptr("reviewed"), 931 SourceCodeLocation: Ptr("https://github.com/project/a-package"), 932 GithubReviewedAt: &date, 933 NVDPublishedAt: &date, 934 Credits: []*Credit{ 935 { 936 User: &User{ 937 Login: Ptr("user"), 938 ID: Ptr(int64(1)), 939 NodeID: Ptr("12="), 940 AvatarURL: Ptr("a"), 941 GravatarID: Ptr(""), 942 URL: Ptr("a"), 943 HTMLURL: Ptr("b"), 944 FollowersURL: Ptr("b"), 945 FollowingURL: Ptr("c"), 946 GistsURL: Ptr("d"), 947 StarredURL: Ptr("e"), 948 SubscriptionsURL: Ptr("f"), 949 OrganizationsURL: Ptr("g"), 950 ReposURL: Ptr("h"), 951 EventsURL: Ptr("i"), 952 ReceivedEventsURL: Ptr("j"), 953 Type: Ptr("User"), 954 SiteAdmin: Ptr(false), 955 }, 956 Type: Ptr("analyst"), 957 }, 958 }, 959 }, 960 } 961 962 if !cmp.Equal(advisories, want) { 963 t.Errorf("SecurityAdvisories.ListGlobalSecurityAdvisories %+v, want %+v", advisories, want) 964 } 965 966 const methodName = "ListGlobalSecurityAdvisories" 967 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 968 _, resp, err := client.SecurityAdvisories.ListGlobalSecurityAdvisories(ctx, nil) 969 return resp, err 970 }) 971 } 972 973 func TestGetGlobalSecurityAdvisories(t *testing.T) { 974 t.Parallel() 975 client, mux, _ := setup(t) 976 977 mux.HandleFunc("/advisories/GHSA-xoxo-1234-xoxo", func(w http.ResponseWriter, r *http.Request) { 978 testMethod(t, r, "GET") 979 980 fmt.Fprint(w, `{ 981 "id": 1, 982 "ghsa_id": "GHSA-xoxo-1234-xoxo", 983 "cve_id": "CVE-xoxo-1234", 984 "url": "https://api.github.com/advisories/GHSA-xoxo-1234-xoxo", 985 "html_url": "https://github.com/advisories/GHSA-xoxo-1234-xoxo", 986 "repository_advisory_url": "https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo", 987 "summary": "Heartbleed security advisory", 988 "description": "This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information.", 989 "type": "reviewed", 990 "severity": "high", 991 "source_code_location": "https://github.com/project/a-package", 992 "identifiers": [ 993 { 994 "type": "GHSA", 995 "value": "GHSA-xoxo-1234-xoxo" 996 }, 997 { 998 "type": "CVE", 999 "value": "CVE-xoxo-1234" 1000 } 1001 ], 1002 "references": ["https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"], 1003 "published_at": "1996-06-20T00:00:00Z", 1004 "updated_at": "1996-06-20T00:00:00Z", 1005 "github_reviewed_at": "1996-06-20T00:00:00Z", 1006 "nvd_published_at": "1996-06-20T00:00:00Z", 1007 "withdrawn_at": null, 1008 "vulnerabilities": [ 1009 { 1010 "package": { 1011 "ecosystem": "npm", 1012 "name": "a-package" 1013 }, 1014 "first_patched_version": "1.0.3", 1015 "vulnerable_version_range": "<=1.0.2", 1016 "vulnerable_functions": ["a_function"] 1017 } 1018 ], 1019 "cvss": { 1020 "vector_string": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H", 1021 "score": 7.6 1022 }, 1023 "cwes": [ 1024 { 1025 "cwe_id": "CWE-400", 1026 "name": "Uncontrolled Resource Consumption" 1027 } 1028 ], 1029 "credits": [ 1030 { 1031 "user": { 1032 "login": "user", 1033 "id": 1, 1034 "node_id": "12=", 1035 "avatar_url": "a", 1036 "gravatar_id": "", 1037 "url": "a", 1038 "html_url": "b", 1039 "followers_url": "b", 1040 "following_url": "c", 1041 "gists_url": "d", 1042 "starred_url": "e", 1043 "subscriptions_url": "f", 1044 "organizations_url": "g", 1045 "repos_url": "h", 1046 "events_url": "i", 1047 "received_events_url": "j", 1048 "type": "User", 1049 "site_admin": false 1050 }, 1051 "type": "analyst" 1052 } 1053 ] 1054 }`) 1055 }) 1056 1057 ctx := context.Background() 1058 advisory, _, err := client.SecurityAdvisories.GetGlobalSecurityAdvisories(ctx, "GHSA-xoxo-1234-xoxo") 1059 if err != nil { 1060 t.Errorf("SecurityAdvisories.GetGlobalSecurityAdvisories returned error: %v", err) 1061 } 1062 1063 date := Timestamp{time.Date(1996, time.June, 20, 00, 00, 00, 0, time.UTC)} 1064 want := &GlobalSecurityAdvisory{ 1065 ID: Ptr(int64(1)), 1066 SecurityAdvisory: SecurityAdvisory{ 1067 GHSAID: Ptr("GHSA-xoxo-1234-xoxo"), 1068 CVEID: Ptr("CVE-xoxo-1234"), 1069 URL: Ptr("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 1070 HTMLURL: Ptr("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 1071 Severity: Ptr("high"), 1072 Summary: Ptr("Heartbleed security advisory"), 1073 Description: Ptr("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 1074 Identifiers: []*AdvisoryIdentifier{ 1075 { 1076 Type: Ptr("GHSA"), 1077 Value: Ptr("GHSA-xoxo-1234-xoxo"), 1078 }, 1079 { 1080 Type: Ptr("CVE"), 1081 Value: Ptr("CVE-xoxo-1234"), 1082 }, 1083 }, 1084 PublishedAt: &date, 1085 UpdatedAt: &date, 1086 WithdrawnAt: nil, 1087 CVSS: &AdvisoryCVSS{ 1088 VectorString: Ptr("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 1089 Score: Ptr(7.6), 1090 }, 1091 CWEs: []*AdvisoryCWEs{ 1092 { 1093 CWEID: Ptr("CWE-400"), 1094 Name: Ptr("Uncontrolled Resource Consumption"), 1095 }, 1096 }, 1097 }, 1098 RepositoryAdvisoryURL: Ptr("https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo"), 1099 Type: Ptr("reviewed"), 1100 SourceCodeLocation: Ptr("https://github.com/project/a-package"), 1101 References: []string{"https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"}, 1102 GithubReviewedAt: &date, 1103 NVDPublishedAt: &date, 1104 1105 Vulnerabilities: []*GlobalSecurityVulnerability{ 1106 { 1107 Package: &VulnerabilityPackage{ 1108 Ecosystem: Ptr("npm"), 1109 Name: Ptr("a-package"), 1110 }, 1111 FirstPatchedVersion: Ptr("1.0.3"), 1112 VulnerableVersionRange: Ptr("<=1.0.2"), 1113 VulnerableFunctions: []string{"a_function"}, 1114 }, 1115 }, 1116 Credits: []*Credit{ 1117 { 1118 User: &User{ 1119 Login: Ptr("user"), 1120 ID: Ptr(int64(1)), 1121 NodeID: Ptr("12="), 1122 AvatarURL: Ptr("a"), 1123 GravatarID: Ptr(""), 1124 URL: Ptr("a"), 1125 HTMLURL: Ptr("b"), 1126 FollowersURL: Ptr("b"), 1127 FollowingURL: Ptr("c"), 1128 GistsURL: Ptr("d"), 1129 StarredURL: Ptr("e"), 1130 SubscriptionsURL: Ptr("f"), 1131 OrganizationsURL: Ptr("g"), 1132 ReposURL: Ptr("h"), 1133 EventsURL: Ptr("i"), 1134 ReceivedEventsURL: Ptr("j"), 1135 Type: Ptr("User"), 1136 SiteAdmin: Ptr(false), 1137 }, 1138 Type: Ptr("analyst"), 1139 }, 1140 }, 1141 } 1142 1143 if !cmp.Equal(advisory, want) { 1144 t.Errorf("SecurityAdvisories.GetGlobalSecurityAdvisories %+v, want %+v", advisory, want) 1145 } 1146 1147 const methodName = "GetGlobalSecurityAdvisories" 1148 1149 testBadOptions(t, methodName, func() (err error) { 1150 _, _, err = client.SecurityAdvisories.GetGlobalSecurityAdvisories(ctx, "CVE-\n-1234") 1151 return err 1152 }) 1153 1154 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1155 got, resp, err := client.SecurityAdvisories.GetGlobalSecurityAdvisories(ctx, "e") 1156 if got != nil { 1157 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1158 } 1159 return resp, err 1160 }) 1161 } 1162 1163 func TestSecurityAdvisorySubmission_Marshal(t *testing.T) { 1164 t.Parallel() 1165 testJSONMarshal(t, &SecurityAdvisorySubmission{}, `{}`) 1166 1167 u := &SecurityAdvisorySubmission{ 1168 Accepted: Ptr(true), 1169 } 1170 1171 w := `{ 1172 "accepted": true 1173 }` 1174 1175 testJSONMarshal(t, u, w) 1176 } 1177 1178 func TestRepoAdvisoryCredit_Marshal(t *testing.T) { 1179 t.Parallel() 1180 testJSONMarshal(t, &RepoAdvisoryCredit{}, `{}`) 1181 1182 u := &RepoAdvisoryCredit{ 1183 Login: Ptr("l"), 1184 Type: Ptr("t"), 1185 } 1186 1187 w := `{ 1188 "login": "l", 1189 "type": "t" 1190 }` 1191 1192 testJSONMarshal(t, u, w) 1193 } 1194 1195 func TestRepoAdvisoryCreditDetailed_Marshal(t *testing.T) { 1196 t.Parallel() 1197 testJSONMarshal(t, &RepoAdvisoryCreditDetailed{}, `{}`) 1198 1199 testDate := &Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)} 1200 u := &RepoAdvisoryCreditDetailed{ 1201 Type: Ptr("t"), 1202 State: Ptr("s"), 1203 User: &User{ 1204 Name: Ptr("u"), 1205 Company: Ptr("c"), 1206 Blog: Ptr("b"), 1207 Location: Ptr("l"), 1208 Email: Ptr("e"), 1209 Hireable: Ptr(false), 1210 Bio: Ptr("bio"), 1211 TwitterUsername: Ptr("tu"), 1212 PublicRepos: Ptr(1), 1213 PublicGists: Ptr(1), 1214 Followers: Ptr(2), 1215 Following: Ptr(2), 1216 CreatedAt: testDate, 1217 UpdatedAt: testDate, 1218 SuspendedAt: testDate, 1219 Type: Ptr("type"), 1220 SiteAdmin: Ptr(false), 1221 TotalPrivateRepos: Ptr(int64(10)), 1222 OwnedPrivateRepos: Ptr(int64(10)), 1223 PrivateGists: Ptr(10), 1224 DiskUsage: Ptr(10), 1225 Collaborators: Ptr(10), 1226 TwoFactorAuthentication: Ptr(true), 1227 Plan: &Plan{ 1228 Name: Ptr("p"), 1229 Space: Ptr(2), 1230 Collaborators: Ptr(2), 1231 PrivateRepos: Ptr(int64(2)), 1232 Seats: Ptr(2), 1233 FilledSeats: Ptr(1), 1234 }, 1235 LdapDn: Ptr("l"), 1236 URL: Ptr("url"), 1237 EventsURL: Ptr("e"), 1238 FollowingURL: Ptr("f"), 1239 FollowersURL: Ptr("f"), 1240 GistsURL: Ptr("g"), 1241 OrganizationsURL: Ptr("o"), 1242 ReceivedEventsURL: Ptr("r"), 1243 ReposURL: Ptr("rep"), 1244 StarredURL: Ptr("star"), 1245 SubscriptionsURL: Ptr("sub"), 1246 TextMatches: []*TextMatch{ 1247 { 1248 ObjectURL: Ptr("u"), 1249 ObjectType: Ptr("t"), 1250 Property: Ptr("p"), 1251 Fragment: Ptr("f"), 1252 Matches: []*Match{ 1253 { 1254 Text: Ptr("t"), 1255 Indices: []int{1, 2}, 1256 }, 1257 }, 1258 }, 1259 }, 1260 Permissions: map[string]bool{"p1": true}, 1261 RoleName: Ptr("r"), 1262 }, 1263 } 1264 1265 w := `{ 1266 "type": "t", 1267 "state": "s", 1268 "user": { 1269 "name": "u", 1270 "company": "c", 1271 "blog": "b", 1272 "location": "l", 1273 "email": "e", 1274 "hireable": false, 1275 "bio": "bio", 1276 "twitter_username": "tu", 1277 "public_repos": 1, 1278 "public_gists": 1, 1279 "followers": 2, 1280 "following": 2, 1281 "created_at": "2019-08-10T14:59:22Z", 1282 "updated_at": "2019-08-10T14:59:22Z", 1283 "suspended_at": "2019-08-10T14:59:22Z", 1284 "type": "type", 1285 "site_admin": false, 1286 "total_private_repos": 10, 1287 "owned_private_repos": 10, 1288 "private_gists": 10, 1289 "disk_usage": 10, 1290 "collaborators": 10, 1291 "two_factor_authentication": true, 1292 "plan": { 1293 "name": "p", 1294 "space": 2, 1295 "collaborators": 2, 1296 "private_repos": 2, 1297 "seats": 2, 1298 "filled_seats": 1 1299 }, 1300 "ldap_dn": "l", 1301 "url": "url", 1302 "events_url": "e", 1303 "following_url": "f", 1304 "followers_url": "f", 1305 "gists_url": "g", 1306 "organizations_url": "o", 1307 "received_events_url": "r", 1308 "repos_url": "rep", 1309 "starred_url": "star", 1310 "subscriptions_url": "sub", 1311 "text_matches": [ 1312 { 1313 "object_url": "u", 1314 "object_type": "t", 1315 "property": "p", 1316 "fragment": "f", 1317 "matches": [ 1318 { 1319 "text": "t", 1320 "indices": [1, 2] 1321 } 1322 ] 1323 } 1324 ], 1325 "permissions": { 1326 "p1": true 1327 }, 1328 "role_name": "r" 1329 } 1330 }` 1331 1332 testJSONMarshal(t, u, w) 1333 } 1334 1335 func TestCredit_Marshal(t *testing.T) { 1336 t.Parallel() 1337 testJSONMarshal(t, &Credit{}, `{}`) 1338 1339 testDate := &Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)} 1340 u := &Credit{ 1341 Type: Ptr("t"), 1342 User: &User{ 1343 Name: Ptr("u"), 1344 Company: Ptr("c"), 1345 Blog: Ptr("b"), 1346 Location: Ptr("l"), 1347 Email: Ptr("e"), 1348 Hireable: Ptr(false), 1349 Bio: Ptr("bio"), 1350 TwitterUsername: Ptr("tu"), 1351 PublicRepos: Ptr(1), 1352 PublicGists: Ptr(1), 1353 Followers: Ptr(2), 1354 Following: Ptr(2), 1355 CreatedAt: testDate, 1356 UpdatedAt: testDate, 1357 SuspendedAt: testDate, 1358 Type: Ptr("type"), 1359 SiteAdmin: Ptr(false), 1360 TotalPrivateRepos: Ptr(int64(10)), 1361 OwnedPrivateRepos: Ptr(int64(10)), 1362 PrivateGists: Ptr(10), 1363 DiskUsage: Ptr(10), 1364 Collaborators: Ptr(10), 1365 TwoFactorAuthentication: Ptr(true), 1366 Plan: &Plan{ 1367 Name: Ptr("p"), 1368 Space: Ptr(2), 1369 Collaborators: Ptr(2), 1370 PrivateRepos: Ptr(int64(2)), 1371 Seats: Ptr(2), 1372 FilledSeats: Ptr(1), 1373 }, 1374 LdapDn: Ptr("l"), 1375 URL: Ptr("url"), 1376 EventsURL: Ptr("e"), 1377 FollowingURL: Ptr("f"), 1378 FollowersURL: Ptr("f"), 1379 GistsURL: Ptr("g"), 1380 OrganizationsURL: Ptr("o"), 1381 ReceivedEventsURL: Ptr("r"), 1382 ReposURL: Ptr("rep"), 1383 StarredURL: Ptr("star"), 1384 SubscriptionsURL: Ptr("sub"), 1385 TextMatches: []*TextMatch{ 1386 { 1387 ObjectURL: Ptr("u"), 1388 ObjectType: Ptr("t"), 1389 Property: Ptr("p"), 1390 Fragment: Ptr("f"), 1391 Matches: []*Match{ 1392 { 1393 Text: Ptr("t"), 1394 Indices: []int{1, 2}, 1395 }, 1396 }, 1397 }, 1398 }, 1399 Permissions: map[string]bool{"p1": true}, 1400 RoleName: Ptr("r"), 1401 }, 1402 } 1403 1404 w := `{ 1405 "type": "t", 1406 "user": { 1407 "name": "u", 1408 "company": "c", 1409 "blog": "b", 1410 "location": "l", 1411 "email": "e", 1412 "hireable": false, 1413 "bio": "bio", 1414 "twitter_username": "tu", 1415 "public_repos": 1, 1416 "public_gists": 1, 1417 "followers": 2, 1418 "following": 2, 1419 "created_at": "2019-08-10T14:59:22Z", 1420 "updated_at": "2019-08-10T14:59:22Z", 1421 "suspended_at": "2019-08-10T14:59:22Z", 1422 "type": "type", 1423 "site_admin": false, 1424 "total_private_repos": 10, 1425 "owned_private_repos": 10, 1426 "private_gists": 10, 1427 "disk_usage": 10, 1428 "collaborators": 10, 1429 "two_factor_authentication": true, 1430 "plan": { 1431 "name": "p", 1432 "space": 2, 1433 "collaborators": 2, 1434 "private_repos": 2, 1435 "seats": 2, 1436 "filled_seats": 1 1437 }, 1438 "ldap_dn": "l", 1439 "url": "url", 1440 "events_url": "e", 1441 "following_url": "f", 1442 "followers_url": "f", 1443 "gists_url": "g", 1444 "organizations_url": "o", 1445 "received_events_url": "r", 1446 "repos_url": "rep", 1447 "starred_url": "star", 1448 "subscriptions_url": "sub", 1449 "text_matches": [ 1450 { 1451 "object_url": "u", 1452 "object_type": "t", 1453 "property": "p", 1454 "fragment": "f", 1455 "matches": [ 1456 { 1457 "text": "t", 1458 "indices": [1, 2] 1459 } 1460 ] 1461 } 1462 ], 1463 "permissions": { 1464 "p1": true 1465 }, 1466 "role_name": "r" 1467 } 1468 }` 1469 1470 testJSONMarshal(t, u, w) 1471 } 1472 1473 func TestGlobalSecurityAdvisory_Marshal(t *testing.T) { 1474 t.Parallel() 1475 testJSONMarshal(t, &GlobalSecurityAdvisory{}, `{}`) 1476 1477 testDate := &Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)} 1478 u := &GlobalSecurityAdvisory{ 1479 ID: Ptr(int64(1)), 1480 RepositoryAdvisoryURL: Ptr("r"), 1481 Type: Ptr("t"), 1482 SourceCodeLocation: Ptr("s"), 1483 References: []string{"r"}, 1484 Vulnerabilities: []*GlobalSecurityVulnerability{ 1485 { 1486 Package: &VulnerabilityPackage{ 1487 Ecosystem: Ptr("npm"), 1488 Name: Ptr("a-package"), 1489 }, 1490 FirstPatchedVersion: Ptr("1.0.3"), 1491 VulnerableVersionRange: Ptr("<=1.0.2"), 1492 VulnerableFunctions: []string{"a_function"}, 1493 }, 1494 }, 1495 GithubReviewedAt: testDate, 1496 NVDPublishedAt: testDate, 1497 Credits: []*Credit{ 1498 { 1499 Type: Ptr("t"), 1500 User: &User{ 1501 Name: Ptr("u"), 1502 Company: Ptr("c"), 1503 Blog: Ptr("b"), 1504 Location: Ptr("l"), 1505 Email: Ptr("e"), 1506 Hireable: Ptr(false), 1507 Bio: Ptr("bio"), 1508 TwitterUsername: Ptr("tu"), 1509 PublicRepos: Ptr(1), 1510 PublicGists: Ptr(1), 1511 Followers: Ptr(2), 1512 Following: Ptr(2), 1513 CreatedAt: testDate, 1514 UpdatedAt: testDate, 1515 SuspendedAt: testDate, 1516 Type: Ptr("type"), 1517 SiteAdmin: Ptr(false), 1518 TotalPrivateRepos: Ptr(int64(10)), 1519 OwnedPrivateRepos: Ptr(int64(10)), 1520 PrivateGists: Ptr(10), 1521 DiskUsage: Ptr(10), 1522 Collaborators: Ptr(10), 1523 TwoFactorAuthentication: Ptr(true), 1524 Plan: &Plan{ 1525 Name: Ptr("p"), 1526 Space: Ptr(2), 1527 Collaborators: Ptr(2), 1528 PrivateRepos: Ptr(int64(2)), 1529 Seats: Ptr(2), 1530 FilledSeats: Ptr(1), 1531 }, 1532 LdapDn: Ptr("l"), 1533 URL: Ptr("url"), 1534 EventsURL: Ptr("e"), 1535 FollowingURL: Ptr("f"), 1536 FollowersURL: Ptr("f"), 1537 GistsURL: Ptr("g"), 1538 OrganizationsURL: Ptr("o"), 1539 ReceivedEventsURL: Ptr("r"), 1540 ReposURL: Ptr("rep"), 1541 StarredURL: Ptr("star"), 1542 SubscriptionsURL: Ptr("sub"), 1543 TextMatches: []*TextMatch{ 1544 { 1545 ObjectURL: Ptr("u"), 1546 ObjectType: Ptr("t"), 1547 Property: Ptr("p"), 1548 Fragment: Ptr("f"), 1549 Matches: []*Match{ 1550 { 1551 Text: Ptr("t"), 1552 Indices: []int{1, 2}, 1553 }, 1554 }, 1555 }, 1556 }, 1557 Permissions: map[string]bool{"p1": true}, 1558 RoleName: Ptr("r"), 1559 }, 1560 }, 1561 }, 1562 SecurityAdvisory: SecurityAdvisory{ 1563 GHSAID: Ptr("GHSA-xoxo-1234-xoxo"), 1564 CVEID: Ptr("CVE-xoxo-1234"), 1565 URL: Ptr("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 1566 HTMLURL: Ptr("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 1567 Severity: Ptr("high"), 1568 Summary: Ptr("Heartbleed security advisory"), 1569 Description: Ptr("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 1570 Identifiers: []*AdvisoryIdentifier{ 1571 { 1572 Type: Ptr("GHSA"), 1573 Value: Ptr("GHSA-xoxo-1234-xoxo"), 1574 }, 1575 { 1576 Type: Ptr("CVE"), 1577 Value: Ptr("CVE-xoxo-1234"), 1578 }, 1579 }, 1580 PublishedAt: testDate, 1581 UpdatedAt: testDate, 1582 WithdrawnAt: nil, 1583 CVSS: &AdvisoryCVSS{ 1584 VectorString: Ptr("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 1585 Score: Ptr(7.6), 1586 }, 1587 CWEs: []*AdvisoryCWEs{ 1588 { 1589 CWEID: Ptr("CWE-400"), 1590 Name: Ptr("Uncontrolled Resource Consumption"), 1591 }, 1592 }, 1593 }, 1594 } 1595 1596 w := `{ 1597 "cvss": { 1598 "score": 7.6, 1599 "vector_string": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H" 1600 }, 1601 "cwes": [ 1602 { 1603 "cwe_id": "CWE-400", 1604 "name": "Uncontrolled Resource Consumption" 1605 } 1606 ], 1607 "ghsa_id": "GHSA-xoxo-1234-xoxo", 1608 "summary": "Heartbleed security advisory", 1609 "description": "This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information.", 1610 "severity": "high", 1611 "identifiers": [ 1612 { 1613 "value": "GHSA-xoxo-1234-xoxo", 1614 "type": "GHSA" 1615 }, 1616 { 1617 "value": "CVE-xoxo-1234", 1618 "type": "CVE" 1619 } 1620 ], 1621 "published_at": "2019-08-10T14:59:22Z", 1622 "updated_at": "2019-08-10T14:59:22Z", 1623 "cve_id": "CVE-xoxo-1234", 1624 "url": "https://api.github.com/advisories/GHSA-xoxo-1234-xoxo", 1625 "html_url": "https://github.com/advisories/GHSA-xoxo-1234-xoxo", 1626 "id": 1, 1627 "repository_advisory_url": "r", 1628 "type": "t", 1629 "source_code_location": "s", 1630 "references": [ 1631 "r" 1632 ], 1633 "vulnerabilities": [ 1634 { 1635 "package": { 1636 "ecosystem": "npm", 1637 "name": "a-package" 1638 }, 1639 "first_patched_version": "1.0.3", 1640 "vulnerable_version_range": "\u003c=1.0.2", 1641 "vulnerable_functions": [ 1642 "a_function" 1643 ] 1644 } 1645 ], 1646 "github_reviewed_at": "2019-08-10T14:59:22Z", 1647 "nvd_published_at": "2019-08-10T14:59:22Z", 1648 "credits": [ 1649 { 1650 "user": { 1651 "name": "u", 1652 "company": "c", 1653 "blog": "b", 1654 "location": "l", 1655 "email": "e", 1656 "hireable": false, 1657 "bio": "bio", 1658 "twitter_username": "tu", 1659 "public_repos": 1, 1660 "public_gists": 1, 1661 "followers": 2, 1662 "following": 2, 1663 "created_at": "2019-08-10T14:59:22Z", 1664 "updated_at": "2019-08-10T14:59:22Z", 1665 "suspended_at": "2019-08-10T14:59:22Z", 1666 "type": "type", 1667 "site_admin": false, 1668 "total_private_repos": 10, 1669 "owned_private_repos": 10, 1670 "private_gists": 10, 1671 "disk_usage": 10, 1672 "collaborators": 10, 1673 "two_factor_authentication": true, 1674 "plan": { 1675 "name": "p", 1676 "space": 2, 1677 "collaborators": 2, 1678 "private_repos": 2, 1679 "filled_seats": 1, 1680 "seats": 2 1681 }, 1682 "ldap_dn": "l", 1683 "url": "url", 1684 "events_url": "e", 1685 "following_url": "f", 1686 "followers_url": "f", 1687 "gists_url": "g", 1688 "organizations_url": "o", 1689 "received_events_url": "r", 1690 "repos_url": "rep", 1691 "starred_url": "star", 1692 "subscriptions_url": "sub", 1693 "text_matches": [ 1694 { 1695 "object_url": "u", 1696 "object_type": "t", 1697 "property": "p", 1698 "fragment": "f", 1699 "matches": [ 1700 { 1701 "text": "t", 1702 "indices": [ 1703 1, 1704 2 1705 ] 1706 } 1707 ] 1708 } 1709 ], 1710 "permissions": { 1711 "p1": true 1712 }, 1713 "role_name": "r" 1714 }, 1715 "type": "t" 1716 } 1717 ] 1718 }` 1719 1720 testJSONMarshal(t, u, w) 1721 }