github.com/google/go-github/v49@v49.1.0/github/repos_deployments_test.go (about) 1 // Copyright 2014 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 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestRepositoriesService_ListDeployments(t *testing.T) { 20 client, mux, _, teardown := setup() 21 defer teardown() 22 23 mux.HandleFunc("/repos/o/r/deployments", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "GET") 25 testFormValues(t, r, values{"environment": "test"}) 26 fmt.Fprint(w, `[{"id":1}, {"id":2}]`) 27 }) 28 29 opt := &DeploymentsListOptions{Environment: "test"} 30 ctx := context.Background() 31 deployments, _, err := client.Repositories.ListDeployments(ctx, "o", "r", opt) 32 if err != nil { 33 t.Errorf("Repositories.ListDeployments returned error: %v", err) 34 } 35 36 want := []*Deployment{{ID: Int64(1)}, {ID: Int64(2)}} 37 if !cmp.Equal(deployments, want) { 38 t.Errorf("Repositories.ListDeployments returned %+v, want %+v", deployments, want) 39 } 40 41 const methodName = "ListDeployments" 42 testBadOptions(t, methodName, func() (err error) { 43 _, _, err = client.Repositories.ListDeployments(ctx, "\n", "\n", opt) 44 return err 45 }) 46 47 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 48 got, resp, err := client.Repositories.ListDeployments(ctx, "o", "r", opt) 49 if got != nil { 50 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 51 } 52 return resp, err 53 }) 54 } 55 56 func TestRepositoriesService_GetDeployment(t *testing.T) { 57 client, mux, _, teardown := setup() 58 defer teardown() 59 60 mux.HandleFunc("/repos/o/r/deployments/3", func(w http.ResponseWriter, r *http.Request) { 61 testMethod(t, r, "GET") 62 fmt.Fprint(w, `{"id":3}`) 63 }) 64 65 ctx := context.Background() 66 deployment, _, err := client.Repositories.GetDeployment(ctx, "o", "r", 3) 67 if err != nil { 68 t.Errorf("Repositories.GetDeployment returned error: %v", err) 69 } 70 71 want := &Deployment{ID: Int64(3)} 72 73 if !cmp.Equal(deployment, want) { 74 t.Errorf("Repositories.GetDeployment returned %+v, want %+v", deployment, want) 75 } 76 77 const methodName = "GetDeployment" 78 testBadOptions(t, methodName, func() (err error) { 79 _, _, err = client.Repositories.GetDeployment(ctx, "\n", "\n", 3) 80 return err 81 }) 82 83 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 84 got, resp, err := client.Repositories.GetDeployment(ctx, "o", "r", 3) 85 if got != nil { 86 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 87 } 88 return resp, err 89 }) 90 } 91 92 func TestRepositoriesService_CreateDeployment(t *testing.T) { 93 client, mux, _, teardown := setup() 94 defer teardown() 95 96 input := &DeploymentRequest{Ref: String("1111"), Task: String("deploy"), TransientEnvironment: Bool(true)} 97 98 mux.HandleFunc("/repos/o/r/deployments", func(w http.ResponseWriter, r *http.Request) { 99 v := new(DeploymentRequest) 100 json.NewDecoder(r.Body).Decode(v) 101 102 testMethod(t, r, "POST") 103 wantAcceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview} 104 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 105 if !cmp.Equal(v, input) { 106 t.Errorf("Request body = %+v, want %+v", v, input) 107 } 108 109 fmt.Fprint(w, `{"ref": "1111", "task": "deploy"}`) 110 }) 111 112 ctx := context.Background() 113 deployment, _, err := client.Repositories.CreateDeployment(ctx, "o", "r", input) 114 if err != nil { 115 t.Errorf("Repositories.CreateDeployment returned error: %v", err) 116 } 117 118 want := &Deployment{Ref: String("1111"), Task: String("deploy")} 119 if !cmp.Equal(deployment, want) { 120 t.Errorf("Repositories.CreateDeployment returned %+v, want %+v", deployment, want) 121 } 122 123 const methodName = "CreateDeployment" 124 testBadOptions(t, methodName, func() (err error) { 125 _, _, err = client.Repositories.CreateDeployment(ctx, "\n", "\n", input) 126 return err 127 }) 128 129 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 130 got, resp, err := client.Repositories.CreateDeployment(ctx, "o", "r", input) 131 if got != nil { 132 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 133 } 134 return resp, err 135 }) 136 } 137 138 func TestRepositoriesService_DeleteDeployment(t *testing.T) { 139 client, mux, _, teardown := setup() 140 defer teardown() 141 142 mux.HandleFunc("/repos/o/r/deployments/1", func(w http.ResponseWriter, r *http.Request) { 143 testMethod(t, r, "DELETE") 144 w.WriteHeader(http.StatusNoContent) 145 }) 146 147 ctx := context.Background() 148 resp, err := client.Repositories.DeleteDeployment(ctx, "o", "r", 1) 149 if err != nil { 150 t.Errorf("Repositories.DeleteDeployment returned error: %v", err) 151 } 152 if resp.StatusCode != http.StatusNoContent { 153 t.Error("Repositories.DeleteDeployment should return a 204 status") 154 } 155 156 resp, err = client.Repositories.DeleteDeployment(ctx, "o", "r", 2) 157 if err == nil { 158 t.Error("Repositories.DeleteDeployment should return an error") 159 } 160 if resp.StatusCode != http.StatusNotFound { 161 t.Error("Repositories.DeleteDeployment should return a 404 status") 162 } 163 164 const methodName = "DeleteDeployment" 165 testBadOptions(t, methodName, func() (err error) { 166 _, err = client.Repositories.DeleteDeployment(ctx, "\n", "\n", 1) 167 return err 168 }) 169 170 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 171 return client.Repositories.DeleteDeployment(ctx, "o", "r", 1) 172 }) 173 } 174 175 func TestRepositoriesService_ListDeploymentStatuses(t *testing.T) { 176 client, mux, _, teardown := setup() 177 defer teardown() 178 179 wantAcceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview} 180 mux.HandleFunc("/repos/o/r/deployments/1/statuses", func(w http.ResponseWriter, r *http.Request) { 181 testMethod(t, r, "GET") 182 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 183 testFormValues(t, r, values{"page": "2"}) 184 fmt.Fprint(w, `[{"id":1}, {"id":2}]`) 185 }) 186 187 opt := &ListOptions{Page: 2} 188 ctx := context.Background() 189 statutses, _, err := client.Repositories.ListDeploymentStatuses(ctx, "o", "r", 1, opt) 190 if err != nil { 191 t.Errorf("Repositories.ListDeploymentStatuses returned error: %v", err) 192 } 193 194 want := []*DeploymentStatus{{ID: Int64(1)}, {ID: Int64(2)}} 195 if !cmp.Equal(statutses, want) { 196 t.Errorf("Repositories.ListDeploymentStatuses returned %+v, want %+v", statutses, want) 197 } 198 199 const methodName = "ListDeploymentStatuses" 200 testBadOptions(t, methodName, func() (err error) { 201 _, _, err = client.Repositories.ListDeploymentStatuses(ctx, "\n", "\n", 1, opt) 202 return err 203 }) 204 205 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 206 got, resp, err := client.Repositories.ListDeploymentStatuses(ctx, "o", "r", 1, opt) 207 if got != nil { 208 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 209 } 210 return resp, err 211 }) 212 } 213 214 func TestRepositoriesService_GetDeploymentStatus(t *testing.T) { 215 client, mux, _, teardown := setup() 216 defer teardown() 217 218 wantAcceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview} 219 mux.HandleFunc("/repos/o/r/deployments/3/statuses/4", func(w http.ResponseWriter, r *http.Request) { 220 testMethod(t, r, "GET") 221 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 222 fmt.Fprint(w, `{"id":4}`) 223 }) 224 225 ctx := context.Background() 226 deploymentStatus, _, err := client.Repositories.GetDeploymentStatus(ctx, "o", "r", 3, 4) 227 if err != nil { 228 t.Errorf("Repositories.GetDeploymentStatus returned error: %v", err) 229 } 230 231 want := &DeploymentStatus{ID: Int64(4)} 232 if !cmp.Equal(deploymentStatus, want) { 233 t.Errorf("Repositories.GetDeploymentStatus returned %+v, want %+v", deploymentStatus, want) 234 } 235 236 const methodName = "GetDeploymentStatus" 237 testBadOptions(t, methodName, func() (err error) { 238 _, _, err = client.Repositories.GetDeploymentStatus(ctx, "\n", "\n", 3, 4) 239 return err 240 }) 241 242 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 243 got, resp, err := client.Repositories.GetDeploymentStatus(ctx, "o", "r", 3, 4) 244 if got != nil { 245 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 246 } 247 return resp, err 248 }) 249 } 250 251 func TestRepositoriesService_CreateDeploymentStatus(t *testing.T) { 252 client, mux, _, teardown := setup() 253 defer teardown() 254 255 input := &DeploymentStatusRequest{State: String("inactive"), Description: String("deploy"), AutoInactive: Bool(false)} 256 257 mux.HandleFunc("/repos/o/r/deployments/1/statuses", func(w http.ResponseWriter, r *http.Request) { 258 v := new(DeploymentStatusRequest) 259 json.NewDecoder(r.Body).Decode(v) 260 261 testMethod(t, r, "POST") 262 wantAcceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview} 263 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 264 if !cmp.Equal(v, input) { 265 t.Errorf("Request body = %+v, want %+v", v, input) 266 } 267 268 fmt.Fprint(w, `{"state": "inactive", "description": "deploy"}`) 269 }) 270 271 ctx := context.Background() 272 deploymentStatus, _, err := client.Repositories.CreateDeploymentStatus(ctx, "o", "r", 1, input) 273 if err != nil { 274 t.Errorf("Repositories.CreateDeploymentStatus returned error: %v", err) 275 } 276 277 want := &DeploymentStatus{State: String("inactive"), Description: String("deploy")} 278 if !cmp.Equal(deploymentStatus, want) { 279 t.Errorf("Repositories.CreateDeploymentStatus returned %+v, want %+v", deploymentStatus, want) 280 } 281 282 const methodName = "CreateDeploymentStatus" 283 testBadOptions(t, methodName, func() (err error) { 284 _, _, err = client.Repositories.CreateDeploymentStatus(ctx, "\n", "\n", 1, input) 285 return err 286 }) 287 288 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 289 got, resp, err := client.Repositories.CreateDeploymentStatus(ctx, "o", "r", 1, input) 290 if got != nil { 291 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 292 } 293 return resp, err 294 }) 295 } 296 297 func TestDeploymentStatusRequest_Marshal(t *testing.T) { 298 testJSONMarshal(t, &DeploymentStatusRequest{}, "{}") 299 300 r := &DeploymentStatusRequest{ 301 State: String("state"), 302 LogURL: String("logurl"), 303 Description: String("desc"), 304 Environment: String("env"), 305 EnvironmentURL: String("eurl"), 306 AutoInactive: Bool(false), 307 } 308 309 want := `{ 310 "state": "state", 311 "log_url": "logurl", 312 "description": "desc", 313 "environment": "env", 314 "environment_url": "eurl", 315 "auto_inactive": false 316 }` 317 318 testJSONMarshal(t, r, want) 319 } 320 321 func TestDeploymentStatus_Marshal(t *testing.T) { 322 testJSONMarshal(t, &DeploymentStatus{}, "{}") 323 324 r := &DeploymentStatus{ 325 ID: Int64(1), 326 State: String("state"), 327 Creator: &User{ 328 Login: String("l"), 329 ID: Int64(1), 330 URL: String("u"), 331 AvatarURL: String("a"), 332 GravatarID: String("g"), 333 Name: String("n"), 334 Company: String("c"), 335 Blog: String("b"), 336 Location: String("l"), 337 Email: String("e"), 338 Hireable: Bool(true), 339 Bio: String("b"), 340 TwitterUsername: String("t"), 341 PublicRepos: Int(1), 342 Followers: Int(1), 343 Following: Int(1), 344 CreatedAt: &Timestamp{referenceTime}, 345 SuspendedAt: &Timestamp{referenceTime}, 346 }, 347 Description: String("desc"), 348 Environment: String("env"), 349 NodeID: String("nid"), 350 CreatedAt: &Timestamp{referenceTime}, 351 UpdatedAt: &Timestamp{referenceTime}, 352 TargetURL: String("turl"), 353 DeploymentURL: String("durl"), 354 RepositoryURL: String("rurl"), 355 EnvironmentURL: String("eurl"), 356 LogURL: String("lurl"), 357 URL: String("url"), 358 } 359 360 want := `{ 361 "id": 1, 362 "state": "state", 363 "creator": { 364 "login": "l", 365 "id": 1, 366 "avatar_url": "a", 367 "gravatar_id": "g", 368 "name": "n", 369 "company": "c", 370 "blog": "b", 371 "location": "l", 372 "email": "e", 373 "hireable": true, 374 "bio": "b", 375 "twitter_username": "t", 376 "public_repos": 1, 377 "followers": 1, 378 "following": 1, 379 "created_at": ` + referenceTimeStr + `, 380 "suspended_at": ` + referenceTimeStr + `, 381 "url": "u" 382 }, 383 "description": "desc", 384 "environment": "env", 385 "node_id": "nid", 386 "created_at": ` + referenceTimeStr + `, 387 "updated_at": ` + referenceTimeStr + `, 388 "target_url": "turl", 389 "deployment_url": "durl", 390 "repository_url": "rurl", 391 "environment_url": "eurl", 392 "log_url": "lurl", 393 "url": "url" 394 }` 395 396 testJSONMarshal(t, r, want) 397 } 398 399 func TestDeploymentRequest_Marshal(t *testing.T) { 400 testJSONMarshal(t, &DeploymentRequest{}, "{}") 401 402 r := &DeploymentRequest{ 403 Ref: String("ref"), 404 Task: String("task"), 405 AutoMerge: Bool(false), 406 RequiredContexts: &[]string{"s"}, 407 Payload: "payload", 408 Environment: String("environment"), 409 Description: String("description"), 410 TransientEnvironment: Bool(false), 411 ProductionEnvironment: Bool(false), 412 } 413 414 want := `{ 415 "ref": "ref", 416 "task": "task", 417 "auto_merge": false, 418 "required_contexts": ["s"], 419 "payload": "payload", 420 "environment": "environment", 421 "description": "description", 422 "transient_environment": false, 423 "production_environment": false 424 }` 425 426 testJSONMarshal(t, r, want) 427 } 428 429 func TestDeployment_Marshal(t *testing.T) { 430 testJSONMarshal(t, &Deployment{}, "{}") 431 432 str := "s" 433 jsonMsg, _ := json.Marshal(str) 434 435 r := &Deployment{ 436 URL: String("url"), 437 ID: Int64(1), 438 SHA: String("sha"), 439 Ref: String("ref"), 440 Task: String("task"), 441 Payload: jsonMsg, 442 Environment: String("env"), 443 Description: String("desc"), 444 Creator: &User{ 445 Login: String("l"), 446 ID: Int64(1), 447 URL: String("u"), 448 AvatarURL: String("a"), 449 GravatarID: String("g"), 450 Name: String("n"), 451 Company: String("c"), 452 Blog: String("b"), 453 Location: String("l"), 454 Email: String("e"), 455 Hireable: Bool(true), 456 Bio: String("b"), 457 TwitterUsername: String("t"), 458 PublicRepos: Int(1), 459 Followers: Int(1), 460 Following: Int(1), 461 CreatedAt: &Timestamp{referenceTime}, 462 SuspendedAt: &Timestamp{referenceTime}, 463 }, 464 CreatedAt: &Timestamp{referenceTime}, 465 UpdatedAt: &Timestamp{referenceTime}, 466 StatusesURL: String("surl"), 467 RepositoryURL: String("rurl"), 468 NodeID: String("nid"), 469 } 470 471 want := `{ 472 "url": "url", 473 "id": 1, 474 "sha": "sha", 475 "ref": "ref", 476 "task": "task", 477 "payload": "s", 478 "environment": "env", 479 "description": "desc", 480 "creator": { 481 "login": "l", 482 "id": 1, 483 "avatar_url": "a", 484 "gravatar_id": "g", 485 "name": "n", 486 "company": "c", 487 "blog": "b", 488 "location": "l", 489 "email": "e", 490 "hireable": true, 491 "bio": "b", 492 "twitter_username": "t", 493 "public_repos": 1, 494 "followers": 1, 495 "following": 1, 496 "created_at": ` + referenceTimeStr + `, 497 "suspended_at": ` + referenceTimeStr + `, 498 "url": "u" 499 }, 500 "created_at": ` + referenceTimeStr + `, 501 "updated_at": ` + referenceTimeStr + `, 502 "statuses_url": "surl", 503 "repository_url": "rurl", 504 "node_id": "nid" 505 }` 506 507 testJSONMarshal(t, r, want) 508 }