github.com/google/go-github/v74@v74.0.0/github/pulls_comments_test.go (about) 1 // Copyright 2013 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 "encoding/json" 11 "fmt" 12 "net/http" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/google/go-cmp/cmp" 18 ) 19 20 func TestPullComments_Marshal(t *testing.T) { 21 t.Parallel() 22 testJSONMarshal(t, &PullRequestComment{}, "{}") 23 24 createdAt := Timestamp{time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)} 25 updatedAt := Timestamp{time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)} 26 reactions := &Reactions{ 27 TotalCount: Ptr(1), 28 PlusOne: Ptr(1), 29 MinusOne: Ptr(0), 30 Laugh: Ptr(0), 31 Confused: Ptr(0), 32 Heart: Ptr(0), 33 Hooray: Ptr(0), 34 Rocket: Ptr(0), 35 Eyes: Ptr(0), 36 URL: Ptr("u"), 37 } 38 39 u := &PullRequestComment{ 40 ID: Ptr(int64(10)), 41 InReplyTo: Ptr(int64(8)), 42 Body: Ptr("Test comment"), 43 Path: Ptr("file1.txt"), 44 DiffHunk: Ptr("@@ -16,33 +16,40 @@ fmt.Println()"), 45 PullRequestReviewID: Ptr(int64(42)), 46 Position: Ptr(1), 47 OriginalPosition: Ptr(4), 48 StartLine: Ptr(2), 49 Line: Ptr(3), 50 OriginalLine: Ptr(2), 51 OriginalStartLine: Ptr(2), 52 Side: Ptr("RIGHT"), 53 StartSide: Ptr("LEFT"), 54 CommitID: Ptr("ab"), 55 OriginalCommitID: Ptr("9c"), 56 User: &User{ 57 Login: Ptr("ll"), 58 ID: Ptr(int64(123)), 59 AvatarURL: Ptr("a"), 60 GravatarID: Ptr("g"), 61 Name: Ptr("n"), 62 Company: Ptr("c"), 63 Blog: Ptr("b"), 64 Location: Ptr("l"), 65 Email: Ptr("e"), 66 Hireable: Ptr(true), 67 PublicRepos: Ptr(1), 68 Followers: Ptr(1), 69 Following: Ptr(1), 70 CreatedAt: &Timestamp{referenceTime}, 71 URL: Ptr("u"), 72 }, 73 Reactions: reactions, 74 CreatedAt: &createdAt, 75 UpdatedAt: &updatedAt, 76 URL: Ptr("pullrequestcommentUrl"), 77 HTMLURL: Ptr("pullrequestcommentHTMLUrl"), 78 PullRequestURL: Ptr("pullrequestcommentPullRequestURL"), 79 } 80 81 want := `{ 82 "id": 10, 83 "in_reply_to_id": 8, 84 "body": "Test comment", 85 "path": "file1.txt", 86 "diff_hunk": "@@ -16,33 +16,40 @@ fmt.Println()", 87 "pull_request_review_id": 42, 88 "position": 1, 89 "original_position": 4, 90 "start_line": 2, 91 "line": 3, 92 "original_line": 2, 93 "original_start_line": 2, 94 "side": "RIGHT", 95 "start_side": "LEFT", 96 "commit_id": "ab", 97 "original_commit_id": "9c", 98 "user": { 99 "login": "ll", 100 "id": 123, 101 "avatar_url": "a", 102 "gravatar_id": "g", 103 "name": "n", 104 "company": "c", 105 "blog": "b", 106 "location": "l", 107 "email": "e", 108 "hireable": true, 109 "public_repos": 1, 110 "followers": 1, 111 "following": 1, 112 "created_at": ` + referenceTimeStr + `, 113 "url": "u" 114 }, 115 "reactions": { 116 "total_count": 1, 117 "+1": 1, 118 "-1": 0, 119 "laugh": 0, 120 "confused": 0, 121 "heart": 0, 122 "hooray": 0, 123 "rocket": 0, 124 "eyes": 0, 125 "url": "u" 126 }, 127 "created_at": "2002-02-10T15:30:00Z", 128 "updated_at": "2002-02-10T15:30:00Z", 129 "url": "pullrequestcommentUrl", 130 "html_url": "pullrequestcommentHTMLUrl", 131 "pull_request_url": "pullrequestcommentPullRequestURL" 132 }` 133 134 testJSONMarshal(t, u, want) 135 } 136 137 func TestPullRequestsService_ListComments_allPulls(t *testing.T) { 138 t.Parallel() 139 client, mux, _ := setup(t) 140 141 wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} 142 mux.HandleFunc("/repos/o/r/pulls/comments", func(w http.ResponseWriter, r *http.Request) { 143 testMethod(t, r, "GET") 144 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 145 testFormValues(t, r, values{ 146 "sort": "updated", 147 "direction": "desc", 148 "since": "2002-02-10T15:30:00Z", 149 "page": "2", 150 }) 151 fmt.Fprint(w, `[{"id":1}]`) 152 }) 153 154 opt := &PullRequestListCommentsOptions{ 155 Sort: "updated", 156 Direction: "desc", 157 Since: time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC), 158 ListOptions: ListOptions{Page: 2}, 159 } 160 ctx := context.Background() 161 pulls, _, err := client.PullRequests.ListComments(ctx, "o", "r", 0, opt) 162 if err != nil { 163 t.Errorf("PullRequests.ListComments returned error: %v", err) 164 } 165 166 want := []*PullRequestComment{{ID: Ptr(int64(1))}} 167 if !cmp.Equal(pulls, want) { 168 t.Errorf("PullRequests.ListComments returned %+v, want %+v", pulls, want) 169 } 170 171 const methodName = "ListComments" 172 testBadOptions(t, methodName, func() (err error) { 173 _, _, err = client.PullRequests.ListComments(ctx, "\n", "\n", -1, opt) 174 return err 175 }) 176 177 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 178 got, resp, err := client.PullRequests.ListComments(ctx, "o", "r", 0, opt) 179 if got != nil { 180 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 181 } 182 return resp, err 183 }) 184 } 185 186 func TestPullRequestsService_ListComments_specificPull(t *testing.T) { 187 t.Parallel() 188 client, mux, _ := setup(t) 189 190 wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} 191 mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) { 192 testMethod(t, r, "GET") 193 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 194 fmt.Fprint(w, `[{"id":1, "pull_request_review_id":42}]`) 195 }) 196 197 ctx := context.Background() 198 pulls, _, err := client.PullRequests.ListComments(ctx, "o", "r", 1, nil) 199 if err != nil { 200 t.Errorf("PullRequests.ListComments returned error: %v", err) 201 } 202 203 want := []*PullRequestComment{{ID: Ptr(int64(1)), PullRequestReviewID: Ptr(int64(42))}} 204 if !cmp.Equal(pulls, want) { 205 t.Errorf("PullRequests.ListComments returned %+v, want %+v", pulls, want) 206 } 207 } 208 209 func TestPullRequestsService_ListComments_invalidOwner(t *testing.T) { 210 t.Parallel() 211 client, _, _ := setup(t) 212 213 ctx := context.Background() 214 _, _, err := client.PullRequests.ListComments(ctx, "%", "r", 1, nil) 215 testURLParseError(t, err) 216 } 217 218 func TestPullRequestsService_GetComment(t *testing.T) { 219 t.Parallel() 220 client, mux, _ := setup(t) 221 222 wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} 223 mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) { 224 testMethod(t, r, "GET") 225 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 226 fmt.Fprint(w, `{"id":1}`) 227 }) 228 229 ctx := context.Background() 230 comment, _, err := client.PullRequests.GetComment(ctx, "o", "r", 1) 231 if err != nil { 232 t.Errorf("PullRequests.GetComment returned error: %v", err) 233 } 234 235 want := &PullRequestComment{ID: Ptr(int64(1))} 236 if !cmp.Equal(comment, want) { 237 t.Errorf("PullRequests.GetComment returned %+v, want %+v", comment, want) 238 } 239 240 const methodName = "GetComment" 241 testBadOptions(t, methodName, func() (err error) { 242 _, _, err = client.PullRequests.GetComment(ctx, "\n", "\n", -1) 243 return err 244 }) 245 246 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 247 got, resp, err := client.PullRequests.GetComment(ctx, "o", "r", 1) 248 if got != nil { 249 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 250 } 251 return resp, err 252 }) 253 } 254 255 func TestPullRequestsService_GetComment_invalidOwner(t *testing.T) { 256 t.Parallel() 257 client, _, _ := setup(t) 258 259 ctx := context.Background() 260 _, _, err := client.PullRequests.GetComment(ctx, "%", "r", 1) 261 testURLParseError(t, err) 262 } 263 264 func TestPullRequestsService_CreateComment(t *testing.T) { 265 t.Parallel() 266 client, mux, _ := setup(t) 267 268 input := &PullRequestComment{Body: Ptr("b")} 269 270 wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview} 271 mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) { 272 v := new(PullRequestComment) 273 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 274 275 // TODO: remove custom Accept header assertion when the API fully launches. 276 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 277 testMethod(t, r, "POST") 278 if !cmp.Equal(v, input) { 279 t.Errorf("Request body = %+v, want %+v", v, input) 280 } 281 282 fmt.Fprint(w, `{"id":1}`) 283 }) 284 285 ctx := context.Background() 286 comment, _, err := client.PullRequests.CreateComment(ctx, "o", "r", 1, input) 287 if err != nil { 288 t.Errorf("PullRequests.CreateComment returned error: %v", err) 289 } 290 291 want := &PullRequestComment{ID: Ptr(int64(1))} 292 if !cmp.Equal(comment, want) { 293 t.Errorf("PullRequests.CreateComment returned %+v, want %+v", comment, want) 294 } 295 296 const methodName = "CreateComment" 297 testBadOptions(t, methodName, func() (err error) { 298 _, _, err = client.PullRequests.CreateComment(ctx, "\n", "\n", -1, input) 299 return err 300 }) 301 302 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 303 got, resp, err := client.PullRequests.CreateComment(ctx, "o", "r", 1, input) 304 if got != nil { 305 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 306 } 307 return resp, err 308 }) 309 } 310 311 func TestPullRequestsService_CreateComment_invalidOwner(t *testing.T) { 312 t.Parallel() 313 client, _, _ := setup(t) 314 315 ctx := context.Background() 316 _, _, err := client.PullRequests.CreateComment(ctx, "%", "r", 1, nil) 317 testURLParseError(t, err) 318 } 319 320 func TestPullRequestsService_CreateCommentInReplyTo(t *testing.T) { 321 t.Parallel() 322 client, mux, _ := setup(t) 323 324 input := &PullRequestComment{Body: Ptr("b")} 325 326 mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) { 327 v := new(PullRequestComment) 328 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 329 330 testMethod(t, r, "POST") 331 if !cmp.Equal(v, input) { 332 t.Errorf("Request body = %+v, want %+v", v, input) 333 } 334 335 fmt.Fprint(w, `{"id":1}`) 336 }) 337 338 ctx := context.Background() 339 comment, _, err := client.PullRequests.CreateCommentInReplyTo(ctx, "o", "r", 1, "b", 2) 340 if err != nil { 341 t.Errorf("PullRequests.CreateCommentInReplyTo returned error: %v", err) 342 } 343 344 want := &PullRequestComment{ID: Ptr(int64(1))} 345 if !cmp.Equal(comment, want) { 346 t.Errorf("PullRequests.CreateCommentInReplyTo returned %+v, want %+v", comment, want) 347 } 348 349 const methodName = "CreateCommentInReplyTo" 350 testBadOptions(t, methodName, func() (err error) { 351 _, _, err = client.PullRequests.CreateCommentInReplyTo(ctx, "\n", "\n", -1, "\n", -2) 352 return err 353 }) 354 355 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 356 got, resp, err := client.PullRequests.CreateCommentInReplyTo(ctx, "o", "r", 1, "b", 2) 357 if got != nil { 358 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 359 } 360 return resp, err 361 }) 362 } 363 364 func TestPullRequestsService_EditComment(t *testing.T) { 365 t.Parallel() 366 client, mux, _ := setup(t) 367 368 input := &PullRequestComment{Body: Ptr("b")} 369 370 mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) { 371 v := new(PullRequestComment) 372 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 373 374 testMethod(t, r, "PATCH") 375 if !cmp.Equal(v, input) { 376 t.Errorf("Request body = %+v, want %+v", v, input) 377 } 378 379 fmt.Fprint(w, `{"id":1}`) 380 }) 381 382 ctx := context.Background() 383 comment, _, err := client.PullRequests.EditComment(ctx, "o", "r", 1, input) 384 if err != nil { 385 t.Errorf("PullRequests.EditComment returned error: %v", err) 386 } 387 388 want := &PullRequestComment{ID: Ptr(int64(1))} 389 if !cmp.Equal(comment, want) { 390 t.Errorf("PullRequests.EditComment returned %+v, want %+v", comment, want) 391 } 392 393 const methodName = "EditComment" 394 testBadOptions(t, methodName, func() (err error) { 395 _, _, err = client.PullRequests.EditComment(ctx, "\n", "\n", -1, input) 396 return err 397 }) 398 399 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 400 got, resp, err := client.PullRequests.EditComment(ctx, "o", "r", 1, input) 401 if got != nil { 402 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 403 } 404 return resp, err 405 }) 406 } 407 408 func TestPullRequestsService_EditComment_invalidOwner(t *testing.T) { 409 t.Parallel() 410 client, _, _ := setup(t) 411 412 ctx := context.Background() 413 _, _, err := client.PullRequests.EditComment(ctx, "%", "r", 1, nil) 414 testURLParseError(t, err) 415 } 416 417 func TestPullRequestsService_DeleteComment(t *testing.T) { 418 t.Parallel() 419 client, mux, _ := setup(t) 420 421 mux.HandleFunc("/repos/o/r/pulls/comments/1", func(_ http.ResponseWriter, r *http.Request) { 422 testMethod(t, r, "DELETE") 423 }) 424 425 ctx := context.Background() 426 _, err := client.PullRequests.DeleteComment(ctx, "o", "r", 1) 427 if err != nil { 428 t.Errorf("PullRequests.DeleteComment returned error: %v", err) 429 } 430 431 const methodName = "DeleteComment" 432 testBadOptions(t, methodName, func() (err error) { 433 _, err = client.PullRequests.DeleteComment(ctx, "\n", "\n", -1) 434 return err 435 }) 436 437 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 438 return client.PullRequests.DeleteComment(ctx, "o", "r", 1) 439 }) 440 } 441 442 func TestPullRequestsService_DeleteComment_invalidOwner(t *testing.T) { 443 t.Parallel() 444 client, _, _ := setup(t) 445 446 ctx := context.Background() 447 _, err := client.PullRequests.DeleteComment(ctx, "%", "r", 1) 448 testURLParseError(t, err) 449 }