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