github.com/google/go-github/v71@v71.0.0/github/repos_environments_test.go (about) 1 // Copyright 2021 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 "testing" 14 15 "github.com/google/go-cmp/cmp" 16 ) 17 18 func TestRequiredReviewer_UnmarshalJSON(t *testing.T) { 19 t.Parallel() 20 var testCases = map[string]struct { 21 data []byte 22 wantRule []*RequiredReviewer 23 wantError bool 24 }{ 25 "User Reviewer": { 26 data: []byte(`[{"type": "User", "reviewer": {"id": 1,"login": "octocat"}}]`), 27 wantRule: []*RequiredReviewer{{Type: Ptr("User"), Reviewer: &User{ID: Ptr(int64(1)), Login: Ptr("octocat")}}}, 28 wantError: false, 29 }, 30 "Team Reviewer": { 31 data: []byte(`[{"type": "Team", "reviewer": {"id": 1, "name": "Justice League"}}]`), 32 wantRule: []*RequiredReviewer{{Type: Ptr("Team"), Reviewer: &Team{ID: Ptr(int64(1)), Name: Ptr("Justice League")}}}, 33 wantError: false, 34 }, 35 "Both Types Reviewer": { 36 data: []byte(`[{"type": "User", "reviewer": {"id": 1,"login": "octocat"}},{"type": "Team", "reviewer": {"id": 1, "name": "Justice League"}}]`), 37 wantRule: []*RequiredReviewer{{Type: Ptr("User"), Reviewer: &User{ID: Ptr(int64(1)), Login: Ptr("octocat")}}, {Type: Ptr("Team"), Reviewer: &Team{ID: Ptr(int64(1)), Name: Ptr("Justice League")}}}, 38 wantError: false, 39 }, 40 "Empty JSON Object": { 41 data: []byte(`[]`), 42 wantRule: []*RequiredReviewer{}, 43 wantError: false, 44 }, 45 "Bad JSON Object": { 46 data: []byte(`[badjson: 1]`), 47 wantRule: []*RequiredReviewer{}, 48 wantError: true, 49 }, 50 "Wrong Type Type in Reviewer Object": { 51 data: []byte(`[{"type": 1, "reviewer": {"id": 1}}]`), 52 wantRule: []*RequiredReviewer{{Type: nil, Reviewer: nil}}, 53 wantError: true, 54 }, 55 "Wrong ID Type in User Object": { 56 data: []byte(`[{"type": "User", "reviewer": {"id": "string"}}]`), 57 wantRule: []*RequiredReviewer{{Type: Ptr("User"), Reviewer: nil}}, 58 wantError: true, 59 }, 60 "Wrong ID Type in Team Object": { 61 data: []byte(`[{"type": "Team", "reviewer": {"id": "string"}}]`), 62 wantRule: []*RequiredReviewer{{Type: Ptr("Team"), Reviewer: nil}}, 63 wantError: true, 64 }, 65 "Wrong Type of Reviewer": { 66 data: []byte(`[{"type": "Cat", "reviewer": {"id": 1,"login": "octocat"}}]`), 67 wantRule: []*RequiredReviewer{{Type: nil, Reviewer: nil}}, 68 wantError: true, 69 }, 70 } 71 72 for name, test := range testCases { 73 t.Run(name, func(t *testing.T) { 74 t.Parallel() 75 rule := []*RequiredReviewer{} 76 err := json.Unmarshal(test.data, &rule) 77 if err != nil && !test.wantError { 78 t.Errorf("RequiredReviewer.UnmarshalJSON returned an error when we expected nil") 79 } 80 if err == nil && test.wantError { 81 t.Errorf("RequiredReviewer.UnmarshalJSON returned no error when we expected one") 82 } 83 if !cmp.Equal(test.wantRule, rule) { 84 t.Errorf("RequiredReviewer.UnmarshalJSON expected rule %+v, got %+v", test.wantRule, rule) 85 } 86 }) 87 } 88 } 89 90 func TestCreateUpdateEnvironment_MarshalJSON(t *testing.T) { 91 t.Parallel() 92 cu := &CreateUpdateEnvironment{} 93 94 got, err := cu.MarshalJSON() 95 if err != nil { 96 t.Errorf("MarshalJSON: %v", err) 97 } 98 99 want := `{"wait_timer":0,"reviewers":null,"can_admins_bypass":true,"deployment_branch_policy":null}` 100 if string(got) != want { 101 t.Errorf("MarshalJSON = %s, want %v", got, want) 102 } 103 } 104 105 func TestRepositoriesService_ListEnvironments(t *testing.T) { 106 t.Parallel() 107 client, mux, _ := setup(t) 108 109 mux.HandleFunc("/repos/o/r/environments", func(w http.ResponseWriter, r *http.Request) { 110 testMethod(t, r, "GET") 111 fmt.Fprint(w, `{"total_count":1, "environments":[{"id":1}, {"id": 2}]}`) 112 }) 113 114 opt := &EnvironmentListOptions{ 115 ListOptions: ListOptions{ 116 Page: 2, 117 PerPage: 2, 118 }, 119 } 120 ctx := context.Background() 121 environments, _, err := client.Repositories.ListEnvironments(ctx, "o", "r", opt) 122 if err != nil { 123 t.Errorf("Repositories.ListEnvironments returned error: %v", err) 124 } 125 want := &EnvResponse{TotalCount: Ptr(1), Environments: []*Environment{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}} 126 if !cmp.Equal(environments, want) { 127 t.Errorf("Repositories.ListEnvironments returned %+v, want %+v", environments, want) 128 } 129 130 const methodName = "ListEnvironments" 131 testBadOptions(t, methodName, func() (err error) { 132 _, _, err = client.Repositories.ListEnvironments(ctx, "\n", "\n", opt) 133 return err 134 }) 135 136 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 137 got, resp, err := client.Repositories.ListEnvironments(ctx, "o", "r", opt) 138 if got != nil { 139 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 140 } 141 return resp, err 142 }) 143 } 144 145 func TestRepositoriesService_GetEnvironment(t *testing.T) { 146 t.Parallel() 147 client, mux, _ := setup(t) 148 149 mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) { 150 testMethod(t, r, "GET") 151 fmt.Fprint(w, `{"id": 1,"name": "staging", "deployment_branch_policy": {"protected_branches": true, "custom_branch_policies": false}, "can_admins_bypass": false}`) 152 }) 153 154 ctx := context.Background() 155 release, resp, err := client.Repositories.GetEnvironment(ctx, "o", "r", "e") 156 if err != nil { 157 t.Errorf("Repositories.GetEnvironment returned error: %v\n%v", err, resp.Body) 158 } 159 160 want := &Environment{ID: Ptr(int64(1)), Name: Ptr("staging"), DeploymentBranchPolicy: &BranchPolicy{ProtectedBranches: Ptr(true), CustomBranchPolicies: Ptr(false)}, CanAdminsBypass: Ptr(false)} 161 if !cmp.Equal(release, want) { 162 t.Errorf("Repositories.GetEnvironment returned %+v, want %+v", release, want) 163 } 164 165 const methodName = "GetEnvironment" 166 testBadOptions(t, methodName, func() (err error) { 167 _, _, err = client.Repositories.GetEnvironment(ctx, "\n", "\n", "\n") 168 return err 169 }) 170 171 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 172 got, resp, err := client.Repositories.GetEnvironment(ctx, "o", "r", "e") 173 if got != nil { 174 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 175 } 176 return resp, err 177 }) 178 } 179 180 func TestRepositoriesService_CreateEnvironment(t *testing.T) { 181 t.Parallel() 182 client, mux, _ := setup(t) 183 184 input := &CreateUpdateEnvironment{ 185 WaitTimer: Ptr(30), 186 } 187 188 mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) { 189 v := new(CreateUpdateEnvironment) 190 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 191 192 testMethod(t, r, "PUT") 193 want := &CreateUpdateEnvironment{WaitTimer: Ptr(30), CanAdminsBypass: Ptr(true)} 194 if !cmp.Equal(v, want) { 195 t.Errorf("Request body = %+v, want %+v", v, want) 196 } 197 fmt.Fprint(w, `{"id": 1, "name": "staging", "protection_rules": [{"id": 1, "type": "wait_timer", "wait_timer": 30}]}`) 198 }) 199 200 ctx := context.Background() 201 release, _, err := client.Repositories.CreateUpdateEnvironment(ctx, "o", "r", "e", input) 202 if err != nil { 203 t.Errorf("Repositories.CreateUpdateEnvironment returned error: %v", err) 204 } 205 206 want := &Environment{ID: Ptr(int64(1)), Name: Ptr("staging"), ProtectionRules: []*ProtectionRule{{ID: Ptr(int64(1)), Type: Ptr("wait_timer"), WaitTimer: Ptr(30)}}} 207 if !cmp.Equal(release, want) { 208 t.Errorf("Repositories.CreateUpdateEnvironment returned %+v, want %+v", release, want) 209 } 210 211 const methodName = "CreateUpdateEnvironment" 212 testBadOptions(t, methodName, func() (err error) { 213 _, _, err = client.Repositories.CreateUpdateEnvironment(ctx, "\n", "\n", "\n", input) 214 return err 215 }) 216 217 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 218 got, resp, err := client.Repositories.CreateUpdateEnvironment(ctx, "o", "r", "e", input) 219 if got != nil { 220 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 221 } 222 return resp, err 223 }) 224 } 225 226 func TestRepositoriesService_CreateEnvironment_noEnterprise(t *testing.T) { 227 t.Parallel() 228 client, mux, _ := setup(t) 229 230 input := &CreateUpdateEnvironment{} 231 callCount := 0 232 233 mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) { 234 v := new(CreateUpdateEnvironment) 235 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 236 237 testMethod(t, r, "PUT") 238 if callCount == 0 { 239 w.WriteHeader(http.StatusUnprocessableEntity) 240 callCount++ 241 } else { 242 want := &CreateUpdateEnvironment{} 243 if !cmp.Equal(v, want) { 244 t.Errorf("Request body = %+v, want %+v", v, want) 245 } 246 fmt.Fprint(w, `{"id": 1, "name": "staging", "protection_rules": []}`) 247 } 248 }) 249 250 ctx := context.Background() 251 release, _, err := client.Repositories.CreateUpdateEnvironment(ctx, "o", "r", "e", input) 252 if err != nil { 253 t.Errorf("Repositories.CreateUpdateEnvironment returned error: %v", err) 254 } 255 256 want := &Environment{ID: Ptr(int64(1)), Name: Ptr("staging"), ProtectionRules: []*ProtectionRule{}} 257 if !cmp.Equal(release, want) { 258 t.Errorf("Repositories.CreateUpdateEnvironment returned %+v, want %+v", release, want) 259 } 260 } 261 262 func TestRepositoriesService_createNewEnvNoEnterprise(t *testing.T) { 263 t.Parallel() 264 client, mux, _ := setup(t) 265 266 input := &CreateUpdateEnvironment{ 267 DeploymentBranchPolicy: &BranchPolicy{ 268 ProtectedBranches: Ptr(true), 269 CustomBranchPolicies: Ptr(false), 270 }, 271 } 272 273 mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) { 274 v := new(createUpdateEnvironmentNoEnterprise) 275 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 276 277 testMethod(t, r, "PUT") 278 want := &createUpdateEnvironmentNoEnterprise{ 279 DeploymentBranchPolicy: &BranchPolicy{ 280 ProtectedBranches: Ptr(true), 281 CustomBranchPolicies: Ptr(false), 282 }, 283 } 284 if !cmp.Equal(v, want) { 285 t.Errorf("Request body = %+v, want %+v", v, want) 286 } 287 fmt.Fprint(w, `{"id": 1, "name": "staging", "protection_rules": [{"id": 1, "node_id": "id", "type": "branch_policy"}], "deployment_branch_policy": {"protected_branches": true, "custom_branch_policies": false}}`) 288 }) 289 290 ctx := context.Background() 291 release, _, err := client.Repositories.createNewEnvNoEnterprise(ctx, "repos/o/r/environments/e", input) 292 if err != nil { 293 t.Errorf("Repositories.createNewEnvNoEnterprise returned error: %v", err) 294 } 295 296 want := &Environment{ 297 ID: Ptr(int64(1)), 298 Name: Ptr("staging"), 299 ProtectionRules: []*ProtectionRule{ 300 { 301 ID: Ptr(int64(1)), 302 NodeID: Ptr("id"), 303 Type: Ptr("branch_policy"), 304 }, 305 }, 306 DeploymentBranchPolicy: &BranchPolicy{ 307 ProtectedBranches: Ptr(true), 308 CustomBranchPolicies: Ptr(false), 309 }, 310 } 311 if !cmp.Equal(release, want) { 312 t.Errorf("Repositories.createNewEnvNoEnterprise returned %+v, want %+v", release, want) 313 } 314 315 const methodName = "createNewEnvNoEnterprise" 316 testBadOptions(t, methodName, func() (err error) { 317 _, _, err = client.Repositories.createNewEnvNoEnterprise(ctx, "\n", input) 318 return err 319 }) 320 321 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 322 got, resp, err := client.Repositories.createNewEnvNoEnterprise(ctx, "repos/o/r/environments/e", input) 323 if got != nil { 324 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 325 } 326 return resp, err 327 }) 328 } 329 330 func TestRepositoriesService_DeleteEnvironment(t *testing.T) { 331 t.Parallel() 332 client, mux, _ := setup(t) 333 334 mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) { 335 testMethod(t, r, "DELETE") 336 }) 337 338 ctx := context.Background() 339 _, err := client.Repositories.DeleteEnvironment(ctx, "o", "r", "e") 340 if err != nil { 341 t.Errorf("Repositories.DeleteEnvironment returned error: %v", err) 342 } 343 344 const methodName = "DeleteEnvironment" 345 testBadOptions(t, methodName, func() (err error) { 346 _, err = client.Repositories.DeleteEnvironment(ctx, "\n", "\n", "\n") 347 return err 348 }) 349 350 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 351 return client.Repositories.DeleteEnvironment(ctx, "o", "r", "e") 352 }) 353 } 354 355 func TestRepoEnvironment_Marshal(t *testing.T) { 356 t.Parallel() 357 testJSONMarshal(t, &EnvResponse{}, "{}") 358 359 repoEnv := &EnvResponse{ 360 TotalCount: Ptr(1), 361 Environments: []*Environment{ 362 { 363 Owner: Ptr("me"), 364 Repo: Ptr("se"), 365 EnvironmentName: Ptr("dev"), 366 WaitTimer: Ptr(123), 367 Reviewers: []*EnvReviewers{ 368 { 369 Type: Ptr("main"), 370 ID: Ptr(int64(1)), 371 }, 372 { 373 Type: Ptr("rev"), 374 ID: Ptr(int64(2)), 375 }, 376 }, 377 DeploymentBranchPolicy: &BranchPolicy{ 378 ProtectedBranches: Ptr(false), 379 CustomBranchPolicies: Ptr(false), 380 }, 381 ID: Ptr(int64(2)), 382 NodeID: Ptr("star"), 383 Name: Ptr("eg"), 384 URL: Ptr("https://hey.in"), 385 HTMLURL: Ptr("htmlurl"), 386 CreatedAt: &Timestamp{referenceTime}, 387 UpdatedAt: &Timestamp{referenceTime}, 388 ProtectionRules: []*ProtectionRule{ 389 { 390 ID: Ptr(int64(21)), 391 NodeID: Ptr("mnb"), 392 Type: Ptr("ewq"), 393 WaitTimer: Ptr(9090), 394 }, 395 }, 396 }, 397 }, 398 } 399 400 want := `{ 401 "total_count":1, 402 "environments":[ 403 { 404 "owner":"me", 405 "repo":"se", 406 "environment_name":"dev", 407 "wait_timer":123, 408 "reviewers":[ 409 { 410 "type":"main", 411 "id":1 412 }, 413 { 414 "type":"rev", 415 "id":2 416 } 417 ], 418 "deployment_branch_policy":{ 419 "protected_branches":false, 420 "custom_branch_policies":false 421 }, 422 "id":2, 423 "node_id":"star", 424 "name":"eg", 425 "url":"https://hey.in", 426 "html_url":"htmlurl", 427 "created_at":` + referenceTimeStr + `, 428 "updated_at":` + referenceTimeStr + `, 429 "protection_rules":[ 430 { 431 "id":21, 432 "node_id":"mnb", 433 "type":"ewq", 434 "wait_timer":9090 435 } 436 ] 437 } 438 ] 439 }` 440 441 testJSONMarshal(t, repoEnv, want) 442 } 443 444 func TestEnvReviewers_Marshal(t *testing.T) { 445 t.Parallel() 446 testJSONMarshal(t, &EnvReviewers{}, "{}") 447 448 repoEnv := &EnvReviewers{ 449 Type: Ptr("main"), 450 ID: Ptr(int64(1)), 451 } 452 453 want := `{ 454 "type":"main", 455 "id":1 456 }` 457 458 testJSONMarshal(t, repoEnv, want) 459 } 460 461 func TestEnvironment_Marshal(t *testing.T) { 462 t.Parallel() 463 testJSONMarshal(t, &Environment{}, "{}") 464 465 repoEnv := &Environment{ 466 Owner: Ptr("o"), 467 Repo: Ptr("r"), 468 EnvironmentName: Ptr("e"), 469 WaitTimer: Ptr(123), 470 Reviewers: []*EnvReviewers{ 471 { 472 Type: Ptr("main"), 473 ID: Ptr(int64(1)), 474 }, 475 { 476 Type: Ptr("rev"), 477 ID: Ptr(int64(2)), 478 }, 479 }, 480 DeploymentBranchPolicy: &BranchPolicy{ 481 ProtectedBranches: Ptr(false), 482 CustomBranchPolicies: Ptr(false), 483 }, 484 ID: Ptr(int64(2)), 485 NodeID: Ptr("star"), 486 Name: Ptr("eg"), 487 URL: Ptr("https://hey.in"), 488 HTMLURL: Ptr("htmlurl"), 489 CreatedAt: &Timestamp{referenceTime}, 490 UpdatedAt: &Timestamp{referenceTime}, 491 ProtectionRules: []*ProtectionRule{ 492 { 493 ID: Ptr(int64(21)), 494 NodeID: Ptr("mnb"), 495 Type: Ptr("ewq"), 496 WaitTimer: Ptr(9090), 497 }, 498 }, 499 } 500 501 want := `{ 502 "owner":"o", 503 "repo":"r", 504 "environment_name":"e", 505 "wait_timer":123, 506 "reviewers":[ 507 { 508 "type":"main", 509 "id":1 510 }, 511 { 512 "type":"rev", 513 "id":2 514 } 515 ], 516 "deployment_branch_policy":{ 517 "protected_branches":false, 518 "custom_branch_policies":false 519 }, 520 "id":2, 521 "node_id":"star", 522 "name":"eg", 523 "url":"https://hey.in", 524 "html_url":"htmlurl", 525 "created_at":` + referenceTimeStr + `, 526 "updated_at":` + referenceTimeStr + `, 527 "protection_rules":[ 528 { 529 "id":21, 530 "node_id":"mnb", 531 "type":"ewq", 532 "wait_timer":9090 533 } 534 ] 535 }` 536 537 testJSONMarshal(t, repoEnv, want) 538 } 539 540 func TestBranchPolicy_Marshal(t *testing.T) { 541 t.Parallel() 542 testJSONMarshal(t, &BranchPolicy{}, "{}") 543 544 bp := &BranchPolicy{ 545 ProtectedBranches: Ptr(false), 546 CustomBranchPolicies: Ptr(false), 547 } 548 549 want := `{ 550 "protected_branches": false, 551 "custom_branch_policies": false 552 }` 553 554 testJSONMarshal(t, bp, want) 555 }