github.com/google/go-github/v49@v49.1.0/github/actions_artifacts_test.go (about) 1 // Copyright 2020 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 "errors" 11 "fmt" 12 "net/http" 13 "net/url" 14 "testing" 15 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestActionsService_ListArtifacts(t *testing.T) { 20 client, mux, _, teardown := setup() 21 defer teardown() 22 23 mux.HandleFunc("/repos/o/r/actions/artifacts", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "GET") 25 testFormValues(t, r, values{"page": "2"}) 26 fmt.Fprint(w, 27 `{ 28 "total_count":1, 29 "artifacts":[{"id":1}] 30 }`, 31 ) 32 }) 33 34 opts := &ListOptions{Page: 2} 35 ctx := context.Background() 36 artifacts, _, err := client.Actions.ListArtifacts(ctx, "o", "r", opts) 37 if err != nil { 38 t.Errorf("Actions.ListArtifacts returned error: %v", err) 39 } 40 41 want := &ArtifactList{TotalCount: Int64(1), Artifacts: []*Artifact{{ID: Int64(1)}}} 42 if !cmp.Equal(artifacts, want) { 43 t.Errorf("Actions.ListArtifacts returned %+v, want %+v", artifacts, want) 44 } 45 46 const methodName = "ListArtifacts" 47 testBadOptions(t, methodName, func() (err error) { 48 _, _, err = client.Actions.ListArtifacts(ctx, "\n", "\n", opts) 49 return err 50 }) 51 52 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 53 got, resp, err := client.Actions.ListArtifacts(ctx, "o", "r", opts) 54 if got != nil { 55 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 56 } 57 return resp, err 58 }) 59 } 60 61 func TestActionsService_ListArtifacts_invalidOwner(t *testing.T) { 62 client, _, _, teardown := setup() 63 defer teardown() 64 65 ctx := context.Background() 66 _, _, err := client.Actions.ListArtifacts(ctx, "%", "r", nil) 67 testURLParseError(t, err) 68 } 69 70 func TestActionsService_ListArtifacts_invalidRepo(t *testing.T) { 71 client, _, _, teardown := setup() 72 defer teardown() 73 74 ctx := context.Background() 75 _, _, err := client.Actions.ListArtifacts(ctx, "o", "%", nil) 76 testURLParseError(t, err) 77 } 78 79 func TestActionsService_ListArtifacts_notFound(t *testing.T) { 80 client, mux, _, teardown := setup() 81 defer teardown() 82 83 mux.HandleFunc("/repos/o/r/actions/artifacts", func(w http.ResponseWriter, r *http.Request) { 84 testMethod(t, r, "GET") 85 w.WriteHeader(http.StatusNotFound) 86 }) 87 88 ctx := context.Background() 89 artifacts, resp, err := client.Actions.ListArtifacts(ctx, "o", "r", nil) 90 if err == nil { 91 t.Errorf("Expected HTTP 404 response") 92 } 93 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 94 t.Errorf("Actions.ListArtifacts return status %d, want %d", got, want) 95 } 96 if artifacts != nil { 97 t.Errorf("Actions.ListArtifacts return %+v, want nil", artifacts) 98 } 99 } 100 101 func TestActionsService_ListWorkflowRunArtifacts(t *testing.T) { 102 client, mux, _, teardown := setup() 103 defer teardown() 104 105 mux.HandleFunc("/repos/o/r/actions/runs/1/artifacts", func(w http.ResponseWriter, r *http.Request) { 106 testMethod(t, r, "GET") 107 testFormValues(t, r, values{"page": "2"}) 108 fmt.Fprint(w, 109 `{ 110 "total_count":1, 111 "artifacts":[{"id":1}] 112 }`, 113 ) 114 }) 115 116 opts := &ListOptions{Page: 2} 117 ctx := context.Background() 118 artifacts, _, err := client.Actions.ListWorkflowRunArtifacts(ctx, "o", "r", 1, opts) 119 if err != nil { 120 t.Errorf("Actions.ListWorkflowRunArtifacts returned error: %v", err) 121 } 122 123 want := &ArtifactList{TotalCount: Int64(1), Artifacts: []*Artifact{{ID: Int64(1)}}} 124 if !cmp.Equal(artifacts, want) { 125 t.Errorf("Actions.ListWorkflowRunArtifacts returned %+v, want %+v", artifacts, want) 126 } 127 128 const methodName = "ListWorkflowRunArtifacts" 129 testBadOptions(t, methodName, func() (err error) { 130 _, _, err = client.Actions.ListWorkflowRunArtifacts(ctx, "\n", "\n", -1, opts) 131 return err 132 }) 133 134 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 135 got, resp, err := client.Actions.ListWorkflowRunArtifacts(ctx, "o", "r", 1, opts) 136 if got != nil { 137 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 138 } 139 return resp, err 140 }) 141 } 142 143 func TestActionsService_ListWorkflowRunArtifacts_invalidOwner(t *testing.T) { 144 client, _, _, teardown := setup() 145 defer teardown() 146 147 ctx := context.Background() 148 _, _, err := client.Actions.ListWorkflowRunArtifacts(ctx, "%", "r", 1, nil) 149 testURLParseError(t, err) 150 } 151 152 func TestActionsService_ListWorkflowRunArtifacts_invalidRepo(t *testing.T) { 153 client, _, _, teardown := setup() 154 defer teardown() 155 156 ctx := context.Background() 157 _, _, err := client.Actions.ListWorkflowRunArtifacts(ctx, "o", "%", 1, nil) 158 testURLParseError(t, err) 159 } 160 161 func TestActionsService_ListWorkflowRunArtifacts_notFound(t *testing.T) { 162 client, mux, _, teardown := setup() 163 defer teardown() 164 165 mux.HandleFunc("/repos/o/r/actions/runs/1/artifacts", func(w http.ResponseWriter, r *http.Request) { 166 testMethod(t, r, "GET") 167 w.WriteHeader(http.StatusNotFound) 168 }) 169 170 ctx := context.Background() 171 artifacts, resp, err := client.Actions.ListWorkflowRunArtifacts(ctx, "o", "r", 1, nil) 172 if err == nil { 173 t.Errorf("Expected HTTP 404 response") 174 } 175 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 176 t.Errorf("Actions.ListWorkflowRunArtifacts return status %d, want %d", got, want) 177 } 178 if artifacts != nil { 179 t.Errorf("Actions.ListWorkflowRunArtifacts return %+v, want nil", artifacts) 180 } 181 } 182 183 func TestActionsService_GetArtifact(t *testing.T) { 184 client, mux, _, teardown := setup() 185 defer teardown() 186 187 mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { 188 testMethod(t, r, "GET") 189 fmt.Fprint(w, `{ 190 "id":1, 191 "node_id":"xyz", 192 "name":"a", 193 "size_in_bytes":5, 194 "archive_download_url":"u" 195 }`) 196 }) 197 198 ctx := context.Background() 199 artifact, _, err := client.Actions.GetArtifact(ctx, "o", "r", 1) 200 if err != nil { 201 t.Errorf("Actions.GetArtifact returned error: %v", err) 202 } 203 204 want := &Artifact{ 205 ID: Int64(1), 206 NodeID: String("xyz"), 207 Name: String("a"), 208 SizeInBytes: Int64(5), 209 ArchiveDownloadURL: String("u"), 210 } 211 if !cmp.Equal(artifact, want) { 212 t.Errorf("Actions.GetArtifact returned %+v, want %+v", artifact, want) 213 } 214 215 const methodName = "GetArtifact" 216 testBadOptions(t, methodName, func() (err error) { 217 _, _, err = client.Actions.GetArtifact(ctx, "\n", "\n", -1) 218 return err 219 }) 220 221 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 222 got, resp, err := client.Actions.GetArtifact(ctx, "o", "r", 1) 223 if got != nil { 224 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 225 } 226 return resp, err 227 }) 228 } 229 230 func TestActionsService_GetArtifact_invalidOwner(t *testing.T) { 231 client, _, _, teardown := setup() 232 defer teardown() 233 234 ctx := context.Background() 235 _, _, err := client.Actions.GetArtifact(ctx, "%", "r", 1) 236 testURLParseError(t, err) 237 } 238 239 func TestActionsService_GetArtifact_invalidRepo(t *testing.T) { 240 client, _, _, teardown := setup() 241 defer teardown() 242 243 ctx := context.Background() 244 _, _, err := client.Actions.GetArtifact(ctx, "o", "%", 1) 245 testURLParseError(t, err) 246 } 247 248 func TestActionsService_GetArtifact_notFound(t *testing.T) { 249 client, mux, _, teardown := setup() 250 defer teardown() 251 252 mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { 253 testMethod(t, r, "GET") 254 w.WriteHeader(http.StatusNotFound) 255 }) 256 257 ctx := context.Background() 258 artifact, resp, err := client.Actions.GetArtifact(ctx, "o", "r", 1) 259 if err == nil { 260 t.Errorf("Expected HTTP 404 response") 261 } 262 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 263 t.Errorf("Actions.GetArtifact return status %d, want %d", got, want) 264 } 265 if artifact != nil { 266 t.Errorf("Actions.GetArtifact return %+v, want nil", artifact) 267 } 268 } 269 270 func TestActionsSerivice_DownloadArtifact(t *testing.T) { 271 client, mux, _, teardown := setup() 272 defer teardown() 273 274 mux.HandleFunc("/repos/o/r/actions/artifacts/1/zip", func(w http.ResponseWriter, r *http.Request) { 275 testMethod(t, r, "GET") 276 http.Redirect(w, r, "https://github.com/artifact", http.StatusFound) 277 }) 278 279 ctx := context.Background() 280 url, resp, err := client.Actions.DownloadArtifact(ctx, "o", "r", 1, true) 281 if err != nil { 282 t.Errorf("Actions.DownloadArtifact returned error: %v", err) 283 } 284 if resp.StatusCode != http.StatusFound { 285 t.Errorf("Actions.DownloadArtifact returned status: %d, want %d", resp.StatusCode, http.StatusFound) 286 } 287 288 want := "https://github.com/artifact" 289 if url.String() != want { 290 t.Errorf("Actions.DownloadArtifact returned %+v, want %+v", url.String(), want) 291 } 292 293 const methodName = "DownloadArtifact" 294 testBadOptions(t, methodName, func() (err error) { 295 _, _, err = client.Actions.DownloadArtifact(ctx, "\n", "\n", -1, true) 296 return err 297 }) 298 299 // Add custom round tripper 300 client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) { 301 return nil, errors.New("failed to download artifact") 302 }) 303 testBadOptions(t, methodName, func() (err error) { 304 _, _, err = client.Actions.DownloadArtifact(ctx, "o", "r", 1, true) 305 return err 306 }) 307 } 308 309 func TestActionsService_DownloadArtifact_invalidOwner(t *testing.T) { 310 client, _, _, teardown := setup() 311 defer teardown() 312 313 ctx := context.Background() 314 _, _, err := client.Actions.DownloadArtifact(ctx, "%", "r", 1, true) 315 testURLParseError(t, err) 316 } 317 318 func TestActionsService_DownloadArtifact_invalidRepo(t *testing.T) { 319 client, _, _, teardown := setup() 320 defer teardown() 321 322 ctx := context.Background() 323 _, _, err := client.Actions.DownloadArtifact(ctx, "o", "%", 1, true) 324 testURLParseError(t, err) 325 } 326 327 func TestActionsService_DownloadArtifact_StatusMovedPermanently_dontFollowRedirects(t *testing.T) { 328 client, mux, _, teardown := setup() 329 defer teardown() 330 331 mux.HandleFunc("/repos/o/r/actions/artifacts/1/zip", func(w http.ResponseWriter, r *http.Request) { 332 testMethod(t, r, "GET") 333 http.Redirect(w, r, "https://github.com/artifact", http.StatusMovedPermanently) 334 }) 335 336 ctx := context.Background() 337 _, resp, _ := client.Actions.DownloadArtifact(ctx, "o", "r", 1, false) 338 if resp.StatusCode != http.StatusMovedPermanently { 339 t.Errorf("Actions.DownloadArtifact return status %d, want %d", resp.StatusCode, http.StatusMovedPermanently) 340 } 341 } 342 343 func TestActionsService_DownloadArtifact_StatusMovedPermanently_followRedirects(t *testing.T) { 344 client, mux, serverURL, teardown := setup() 345 defer teardown() 346 347 mux.HandleFunc("/repos/o/r/actions/artifacts/1/zip", func(w http.ResponseWriter, r *http.Request) { 348 testMethod(t, r, "GET") 349 redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect") 350 http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) 351 }) 352 mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) { 353 testMethod(t, r, "GET") 354 http.Redirect(w, r, "http://github.com/artifact", http.StatusFound) 355 }) 356 357 ctx := context.Background() 358 url, resp, err := client.Actions.DownloadArtifact(ctx, "o", "r", 1, true) 359 if err != nil { 360 t.Errorf("Actions.DownloadArtifact return error: %v", err) 361 } 362 if resp.StatusCode != http.StatusFound { 363 t.Errorf("Actions.DownloadArtifact return status %d, want %d", resp.StatusCode, http.StatusFound) 364 } 365 want := "http://github.com/artifact" 366 if url.String() != want { 367 t.Errorf("Actions.DownloadArtifact returned %+v, want %+v", url.String(), want) 368 } 369 } 370 371 func TestActionsService_DownloadArtifact_invalidLocationHeader(t *testing.T) { 372 client, mux, _, teardown := setup() 373 defer teardown() 374 375 mux.HandleFunc("/repos/o/r/actions/artifacts/1/zip", func(w http.ResponseWriter, r *http.Request) { 376 testMethod(t, r, "GET") 377 ctlChar := 0x7f 378 badURL := "https://google.com" + string(byte(ctlChar)) 379 w.Header().Add("Location", badURL) 380 w.WriteHeader(http.StatusFound) 381 }) 382 383 ctx := context.Background() 384 _, _, err := client.Actions.DownloadArtifact(ctx, "o", "r", 1, false) 385 testURLParseError(t, err) 386 } 387 388 func TestActionsService_DeleteArtifact(t *testing.T) { 389 client, mux, _, teardown := setup() 390 defer teardown() 391 392 mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { 393 testMethod(t, r, "DELETE") 394 }) 395 396 ctx := context.Background() 397 _, err := client.Actions.DeleteArtifact(ctx, "o", "r", 1) 398 if err != nil { 399 t.Errorf("Actions.DeleteArtifact return error: %v", err) 400 } 401 402 const methodName = "DeleteArtifact" 403 testBadOptions(t, methodName, func() (err error) { 404 _, err = client.Actions.DeleteArtifact(ctx, "\n", "\n", -1) 405 return err 406 }) 407 408 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 409 return client.Actions.DeleteArtifact(ctx, "o", "r", 1) 410 }) 411 } 412 413 func TestActionsService_DeleteArtifact_invalidOwner(t *testing.T) { 414 client, _, _, teardown := setup() 415 defer teardown() 416 417 ctx := context.Background() 418 _, err := client.Actions.DeleteArtifact(ctx, "%", "r", 1) 419 testURLParseError(t, err) 420 } 421 422 func TestActionsService_DeleteArtifact_invalidRepo(t *testing.T) { 423 client, _, _, teardown := setup() 424 defer teardown() 425 426 ctx := context.Background() 427 _, err := client.Actions.DeleteArtifact(ctx, "o", "%", 1) 428 testURLParseError(t, err) 429 } 430 431 func TestActionsService_DeleteArtifact_notFound(t *testing.T) { 432 client, mux, _, teardown := setup() 433 defer teardown() 434 435 mux.HandleFunc("/repos/o/r/actions/artifacts/1", func(w http.ResponseWriter, r *http.Request) { 436 testMethod(t, r, "DELETE") 437 w.WriteHeader(http.StatusNotFound) 438 }) 439 440 ctx := context.Background() 441 resp, err := client.Actions.DeleteArtifact(ctx, "o", "r", 1) 442 if err == nil { 443 t.Errorf("Expected HTTP 404 response") 444 } 445 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 446 t.Errorf("Actions.DeleteArtifact return status %d, want %d", got, want) 447 } 448 } 449 450 func TestArtifact_Marshal(t *testing.T) { 451 testJSONMarshal(t, &Artifact{}, "{}") 452 453 u := &Artifact{ 454 ID: Int64(1), 455 NodeID: String("nid"), 456 Name: String("n"), 457 SizeInBytes: Int64(1), 458 ArchiveDownloadURL: String("a"), 459 Expired: Bool(false), 460 CreatedAt: &Timestamp{referenceTime}, 461 ExpiresAt: &Timestamp{referenceTime}, 462 } 463 464 want := `{ 465 "id": 1, 466 "node_id": "nid", 467 "name": "n", 468 "size_in_bytes": 1, 469 "archive_download_url": "a", 470 "expired": false, 471 "created_at": ` + referenceTimeStr + `, 472 "expires_at": ` + referenceTimeStr + ` 473 }` 474 475 testJSONMarshal(t, u, want) 476 } 477 478 func TestArtifactList_Marshal(t *testing.T) { 479 testJSONMarshal(t, &ArtifactList{}, "{}") 480 481 u := &ArtifactList{ 482 TotalCount: Int64(1), 483 Artifacts: []*Artifact{ 484 { 485 ID: Int64(1), 486 NodeID: String("nid"), 487 Name: String("n"), 488 SizeInBytes: Int64(1), 489 ArchiveDownloadURL: String("a"), 490 Expired: Bool(false), 491 CreatedAt: &Timestamp{referenceTime}, 492 ExpiresAt: &Timestamp{referenceTime}, 493 }, 494 }, 495 } 496 497 want := `{ 498 "total_count": 1, 499 "artifacts": [{ 500 "id": 1, 501 "node_id": "nid", 502 "name": "n", 503 "size_in_bytes": 1, 504 "archive_download_url": "a", 505 "expired": false, 506 "created_at": ` + referenceTimeStr + `, 507 "expires_at": ` + referenceTimeStr + ` 508 }] 509 }` 510 511 testJSONMarshal(t, u, want) 512 }