github.com/google/go-github/v64@v64.0.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 client, mux, _, teardown := setup() 21 defer teardown() 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 client, mux, _, teardown := setup() 61 defer teardown() 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: Int64(1), 176 NodeID: String("R_kgDPP3c6pQ"), 177 Owner: &User{ 178 Login: String("owner"), 179 ID: Int64(2), 180 NodeID: String("MDQ6VXFGcjYyMjcyMTQw"), 181 AvatarURL: String("https://avatars.githubusercontent.com/u/111111?v=4"), 182 HTMLURL: String("https://github.com/xxxxx"), 183 GravatarID: String(""), 184 Type: String("User"), 185 SiteAdmin: Bool(false), 186 URL: String("https://api.github.com/users/owner"), 187 EventsURL: String("https://api.github.com/users/owner/events{/privacy}"), 188 FollowingURL: String("https://api.github.com/users/owner/following{/other_user}"), 189 FollowersURL: String("https://api.github.com/users/owner/followers"), 190 GistsURL: String("https://api.github.com/users/owner/gists{/gist_id}"), 191 OrganizationsURL: String("https://api.github.com/users/owner/orgs"), 192 ReceivedEventsURL: String("https://api.github.com/users/owner/received_events"), 193 ReposURL: String("https://api.github.com/users/owner/repos"), 194 StarredURL: String("https://api.github.com/users/owner/starred{/owner}{/repo}"), 195 SubscriptionsURL: String("https://api.github.com/users/owner/subscriptions"), 196 }, 197 Name: String("repo-ghsa-xxxx-xxxx-xxxx"), 198 FullName: String("owner/repo-ghsa-xxxx-xxxx-xxxx"), 199 DefaultBranch: String("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: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 204 CloneURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 205 GitURL: String("git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 206 SSHURL: String("git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 207 SVNURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 208 Fork: Bool(false), 209 ForksCount: Int(0), 210 NetworkCount: Int(0), 211 OpenIssuesCount: Int(0), 212 OpenIssues: Int(0), 213 StargazersCount: Int(0), 214 SubscribersCount: Int(0), 215 WatchersCount: Int(0), 216 Watchers: Int(0), 217 Size: Int(0), 218 Permissions: map[string]bool{ 219 "admin": true, 220 "maintain": true, 221 "pull": true, 222 "push": true, 223 "triage": true, 224 }, 225 AllowForking: Bool(true), 226 WebCommitSignoffRequired: Bool(false), 227 Archived: Bool(false), 228 Disabled: Bool(false), 229 Private: Bool(true), 230 HasIssues: Bool(false), 231 HasWiki: Bool(false), 232 HasPages: Bool(false), 233 HasProjects: Bool(false), 234 HasDownloads: Bool(false), 235 HasDiscussions: Bool(false), 236 IsTemplate: Bool(false), 237 URL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx"), 238 ArchiveURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}"), 239 AssigneesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}"), 240 BlobsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}"), 241 BranchesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}"), 242 CollaboratorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}"), 243 CommentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}"), 244 CommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}"), 245 CompareURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}"), 246 ContentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}"), 247 ContributorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors"), 248 DeploymentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments"), 249 DownloadsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads"), 250 EventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events"), 251 ForksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks"), 252 GitCommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}"), 253 GitRefsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}"), 254 GitTagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}"), 255 HooksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks"), 256 IssueCommentURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}"), 257 IssueEventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}"), 258 IssuesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}"), 259 KeysURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}"), 260 LabelsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}"), 261 LanguagesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages"), 262 MergesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges"), 263 MilestonesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}"), 264 NotificationsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}"), 265 PullsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}"), 266 ReleasesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}"), 267 StargazersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers"), 268 StatusesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}"), 269 SubscribersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers"), 270 SubscriptionURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription"), 271 TagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags"), 272 TeamsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams"), 273 Visibility: String("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 client, mux, _, teardown := setup() 296 defer teardown() 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: Int64(1), 412 NodeID: String("R_kgDPP3c6pQ"), 413 Owner: &User{ 414 Login: String("owner"), 415 ID: Int64(2), 416 NodeID: String("MDQ6VXFGcjYyMjcyMTQw"), 417 AvatarURL: String("https://avatars.githubusercontent.com/u/111111?v=4"), 418 HTMLURL: String("https://github.com/xxxxx"), 419 GravatarID: String(""), 420 Type: String("User"), 421 SiteAdmin: Bool(false), 422 URL: String("https://api.github.com/users/owner"), 423 EventsURL: String("https://api.github.com/users/owner/events{/privacy}"), 424 FollowingURL: String("https://api.github.com/users/owner/following{/other_user}"), 425 FollowersURL: String("https://api.github.com/users/owner/followers"), 426 GistsURL: String("https://api.github.com/users/owner/gists{/gist_id}"), 427 OrganizationsURL: String("https://api.github.com/users/owner/orgs"), 428 ReceivedEventsURL: String("https://api.github.com/users/owner/received_events"), 429 ReposURL: String("https://api.github.com/users/owner/repos"), 430 StarredURL: String("https://api.github.com/users/owner/starred{/owner}{/repo}"), 431 SubscriptionsURL: String("https://api.github.com/users/owner/subscriptions"), 432 }, 433 Name: String("repo-ghsa-xxxx-xxxx-xxxx"), 434 FullName: String("owner/repo-ghsa-xxxx-xxxx-xxxx"), 435 DefaultBranch: String("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: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 440 CloneURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 441 GitURL: String("git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 442 SSHURL: String("git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git"), 443 SVNURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), 444 Fork: Bool(false), 445 ForksCount: Int(0), 446 NetworkCount: Int(0), 447 OpenIssuesCount: Int(0), 448 OpenIssues: Int(0), 449 StargazersCount: Int(0), 450 SubscribersCount: Int(0), 451 WatchersCount: Int(0), 452 Watchers: Int(0), 453 Size: Int(0), 454 Permissions: map[string]bool{ 455 "admin": true, 456 "maintain": true, 457 "pull": true, 458 "push": true, 459 "triage": true, 460 }, 461 AllowForking: Bool(true), 462 WebCommitSignoffRequired: Bool(false), 463 Archived: Bool(false), 464 Disabled: Bool(false), 465 Private: Bool(true), 466 HasIssues: Bool(false), 467 HasWiki: Bool(false), 468 HasPages: Bool(false), 469 HasProjects: Bool(false), 470 HasDownloads: Bool(false), 471 HasDiscussions: Bool(false), 472 IsTemplate: Bool(false), 473 URL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx"), 474 ArchiveURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}"), 475 AssigneesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}"), 476 BlobsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}"), 477 BranchesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}"), 478 CollaboratorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}"), 479 CommentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}"), 480 CommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}"), 481 CompareURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}"), 482 ContentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}"), 483 ContributorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors"), 484 DeploymentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments"), 485 DownloadsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads"), 486 EventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events"), 487 ForksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks"), 488 GitCommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}"), 489 GitRefsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}"), 490 GitTagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}"), 491 HooksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks"), 492 IssueCommentURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}"), 493 IssueEventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}"), 494 IssuesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}"), 495 KeysURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}"), 496 LabelsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}"), 497 LanguagesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages"), 498 MergesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges"), 499 MilestonesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}"), 500 NotificationsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}"), 501 PullsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}"), 502 ReleasesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}"), 503 StargazersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers"), 504 StatusesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}"), 505 SubscribersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers"), 506 SubscriptionURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription"), 507 TagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags"), 508 TeamsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams"), 509 Visibility: String("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 client, _, _, teardown := setup() 518 defer teardown() 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 client, mux, _, teardown := setup() 527 defer teardown() 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 client, mux, _, teardown := setup() 550 defer teardown() 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 client, mux, _, teardown := setup() 580 defer teardown() 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 client, mux, _, teardown := setup() 606 defer teardown() 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: String("GHSA-abcd-1234-efgh"), 632 CVEID: String("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 client, mux, _, teardown := setup() 658 defer teardown() 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 client, mux, _, teardown := setup() 681 defer teardown() 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 client, mux, _, teardown := setup() 711 defer teardown() 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 client, mux, _, teardown := setup() 737 defer teardown() 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: String("GHSA-abcd-1234-efgh"), 763 CVEID: String("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 client, mux, _, teardown := setup() 789 defer teardown() 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: String("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: Int64(1), 885 SecurityAdvisory: SecurityAdvisory{ 886 GHSAID: String("GHSA-xoxo-1234-xoxo"), 887 CVEID: String("CVE-xoxo-1234"), 888 URL: String("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 889 HTMLURL: String("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 890 Severity: String("high"), 891 Summary: String("Heartbleed security advisory"), 892 Description: String("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 893 Identifiers: []*AdvisoryIdentifier{ 894 { 895 Type: String("GHSA"), 896 Value: String("GHSA-xoxo-1234-xoxo"), 897 }, 898 { 899 Type: String("CVE"), 900 Value: String("CVE-xoxo-1234"), 901 }, 902 }, 903 PublishedAt: &date, 904 UpdatedAt: &date, 905 WithdrawnAt: nil, 906 CVSS: &AdvisoryCVSS{ 907 VectorString: String("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 908 Score: Float64(7.6), 909 }, 910 CWEs: []*AdvisoryCWEs{ 911 { 912 CWEID: String("CWE-400"), 913 Name: String("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: String("npm"), 922 Name: String("a-package"), 923 }, 924 FirstPatchedVersion: String("1.0.3"), 925 VulnerableVersionRange: String("<=1.0.2"), 926 VulnerableFunctions: []string{"a_function"}, 927 }, 928 }, 929 RepositoryAdvisoryURL: String("https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo"), 930 Type: String("reviewed"), 931 SourceCodeLocation: String("https://github.com/project/a-package"), 932 GithubReviewedAt: &date, 933 NVDPublishedAt: &date, 934 Credits: []*Credit{ 935 { 936 User: &User{ 937 Login: String("user"), 938 ID: Int64(1), 939 NodeID: String("12="), 940 AvatarURL: String("a"), 941 GravatarID: String(""), 942 URL: String("a"), 943 HTMLURL: String("b"), 944 FollowersURL: String("b"), 945 FollowingURL: String("c"), 946 GistsURL: String("d"), 947 StarredURL: String("e"), 948 SubscriptionsURL: String("f"), 949 OrganizationsURL: String("g"), 950 ReposURL: String("h"), 951 EventsURL: String("i"), 952 ReceivedEventsURL: String("j"), 953 Type: String("User"), 954 SiteAdmin: Bool(false), 955 }, 956 Type: String("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 client, mux, _, teardown := setup() 975 defer teardown() 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: Int64(1), 1066 SecurityAdvisory: SecurityAdvisory{ 1067 GHSAID: String("GHSA-xoxo-1234-xoxo"), 1068 CVEID: String("CVE-xoxo-1234"), 1069 URL: String("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 1070 HTMLURL: String("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 1071 Severity: String("high"), 1072 Summary: String("Heartbleed security advisory"), 1073 Description: String("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 1074 Identifiers: []*AdvisoryIdentifier{ 1075 { 1076 Type: String("GHSA"), 1077 Value: String("GHSA-xoxo-1234-xoxo"), 1078 }, 1079 { 1080 Type: String("CVE"), 1081 Value: String("CVE-xoxo-1234"), 1082 }, 1083 }, 1084 PublishedAt: &date, 1085 UpdatedAt: &date, 1086 WithdrawnAt: nil, 1087 CVSS: &AdvisoryCVSS{ 1088 VectorString: String("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 1089 Score: Float64(7.6), 1090 }, 1091 CWEs: []*AdvisoryCWEs{ 1092 { 1093 CWEID: String("CWE-400"), 1094 Name: String("Uncontrolled Resource Consumption"), 1095 }, 1096 }, 1097 }, 1098 RepositoryAdvisoryURL: String("https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo"), 1099 Type: String("reviewed"), 1100 SourceCodeLocation: String("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: String("npm"), 1109 Name: String("a-package"), 1110 }, 1111 FirstPatchedVersion: String("1.0.3"), 1112 VulnerableVersionRange: String("<=1.0.2"), 1113 VulnerableFunctions: []string{"a_function"}, 1114 }, 1115 }, 1116 Credits: []*Credit{ 1117 { 1118 User: &User{ 1119 Login: String("user"), 1120 ID: Int64(1), 1121 NodeID: String("12="), 1122 AvatarURL: String("a"), 1123 GravatarID: String(""), 1124 URL: String("a"), 1125 HTMLURL: String("b"), 1126 FollowersURL: String("b"), 1127 FollowingURL: String("c"), 1128 GistsURL: String("d"), 1129 StarredURL: String("e"), 1130 SubscriptionsURL: String("f"), 1131 OrganizationsURL: String("g"), 1132 ReposURL: String("h"), 1133 EventsURL: String("i"), 1134 ReceivedEventsURL: String("j"), 1135 Type: String("User"), 1136 SiteAdmin: Bool(false), 1137 }, 1138 Type: String("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 testJSONMarshal(t, &SecurityAdvisorySubmission{}, `{}`) 1165 1166 u := &SecurityAdvisorySubmission{ 1167 Accepted: Bool(true), 1168 } 1169 1170 w := `{ 1171 "accepted": true 1172 }` 1173 1174 testJSONMarshal(t, u, w) 1175 } 1176 1177 func TestRepoAdvisoryCredit_Marshal(t *testing.T) { 1178 testJSONMarshal(t, &RepoAdvisoryCredit{}, `{}`) 1179 1180 u := &RepoAdvisoryCredit{ 1181 Login: String("l"), 1182 Type: String("t"), 1183 } 1184 1185 w := `{ 1186 "login": "l", 1187 "type": "t" 1188 }` 1189 1190 testJSONMarshal(t, u, w) 1191 } 1192 1193 func TestRepoAdvisoryCreditDetailed_Marshal(t *testing.T) { 1194 testJSONMarshal(t, &RepoAdvisoryCreditDetailed{}, `{}`) 1195 1196 testDate := &Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)} 1197 u := &RepoAdvisoryCreditDetailed{ 1198 Type: String("t"), 1199 State: String("s"), 1200 User: &User{ 1201 Name: String("u"), 1202 Company: String("c"), 1203 Blog: String("b"), 1204 Location: String("l"), 1205 Email: String("e"), 1206 Hireable: Bool(false), 1207 Bio: String("bio"), 1208 TwitterUsername: String("tu"), 1209 PublicRepos: Int(1), 1210 PublicGists: Int(1), 1211 Followers: Int(2), 1212 Following: Int(2), 1213 CreatedAt: testDate, 1214 UpdatedAt: testDate, 1215 SuspendedAt: testDate, 1216 Type: String("type"), 1217 SiteAdmin: Bool(false), 1218 TotalPrivateRepos: Int64(10), 1219 OwnedPrivateRepos: Int64(10), 1220 PrivateGists: Int(10), 1221 DiskUsage: Int(10), 1222 Collaborators: Int(10), 1223 TwoFactorAuthentication: Bool(true), 1224 Plan: &Plan{ 1225 Name: String("p"), 1226 Space: Int(2), 1227 Collaborators: Int(2), 1228 PrivateRepos: Int64(2), 1229 Seats: Int(2), 1230 FilledSeats: Int(1), 1231 }, 1232 LdapDn: String("l"), 1233 URL: String("url"), 1234 EventsURL: String("e"), 1235 FollowingURL: String("f"), 1236 FollowersURL: String("f"), 1237 GistsURL: String("g"), 1238 OrganizationsURL: String("o"), 1239 ReceivedEventsURL: String("r"), 1240 ReposURL: String("rep"), 1241 StarredURL: String("star"), 1242 SubscriptionsURL: String("sub"), 1243 TextMatches: []*TextMatch{ 1244 { 1245 ObjectURL: String("u"), 1246 ObjectType: String("t"), 1247 Property: String("p"), 1248 Fragment: String("f"), 1249 Matches: []*Match{ 1250 { 1251 Text: String("t"), 1252 Indices: []int{1, 2}, 1253 }, 1254 }, 1255 }, 1256 }, 1257 Permissions: map[string]bool{"p1": true}, 1258 RoleName: String("r"), 1259 }, 1260 } 1261 1262 w := `{ 1263 "type": "t", 1264 "state": "s", 1265 "user": { 1266 "name": "u", 1267 "company": "c", 1268 "blog": "b", 1269 "location": "l", 1270 "email": "e", 1271 "hireable": false, 1272 "bio": "bio", 1273 "twitter_username": "tu", 1274 "public_repos": 1, 1275 "public_gists": 1, 1276 "followers": 2, 1277 "following": 2, 1278 "created_at": "2019-08-10T14:59:22Z", 1279 "updated_at": "2019-08-10T14:59:22Z", 1280 "suspended_at": "2019-08-10T14:59:22Z", 1281 "type": "type", 1282 "site_admin": false, 1283 "total_private_repos": 10, 1284 "owned_private_repos": 10, 1285 "private_gists": 10, 1286 "disk_usage": 10, 1287 "collaborators": 10, 1288 "two_factor_authentication": true, 1289 "plan": { 1290 "name": "p", 1291 "space": 2, 1292 "collaborators": 2, 1293 "private_repos": 2, 1294 "seats": 2, 1295 "filled_seats": 1 1296 }, 1297 "ldap_dn": "l", 1298 "url": "url", 1299 "events_url": "e", 1300 "following_url": "f", 1301 "followers_url": "f", 1302 "gists_url": "g", 1303 "organizations_url": "o", 1304 "received_events_url": "r", 1305 "repos_url": "rep", 1306 "starred_url": "star", 1307 "subscriptions_url": "sub", 1308 "text_matches": [ 1309 { 1310 "object_url": "u", 1311 "object_type": "t", 1312 "property": "p", 1313 "fragment": "f", 1314 "matches": [ 1315 { 1316 "text": "t", 1317 "indices": [1, 2] 1318 } 1319 ] 1320 } 1321 ], 1322 "permissions": { 1323 "p1": true 1324 }, 1325 "role_name": "r" 1326 } 1327 }` 1328 1329 testJSONMarshal(t, u, w) 1330 } 1331 1332 func TestCredit_Marshal(t *testing.T) { 1333 testJSONMarshal(t, &Credit{}, `{}`) 1334 1335 testDate := &Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)} 1336 u := &Credit{ 1337 Type: String("t"), 1338 User: &User{ 1339 Name: String("u"), 1340 Company: String("c"), 1341 Blog: String("b"), 1342 Location: String("l"), 1343 Email: String("e"), 1344 Hireable: Bool(false), 1345 Bio: String("bio"), 1346 TwitterUsername: String("tu"), 1347 PublicRepos: Int(1), 1348 PublicGists: Int(1), 1349 Followers: Int(2), 1350 Following: Int(2), 1351 CreatedAt: testDate, 1352 UpdatedAt: testDate, 1353 SuspendedAt: testDate, 1354 Type: String("type"), 1355 SiteAdmin: Bool(false), 1356 TotalPrivateRepos: Int64(10), 1357 OwnedPrivateRepos: Int64(10), 1358 PrivateGists: Int(10), 1359 DiskUsage: Int(10), 1360 Collaborators: Int(10), 1361 TwoFactorAuthentication: Bool(true), 1362 Plan: &Plan{ 1363 Name: String("p"), 1364 Space: Int(2), 1365 Collaborators: Int(2), 1366 PrivateRepos: Int64(2), 1367 Seats: Int(2), 1368 FilledSeats: Int(1), 1369 }, 1370 LdapDn: String("l"), 1371 URL: String("url"), 1372 EventsURL: String("e"), 1373 FollowingURL: String("f"), 1374 FollowersURL: String("f"), 1375 GistsURL: String("g"), 1376 OrganizationsURL: String("o"), 1377 ReceivedEventsURL: String("r"), 1378 ReposURL: String("rep"), 1379 StarredURL: String("star"), 1380 SubscriptionsURL: String("sub"), 1381 TextMatches: []*TextMatch{ 1382 { 1383 ObjectURL: String("u"), 1384 ObjectType: String("t"), 1385 Property: String("p"), 1386 Fragment: String("f"), 1387 Matches: []*Match{ 1388 { 1389 Text: String("t"), 1390 Indices: []int{1, 2}, 1391 }, 1392 }, 1393 }, 1394 }, 1395 Permissions: map[string]bool{"p1": true}, 1396 RoleName: String("r"), 1397 }, 1398 } 1399 1400 w := `{ 1401 "type": "t", 1402 "user": { 1403 "name": "u", 1404 "company": "c", 1405 "blog": "b", 1406 "location": "l", 1407 "email": "e", 1408 "hireable": false, 1409 "bio": "bio", 1410 "twitter_username": "tu", 1411 "public_repos": 1, 1412 "public_gists": 1, 1413 "followers": 2, 1414 "following": 2, 1415 "created_at": "2019-08-10T14:59:22Z", 1416 "updated_at": "2019-08-10T14:59:22Z", 1417 "suspended_at": "2019-08-10T14:59:22Z", 1418 "type": "type", 1419 "site_admin": false, 1420 "total_private_repos": 10, 1421 "owned_private_repos": 10, 1422 "private_gists": 10, 1423 "disk_usage": 10, 1424 "collaborators": 10, 1425 "two_factor_authentication": true, 1426 "plan": { 1427 "name": "p", 1428 "space": 2, 1429 "collaborators": 2, 1430 "private_repos": 2, 1431 "seats": 2, 1432 "filled_seats": 1 1433 }, 1434 "ldap_dn": "l", 1435 "url": "url", 1436 "events_url": "e", 1437 "following_url": "f", 1438 "followers_url": "f", 1439 "gists_url": "g", 1440 "organizations_url": "o", 1441 "received_events_url": "r", 1442 "repos_url": "rep", 1443 "starred_url": "star", 1444 "subscriptions_url": "sub", 1445 "text_matches": [ 1446 { 1447 "object_url": "u", 1448 "object_type": "t", 1449 "property": "p", 1450 "fragment": "f", 1451 "matches": [ 1452 { 1453 "text": "t", 1454 "indices": [1, 2] 1455 } 1456 ] 1457 } 1458 ], 1459 "permissions": { 1460 "p1": true 1461 }, 1462 "role_name": "r" 1463 } 1464 }` 1465 1466 testJSONMarshal(t, u, w) 1467 } 1468 1469 func TestGlobalSecurityAdvisory_Marshal(t *testing.T) { 1470 testJSONMarshal(t, &GlobalSecurityAdvisory{}, `{}`) 1471 1472 testDate := &Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)} 1473 u := &GlobalSecurityAdvisory{ 1474 ID: Int64(1), 1475 RepositoryAdvisoryURL: String("r"), 1476 Type: String("t"), 1477 SourceCodeLocation: String("s"), 1478 References: []string{"r"}, 1479 Vulnerabilities: []*GlobalSecurityVulnerability{ 1480 { 1481 Package: &VulnerabilityPackage{ 1482 Ecosystem: String("npm"), 1483 Name: String("a-package"), 1484 }, 1485 FirstPatchedVersion: String("1.0.3"), 1486 VulnerableVersionRange: String("<=1.0.2"), 1487 VulnerableFunctions: []string{"a_function"}, 1488 }, 1489 }, 1490 GithubReviewedAt: testDate, 1491 NVDPublishedAt: testDate, 1492 Credits: []*Credit{ 1493 { 1494 Type: String("t"), 1495 User: &User{ 1496 Name: String("u"), 1497 Company: String("c"), 1498 Blog: String("b"), 1499 Location: String("l"), 1500 Email: String("e"), 1501 Hireable: Bool(false), 1502 Bio: String("bio"), 1503 TwitterUsername: String("tu"), 1504 PublicRepos: Int(1), 1505 PublicGists: Int(1), 1506 Followers: Int(2), 1507 Following: Int(2), 1508 CreatedAt: testDate, 1509 UpdatedAt: testDate, 1510 SuspendedAt: testDate, 1511 Type: String("type"), 1512 SiteAdmin: Bool(false), 1513 TotalPrivateRepos: Int64(10), 1514 OwnedPrivateRepos: Int64(10), 1515 PrivateGists: Int(10), 1516 DiskUsage: Int(10), 1517 Collaborators: Int(10), 1518 TwoFactorAuthentication: Bool(true), 1519 Plan: &Plan{ 1520 Name: String("p"), 1521 Space: Int(2), 1522 Collaborators: Int(2), 1523 PrivateRepos: Int64(2), 1524 Seats: Int(2), 1525 FilledSeats: Int(1), 1526 }, 1527 LdapDn: String("l"), 1528 URL: String("url"), 1529 EventsURL: String("e"), 1530 FollowingURL: String("f"), 1531 FollowersURL: String("f"), 1532 GistsURL: String("g"), 1533 OrganizationsURL: String("o"), 1534 ReceivedEventsURL: String("r"), 1535 ReposURL: String("rep"), 1536 StarredURL: String("star"), 1537 SubscriptionsURL: String("sub"), 1538 TextMatches: []*TextMatch{ 1539 { 1540 ObjectURL: String("u"), 1541 ObjectType: String("t"), 1542 Property: String("p"), 1543 Fragment: String("f"), 1544 Matches: []*Match{ 1545 { 1546 Text: String("t"), 1547 Indices: []int{1, 2}, 1548 }, 1549 }, 1550 }, 1551 }, 1552 Permissions: map[string]bool{"p1": true}, 1553 RoleName: String("r"), 1554 }, 1555 }, 1556 }, 1557 SecurityAdvisory: SecurityAdvisory{ 1558 GHSAID: String("GHSA-xoxo-1234-xoxo"), 1559 CVEID: String("CVE-xoxo-1234"), 1560 URL: String("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 1561 HTMLURL: String("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 1562 Severity: String("high"), 1563 Summary: String("Heartbleed security advisory"), 1564 Description: String("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 1565 Identifiers: []*AdvisoryIdentifier{ 1566 { 1567 Type: String("GHSA"), 1568 Value: String("GHSA-xoxo-1234-xoxo"), 1569 }, 1570 { 1571 Type: String("CVE"), 1572 Value: String("CVE-xoxo-1234"), 1573 }, 1574 }, 1575 PublishedAt: testDate, 1576 UpdatedAt: testDate, 1577 WithdrawnAt: nil, 1578 CVSS: &AdvisoryCVSS{ 1579 VectorString: String("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 1580 Score: Float64(7.6), 1581 }, 1582 CWEs: []*AdvisoryCWEs{ 1583 { 1584 CWEID: String("CWE-400"), 1585 Name: String("Uncontrolled Resource Consumption"), 1586 }, 1587 }, 1588 }, 1589 } 1590 1591 w := `{ 1592 "cvss": { 1593 "score": 7.6, 1594 "vector_string": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H" 1595 }, 1596 "cwes": [ 1597 { 1598 "cwe_id": "CWE-400", 1599 "name": "Uncontrolled Resource Consumption" 1600 } 1601 ], 1602 "ghsa_id": "GHSA-xoxo-1234-xoxo", 1603 "summary": "Heartbleed security advisory", 1604 "description": "This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information.", 1605 "severity": "high", 1606 "identifiers": [ 1607 { 1608 "value": "GHSA-xoxo-1234-xoxo", 1609 "type": "GHSA" 1610 }, 1611 { 1612 "value": "CVE-xoxo-1234", 1613 "type": "CVE" 1614 } 1615 ], 1616 "published_at": "2019-08-10T14:59:22Z", 1617 "updated_at": "2019-08-10T14:59:22Z", 1618 "cve_id": "CVE-xoxo-1234", 1619 "url": "https://api.github.com/advisories/GHSA-xoxo-1234-xoxo", 1620 "html_url": "https://github.com/advisories/GHSA-xoxo-1234-xoxo", 1621 "id": 1, 1622 "repository_advisory_url": "r", 1623 "type": "t", 1624 "source_code_location": "s", 1625 "references": [ 1626 "r" 1627 ], 1628 "vulnerabilities": [ 1629 { 1630 "package": { 1631 "ecosystem": "npm", 1632 "name": "a-package" 1633 }, 1634 "first_patched_version": "1.0.3", 1635 "vulnerable_version_range": "\u003c=1.0.2", 1636 "vulnerable_functions": [ 1637 "a_function" 1638 ] 1639 } 1640 ], 1641 "github_reviewed_at": "2019-08-10T14:59:22Z", 1642 "nvd_published_at": "2019-08-10T14:59:22Z", 1643 "credits": [ 1644 { 1645 "user": { 1646 "name": "u", 1647 "company": "c", 1648 "blog": "b", 1649 "location": "l", 1650 "email": "e", 1651 "hireable": false, 1652 "bio": "bio", 1653 "twitter_username": "tu", 1654 "public_repos": 1, 1655 "public_gists": 1, 1656 "followers": 2, 1657 "following": 2, 1658 "created_at": "2019-08-10T14:59:22Z", 1659 "updated_at": "2019-08-10T14:59:22Z", 1660 "suspended_at": "2019-08-10T14:59:22Z", 1661 "type": "type", 1662 "site_admin": false, 1663 "total_private_repos": 10, 1664 "owned_private_repos": 10, 1665 "private_gists": 10, 1666 "disk_usage": 10, 1667 "collaborators": 10, 1668 "two_factor_authentication": true, 1669 "plan": { 1670 "name": "p", 1671 "space": 2, 1672 "collaborators": 2, 1673 "private_repos": 2, 1674 "filled_seats": 1, 1675 "seats": 2 1676 }, 1677 "ldap_dn": "l", 1678 "url": "url", 1679 "events_url": "e", 1680 "following_url": "f", 1681 "followers_url": "f", 1682 "gists_url": "g", 1683 "organizations_url": "o", 1684 "received_events_url": "r", 1685 "repos_url": "rep", 1686 "starred_url": "star", 1687 "subscriptions_url": "sub", 1688 "text_matches": [ 1689 { 1690 "object_url": "u", 1691 "object_type": "t", 1692 "property": "p", 1693 "fragment": "f", 1694 "matches": [ 1695 { 1696 "text": "t", 1697 "indices": [ 1698 1, 1699 2 1700 ] 1701 } 1702 ] 1703 } 1704 ], 1705 "permissions": { 1706 "p1": true 1707 }, 1708 "role_name": "r" 1709 }, 1710 "type": "t" 1711 } 1712 ] 1713 }` 1714 1715 testJSONMarshal(t, u, w) 1716 }