Skip to content

Commit 1195222

Browse files
committed
test(ruleset): add tests for required_reviewers feature
Add comprehensive unit tests for the expand/flatten helper functions: - TestExpandRequiredReviewers: validates expansion logic - TestExpandRequiredReviewersEmpty: handles edge cases - TestFlattenRequiredReviewers: validates flattening logic - TestFlattenRequiredReviewersEmpty: handles edge cases - TestRoundTripRequiredReviewers: verifies data integrity Add acceptance tests for both organization and repository rulesets: - Single reviewer configuration with file patterns - Multiple reviewers configuration - Update operations (minimum_approvals change) - Import state verification
1 parent 0ff0a4c commit 1195222

3 files changed

Lines changed: 543 additions & 0 deletions

File tree

github/resource_github_organization_ruleset_test.go

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,3 +934,204 @@ func TestOrganizationPushRulesetSupport(t *testing.T) {
934934
t.Errorf("Expected 4 restricted file extensions, got %d", len(restrictedExts))
935935
}
936936
}
937+
938+
func TestAccGithubOrganizationRuleset_requiredReviewers(t *testing.T) {
939+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
940+
teamName := fmt.Sprintf("%steam-req-rev-%s", testResourcePrefix, randomID)
941+
rulesetName := fmt.Sprintf("%s-ruleset-req-rev-%s", testResourcePrefix, randomID)
942+
943+
config := fmt.Sprintf(`
944+
resource "github_team" "test" {
945+
name = "%s"
946+
}
947+
948+
resource "github_organization_ruleset" "test" {
949+
name = "%s"
950+
target = "branch"
951+
enforcement = "active"
952+
953+
conditions {
954+
repository_name {
955+
include = ["~ALL"]
956+
exclude = []
957+
}
958+
959+
ref_name {
960+
include = ["~ALL"]
961+
exclude = []
962+
}
963+
}
964+
965+
rules {
966+
pull_request {
967+
allowed_merge_methods = ["merge", "squash"]
968+
required_approving_review_count = 1
969+
970+
required_reviewers {
971+
reviewer {
972+
id = github_team.test.id
973+
type = "Team"
974+
}
975+
file_patterns = ["*.go", "src/**/*.ts"]
976+
minimum_approvals = 1
977+
}
978+
}
979+
}
980+
}
981+
`, teamName, rulesetName)
982+
983+
// Updated config: change minimum_approvals from 1 to 2
984+
configUpdated := fmt.Sprintf(`
985+
resource "github_team" "test" {
986+
name = "%s"
987+
}
988+
989+
resource "github_organization_ruleset" "test" {
990+
name = "%s"
991+
target = "branch"
992+
enforcement = "active"
993+
994+
conditions {
995+
repository_name {
996+
include = ["~ALL"]
997+
exclude = []
998+
}
999+
1000+
ref_name {
1001+
include = ["~ALL"]
1002+
exclude = []
1003+
}
1004+
}
1005+
1006+
rules {
1007+
pull_request {
1008+
allowed_merge_methods = ["merge", "squash"]
1009+
required_approving_review_count = 1
1010+
1011+
required_reviewers {
1012+
reviewer {
1013+
id = github_team.test.id
1014+
type = "Team"
1015+
}
1016+
file_patterns = ["*.go", "src/**/*.ts"]
1017+
minimum_approvals = 2
1018+
}
1019+
}
1020+
}
1021+
}
1022+
`, teamName, rulesetName)
1023+
1024+
resource.Test(t, resource.TestCase{
1025+
PreCheck: func() { skipUnlessHasPaidOrgs(t) },
1026+
ProviderFactories: providerFactories,
1027+
Steps: []resource.TestStep{
1028+
{
1029+
Config: config,
1030+
Check: resource.ComposeTestCheckFunc(
1031+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "name", rulesetName),
1032+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "target", "branch"),
1033+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "enforcement", "active"),
1034+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.#", "1"),
1035+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.minimum_approvals", "1"),
1036+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.file_patterns.#", "2"),
1037+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.file_patterns.0", "*.go"),
1038+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.file_patterns.1", "src/**/*.ts"),
1039+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.reviewer.0.type", "Team"),
1040+
),
1041+
},
1042+
{
1043+
Config: configUpdated,
1044+
Check: resource.ComposeTestCheckFunc(
1045+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.minimum_approvals", "2"),
1046+
),
1047+
},
1048+
{
1049+
ResourceName: "github_organization_ruleset.test",
1050+
ImportState: true,
1051+
ImportStateVerify: true,
1052+
ImportStateVerifyIgnore: []string{"etag"},
1053+
},
1054+
},
1055+
})
1056+
}
1057+
1058+
func TestAccGithubOrganizationRuleset_requiredReviewersMultiple(t *testing.T) {
1059+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
1060+
teamName1 := fmt.Sprintf("%steam-req-rev-1-%s", testResourcePrefix, randomID)
1061+
teamName2 := fmt.Sprintf("%steam-req-rev-2-%s", testResourcePrefix, randomID)
1062+
rulesetName := fmt.Sprintf("%s-ruleset-multi-rev-%s", testResourcePrefix, randomID)
1063+
1064+
config := fmt.Sprintf(`
1065+
resource "github_team" "test1" {
1066+
name = "%s"
1067+
}
1068+
1069+
resource "github_team" "test2" {
1070+
name = "%s"
1071+
}
1072+
1073+
resource "github_organization_ruleset" "test" {
1074+
name = "%s"
1075+
target = "branch"
1076+
enforcement = "active"
1077+
1078+
conditions {
1079+
repository_name {
1080+
include = ["~ALL"]
1081+
exclude = []
1082+
}
1083+
1084+
ref_name {
1085+
include = ["~ALL"]
1086+
exclude = []
1087+
}
1088+
}
1089+
1090+
rules {
1091+
pull_request {
1092+
allowed_merge_methods = ["merge", "squash"]
1093+
required_approving_review_count = 1
1094+
1095+
required_reviewers {
1096+
reviewer {
1097+
id = github_team.test1.id
1098+
type = "Team"
1099+
}
1100+
file_patterns = ["*.go"]
1101+
minimum_approvals = 1
1102+
}
1103+
1104+
required_reviewers {
1105+
reviewer {
1106+
id = github_team.test2.id
1107+
type = "Team"
1108+
}
1109+
file_patterns = ["*.md", "docs/**/*"]
1110+
minimum_approvals = 1
1111+
}
1112+
}
1113+
}
1114+
}
1115+
`, teamName1, teamName2, rulesetName)
1116+
1117+
resource.Test(t, resource.TestCase{
1118+
PreCheck: func() { skipUnlessHasPaidOrgs(t) },
1119+
ProviderFactories: providerFactories,
1120+
Steps: []resource.TestStep{
1121+
{
1122+
Config: config,
1123+
Check: resource.ComposeTestCheckFunc(
1124+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "name", rulesetName),
1125+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "target", "branch"),
1126+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "enforcement", "active"),
1127+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.#", "2"),
1128+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.minimum_approvals", "1"),
1129+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.file_patterns.#", "1"),
1130+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.file_patterns.0", "*.go"),
1131+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.1.minimum_approvals", "1"),
1132+
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.pull_request.0.required_reviewers.1.file_patterns.#", "2"),
1133+
),
1134+
},
1135+
},
1136+
})
1137+
}

github/resource_github_repository_ruleset_test.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,159 @@ func TestAccGithubRepositoryRulesetValidation(t *testing.T) {
747747
})
748748
}
749749

750+
func TestAccGithubRepositoryRuleset_requiredReviewers(t *testing.T) {
751+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
752+
repoName := fmt.Sprintf("%srepo-ruleset-req-rev-%s", testResourcePrefix, randomID)
753+
teamName := fmt.Sprintf("%steam-req-rev-%s", testResourcePrefix, randomID)
754+
rulesetName := fmt.Sprintf("%s-ruleset-req-rev-%s", testResourcePrefix, randomID)
755+
baseRepoVisibility := "public"
756+
757+
if testAccConf.authMode == enterprise {
758+
// This enables repos to be created even in GHEC EMU
759+
baseRepoVisibility = "private"
760+
}
761+
762+
config := fmt.Sprintf(`
763+
resource "github_repository" "test" {
764+
name = "%s"
765+
auto_init = true
766+
visibility = "%s"
767+
768+
ignore_vulnerability_alerts_during_read = true
769+
}
770+
771+
resource "github_team" "test" {
772+
name = "%s"
773+
}
774+
775+
resource "github_team_repository" "test" {
776+
team_id = github_team.test.id
777+
repository = github_repository.test.name
778+
permission = "push"
779+
}
780+
781+
resource "github_repository_ruleset" "test" {
782+
name = "%s"
783+
repository = github_repository.test.name
784+
target = "branch"
785+
enforcement = "active"
786+
787+
788+
conditions {
789+
ref_name {
790+
include = ["~ALL"]
791+
exclude = []
792+
}
793+
}
794+
795+
rules {
796+
pull_request {
797+
allowed_merge_methods = ["merge", "squash"]
798+
required_approving_review_count = 1
799+
800+
required_reviewers {
801+
reviewer {
802+
id = github_team.test.id
803+
type = "Team"
804+
}
805+
file_patterns = ["*.go"]
806+
minimum_approvals = 1
807+
}
808+
}
809+
}
810+
811+
depends_on = [github_team_repository.test]
812+
}
813+
`, repoName, baseRepoVisibility, teamName, rulesetName)
814+
815+
// Updated config: change minimum_approvals from 1 to 2
816+
configUpdated := fmt.Sprintf(`
817+
resource "github_repository" "test" {
818+
name = "%s"
819+
auto_init = true
820+
visibility = "%s"
821+
822+
ignore_vulnerability_alerts_during_read = true
823+
}
824+
825+
resource "github_team" "test" {
826+
name = "%s"
827+
}
828+
829+
resource "github_team_repository" "test" {
830+
team_id = github_team.test.id
831+
repository = github_repository.test.name
832+
permission = "push"
833+
}
834+
835+
resource "github_repository_ruleset" "test" {
836+
name = "%s"
837+
repository = github_repository.test.name
838+
target = "branch"
839+
enforcement = "active"
840+
841+
842+
conditions {
843+
ref_name {
844+
include = ["~ALL"]
845+
exclude = []
846+
}
847+
}
848+
849+
rules {
850+
pull_request {
851+
allowed_merge_methods = ["merge", "squash"]
852+
required_approving_review_count = 1
853+
854+
required_reviewers {
855+
reviewer {
856+
id = github_team.test.id
857+
type = "Team"
858+
}
859+
file_patterns = ["*.go"]
860+
minimum_approvals = 2
861+
}
862+
}
863+
}
864+
865+
depends_on = [github_team_repository.test]
866+
}
867+
`, repoName, baseRepoVisibility, teamName, rulesetName)
868+
869+
resource.Test(t, resource.TestCase{
870+
PreCheck: func() { skipUnlessHasOrgs(t) },
871+
ProviderFactories: providerFactories,
872+
Steps: []resource.TestStep{
873+
{
874+
Config: config,
875+
Check: resource.ComposeTestCheckFunc(
876+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "name", rulesetName),
877+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "target", "branch"),
878+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "enforcement", "active"),
879+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.pull_request.0.required_reviewers.#", "1"),
880+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.minimum_approvals", "1"),
881+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.file_patterns.#", "1"),
882+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.file_patterns.0", "*.go"),
883+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.reviewer.0.type", "Team"),
884+
),
885+
},
886+
{
887+
Config: configUpdated,
888+
Check: resource.ComposeTestCheckFunc(
889+
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.pull_request.0.required_reviewers.0.minimum_approvals", "2"),
890+
),
891+
},
892+
{
893+
ResourceName: "github_repository_ruleset.test",
894+
ImportState: true,
895+
ImportStateVerify: true,
896+
ImportStateIdFunc: importRepositoryRulesetByResourcePaths("github_repository.test", "github_repository_ruleset.test"),
897+
ImportStateVerifyIgnore: []string{"etag"},
898+
},
899+
},
900+
})
901+
}
902+
750903
func importRepositoryRulesetByResourcePaths(repoLogicalName, rulesetLogicalName string) resource.ImportStateIdFunc {
751904
// test importing using an ID of the form <repo-node-id>:<ruleset-id>
752905
return func(s *terraform.State) (string, error) {

0 commit comments

Comments
 (0)