github.com/google/go-github/v69@v69.2.0/github/git_trees_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 "bytes" 10 "context" 11 "fmt" 12 "io" 13 "net/http" 14 "testing" 15 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestMarshalJSON_withNilContentAndSHA(t *testing.T) { 20 t.Parallel() 21 te := &TreeEntry{ 22 Path: Ptr("path"), 23 Mode: Ptr("mode"), 24 Type: Ptr("type"), 25 Size: Ptr(1), 26 URL: Ptr("url"), 27 } 28 29 got, err := te.MarshalJSON() 30 if err != nil { 31 t.Errorf("MarshalJSON: %v", err) 32 } 33 34 want := `{"sha":null,"path":"path","mode":"mode","type":"type"}` 35 if string(got) != want { 36 t.Errorf("MarshalJSON = %s, want %v", got, want) 37 } 38 } 39 40 func TestGitService_GetTree(t *testing.T) { 41 t.Parallel() 42 client, mux, _ := setup(t) 43 44 mux.HandleFunc("/repos/o/r/git/trees/s", func(w http.ResponseWriter, r *http.Request) { 45 testMethod(t, r, "GET") 46 fmt.Fprint(w, `{ 47 "sha": "s", 48 "tree": [ { "type": "blob" } ], 49 "truncated": true 50 }`) 51 }) 52 53 ctx := context.Background() 54 tree, _, err := client.Git.GetTree(ctx, "o", "r", "s", true) 55 if err != nil { 56 t.Errorf("Git.GetTree returned error: %v", err) 57 } 58 59 want := Tree{ 60 SHA: Ptr("s"), 61 Entries: []*TreeEntry{ 62 { 63 Type: Ptr("blob"), 64 }, 65 }, 66 Truncated: Ptr(true), 67 } 68 if !cmp.Equal(*tree, want) { 69 t.Errorf("Tree.Get returned %+v, want %+v", *tree, want) 70 } 71 72 const methodName = "GetTree" 73 testBadOptions(t, methodName, func() (err error) { 74 _, _, err = client.Git.GetTree(ctx, "\n", "\n", "\n", true) 75 return err 76 }) 77 78 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 79 got, resp, err := client.Git.GetTree(ctx, "o", "r", "s", true) 80 if got != nil { 81 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 82 } 83 return resp, err 84 }) 85 } 86 87 func TestGitService_GetTree_invalidOwner(t *testing.T) { 88 t.Parallel() 89 client, _, _ := setup(t) 90 91 ctx := context.Background() 92 _, _, err := client.Git.GetTree(ctx, "%", "%", "%", false) 93 testURLParseError(t, err) 94 } 95 96 func TestGitService_CreateTree(t *testing.T) { 97 t.Parallel() 98 client, mux, _ := setup(t) 99 100 input := []*TreeEntry{ 101 { 102 Path: Ptr("file.rb"), 103 Mode: Ptr("100644"), 104 Type: Ptr("blob"), 105 SHA: Ptr("7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"), 106 }, 107 } 108 109 mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) { 110 got, err := io.ReadAll(r.Body) 111 if err != nil { 112 t.Fatalf("unable to read body: %v", err) 113 } 114 115 testMethod(t, r, "POST") 116 117 want := []byte(`{"base_tree":"b","tree":[{"sha":"7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b","path":"file.rb","mode":"100644","type":"blob"}]}` + "\n") 118 if !bytes.Equal(got, want) { 119 t.Errorf("Git.CreateTree request body: %s, want %s", got, want) 120 } 121 122 fmt.Fprint(w, `{ 123 "sha": "cd8274d15fa3ae2ab983129fb037999f264ba9a7", 124 "tree": [ 125 { 126 "path": "file.rb", 127 "mode": "100644", 128 "type": "blob", 129 "size": 132, 130 "sha": "7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b" 131 } 132 ] 133 }`) 134 }) 135 136 ctx := context.Background() 137 tree, _, err := client.Git.CreateTree(ctx, "o", "r", "b", input) 138 if err != nil { 139 t.Errorf("Git.CreateTree returned error: %v", err) 140 } 141 142 want := Tree{ 143 Ptr("cd8274d15fa3ae2ab983129fb037999f264ba9a7"), 144 []*TreeEntry{ 145 { 146 Path: Ptr("file.rb"), 147 Mode: Ptr("100644"), 148 Type: Ptr("blob"), 149 Size: Ptr(132), 150 SHA: Ptr("7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"), 151 }, 152 }, 153 nil, 154 } 155 156 if !cmp.Equal(*tree, want) { 157 t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want) 158 } 159 160 const methodName = "CreateTree" 161 testBadOptions(t, methodName, func() (err error) { 162 _, _, err = client.Git.CreateTree(ctx, "\n", "\n", "\n", input) 163 return err 164 }) 165 166 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 167 got, resp, err := client.Git.CreateTree(ctx, "o", "r", "b", input) 168 if got != nil { 169 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 170 } 171 return resp, err 172 }) 173 } 174 175 func TestGitService_CreateTree_Content(t *testing.T) { 176 t.Parallel() 177 client, mux, _ := setup(t) 178 179 input := []*TreeEntry{ 180 { 181 Path: Ptr("content.md"), 182 Mode: Ptr("100644"), 183 Content: Ptr("file content"), 184 }, 185 } 186 187 mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) { 188 got, err := io.ReadAll(r.Body) 189 if err != nil { 190 t.Fatalf("unable to read body: %v", err) 191 } 192 193 testMethod(t, r, "POST") 194 195 want := []byte(`{"base_tree":"b","tree":[{"path":"content.md","mode":"100644","content":"file content"}]}` + "\n") 196 if !bytes.Equal(got, want) { 197 t.Errorf("Git.CreateTree request body: %s, want %s", got, want) 198 } 199 200 fmt.Fprint(w, `{ 201 "sha": "5c6780ad2c68743383b740fd1dab6f6a33202b11", 202 "url": "https://api.github.com/repos/o/r/git/trees/5c6780ad2c68743383b740fd1dab6f6a33202b11", 203 "tree": [ 204 { 205 "mode": "100644", 206 "type": "blob", 207 "sha": "aad8feacf6f8063150476a7b2bd9770f2794c08b", 208 "path": "content.md", 209 "size": 12, 210 "url": "https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b" 211 } 212 ] 213 }`) 214 }) 215 216 ctx := context.Background() 217 tree, _, err := client.Git.CreateTree(ctx, "o", "r", "b", input) 218 if err != nil { 219 t.Errorf("Git.CreateTree returned error: %v", err) 220 } 221 222 want := Tree{ 223 Ptr("5c6780ad2c68743383b740fd1dab6f6a33202b11"), 224 []*TreeEntry{ 225 { 226 Path: Ptr("content.md"), 227 Mode: Ptr("100644"), 228 Type: Ptr("blob"), 229 Size: Ptr(12), 230 SHA: Ptr("aad8feacf6f8063150476a7b2bd9770f2794c08b"), 231 URL: Ptr("https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b"), 232 }, 233 }, 234 nil, 235 } 236 237 if !cmp.Equal(*tree, want) { 238 t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want) 239 } 240 241 const methodName = "CreateTree" 242 testBadOptions(t, methodName, func() (err error) { 243 _, _, err = client.Git.CreateTree(ctx, "\n", "\n", "\n", input) 244 return err 245 }) 246 247 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 248 got, resp, err := client.Git.CreateTree(ctx, "o", "r", "b", input) 249 if got != nil { 250 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 251 } 252 return resp, err 253 }) 254 } 255 256 func TestGitService_CreateTree_Delete(t *testing.T) { 257 t.Parallel() 258 client, mux, _ := setup(t) 259 260 input := []*TreeEntry{ 261 { 262 Path: Ptr("content.md"), 263 Mode: Ptr("100644"), 264 }, 265 } 266 267 mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) { 268 got, err := io.ReadAll(r.Body) 269 if err != nil { 270 t.Fatalf("unable to read body: %v", err) 271 } 272 273 testMethod(t, r, "POST") 274 275 want := []byte(`{"base_tree":"b","tree":[{"sha":null,"path":"content.md","mode":"100644"}]}` + "\n") 276 if !bytes.Equal(got, want) { 277 t.Errorf("Git.CreateTree request body: %s, want %s", got, want) 278 } 279 280 fmt.Fprint(w, `{ 281 "sha": "5c6780ad2c68743383b740fd1dab6f6a33202b11", 282 "url": "https://api.github.com/repos/o/r/git/trees/5c6780ad2c68743383b740fd1dab6f6a33202b11", 283 "tree": [ 284 { 285 "mode": "100644", 286 "type": "blob", 287 "sha": null, 288 "path": "content.md", 289 "size": 12, 290 "url": "https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b" 291 } 292 ] 293 }`) 294 }) 295 296 ctx := context.Background() 297 tree, _, err := client.Git.CreateTree(ctx, "o", "r", "b", input) 298 if err != nil { 299 t.Errorf("Git.CreateTree returned error: %v", err) 300 } 301 302 want := Tree{ 303 Ptr("5c6780ad2c68743383b740fd1dab6f6a33202b11"), 304 []*TreeEntry{ 305 { 306 Path: Ptr("content.md"), 307 Mode: Ptr("100644"), 308 Type: Ptr("blob"), 309 Size: Ptr(12), 310 SHA: nil, 311 URL: Ptr("https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b"), 312 }, 313 }, 314 nil, 315 } 316 317 if !cmp.Equal(*tree, want) { 318 t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want) 319 } 320 321 const methodName = "CreateTree" 322 testBadOptions(t, methodName, func() (err error) { 323 _, _, err = client.Git.CreateTree(ctx, "\n", "\n", "\n", input) 324 return err 325 }) 326 327 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 328 got, resp, err := client.Git.CreateTree(ctx, "o", "r", "b", input) 329 if got != nil { 330 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 331 } 332 return resp, err 333 }) 334 } 335 336 func TestGitService_CreateTree_invalidOwner(t *testing.T) { 337 t.Parallel() 338 client, _, _ := setup(t) 339 340 ctx := context.Background() 341 _, _, err := client.Git.CreateTree(ctx, "%", "%", "", nil) 342 testURLParseError(t, err) 343 } 344 345 func TestTree_Marshal(t *testing.T) { 346 t.Parallel() 347 testJSONMarshal(t, &Tree{}, "{}") 348 349 u := &Tree{ 350 SHA: Ptr("sha"), 351 Entries: []*TreeEntry{ 352 { 353 SHA: Ptr("sha"), 354 Path: Ptr("path"), 355 Mode: Ptr("mode"), 356 Type: Ptr("type"), 357 Size: Ptr(1), 358 Content: Ptr("content"), 359 URL: Ptr("url"), 360 }, 361 }, 362 Truncated: Ptr(false), 363 } 364 365 want := `{ 366 "sha": "sha", 367 "tree": [ 368 { 369 "sha": "sha", 370 "path": "path", 371 "mode": "mode", 372 "type": "type", 373 "size": 1, 374 "content": "content", 375 "url": "url" 376 } 377 ], 378 "truncated": false 379 }` 380 381 testJSONMarshal(t, u, want) 382 } 383 384 func TestTreeEntry_Marshal(t *testing.T) { 385 t.Parallel() 386 testJSONMarshal(t, &TreeEntry{}, "{}") 387 388 u := &TreeEntry{ 389 SHA: Ptr("sha"), 390 Path: Ptr("path"), 391 Mode: Ptr("mode"), 392 Type: Ptr("type"), 393 Size: Ptr(1), 394 Content: Ptr("content"), 395 URL: Ptr("url"), 396 } 397 398 want := `{ 399 "sha": "sha", 400 "path": "path", 401 "mode": "mode", 402 "type": "type", 403 "size": 1, 404 "content": "content", 405 "url": "url" 406 }` 407 408 testJSONMarshal(t, u, want) 409 } 410 411 func TestTreeEntryWithFileDelete_Marshal(t *testing.T) { 412 t.Parallel() 413 testJSONMarshal(t, &treeEntryWithFileDelete{}, "{}") 414 415 u := &treeEntryWithFileDelete{ 416 SHA: Ptr("sha"), 417 Path: Ptr("path"), 418 Mode: Ptr("mode"), 419 Type: Ptr("type"), 420 Size: Ptr(1), 421 Content: Ptr("content"), 422 URL: Ptr("url"), 423 } 424 425 want := `{ 426 "sha": "sha", 427 "path": "path", 428 "mode": "mode", 429 "type": "type", 430 "size": 1, 431 "content": "content", 432 "url": "url" 433 }` 434 435 testJSONMarshal(t, u, want) 436 } 437 438 func TestCreateTree_Marshal(t *testing.T) { 439 t.Parallel() 440 testJSONMarshal(t, &createTree{}, "{}") 441 442 u := &createTree{ 443 BaseTree: "bt", 444 Entries: []interface{}{"e"}, 445 } 446 447 want := `{ 448 "base_tree": "bt", 449 "tree": ["e"] 450 }` 451 452 testJSONMarshal(t, u, want) 453 }