github.com/google/go-github/v53@v53.2.0/github/orgs_rules_test.go (about) 1 // Copyright 2023 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 "fmt" 11 "net/http" 12 "testing" 13 14 "github.com/google/go-cmp/cmp" 15 ) 16 17 func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { 18 client, mux, _, teardown := setup() 19 defer teardown() 20 21 mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { 22 testMethod(t, r, "GET") 23 fmt.Fprint(w, `[{ 24 "id": 26110, 25 "name": "test ruleset", 26 "target": "branch", 27 "source_type": "Organization", 28 "source": "o", 29 "enforcement": "active", 30 "bypass_mode": "none", 31 "node_id": "nid", 32 "_links": { 33 "self": { 34 "href": "https://api.github.com/orgs/o/rulesets/26110" 35 } 36 } 37 }]`) 38 }) 39 40 ctx := context.Background() 41 rulesets, _, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") 42 if err != nil { 43 t.Errorf("Organizations.GetAllOrganizationRulesets returned error: %v", err) 44 } 45 46 want := []*Ruleset{{ 47 ID: 26110, 48 Name: "test ruleset", 49 Target: String("branch"), 50 SourceType: String("Organization"), 51 Source: "o", 52 Enforcement: "active", 53 BypassMode: String("none"), 54 NodeID: String("nid"), 55 Links: &RulesetLinks{ 56 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 57 }, 58 }} 59 if !cmp.Equal(rulesets, want) { 60 t.Errorf("Organizations.GetAllOrganizationRulesets returned %+v, want %+v", rulesets, want) 61 } 62 63 const methodName = "GetAllOrganizationRulesets" 64 65 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 66 got, resp, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") 67 if got != nil { 68 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 69 } 70 return resp, err 71 }) 72 } 73 74 func TestOrganizationsService_CreateOrganizationRuleset(t *testing.T) { 75 client, mux, _, teardown := setup() 76 defer teardown() 77 78 mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { 79 testMethod(t, r, "POST") 80 fmt.Fprint(w, `{ 81 "id": 21, 82 "name": "ruleset", 83 "target": "branch", 84 "source_type": "Organization", 85 "source": "o", 86 "enforcement": "active", 87 "bypass_actors": [ 88 { 89 "actor_id": 234, 90 "actor_type": "Team" 91 } 92 ], 93 "conditions": { 94 "ref_name": { 95 "include": [ 96 "refs/heads/main", 97 "refs/heads/master" 98 ], 99 "exclude": [ 100 "refs/heads/dev*" 101 ] 102 }, 103 "repository_name": { 104 "include": [ 105 "important_repository", 106 "another_important_repository" 107 ], 108 "exclude": [ 109 "unimportant_repository" 110 ], 111 "protected": true 112 } 113 }, 114 "rules": [ 115 { 116 "type": "creation" 117 }, 118 { 119 "type": "update", 120 "parameters": { 121 "update_allows_fetch_and_merge": true 122 } 123 }, 124 { 125 "type": "deletion" 126 }, 127 { 128 "type": "required_linear_history" 129 }, 130 { 131 "type": "required_deployments", 132 "parameters": { 133 "required_deployment_environments": ["test"] 134 } 135 }, 136 { 137 "type": "required_signatures" 138 }, 139 { 140 "type": "pull_request", 141 "parameters": { 142 "dismiss_stale_reviews_on_push": true, 143 "require_code_owner_review": true, 144 "require_last_push_approval": true, 145 "required_approving_review_count": 1, 146 "required_review_thread_resolution": true 147 } 148 }, 149 { 150 "type": "required_status_checks", 151 "parameters": { 152 "required_status_checks": [ 153 { 154 "context": "test", 155 "integration_id": 1 156 } 157 ], 158 "strict_required_status_checks_policy": true 159 } 160 }, 161 { 162 "type": "non_fast_forward" 163 }, 164 { 165 "type": "commit_message_pattern", 166 "parameters": { 167 "name": "avoid test commits", 168 "negate": true, 169 "operator": "starts_with", 170 "pattern": "[test]" 171 } 172 }, 173 { 174 "type": "commit_author_email_pattern", 175 "parameters": { 176 "operator": "contains", 177 "pattern": "github" 178 } 179 }, 180 { 181 "type": "committer_email_pattern", 182 "parameters": { 183 "name": "avoid commit emails", 184 "negate": true, 185 "operator": "ends_with", 186 "pattern": "abc" 187 } 188 }, 189 { 190 "type": "branch_name_pattern", 191 "parameters": { 192 "name": "avoid branch names", 193 "negate": true, 194 "operator": "regex", 195 "pattern": "github$" 196 } 197 }, 198 { 199 "type": "tag_name_pattern", 200 "parameters": { 201 "name": "avoid tag names", 202 "negate": true, 203 "operator": "contains", 204 "pattern": "github" 205 } 206 } 207 ] 208 }`) 209 }) 210 211 ctx := context.Background() 212 ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ 213 ID: 21, 214 Name: "ruleset", 215 Target: String("branch"), 216 SourceType: String("Organization"), 217 Source: "o", 218 Enforcement: "active", 219 BypassActors: []*BypassActor{ 220 { 221 ActorID: Int64(234), 222 ActorType: String("Team"), 223 }, 224 }, 225 Conditions: &RulesetConditions{ 226 RefName: &RulesetRefConditionParameters{ 227 Include: []string{"refs/heads/main", "refs/heads/master"}, 228 Exclude: []string{"refs/heads/dev*"}, 229 }, 230 RepositoryName: &RulesetRepositoryConditionParameters{ 231 Include: []string{"important_repository", "another_important_repository"}, 232 Exclude: []string{"unimportant_repository"}, 233 Protected: Bool(true), 234 }, 235 }, 236 Rules: []*RepositoryRule{ 237 NewCreationRule(), 238 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 239 UpdateAllowsFetchAndMerge: true, 240 }), 241 NewDeletionRule(), 242 NewRequiredLinearHistoryRule(), 243 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 244 RequiredDeploymentEnvironments: []string{"test"}, 245 }), 246 NewRequiredSignaturesRule(), 247 NewPullRequestRule(&PullRequestRuleParameters{ 248 RequireCodeOwnerReview: true, 249 RequireLastPushApproval: true, 250 RequiredApprovingReviewCount: 1, 251 RequiredReviewThreadResolution: true, 252 DismissStaleReviewsOnPush: true, 253 }), 254 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 255 RequiredStatusChecks: []RuleRequiredStatusChecks{ 256 { 257 Context: "test", 258 IntegrationID: Int64(1), 259 }, 260 }, 261 StrictRequiredStatusChecksPolicy: true, 262 }), 263 NewNonFastForwardRule(), 264 NewCommitMessagePatternRule(&RulePatternParameters{ 265 Name: String("avoid test commits"), 266 Negate: Bool(true), 267 Operator: "starts_with", 268 Pattern: "[test]", 269 }), 270 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 271 Operator: "contains", 272 Pattern: "github", 273 }), 274 NewCommitterEmailPatternRule(&RulePatternParameters{ 275 Name: String("avoid commit emails"), 276 Negate: Bool(true), 277 Operator: "ends_with", 278 Pattern: "abc", 279 }), 280 NewBranchNamePatternRule(&RulePatternParameters{ 281 Name: String("avoid branch names"), 282 Negate: Bool(true), 283 Operator: "regex", 284 Pattern: "github$", 285 }), 286 NewTagNamePatternRule(&RulePatternParameters{ 287 Name: String("avoid tag names"), 288 Negate: Bool(true), 289 Operator: "contains", 290 Pattern: "github", 291 }), 292 }, 293 }) 294 if err != nil { 295 t.Errorf("Organizations.CreateOrganizationRuleset returned error: %v", err) 296 } 297 298 want := &Ruleset{ 299 ID: 21, 300 Name: "ruleset", 301 Target: String("branch"), 302 SourceType: String("Organization"), 303 Source: "o", 304 Enforcement: "active", 305 BypassActors: []*BypassActor{ 306 { 307 ActorID: Int64(234), 308 ActorType: String("Team"), 309 }, 310 }, 311 Conditions: &RulesetConditions{ 312 RefName: &RulesetRefConditionParameters{ 313 Include: []string{"refs/heads/main", "refs/heads/master"}, 314 Exclude: []string{"refs/heads/dev*"}, 315 }, 316 RepositoryName: &RulesetRepositoryConditionParameters{ 317 Include: []string{"important_repository", "another_important_repository"}, 318 Exclude: []string{"unimportant_repository"}, 319 Protected: Bool(true), 320 }, 321 }, 322 Rules: []*RepositoryRule{ 323 NewCreationRule(), 324 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 325 UpdateAllowsFetchAndMerge: true, 326 }), 327 NewDeletionRule(), 328 NewRequiredLinearHistoryRule(), 329 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 330 RequiredDeploymentEnvironments: []string{"test"}, 331 }), 332 NewRequiredSignaturesRule(), 333 NewPullRequestRule(&PullRequestRuleParameters{ 334 RequireCodeOwnerReview: true, 335 RequireLastPushApproval: true, 336 RequiredApprovingReviewCount: 1, 337 RequiredReviewThreadResolution: true, 338 DismissStaleReviewsOnPush: true, 339 }), 340 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 341 RequiredStatusChecks: []RuleRequiredStatusChecks{ 342 { 343 Context: "test", 344 IntegrationID: Int64(1), 345 }, 346 }, 347 StrictRequiredStatusChecksPolicy: true, 348 }), 349 NewNonFastForwardRule(), 350 NewCommitMessagePatternRule(&RulePatternParameters{ 351 Name: String("avoid test commits"), 352 Negate: Bool(true), 353 Operator: "starts_with", 354 Pattern: "[test]", 355 }), 356 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 357 Operator: "contains", 358 Pattern: "github", 359 }), 360 NewCommitterEmailPatternRule(&RulePatternParameters{ 361 Name: String("avoid commit emails"), 362 Negate: Bool(true), 363 Operator: "ends_with", 364 Pattern: "abc", 365 }), 366 NewBranchNamePatternRule(&RulePatternParameters{ 367 Name: String("avoid branch names"), 368 Negate: Bool(true), 369 Operator: "regex", 370 Pattern: "github$", 371 }), 372 NewTagNamePatternRule(&RulePatternParameters{ 373 Name: String("avoid tag names"), 374 Negate: Bool(true), 375 Operator: "contains", 376 Pattern: "github", 377 }), 378 }, 379 } 380 if !cmp.Equal(ruleset, want) { 381 t.Errorf("Organizations.CreateOrganizationRuleset returned %+v, want %+v", ruleset, want) 382 } 383 384 const methodName = "CreateOrganizationRuleset" 385 386 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 387 got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) 388 if got != nil { 389 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 390 } 391 return resp, err 392 }) 393 } 394 395 func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { 396 client, mux, _, teardown := setup() 397 defer teardown() 398 399 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 400 testMethod(t, r, "GET") 401 fmt.Fprint(w, `{ 402 "id": 26110, 403 "name": "test ruleset", 404 "target": "branch", 405 "source_type": "Organization", 406 "source": "o", 407 "enforcement": "active", 408 "bypass_mode": "none", 409 "node_id": "nid", 410 "_links": { 411 "self": { 412 "href": "https://api.github.com/orgs/o/rulesets/26110" 413 } 414 }, 415 "conditions": { 416 "ref_name": { 417 "include": [ 418 "refs/heads/main", 419 "refs/heads/master" 420 ], 421 "exclude": [ 422 "refs/heads/dev*" 423 ] 424 }, 425 "repository_name": { 426 "include": [ 427 "important_repository", 428 "another_important_repository" 429 ], 430 "exclude": [ 431 "unimportant_repository" 432 ], 433 "protected": true 434 } 435 }, 436 "rules": [ 437 { 438 "type": "creation" 439 } 440 ] 441 }`) 442 }) 443 444 ctx := context.Background() 445 rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) 446 if err != nil { 447 t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) 448 } 449 450 want := &Ruleset{ 451 ID: 26110, 452 Name: "test ruleset", 453 Target: String("branch"), 454 SourceType: String("Organization"), 455 Source: "o", 456 Enforcement: "active", 457 BypassMode: String("none"), 458 NodeID: String("nid"), 459 Links: &RulesetLinks{ 460 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 461 }, 462 Conditions: &RulesetConditions{ 463 RefName: &RulesetRefConditionParameters{ 464 Include: []string{"refs/heads/main", "refs/heads/master"}, 465 Exclude: []string{"refs/heads/dev*"}, 466 }, 467 RepositoryName: &RulesetRepositoryConditionParameters{ 468 Include: []string{"important_repository", "another_important_repository"}, 469 Exclude: []string{"unimportant_repository"}, 470 Protected: Bool(true), 471 }, 472 }, 473 Rules: []*RepositoryRule{ 474 NewCreationRule(), 475 }, 476 } 477 if !cmp.Equal(rulesets, want) { 478 t.Errorf("Organizations.GetOrganizationRuleset returned %+v, want %+v", rulesets, want) 479 } 480 481 const methodName = "GetOrganizationRuleset" 482 483 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 484 got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) 485 if got != nil { 486 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 487 } 488 return resp, err 489 }) 490 } 491 492 func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { 493 client, mux, _, teardown := setup() 494 defer teardown() 495 496 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 497 testMethod(t, r, "PUT") 498 fmt.Fprint(w, `{ 499 "id": 26110, 500 "name": "test ruleset", 501 "target": "branch", 502 "source_type": "Organization", 503 "source": "o", 504 "enforcement": "active", 505 "bypass_mode": "none", 506 "node_id": "nid", 507 "_links": { 508 "self": { 509 "href": "https://api.github.com/orgs/o/rulesets/26110" 510 } 511 }, 512 "conditions": { 513 "ref_name": { 514 "include": [ 515 "refs/heads/main", 516 "refs/heads/master" 517 ], 518 "exclude": [ 519 "refs/heads/dev*" 520 ] 521 }, 522 "repository_name": { 523 "include": [ 524 "important_repository", 525 "another_important_repository" 526 ], 527 "exclude": [ 528 "unimportant_repository" 529 ], 530 "protected": true 531 } 532 }, 533 "rules": [ 534 { 535 "type": "creation" 536 } 537 ] 538 }`) 539 }) 540 541 ctx := context.Background() 542 rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ 543 Name: "test ruleset", 544 Target: String("branch"), 545 Enforcement: "active", 546 BypassMode: String("none"), 547 Conditions: &RulesetConditions{ 548 RefName: &RulesetRefConditionParameters{ 549 Include: []string{"refs/heads/main", "refs/heads/master"}, 550 Exclude: []string{"refs/heads/dev*"}, 551 }, 552 RepositoryName: &RulesetRepositoryConditionParameters{ 553 Include: []string{"important_repository", "another_important_repository"}, 554 Exclude: []string{"unimportant_repository"}, 555 Protected: Bool(true), 556 }, 557 }, 558 Rules: []*RepositoryRule{ 559 NewCreationRule(), 560 }, 561 }) 562 563 if err != nil { 564 t.Errorf("Organizations.UpdateOrganizationRuleset returned error: %v", err) 565 } 566 567 want := &Ruleset{ 568 ID: 26110, 569 Name: "test ruleset", 570 Target: String("branch"), 571 SourceType: String("Organization"), 572 Source: "o", 573 Enforcement: "active", 574 BypassMode: String("none"), 575 NodeID: String("nid"), 576 Links: &RulesetLinks{ 577 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 578 }, 579 Conditions: &RulesetConditions{ 580 RefName: &RulesetRefConditionParameters{ 581 Include: []string{"refs/heads/main", "refs/heads/master"}, 582 Exclude: []string{"refs/heads/dev*"}, 583 }, 584 RepositoryName: &RulesetRepositoryConditionParameters{ 585 Include: []string{"important_repository", "another_important_repository"}, 586 Exclude: []string{"unimportant_repository"}, 587 Protected: Bool(true), 588 }, 589 }, 590 Rules: []*RepositoryRule{ 591 NewCreationRule(), 592 }, 593 } 594 if !cmp.Equal(rulesets, want) { 595 t.Errorf("Organizations.UpdateOrganizationRuleset returned %+v, want %+v", rulesets, want) 596 } 597 598 const methodName = "UpdateOrganizationRuleset" 599 600 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 601 got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) 602 if got != nil { 603 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 604 } 605 return resp, err 606 }) 607 } 608 609 func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { 610 client, mux, _, teardown := setup() 611 defer teardown() 612 613 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 614 testMethod(t, r, "DELETE") 615 }) 616 617 ctx := context.Background() 618 _, err := client.Organizations.DeleteOrganizationRuleset(ctx, "o", 26110) 619 if err != nil { 620 t.Errorf("Organizations.DeleteOrganizationRuleset returned error: %v", err) 621 } 622 623 const methodName = "DeleteOrganizationRuleset" 624 625 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 626 return client.Organizations.DeleteOrganizationRuleset(ctx, "0", 26110) 627 }) 628 }