github.com/google/go-github/v69@v69.2.0/github/enterprise_rules_test.go (about)

     1  // Copyright 2025 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 TestEnterpriseService_CreateRepositoryRuleset_OrgNameRepoName(t *testing.T) {
    18  	t.Parallel()
    19  	client, mux, _ := setup(t)
    20  
    21  	mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) {
    22  		testMethod(t, r, "POST")
    23  		fmt.Fprint(w, `{
    24  			"id": 84,
    25  			"name": "ruleset",
    26  			"target": "branch",
    27  			"source_type": "Enterprise",
    28  			"source": "e",
    29  			"enforcement": "active",
    30  			"bypass_actors": [
    31  				{
    32  					"actor_id": 234,
    33  					"actor_type": "Team"
    34  				}
    35  			],
    36  			"conditions": {
    37  				"organization_name": {
    38  					"include": [
    39  						"important_organization",
    40  						"another_important_organization"
    41  					],
    42  					"exclude": [
    43  						"unimportant_organization"
    44  					]
    45  				},
    46  			  "repository_name": {
    47  					"include": [
    48  						"important_repository",
    49  						"another_important_repository"
    50  					],
    51  					"exclude": [
    52  						"unimportant_repository"
    53  					],
    54  					"protected": true
    55  				},
    56  			  "ref_name": {
    57  					"include": [
    58  						"refs/heads/main",
    59  						"refs/heads/master"
    60  					],
    61  					"exclude": [
    62  						"refs/heads/dev*"
    63  					]
    64  				}
    65  			},
    66  			"rules": [
    67  			  {
    68  				"type": "creation"
    69  			  },
    70  			  {
    71  				"type": "update",
    72  				"parameters": {
    73  				  "update_allows_fetch_and_merge": true
    74  				}
    75  			  },
    76  			  {
    77  				"type": "deletion"
    78  			  },
    79  			  {
    80  				"type": "required_linear_history"
    81  			  },
    82  			  {
    83  				"type": "required_deployments",
    84  				"parameters": {
    85  				  "required_deployment_environments": ["test"]
    86  				}
    87  			  },
    88  			  {
    89  				"type": "required_signatures"
    90  			  },
    91  			  {
    92  				"type": "pull_request",
    93  				"parameters": {
    94  					"allowed_merge_methods": ["rebase","squash"],
    95  				  "dismiss_stale_reviews_on_push": true,
    96  				  "require_code_owner_review": true,
    97  				  "require_last_push_approval": true,
    98  				  "required_approving_review_count": 1,
    99  				  "required_review_thread_resolution": true
   100  				}
   101  			  },
   102  			  {
   103  				"type": "required_status_checks",
   104  				"parameters": {
   105  					"do_not_enforce_on_create": true,
   106  				  "required_status_checks": [
   107  					{
   108  					  "context": "test",
   109  					  "integration_id": 1
   110  					}
   111  				  ],
   112  				  "strict_required_status_checks_policy": true
   113  				}
   114  			  },
   115  			  {
   116  				"type": "non_fast_forward"
   117  			  },
   118  			  {
   119  				"type": "commit_message_pattern",
   120  				"parameters": {
   121  				  "name": "avoid test commits",
   122  				  "negate": true,
   123  				  "operator": "starts_with",
   124  				  "pattern": "[test]"
   125  				}
   126  			  },
   127  			  {
   128  				"type": "commit_author_email_pattern",
   129  				"parameters": {
   130  				  "operator": "contains",
   131  				  "pattern": "github"
   132  				}
   133  			  },
   134  			  {
   135  				"type": "committer_email_pattern",
   136  				"parameters": {
   137  				  "name": "avoid commit emails",
   138  				  "negate": true,
   139  				  "operator": "ends_with",
   140  				  "pattern": "abc"
   141  				}
   142  			  },
   143  			  {
   144  				"type": "branch_name_pattern",
   145  				"parameters": {
   146  				  "name": "avoid branch names",
   147  				  "negate": true,
   148  				  "operator": "regex",
   149  				  "pattern": "github$"
   150  				}
   151  			  },
   152  			  {
   153  				"type": "tag_name_pattern",
   154  				"parameters": {
   155  				  "name": "avoid tag names",
   156  				  "negate": true,
   157  				  "operator": "contains",
   158  				  "pattern": "github"
   159  				}
   160  			  },
   161  			  {
   162  			    "type": "code_scanning",
   163  			    "parameters": {
   164  				  "code_scanning_tools": [
   165  				    {
   166  					  "tool": "CodeQL",
   167  					  "security_alerts_threshold": "high_or_higher",
   168  					  "alerts_threshold": "errors"
   169  				    }
   170  				  ]
   171  			    }
   172  			  }
   173  			]
   174  		  }`)
   175  	})
   176  
   177  	ctx := context.Background()
   178  	ruleset, _, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{
   179  		Name:        "ruleset",
   180  		Target:      Ptr(RulesetTargetBranch),
   181  		Enforcement: "active",
   182  		BypassActors: []*BypassActor{
   183  			{
   184  				ActorID:   Ptr(int64(234)),
   185  				ActorType: Ptr(BypassActorTypeTeam),
   186  			},
   187  		},
   188  		Conditions: &RepositoryRulesetConditions{
   189  			OrganizationName: &RepositoryRulesetOrganizationNamesConditionParameters{
   190  				Include: []string{"important_organization", "another_important_organization"},
   191  				Exclude: []string{"unimportant_organization"},
   192  			},
   193  			RepositoryName: &RepositoryRulesetRepositoryNamesConditionParameters{
   194  				Include:   []string{"important_repository", "another_important_repository"},
   195  				Exclude:   []string{"unimportant_repository"},
   196  				Protected: Ptr(true),
   197  			},
   198  			RefName: &RepositoryRulesetRefConditionParameters{
   199  				Include: []string{"refs/heads/main", "refs/heads/master"},
   200  				Exclude: []string{"refs/heads/dev*"},
   201  			},
   202  		},
   203  		Rules: &RepositoryRulesetRules{
   204  			Creation: &EmptyRuleParameters{},
   205  			Update: &UpdateRuleParameters{
   206  				UpdateAllowsFetchAndMerge: true,
   207  			},
   208  			Deletion:              &EmptyRuleParameters{},
   209  			RequiredLinearHistory: &EmptyRuleParameters{},
   210  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
   211  				RequiredDeploymentEnvironments: []string{"test"},
   212  			},
   213  			RequiredSignatures: &EmptyRuleParameters{},
   214  			PullRequest: &PullRequestRuleParameters{
   215  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
   216  				DismissStaleReviewsOnPush:      true,
   217  				RequireCodeOwnerReview:         true,
   218  				RequireLastPushApproval:        true,
   219  				RequiredApprovingReviewCount:   1,
   220  				RequiredReviewThreadResolution: true,
   221  			},
   222  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
   223  				DoNotEnforceOnCreate: Ptr(true),
   224  				RequiredStatusChecks: []*RuleStatusCheck{
   225  					{
   226  						Context:       "test",
   227  						IntegrationID: Ptr(int64(1)),
   228  					},
   229  				},
   230  				StrictRequiredStatusChecksPolicy: true,
   231  			},
   232  			NonFastForward: &EmptyRuleParameters{},
   233  			CommitMessagePattern: &PatternRuleParameters{
   234  				Name:     Ptr("avoid test commits"),
   235  				Negate:   Ptr(true),
   236  				Operator: "starts_with",
   237  				Pattern:  "[test]",
   238  			},
   239  			CommitAuthorEmailPattern: &PatternRuleParameters{
   240  				Operator: "contains",
   241  				Pattern:  "github",
   242  			},
   243  			CommitterEmailPattern: &PatternRuleParameters{
   244  				Name:     Ptr("avoid commit emails"),
   245  				Negate:   Ptr(true),
   246  				Operator: "ends_with",
   247  				Pattern:  "abc",
   248  			},
   249  			BranchNamePattern: &PatternRuleParameters{
   250  				Name:     Ptr("avoid branch names"),
   251  				Negate:   Ptr(true),
   252  				Operator: "regex",
   253  				Pattern:  "github$",
   254  			},
   255  			TagNamePattern: &PatternRuleParameters{
   256  				Name:     Ptr("avoid tag names"),
   257  				Negate:   Ptr(true),
   258  				Operator: "contains",
   259  				Pattern:  "github",
   260  			},
   261  			CodeScanning: &CodeScanningRuleParameters{
   262  				CodeScanningTools: []*RuleCodeScanningTool{
   263  					{
   264  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
   265  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
   266  						Tool:                    "CodeQL",
   267  					},
   268  				},
   269  			},
   270  		},
   271  	})
   272  	if err != nil {
   273  		t.Errorf("Enterprise.CreateRepositoryRuleset returned error: %v", err)
   274  	}
   275  
   276  	want := &RepositoryRuleset{
   277  		ID:          Ptr(int64(84)),
   278  		Name:        "ruleset",
   279  		Target:      Ptr(RulesetTargetBranch),
   280  		SourceType:  Ptr(RulesetSourceTypeEnterprise),
   281  		Source:      "e",
   282  		Enforcement: "active",
   283  		BypassActors: []*BypassActor{
   284  			{
   285  				ActorID:   Ptr(int64(234)),
   286  				ActorType: Ptr(BypassActorTypeTeam),
   287  			},
   288  		},
   289  		Conditions: &RepositoryRulesetConditions{
   290  			OrganizationName: &RepositoryRulesetOrganizationNamesConditionParameters{
   291  				Include: []string{"important_organization", "another_important_organization"},
   292  				Exclude: []string{"unimportant_organization"},
   293  			},
   294  			RepositoryName: &RepositoryRulesetRepositoryNamesConditionParameters{
   295  				Include:   []string{"important_repository", "another_important_repository"},
   296  				Exclude:   []string{"unimportant_repository"},
   297  				Protected: Ptr(true),
   298  			},
   299  			RefName: &RepositoryRulesetRefConditionParameters{
   300  				Include: []string{"refs/heads/main", "refs/heads/master"},
   301  				Exclude: []string{"refs/heads/dev*"},
   302  			},
   303  		},
   304  		Rules: &RepositoryRulesetRules{
   305  			Creation: &EmptyRuleParameters{},
   306  			Update: &UpdateRuleParameters{
   307  				UpdateAllowsFetchAndMerge: true,
   308  			},
   309  			Deletion:              &EmptyRuleParameters{},
   310  			RequiredLinearHistory: &EmptyRuleParameters{},
   311  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
   312  				RequiredDeploymentEnvironments: []string{"test"},
   313  			},
   314  			RequiredSignatures: &EmptyRuleParameters{},
   315  			PullRequest: &PullRequestRuleParameters{
   316  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
   317  				DismissStaleReviewsOnPush:      true,
   318  				RequireCodeOwnerReview:         true,
   319  				RequireLastPushApproval:        true,
   320  				RequiredApprovingReviewCount:   1,
   321  				RequiredReviewThreadResolution: true,
   322  			},
   323  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
   324  				DoNotEnforceOnCreate: Ptr(true),
   325  				RequiredStatusChecks: []*RuleStatusCheck{
   326  					{
   327  						Context:       "test",
   328  						IntegrationID: Ptr(int64(1)),
   329  					},
   330  				},
   331  				StrictRequiredStatusChecksPolicy: true,
   332  			},
   333  			NonFastForward: &EmptyRuleParameters{},
   334  			CommitMessagePattern: &PatternRuleParameters{
   335  				Name:     Ptr("avoid test commits"),
   336  				Negate:   Ptr(true),
   337  				Operator: "starts_with",
   338  				Pattern:  "[test]",
   339  			},
   340  			CommitAuthorEmailPattern: &PatternRuleParameters{
   341  				Operator: "contains",
   342  				Pattern:  "github",
   343  			},
   344  			CommitterEmailPattern: &PatternRuleParameters{
   345  				Name:     Ptr("avoid commit emails"),
   346  				Negate:   Ptr(true),
   347  				Operator: "ends_with",
   348  				Pattern:  "abc",
   349  			},
   350  			BranchNamePattern: &PatternRuleParameters{
   351  				Name:     Ptr("avoid branch names"),
   352  				Negate:   Ptr(true),
   353  				Operator: "regex",
   354  				Pattern:  "github$",
   355  			},
   356  			TagNamePattern: &PatternRuleParameters{
   357  				Name:     Ptr("avoid tag names"),
   358  				Negate:   Ptr(true),
   359  				Operator: "contains",
   360  				Pattern:  "github",
   361  			},
   362  			CodeScanning: &CodeScanningRuleParameters{
   363  				CodeScanningTools: []*RuleCodeScanningTool{
   364  					{
   365  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
   366  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
   367  						Tool:                    "CodeQL",
   368  					},
   369  				},
   370  			},
   371  		},
   372  	}
   373  	if !cmp.Equal(ruleset, want) {
   374  		t.Errorf("Enterprise.CreateRepositoryRuleset returned %+v, want %+v", ruleset, want)
   375  	}
   376  
   377  	const methodName = "CreateRepositoryRuleset"
   378  
   379  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   380  		got, resp, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{})
   381  		if got != nil {
   382  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   383  		}
   384  		return resp, err
   385  	})
   386  }
   387  
   388  func TestEnterpriseService_CreateRepositoryRuleset_OrgNameRepoProperty(t *testing.T) {
   389  	t.Parallel()
   390  	client, mux, _ := setup(t)
   391  
   392  	mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) {
   393  		testMethod(t, r, "POST")
   394  		fmt.Fprint(w, `{
   395  			"id": 84,
   396  			"name": "ruleset",
   397  			"target": "branch",
   398  			"source_type": "Enterprise",
   399  			"source": "e",
   400  			"enforcement": "active",
   401  			"bypass_actors": [
   402  				{
   403  					"actor_id": 234,
   404  					"actor_type": "Team"
   405  				}
   406  			],
   407  			"conditions": {
   408  				"organization_name": {
   409  					"include": [
   410  						"important_organization",
   411  						"another_important_organization"
   412  					],
   413  					"exclude": [
   414  						"unimportant_organization"
   415  					]
   416  				},
   417  			  "repository_property": {
   418  					"include": [
   419  						{
   420  							"name": "testIncludeProp",
   421  							"source": "custom",
   422  							"property_values": [
   423  								"true"
   424  							]
   425  						}
   426  					],
   427  					"exclude": [
   428  						{
   429  							"name": "testExcludeProp",
   430  							"property_values": [
   431  								"false"
   432  							]
   433  						}
   434  					]
   435  				},
   436  			  "ref_name": {
   437  					"include": [
   438  						"refs/heads/main",
   439  						"refs/heads/master"
   440  					],
   441  					"exclude": [
   442  						"refs/heads/dev*"
   443  					]
   444  				}
   445  			},
   446  			"rules": [
   447  			  {
   448  				"type": "creation"
   449  			  },
   450  			  {
   451  				"type": "update",
   452  				"parameters": {
   453  				  "update_allows_fetch_and_merge": true
   454  				}
   455  			  },
   456  			  {
   457  				"type": "deletion"
   458  			  },
   459  			  {
   460  				"type": "required_linear_history"
   461  			  },
   462  			  {
   463  				"type": "required_deployments",
   464  				"parameters": {
   465  				  "required_deployment_environments": ["test"]
   466  				}
   467  			  },
   468  			  {
   469  				"type": "required_signatures"
   470  			  },
   471  			  {
   472  				"type": "pull_request",
   473  				"parameters": {
   474  					"allowed_merge_methods": ["rebase","squash"],
   475  				  "dismiss_stale_reviews_on_push": true,
   476  				  "require_code_owner_review": true,
   477  				  "require_last_push_approval": true,
   478  				  "required_approving_review_count": 1,
   479  				  "required_review_thread_resolution": true
   480  				}
   481  			  },
   482  			  {
   483  				"type": "required_status_checks",
   484  				"parameters": {
   485  					"do_not_enforce_on_create": true,
   486  				  "required_status_checks": [
   487  					{
   488  					  "context": "test",
   489  					  "integration_id": 1
   490  					}
   491  				  ],
   492  				  "strict_required_status_checks_policy": true
   493  				}
   494  			  },
   495  			  {
   496  				"type": "non_fast_forward"
   497  			  },
   498  			  {
   499  				"type": "commit_message_pattern",
   500  				"parameters": {
   501  				  "name": "avoid test commits",
   502  				  "negate": true,
   503  				  "operator": "starts_with",
   504  				  "pattern": "[test]"
   505  				}
   506  			  },
   507  			  {
   508  				"type": "commit_author_email_pattern",
   509  				"parameters": {
   510  				  "operator": "contains",
   511  				  "pattern": "github"
   512  				}
   513  			  },
   514  			  {
   515  				"type": "committer_email_pattern",
   516  				"parameters": {
   517  				  "name": "avoid commit emails",
   518  				  "negate": true,
   519  				  "operator": "ends_with",
   520  				  "pattern": "abc"
   521  				}
   522  			  },
   523  			  {
   524  				"type": "branch_name_pattern",
   525  				"parameters": {
   526  				  "name": "avoid branch names",
   527  				  "negate": true,
   528  				  "operator": "regex",
   529  				  "pattern": "github$"
   530  				}
   531  			  },
   532  			  {
   533  				"type": "tag_name_pattern",
   534  				"parameters": {
   535  				  "name": "avoid tag names",
   536  				  "negate": true,
   537  				  "operator": "contains",
   538  				  "pattern": "github"
   539  				}
   540  			  },
   541  			  {
   542  			    "type": "code_scanning",
   543  			    "parameters": {
   544  				  "code_scanning_tools": [
   545  				    {
   546  					  "tool": "CodeQL",
   547  					  "security_alerts_threshold": "high_or_higher",
   548  					  "alerts_threshold": "errors"
   549  				    }
   550  				  ]
   551  			    }
   552  			  }
   553  			]
   554  		  }`)
   555  	})
   556  
   557  	ctx := context.Background()
   558  	ruleset, _, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{
   559  		Name:        "ruleset",
   560  		Target:      Ptr(RulesetTargetBranch),
   561  		Enforcement: "active",
   562  		BypassActors: []*BypassActor{
   563  			{
   564  				ActorID:   Ptr(int64(234)),
   565  				ActorType: Ptr(BypassActorTypeTeam),
   566  			},
   567  		},
   568  		Conditions: &RepositoryRulesetConditions{
   569  			OrganizationName: &RepositoryRulesetOrganizationNamesConditionParameters{
   570  				Include: []string{"important_organization", "another_important_organization"},
   571  				Exclude: []string{"unimportant_organization"},
   572  			},
   573  			RepositoryProperty: &RepositoryRulesetRepositoryPropertyConditionParameters{
   574  				Include: []*RepositoryRulesetRepositoryPropertyTargetParameters{
   575  					{
   576  						Name:           "testIncludeProp",
   577  						Source:         Ptr("custom"),
   578  						PropertyValues: []string{"true"},
   579  					},
   580  				},
   581  				Exclude: []*RepositoryRulesetRepositoryPropertyTargetParameters{
   582  					{
   583  						Name:           "testExcludeProp",
   584  						PropertyValues: []string{"false"},
   585  					},
   586  				},
   587  			},
   588  			RefName: &RepositoryRulesetRefConditionParameters{
   589  				Include: []string{"refs/heads/main", "refs/heads/master"},
   590  				Exclude: []string{"refs/heads/dev*"},
   591  			},
   592  		},
   593  		Rules: &RepositoryRulesetRules{
   594  			Creation: &EmptyRuleParameters{},
   595  			Update: &UpdateRuleParameters{
   596  				UpdateAllowsFetchAndMerge: true,
   597  			},
   598  			Deletion:              &EmptyRuleParameters{},
   599  			RequiredLinearHistory: &EmptyRuleParameters{},
   600  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
   601  				RequiredDeploymentEnvironments: []string{"test"},
   602  			},
   603  			RequiredSignatures: &EmptyRuleParameters{},
   604  			PullRequest: &PullRequestRuleParameters{
   605  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
   606  				DismissStaleReviewsOnPush:      true,
   607  				RequireCodeOwnerReview:         true,
   608  				RequireLastPushApproval:        true,
   609  				RequiredApprovingReviewCount:   1,
   610  				RequiredReviewThreadResolution: true,
   611  			},
   612  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
   613  				DoNotEnforceOnCreate: Ptr(true),
   614  				RequiredStatusChecks: []*RuleStatusCheck{
   615  					{
   616  						Context:       "test",
   617  						IntegrationID: Ptr(int64(1)),
   618  					},
   619  				},
   620  				StrictRequiredStatusChecksPolicy: true,
   621  			},
   622  			NonFastForward: &EmptyRuleParameters{},
   623  			CommitMessagePattern: &PatternRuleParameters{
   624  				Name:     Ptr("avoid test commits"),
   625  				Negate:   Ptr(true),
   626  				Operator: "starts_with",
   627  				Pattern:  "[test]",
   628  			},
   629  			CommitAuthorEmailPattern: &PatternRuleParameters{
   630  				Operator: "contains",
   631  				Pattern:  "github",
   632  			},
   633  			CommitterEmailPattern: &PatternRuleParameters{
   634  				Name:     Ptr("avoid commit emails"),
   635  				Negate:   Ptr(true),
   636  				Operator: "ends_with",
   637  				Pattern:  "abc",
   638  			},
   639  			BranchNamePattern: &PatternRuleParameters{
   640  				Name:     Ptr("avoid branch names"),
   641  				Negate:   Ptr(true),
   642  				Operator: "regex",
   643  				Pattern:  "github$",
   644  			},
   645  			TagNamePattern: &PatternRuleParameters{
   646  				Name:     Ptr("avoid tag names"),
   647  				Negate:   Ptr(true),
   648  				Operator: "contains",
   649  				Pattern:  "github",
   650  			},
   651  			CodeScanning: &CodeScanningRuleParameters{
   652  				CodeScanningTools: []*RuleCodeScanningTool{
   653  					{
   654  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
   655  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
   656  						Tool:                    "CodeQL",
   657  					},
   658  				},
   659  			},
   660  		},
   661  	})
   662  	if err != nil {
   663  		t.Errorf("Enterprise.CreateRepositoryRuleset returned error: %v", err)
   664  	}
   665  
   666  	want := &RepositoryRuleset{
   667  		ID:          Ptr(int64(84)),
   668  		Name:        "ruleset",
   669  		Target:      Ptr(RulesetTargetBranch),
   670  		SourceType:  Ptr(RulesetSourceTypeEnterprise),
   671  		Source:      "e",
   672  		Enforcement: "active",
   673  		BypassActors: []*BypassActor{
   674  			{
   675  				ActorID:   Ptr(int64(234)),
   676  				ActorType: Ptr(BypassActorTypeTeam),
   677  			},
   678  		},
   679  		Conditions: &RepositoryRulesetConditions{
   680  			OrganizationName: &RepositoryRulesetOrganizationNamesConditionParameters{
   681  				Include: []string{"important_organization", "another_important_organization"},
   682  				Exclude: []string{"unimportant_organization"},
   683  			},
   684  			RepositoryProperty: &RepositoryRulesetRepositoryPropertyConditionParameters{
   685  				Include: []*RepositoryRulesetRepositoryPropertyTargetParameters{
   686  					{
   687  						Name:           "testIncludeProp",
   688  						Source:         Ptr("custom"),
   689  						PropertyValues: []string{"true"},
   690  					},
   691  				},
   692  				Exclude: []*RepositoryRulesetRepositoryPropertyTargetParameters{
   693  					{
   694  						Name:           "testExcludeProp",
   695  						PropertyValues: []string{"false"},
   696  					},
   697  				},
   698  			},
   699  			RefName: &RepositoryRulesetRefConditionParameters{
   700  				Include: []string{"refs/heads/main", "refs/heads/master"},
   701  				Exclude: []string{"refs/heads/dev*"},
   702  			},
   703  		},
   704  		Rules: &RepositoryRulesetRules{
   705  			Creation: &EmptyRuleParameters{},
   706  			Update: &UpdateRuleParameters{
   707  				UpdateAllowsFetchAndMerge: true,
   708  			},
   709  			Deletion:              &EmptyRuleParameters{},
   710  			RequiredLinearHistory: &EmptyRuleParameters{},
   711  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
   712  				RequiredDeploymentEnvironments: []string{"test"},
   713  			},
   714  			RequiredSignatures: &EmptyRuleParameters{},
   715  			PullRequest: &PullRequestRuleParameters{
   716  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
   717  				DismissStaleReviewsOnPush:      true,
   718  				RequireCodeOwnerReview:         true,
   719  				RequireLastPushApproval:        true,
   720  				RequiredApprovingReviewCount:   1,
   721  				RequiredReviewThreadResolution: true,
   722  			},
   723  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
   724  				DoNotEnforceOnCreate: Ptr(true),
   725  				RequiredStatusChecks: []*RuleStatusCheck{
   726  					{
   727  						Context:       "test",
   728  						IntegrationID: Ptr(int64(1)),
   729  					},
   730  				},
   731  				StrictRequiredStatusChecksPolicy: true,
   732  			},
   733  			NonFastForward: &EmptyRuleParameters{},
   734  			CommitMessagePattern: &PatternRuleParameters{
   735  				Name:     Ptr("avoid test commits"),
   736  				Negate:   Ptr(true),
   737  				Operator: "starts_with",
   738  				Pattern:  "[test]",
   739  			},
   740  			CommitAuthorEmailPattern: &PatternRuleParameters{
   741  				Operator: "contains",
   742  				Pattern:  "github",
   743  			},
   744  			CommitterEmailPattern: &PatternRuleParameters{
   745  				Name:     Ptr("avoid commit emails"),
   746  				Negate:   Ptr(true),
   747  				Operator: "ends_with",
   748  				Pattern:  "abc",
   749  			},
   750  			BranchNamePattern: &PatternRuleParameters{
   751  				Name:     Ptr("avoid branch names"),
   752  				Negate:   Ptr(true),
   753  				Operator: "regex",
   754  				Pattern:  "github$",
   755  			},
   756  			TagNamePattern: &PatternRuleParameters{
   757  				Name:     Ptr("avoid tag names"),
   758  				Negate:   Ptr(true),
   759  				Operator: "contains",
   760  				Pattern:  "github",
   761  			},
   762  			CodeScanning: &CodeScanningRuleParameters{
   763  				CodeScanningTools: []*RuleCodeScanningTool{
   764  					{
   765  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
   766  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
   767  						Tool:                    "CodeQL",
   768  					},
   769  				},
   770  			},
   771  		},
   772  	}
   773  	if !cmp.Equal(ruleset, want) {
   774  		t.Errorf("Enterprise.CreateRepositoryRuleset returned %+v, want %+v", ruleset, want)
   775  	}
   776  
   777  	const methodName = "CreateRepositoryRuleset"
   778  
   779  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   780  		got, resp, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{})
   781  		if got != nil {
   782  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   783  		}
   784  		return resp, err
   785  	})
   786  }
   787  
   788  func TestEnterpriseService_CreateRepositoryRuleset_OrgIdRepoName(t *testing.T) {
   789  	t.Parallel()
   790  	client, mux, _ := setup(t)
   791  
   792  	mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) {
   793  		testMethod(t, r, "POST")
   794  		fmt.Fprint(w, `{
   795  			"id": 84,
   796  			"name": "ruleset",
   797  			"target": "branch",
   798  			"source_type": "Enterprise",
   799  			"source": "e",
   800  			"enforcement": "active",
   801  			"bypass_actors": [
   802  				{
   803  					"actor_id": 234,
   804  					"actor_type": "Team"
   805  				}
   806  			],
   807  			"conditions": {
   808  				"organization_id": {
   809  					"organization_ids": [1001, 1002]
   810  				},
   811  			  "repository_name": {
   812  					"include": [
   813  						"important_repository",
   814  						"another_important_repository"
   815  					],
   816  					"exclude": [
   817  						"unimportant_repository"
   818  					],
   819  					"protected": true
   820  				},
   821  			  "ref_name": {
   822  					"include": [
   823  						"refs/heads/main",
   824  						"refs/heads/master"
   825  					],
   826  					"exclude": [
   827  						"refs/heads/dev*"
   828  					]
   829  				}
   830  			},
   831  			"rules": [
   832  			  {
   833  				"type": "creation"
   834  			  },
   835  			  {
   836  				"type": "update",
   837  				"parameters": {
   838  				  "update_allows_fetch_and_merge": true
   839  				}
   840  			  },
   841  			  {
   842  				"type": "deletion"
   843  			  },
   844  			  {
   845  				"type": "required_linear_history"
   846  			  },
   847  			  {
   848  				"type": "required_deployments",
   849  				"parameters": {
   850  				  "required_deployment_environments": ["test"]
   851  				}
   852  			  },
   853  			  {
   854  				"type": "required_signatures"
   855  			  },
   856  			  {
   857  				"type": "pull_request",
   858  				"parameters": {
   859  					"allowed_merge_methods": ["rebase","squash"],
   860  				  "dismiss_stale_reviews_on_push": true,
   861  				  "require_code_owner_review": true,
   862  				  "require_last_push_approval": true,
   863  				  "required_approving_review_count": 1,
   864  				  "required_review_thread_resolution": true
   865  				}
   866  			  },
   867  			  {
   868  				"type": "required_status_checks",
   869  				"parameters": {
   870  					"do_not_enforce_on_create": true,
   871  				  "required_status_checks": [
   872  					{
   873  					  "context": "test",
   874  					  "integration_id": 1
   875  					}
   876  				  ],
   877  				  "strict_required_status_checks_policy": true
   878  				}
   879  			  },
   880  			  {
   881  				"type": "non_fast_forward"
   882  			  },
   883  			  {
   884  				"type": "commit_message_pattern",
   885  				"parameters": {
   886  				  "name": "avoid test commits",
   887  				  "negate": true,
   888  				  "operator": "starts_with",
   889  				  "pattern": "[test]"
   890  				}
   891  			  },
   892  			  {
   893  				"type": "commit_author_email_pattern",
   894  				"parameters": {
   895  				  "operator": "contains",
   896  				  "pattern": "github"
   897  				}
   898  			  },
   899  			  {
   900  				"type": "committer_email_pattern",
   901  				"parameters": {
   902  				  "name": "avoid commit emails",
   903  				  "negate": true,
   904  				  "operator": "ends_with",
   905  				  "pattern": "abc"
   906  				}
   907  			  },
   908  			  {
   909  				"type": "branch_name_pattern",
   910  				"parameters": {
   911  				  "name": "avoid branch names",
   912  				  "negate": true,
   913  				  "operator": "regex",
   914  				  "pattern": "github$"
   915  				}
   916  			  },
   917  			  {
   918  				"type": "tag_name_pattern",
   919  				"parameters": {
   920  				  "name": "avoid tag names",
   921  				  "negate": true,
   922  				  "operator": "contains",
   923  				  "pattern": "github"
   924  				}
   925  			  },
   926  			  {
   927  			    "type": "code_scanning",
   928  			    "parameters": {
   929  				  "code_scanning_tools": [
   930  				    {
   931  					  "tool": "CodeQL",
   932  					  "security_alerts_threshold": "high_or_higher",
   933  					  "alerts_threshold": "errors"
   934  				    }
   935  				  ]
   936  			    }
   937  			  }
   938  			]
   939  		  }`)
   940  	})
   941  
   942  	ctx := context.Background()
   943  	ruleset, _, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{
   944  		Name:        "ruleset",
   945  		Target:      Ptr(RulesetTargetBranch),
   946  		Enforcement: "active",
   947  		BypassActors: []*BypassActor{
   948  			{
   949  				ActorID:   Ptr(int64(234)),
   950  				ActorType: Ptr(BypassActorTypeTeam),
   951  			},
   952  		},
   953  		Conditions: &RepositoryRulesetConditions{
   954  			OrganizationID: &RepositoryRulesetOrganizationIDsConditionParameters{
   955  				OrganizationIDs: []int64{1001, 1002},
   956  			},
   957  			RepositoryName: &RepositoryRulesetRepositoryNamesConditionParameters{
   958  				Include:   []string{"important_repository", "another_important_repository"},
   959  				Exclude:   []string{"unimportant_repository"},
   960  				Protected: Ptr(true),
   961  			},
   962  			RefName: &RepositoryRulesetRefConditionParameters{
   963  				Include: []string{"refs/heads/main", "refs/heads/master"},
   964  				Exclude: []string{"refs/heads/dev*"},
   965  			},
   966  		},
   967  		Rules: &RepositoryRulesetRules{
   968  			Creation: &EmptyRuleParameters{},
   969  			Update: &UpdateRuleParameters{
   970  				UpdateAllowsFetchAndMerge: true,
   971  			},
   972  			Deletion:              &EmptyRuleParameters{},
   973  			RequiredLinearHistory: &EmptyRuleParameters{},
   974  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
   975  				RequiredDeploymentEnvironments: []string{"test"},
   976  			},
   977  			RequiredSignatures: &EmptyRuleParameters{},
   978  			PullRequest: &PullRequestRuleParameters{
   979  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
   980  				DismissStaleReviewsOnPush:      true,
   981  				RequireCodeOwnerReview:         true,
   982  				RequireLastPushApproval:        true,
   983  				RequiredApprovingReviewCount:   1,
   984  				RequiredReviewThreadResolution: true,
   985  			},
   986  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
   987  				DoNotEnforceOnCreate: Ptr(true),
   988  				RequiredStatusChecks: []*RuleStatusCheck{
   989  					{
   990  						Context:       "test",
   991  						IntegrationID: Ptr(int64(1)),
   992  					},
   993  				},
   994  				StrictRequiredStatusChecksPolicy: true,
   995  			},
   996  			NonFastForward: &EmptyRuleParameters{},
   997  			CommitMessagePattern: &PatternRuleParameters{
   998  				Name:     Ptr("avoid test commits"),
   999  				Negate:   Ptr(true),
  1000  				Operator: "starts_with",
  1001  				Pattern:  "[test]",
  1002  			},
  1003  			CommitAuthorEmailPattern: &PatternRuleParameters{
  1004  				Operator: "contains",
  1005  				Pattern:  "github",
  1006  			},
  1007  			CommitterEmailPattern: &PatternRuleParameters{
  1008  				Name:     Ptr("avoid commit emails"),
  1009  				Negate:   Ptr(true),
  1010  				Operator: "ends_with",
  1011  				Pattern:  "abc",
  1012  			},
  1013  			BranchNamePattern: &PatternRuleParameters{
  1014  				Name:     Ptr("avoid branch names"),
  1015  				Negate:   Ptr(true),
  1016  				Operator: "regex",
  1017  				Pattern:  "github$",
  1018  			},
  1019  			TagNamePattern: &PatternRuleParameters{
  1020  				Name:     Ptr("avoid tag names"),
  1021  				Negate:   Ptr(true),
  1022  				Operator: "contains",
  1023  				Pattern:  "github",
  1024  			},
  1025  			CodeScanning: &CodeScanningRuleParameters{
  1026  				CodeScanningTools: []*RuleCodeScanningTool{
  1027  					{
  1028  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
  1029  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
  1030  						Tool:                    "CodeQL",
  1031  					},
  1032  				},
  1033  			},
  1034  		},
  1035  	})
  1036  	if err != nil {
  1037  		t.Errorf("Enterprise.CreateRepositoryRuleset returned error: %v", err)
  1038  	}
  1039  
  1040  	want := &RepositoryRuleset{
  1041  		ID:          Ptr(int64(84)),
  1042  		Name:        "ruleset",
  1043  		Target:      Ptr(RulesetTargetBranch),
  1044  		SourceType:  Ptr(RulesetSourceTypeEnterprise),
  1045  		Source:      "e",
  1046  		Enforcement: "active",
  1047  		BypassActors: []*BypassActor{
  1048  			{
  1049  				ActorID:   Ptr(int64(234)),
  1050  				ActorType: Ptr(BypassActorTypeTeam),
  1051  			},
  1052  		},
  1053  		Conditions: &RepositoryRulesetConditions{
  1054  			OrganizationID: &RepositoryRulesetOrganizationIDsConditionParameters{
  1055  				OrganizationIDs: []int64{1001, 1002},
  1056  			},
  1057  			RepositoryName: &RepositoryRulesetRepositoryNamesConditionParameters{
  1058  				Include:   []string{"important_repository", "another_important_repository"},
  1059  				Exclude:   []string{"unimportant_repository"},
  1060  				Protected: Ptr(true),
  1061  			},
  1062  			RefName: &RepositoryRulesetRefConditionParameters{
  1063  				Include: []string{"refs/heads/main", "refs/heads/master"},
  1064  				Exclude: []string{"refs/heads/dev*"},
  1065  			},
  1066  		},
  1067  		Rules: &RepositoryRulesetRules{
  1068  			Creation: &EmptyRuleParameters{},
  1069  			Update: &UpdateRuleParameters{
  1070  				UpdateAllowsFetchAndMerge: true,
  1071  			},
  1072  			Deletion:              &EmptyRuleParameters{},
  1073  			RequiredLinearHistory: &EmptyRuleParameters{},
  1074  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
  1075  				RequiredDeploymentEnvironments: []string{"test"},
  1076  			},
  1077  			RequiredSignatures: &EmptyRuleParameters{},
  1078  			PullRequest: &PullRequestRuleParameters{
  1079  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
  1080  				DismissStaleReviewsOnPush:      true,
  1081  				RequireCodeOwnerReview:         true,
  1082  				RequireLastPushApproval:        true,
  1083  				RequiredApprovingReviewCount:   1,
  1084  				RequiredReviewThreadResolution: true,
  1085  			},
  1086  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
  1087  				DoNotEnforceOnCreate: Ptr(true),
  1088  				RequiredStatusChecks: []*RuleStatusCheck{
  1089  					{
  1090  						Context:       "test",
  1091  						IntegrationID: Ptr(int64(1)),
  1092  					},
  1093  				},
  1094  				StrictRequiredStatusChecksPolicy: true,
  1095  			},
  1096  			NonFastForward: &EmptyRuleParameters{},
  1097  			CommitMessagePattern: &PatternRuleParameters{
  1098  				Name:     Ptr("avoid test commits"),
  1099  				Negate:   Ptr(true),
  1100  				Operator: "starts_with",
  1101  				Pattern:  "[test]",
  1102  			},
  1103  			CommitAuthorEmailPattern: &PatternRuleParameters{
  1104  				Operator: "contains",
  1105  				Pattern:  "github",
  1106  			},
  1107  			CommitterEmailPattern: &PatternRuleParameters{
  1108  				Name:     Ptr("avoid commit emails"),
  1109  				Negate:   Ptr(true),
  1110  				Operator: "ends_with",
  1111  				Pattern:  "abc",
  1112  			},
  1113  			BranchNamePattern: &PatternRuleParameters{
  1114  				Name:     Ptr("avoid branch names"),
  1115  				Negate:   Ptr(true),
  1116  				Operator: "regex",
  1117  				Pattern:  "github$",
  1118  			},
  1119  			TagNamePattern: &PatternRuleParameters{
  1120  				Name:     Ptr("avoid tag names"),
  1121  				Negate:   Ptr(true),
  1122  				Operator: "contains",
  1123  				Pattern:  "github",
  1124  			},
  1125  			CodeScanning: &CodeScanningRuleParameters{
  1126  				CodeScanningTools: []*RuleCodeScanningTool{
  1127  					{
  1128  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
  1129  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
  1130  						Tool:                    "CodeQL",
  1131  					},
  1132  				},
  1133  			},
  1134  		},
  1135  	}
  1136  	if !cmp.Equal(ruleset, want) {
  1137  		t.Errorf("Enterprise.CreateRepositoryRuleset returned %+v, want %+v", ruleset, want)
  1138  	}
  1139  
  1140  	const methodName = "CreateRepositoryRuleset"
  1141  
  1142  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1143  		got, resp, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{})
  1144  		if got != nil {
  1145  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1146  		}
  1147  		return resp, err
  1148  	})
  1149  }
  1150  
  1151  func TestEnterpriseService_CreateRepositoryRuleset_OrgIdRepoProperty(t *testing.T) {
  1152  	t.Parallel()
  1153  	client, mux, _ := setup(t)
  1154  
  1155  	mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) {
  1156  		testMethod(t, r, "POST")
  1157  		fmt.Fprint(w, `{
  1158  			"id": 84,
  1159  			"name": "ruleset",
  1160  			"target": "branch",
  1161  			"source_type": "Enterprise",
  1162  			"source": "e",
  1163  			"enforcement": "active",
  1164  			"bypass_actors": [
  1165  				{
  1166  					"actor_id": 234,
  1167  					"actor_type": "Team"
  1168  				}
  1169  			],
  1170  			"conditions": {
  1171  				"organization_id": {
  1172  					"organization_ids": [1001, 1002]
  1173  				},
  1174  			  "repository_property": {
  1175  					"include": [
  1176  						{
  1177  							"name": "testIncludeProp",
  1178  							"source": "custom",
  1179  							"property_values": [
  1180  								"true"
  1181  							]
  1182  						}
  1183  					],
  1184  					"exclude": [
  1185  						{
  1186  							"name": "testExcludeProp",
  1187  							"property_values": [
  1188  								"false"
  1189  							]
  1190  						}
  1191  					]
  1192  				},
  1193  			  "ref_name": {
  1194  					"include": [
  1195  						"refs/heads/main",
  1196  						"refs/heads/master"
  1197  					],
  1198  					"exclude": [
  1199  						"refs/heads/dev*"
  1200  					]
  1201  				}
  1202  			},
  1203  			"rules": [
  1204  			  {
  1205  				"type": "creation"
  1206  			  },
  1207  			  {
  1208  				"type": "update",
  1209  				"parameters": {
  1210  				  "update_allows_fetch_and_merge": true
  1211  				}
  1212  			  },
  1213  			  {
  1214  				"type": "deletion"
  1215  			  },
  1216  			  {
  1217  				"type": "required_linear_history"
  1218  			  },
  1219  			  {
  1220  				"type": "required_deployments",
  1221  				"parameters": {
  1222  				  "required_deployment_environments": ["test"]
  1223  				}
  1224  			  },
  1225  			  {
  1226  				"type": "required_signatures"
  1227  			  },
  1228  			  {
  1229  				"type": "pull_request",
  1230  				"parameters": {
  1231  					"allowed_merge_methods": ["rebase","squash"],
  1232  				  "dismiss_stale_reviews_on_push": true,
  1233  				  "require_code_owner_review": true,
  1234  				  "require_last_push_approval": true,
  1235  				  "required_approving_review_count": 1,
  1236  				  "required_review_thread_resolution": true
  1237  				}
  1238  			  },
  1239  			  {
  1240  				"type": "required_status_checks",
  1241  				"parameters": {
  1242  					"do_not_enforce_on_create": true,
  1243  				  "required_status_checks": [
  1244  					{
  1245  					  "context": "test",
  1246  					  "integration_id": 1
  1247  					}
  1248  				  ],
  1249  				  "strict_required_status_checks_policy": true
  1250  				}
  1251  			  },
  1252  			  {
  1253  				"type": "non_fast_forward"
  1254  			  },
  1255  			  {
  1256  				"type": "commit_message_pattern",
  1257  				"parameters": {
  1258  				  "name": "avoid test commits",
  1259  				  "negate": true,
  1260  				  "operator": "starts_with",
  1261  				  "pattern": "[test]"
  1262  				}
  1263  			  },
  1264  			  {
  1265  				"type": "commit_author_email_pattern",
  1266  				"parameters": {
  1267  				  "operator": "contains",
  1268  				  "pattern": "github"
  1269  				}
  1270  			  },
  1271  			  {
  1272  				"type": "committer_email_pattern",
  1273  				"parameters": {
  1274  				  "name": "avoid commit emails",
  1275  				  "negate": true,
  1276  				  "operator": "ends_with",
  1277  				  "pattern": "abc"
  1278  				}
  1279  			  },
  1280  			  {
  1281  				"type": "branch_name_pattern",
  1282  				"parameters": {
  1283  				  "name": "avoid branch names",
  1284  				  "negate": true,
  1285  				  "operator": "regex",
  1286  				  "pattern": "github$"
  1287  				}
  1288  			  },
  1289  			  {
  1290  				"type": "tag_name_pattern",
  1291  				"parameters": {
  1292  				  "name": "avoid tag names",
  1293  				  "negate": true,
  1294  				  "operator": "contains",
  1295  				  "pattern": "github"
  1296  				}
  1297  			  },
  1298  			  {
  1299  			    "type": "code_scanning",
  1300  			    "parameters": {
  1301  				  "code_scanning_tools": [
  1302  				    {
  1303  					  "tool": "CodeQL",
  1304  					  "security_alerts_threshold": "high_or_higher",
  1305  					  "alerts_threshold": "errors"
  1306  				    }
  1307  				  ]
  1308  			    }
  1309  			  }
  1310  			]
  1311  		  }`)
  1312  	})
  1313  
  1314  	ctx := context.Background()
  1315  	ruleset, _, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{
  1316  		Name:        "ruleset",
  1317  		Target:      Ptr(RulesetTargetBranch),
  1318  		Enforcement: "active",
  1319  		BypassActors: []*BypassActor{
  1320  			{
  1321  				ActorID:   Ptr(int64(234)),
  1322  				ActorType: Ptr(BypassActorTypeTeam),
  1323  			},
  1324  		},
  1325  		Conditions: &RepositoryRulesetConditions{
  1326  			OrganizationID: &RepositoryRulesetOrganizationIDsConditionParameters{
  1327  				OrganizationIDs: []int64{1001, 1002},
  1328  			},
  1329  			RepositoryProperty: &RepositoryRulesetRepositoryPropertyConditionParameters{
  1330  				Include: []*RepositoryRulesetRepositoryPropertyTargetParameters{
  1331  					{
  1332  						Name:           "testIncludeProp",
  1333  						Source:         Ptr("custom"),
  1334  						PropertyValues: []string{"true"},
  1335  					},
  1336  				},
  1337  				Exclude: []*RepositoryRulesetRepositoryPropertyTargetParameters{
  1338  					{
  1339  						Name:           "testExcludeProp",
  1340  						PropertyValues: []string{"false"},
  1341  					},
  1342  				},
  1343  			},
  1344  			RefName: &RepositoryRulesetRefConditionParameters{
  1345  				Include: []string{"refs/heads/main", "refs/heads/master"},
  1346  				Exclude: []string{"refs/heads/dev*"},
  1347  			},
  1348  		},
  1349  		Rules: &RepositoryRulesetRules{
  1350  			Creation: &EmptyRuleParameters{},
  1351  			Update: &UpdateRuleParameters{
  1352  				UpdateAllowsFetchAndMerge: true,
  1353  			},
  1354  			Deletion:              &EmptyRuleParameters{},
  1355  			RequiredLinearHistory: &EmptyRuleParameters{},
  1356  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
  1357  				RequiredDeploymentEnvironments: []string{"test"},
  1358  			},
  1359  			RequiredSignatures: &EmptyRuleParameters{},
  1360  			PullRequest: &PullRequestRuleParameters{
  1361  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
  1362  				DismissStaleReviewsOnPush:      true,
  1363  				RequireCodeOwnerReview:         true,
  1364  				RequireLastPushApproval:        true,
  1365  				RequiredApprovingReviewCount:   1,
  1366  				RequiredReviewThreadResolution: true,
  1367  			},
  1368  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
  1369  				DoNotEnforceOnCreate: Ptr(true),
  1370  				RequiredStatusChecks: []*RuleStatusCheck{
  1371  					{
  1372  						Context:       "test",
  1373  						IntegrationID: Ptr(int64(1)),
  1374  					},
  1375  				},
  1376  				StrictRequiredStatusChecksPolicy: true,
  1377  			},
  1378  			NonFastForward: &EmptyRuleParameters{},
  1379  			CommitMessagePattern: &PatternRuleParameters{
  1380  				Name:     Ptr("avoid test commits"),
  1381  				Negate:   Ptr(true),
  1382  				Operator: "starts_with",
  1383  				Pattern:  "[test]",
  1384  			},
  1385  			CommitAuthorEmailPattern: &PatternRuleParameters{
  1386  				Operator: "contains",
  1387  				Pattern:  "github",
  1388  			},
  1389  			CommitterEmailPattern: &PatternRuleParameters{
  1390  				Name:     Ptr("avoid commit emails"),
  1391  				Negate:   Ptr(true),
  1392  				Operator: "ends_with",
  1393  				Pattern:  "abc",
  1394  			},
  1395  			BranchNamePattern: &PatternRuleParameters{
  1396  				Name:     Ptr("avoid branch names"),
  1397  				Negate:   Ptr(true),
  1398  				Operator: "regex",
  1399  				Pattern:  "github$",
  1400  			},
  1401  			TagNamePattern: &PatternRuleParameters{
  1402  				Name:     Ptr("avoid tag names"),
  1403  				Negate:   Ptr(true),
  1404  				Operator: "contains",
  1405  				Pattern:  "github",
  1406  			},
  1407  			CodeScanning: &CodeScanningRuleParameters{
  1408  				CodeScanningTools: []*RuleCodeScanningTool{
  1409  					{
  1410  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
  1411  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
  1412  						Tool:                    "CodeQL",
  1413  					},
  1414  				},
  1415  			},
  1416  		},
  1417  	})
  1418  	if err != nil {
  1419  		t.Errorf("Enterprise.CreateRepositoryRuleset returned error: %v", err)
  1420  	}
  1421  
  1422  	want := &RepositoryRuleset{
  1423  		ID:          Ptr(int64(84)),
  1424  		Name:        "ruleset",
  1425  		Target:      Ptr(RulesetTargetBranch),
  1426  		SourceType:  Ptr(RulesetSourceTypeEnterprise),
  1427  		Source:      "e",
  1428  		Enforcement: "active",
  1429  		BypassActors: []*BypassActor{
  1430  			{
  1431  				ActorID:   Ptr(int64(234)),
  1432  				ActorType: Ptr(BypassActorTypeTeam),
  1433  			},
  1434  		},
  1435  		Conditions: &RepositoryRulesetConditions{
  1436  			OrganizationID: &RepositoryRulesetOrganizationIDsConditionParameters{
  1437  				OrganizationIDs: []int64{1001, 1002},
  1438  			},
  1439  			RepositoryProperty: &RepositoryRulesetRepositoryPropertyConditionParameters{
  1440  				Include: []*RepositoryRulesetRepositoryPropertyTargetParameters{
  1441  					{
  1442  						Name:           "testIncludeProp",
  1443  						Source:         Ptr("custom"),
  1444  						PropertyValues: []string{"true"},
  1445  					},
  1446  				},
  1447  				Exclude: []*RepositoryRulesetRepositoryPropertyTargetParameters{
  1448  					{
  1449  						Name:           "testExcludeProp",
  1450  						PropertyValues: []string{"false"},
  1451  					},
  1452  				},
  1453  			},
  1454  			RefName: &RepositoryRulesetRefConditionParameters{
  1455  				Include: []string{"refs/heads/main", "refs/heads/master"},
  1456  				Exclude: []string{"refs/heads/dev*"},
  1457  			},
  1458  		},
  1459  		Rules: &RepositoryRulesetRules{
  1460  			Creation: &EmptyRuleParameters{},
  1461  			Update: &UpdateRuleParameters{
  1462  				UpdateAllowsFetchAndMerge: true,
  1463  			},
  1464  			Deletion:              &EmptyRuleParameters{},
  1465  			RequiredLinearHistory: &EmptyRuleParameters{},
  1466  			RequiredDeployments: &RequiredDeploymentsRuleParameters{
  1467  				RequiredDeploymentEnvironments: []string{"test"},
  1468  			},
  1469  			RequiredSignatures: &EmptyRuleParameters{},
  1470  			PullRequest: &PullRequestRuleParameters{
  1471  				AllowedMergeMethods:            []MergeMethod{MergeMethodRebase, MergeMethodSquash},
  1472  				DismissStaleReviewsOnPush:      true,
  1473  				RequireCodeOwnerReview:         true,
  1474  				RequireLastPushApproval:        true,
  1475  				RequiredApprovingReviewCount:   1,
  1476  				RequiredReviewThreadResolution: true,
  1477  			},
  1478  			RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
  1479  				DoNotEnforceOnCreate: Ptr(true),
  1480  				RequiredStatusChecks: []*RuleStatusCheck{
  1481  					{
  1482  						Context:       "test",
  1483  						IntegrationID: Ptr(int64(1)),
  1484  					},
  1485  				},
  1486  				StrictRequiredStatusChecksPolicy: true,
  1487  			},
  1488  			NonFastForward: &EmptyRuleParameters{},
  1489  			CommitMessagePattern: &PatternRuleParameters{
  1490  				Name:     Ptr("avoid test commits"),
  1491  				Negate:   Ptr(true),
  1492  				Operator: "starts_with",
  1493  				Pattern:  "[test]",
  1494  			},
  1495  			CommitAuthorEmailPattern: &PatternRuleParameters{
  1496  				Operator: "contains",
  1497  				Pattern:  "github",
  1498  			},
  1499  			CommitterEmailPattern: &PatternRuleParameters{
  1500  				Name:     Ptr("avoid commit emails"),
  1501  				Negate:   Ptr(true),
  1502  				Operator: "ends_with",
  1503  				Pattern:  "abc",
  1504  			},
  1505  			BranchNamePattern: &PatternRuleParameters{
  1506  				Name:     Ptr("avoid branch names"),
  1507  				Negate:   Ptr(true),
  1508  				Operator: "regex",
  1509  				Pattern:  "github$",
  1510  			},
  1511  			TagNamePattern: &PatternRuleParameters{
  1512  				Name:     Ptr("avoid tag names"),
  1513  				Negate:   Ptr(true),
  1514  				Operator: "contains",
  1515  				Pattern:  "github",
  1516  			},
  1517  			CodeScanning: &CodeScanningRuleParameters{
  1518  				CodeScanningTools: []*RuleCodeScanningTool{
  1519  					{
  1520  						AlertsThreshold:         CodeScanningAlertsThresholdErrors,
  1521  						SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher,
  1522  						Tool:                    "CodeQL",
  1523  					},
  1524  				},
  1525  			},
  1526  		},
  1527  	}
  1528  	if !cmp.Equal(ruleset, want) {
  1529  		t.Errorf("Enterprise.CreateRepositoryRuleset returned %+v, want %+v", ruleset, want)
  1530  	}
  1531  
  1532  	const methodName = "CreateRepositoryRuleset"
  1533  
  1534  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1535  		got, resp, err := client.Enterprise.CreateRepositoryRuleset(ctx, "e", RepositoryRuleset{})
  1536  		if got != nil {
  1537  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1538  		}
  1539  		return resp, err
  1540  	})
  1541  }
  1542  
  1543  func TestEnterpriseService_GetRepositoryRuleset(t *testing.T) {
  1544  	t.Parallel()
  1545  	client, mux, _ := setup(t)
  1546  
  1547  	mux.HandleFunc("/enterprises/e/rulesets/84", func(w http.ResponseWriter, r *http.Request) {
  1548  		testMethod(t, r, "GET")
  1549  		fmt.Fprint(w, `{
  1550  			"id": 84,
  1551  			"name": "test ruleset",
  1552  			"target": "branch",
  1553  			"source_type": "Enterprise",
  1554  			"source": "e",
  1555  			"enforcement": "active",
  1556  			"bypass_mode": "none",
  1557  			"node_id": "nid",
  1558  			"_links": {
  1559  			  "self": {
  1560  					"href": "https://api.github.com/enterprises/e/rulesets/84"
  1561  				}
  1562  			},
  1563  			"conditions": {
  1564  				"organization_name": {
  1565  					"include": [
  1566  						"important_organization",
  1567  						"another_important_organization"
  1568  					],
  1569  					"exclude": [
  1570  						"unimportant_organization"
  1571  					]
  1572  				},
  1573  				"repository_name": {
  1574  					"include": [
  1575  						"important_repository",
  1576  						"another_important_repository"
  1577  					],
  1578  					"exclude": [
  1579  						"unimportant_repository"
  1580  				  ],
  1581  				  "protected": true
  1582  				},
  1583  				"ref_name": {
  1584  					"include": [
  1585  						"refs/heads/main",
  1586  						"refs/heads/master"
  1587  				  ],
  1588  				  "exclude": [
  1589  						"refs/heads/dev*"
  1590  				  ]
  1591  				}
  1592  			},
  1593  			  "rules": [
  1594  					{
  1595  						"type": "creation"
  1596  					}
  1597  			  ]
  1598  		}`)
  1599  	})
  1600  
  1601  	ctx := context.Background()
  1602  	rulesets, _, err := client.Enterprise.GetRepositoryRuleset(ctx, "e", 84)
  1603  	if err != nil {
  1604  		t.Errorf("Enterprise.GetRepositoryRuleset returned error: %v", err)
  1605  	}
  1606  
  1607  	want := &RepositoryRuleset{
  1608  		ID:          Ptr(int64(84)),
  1609  		Name:        "test ruleset",
  1610  		Target:      Ptr(RulesetTargetBranch),
  1611  		SourceType:  Ptr(RulesetSourceTypeEnterprise),
  1612  		Source:      "e",
  1613  		Enforcement: "active",
  1614  		NodeID:      Ptr("nid"),
  1615  		Links: &RepositoryRulesetLinks{
  1616  			Self: &RepositoryRulesetLink{HRef: Ptr("https://api.github.com/enterprises/e/rulesets/84")},
  1617  		},
  1618  		Conditions: &RepositoryRulesetConditions{
  1619  			OrganizationName: &RepositoryRulesetOrganizationNamesConditionParameters{
  1620  				Include: []string{"important_organization", "another_important_organization"},
  1621  				Exclude: []string{"unimportant_organization"},
  1622  			},
  1623  			RepositoryName: &RepositoryRulesetRepositoryNamesConditionParameters{
  1624  				Include:   []string{"important_repository", "another_important_repository"},
  1625  				Exclude:   []string{"unimportant_repository"},
  1626  				Protected: Ptr(true),
  1627  			},
  1628  			RefName: &RepositoryRulesetRefConditionParameters{
  1629  				Include: []string{"refs/heads/main", "refs/heads/master"},
  1630  				Exclude: []string{"refs/heads/dev*"},
  1631  			},
  1632  		},
  1633  		Rules: &RepositoryRulesetRules{Creation: &EmptyRuleParameters{}},
  1634  	}
  1635  	if !cmp.Equal(rulesets, want) {
  1636  		t.Errorf("Enterprise.GetRepositoryRuleset returned %+v, want %+v", rulesets, want)
  1637  	}
  1638  
  1639  	const methodName = "GetRepositoryRuleset"
  1640  
  1641  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1642  		got, resp, err := client.Enterprise.GetRepositoryRuleset(ctx, "e", 84)
  1643  		if got != nil {
  1644  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1645  		}
  1646  		return resp, err
  1647  	})
  1648  }
  1649  
  1650  func TestEnterpriseService_UpdateRepositoryRuleset(t *testing.T) {
  1651  	t.Parallel()
  1652  	client, mux, _ := setup(t)
  1653  
  1654  	mux.HandleFunc("/enterprises/e/rulesets/84", func(w http.ResponseWriter, r *http.Request) {
  1655  		testMethod(t, r, "PUT")
  1656  		fmt.Fprint(w, `{
  1657  			"id": 84,
  1658  			"name": "test ruleset",
  1659  			"target": "branch",
  1660  			"source_type": "Enterprise",
  1661  			"source": "e",
  1662  			"enforcement": "active",
  1663  			"bypass_mode": "none",
  1664  			"node_id": "nid",
  1665  			"_links": {
  1666  			  "self": {
  1667  				"href": "https://api.github.com/enterprises/e/rulesets/84"
  1668  			  }
  1669  			},
  1670  			"conditions": {
  1671  				"organization_name": {
  1672  					"include": [
  1673  						"important_organization",
  1674  						"another_important_organization"
  1675  					],
  1676  					"exclude": [
  1677  						"unimportant_organization"
  1678  					]
  1679  				},
  1680  				"repository_name": {
  1681  					"include": [
  1682  						"important_repository",
  1683  						"another_important_repository"
  1684  				  ],
  1685  					"exclude": [
  1686  						"unimportant_repository"
  1687  					],
  1688  				  "protected": true
  1689  				},
  1690  				"ref_name": {
  1691  					"include": [
  1692  						"refs/heads/main",
  1693  						"refs/heads/master"
  1694  					],
  1695  					"exclude": [
  1696  						"refs/heads/dev*"
  1697  					]
  1698  				}
  1699  			},
  1700  			"rules": [
  1701  				{
  1702  				  "type": "creation"
  1703  				}
  1704  			]
  1705  		}`)
  1706  	})
  1707  
  1708  	ctx := context.Background()
  1709  	rulesets, _, err := client.Enterprise.UpdateRepositoryRuleset(ctx, "e", 84, RepositoryRuleset{
  1710  		Name:        "test ruleset",
  1711  		Target:      Ptr(RulesetTargetBranch),
  1712  		Enforcement: "active",
  1713  		Conditions: &RepositoryRulesetConditions{
  1714  			RefName: &RepositoryRulesetRefConditionParameters{
  1715  				Include: []string{"refs/heads/main", "refs/heads/master"},
  1716  				Exclude: []string{"refs/heads/dev*"},
  1717  			},
  1718  			RepositoryName: &RepositoryRulesetRepositoryNamesConditionParameters{
  1719  				Include:   []string{"important_repository", "another_important_repository"},
  1720  				Exclude:   []string{"unimportant_repository"},
  1721  				Protected: Ptr(true),
  1722  			},
  1723  		},
  1724  		Rules: &RepositoryRulesetRules{Creation: &EmptyRuleParameters{}},
  1725  	})
  1726  	if err != nil {
  1727  		t.Errorf("Enterprise.UpdateRepositoryRuleset returned error: %v", err)
  1728  	}
  1729  
  1730  	want := &RepositoryRuleset{
  1731  		ID:          Ptr(int64(84)),
  1732  		Name:        "test ruleset",
  1733  		Target:      Ptr(RulesetTargetBranch),
  1734  		SourceType:  Ptr(RulesetSourceTypeEnterprise),
  1735  		Source:      "e",
  1736  		Enforcement: "active",
  1737  		NodeID:      Ptr("nid"),
  1738  		Links: &RepositoryRulesetLinks{
  1739  			Self: &RepositoryRulesetLink{HRef: Ptr("https://api.github.com/enterprises/e/rulesets/84")},
  1740  		},
  1741  		Conditions: &RepositoryRulesetConditions{
  1742  			OrganizationName: &RepositoryRulesetOrganizationNamesConditionParameters{
  1743  				Include: []string{"important_organization", "another_important_organization"},
  1744  				Exclude: []string{"unimportant_organization"},
  1745  			},
  1746  			RepositoryName: &RepositoryRulesetRepositoryNamesConditionParameters{
  1747  				Include:   []string{"important_repository", "another_important_repository"},
  1748  				Exclude:   []string{"unimportant_repository"},
  1749  				Protected: Ptr(true),
  1750  			},
  1751  			RefName: &RepositoryRulesetRefConditionParameters{
  1752  				Include: []string{"refs/heads/main", "refs/heads/master"},
  1753  				Exclude: []string{"refs/heads/dev*"},
  1754  			},
  1755  		},
  1756  		Rules: &RepositoryRulesetRules{Creation: &EmptyRuleParameters{}},
  1757  	}
  1758  	if !cmp.Equal(rulesets, want) {
  1759  		t.Errorf("Enterprise.UpdateRepositoryRuleset returned %+v, want %+v", rulesets, want)
  1760  	}
  1761  
  1762  	const methodName = "UpdateRepositoryRuleset"
  1763  
  1764  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1765  		got, resp, err := client.Enterprise.UpdateRepositoryRuleset(ctx, "e", 84, RepositoryRuleset{})
  1766  		if got != nil {
  1767  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1768  		}
  1769  		return resp, err
  1770  	})
  1771  }
  1772  
  1773  func TestEnterpriseService_UpdateRepositoryRulesetClearBypassActor(t *testing.T) {
  1774  	t.Parallel()
  1775  	client, mux, _ := setup(t)
  1776  
  1777  	mux.HandleFunc("/enterprises/e/rulesets/84", func(w http.ResponseWriter, r *http.Request) {
  1778  		testMethod(t, r, "PUT")
  1779  		fmt.Fprint(w, `{
  1780  			"id": 84,
  1781  			"name": "test ruleset",
  1782  			"target": "branch",
  1783  			"source_type": "Enterprise",
  1784  			"source": "e",
  1785  			"enforcement": "active",
  1786  			"bypass_mode": "none",
  1787  			"conditions": {
  1788  				"organization_name": {
  1789  					"include": [
  1790  						"important_organization",
  1791  						"another_important_organization"
  1792  					],
  1793  					"exclude": [
  1794  						"unimportant_organization"
  1795  					]
  1796  				},
  1797  			  "repository_name": {
  1798  					"include": [
  1799  						"important_repository",
  1800  						"another_important_repository"
  1801  					],
  1802  					"exclude": [
  1803  						"unimportant_repository"
  1804  					],
  1805  					"protected": true
  1806  				},
  1807  			  "ref_name": {
  1808  					"include": [
  1809  						"refs/heads/main",
  1810  						"refs/heads/master"
  1811  					],
  1812  					"exclude": [
  1813  						"refs/heads/dev*"
  1814  					]
  1815  				}
  1816  			},
  1817  			"rules": [
  1818  			  {
  1819  					"type": "creation"
  1820  			  }
  1821  			]
  1822  		}`)
  1823  	})
  1824  
  1825  	ctx := context.Background()
  1826  
  1827  	_, err := client.Enterprise.UpdateRepositoryRulesetClearBypassActor(ctx, "e", 84)
  1828  	if err != nil {
  1829  		t.Errorf("Enterprise.UpdateRepositoryRulesetClearBypassActor returned error: %v \n", err)
  1830  	}
  1831  
  1832  	const methodName = "UpdateRepositoryRulesetClearBypassActor"
  1833  
  1834  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1835  		return client.Enterprise.UpdateRepositoryRulesetClearBypassActor(ctx, "e", 84)
  1836  	})
  1837  }
  1838  
  1839  func TestEnterpriseService_DeleteRepositoryRuleset(t *testing.T) {
  1840  	t.Parallel()
  1841  	client, mux, _ := setup(t)
  1842  
  1843  	mux.HandleFunc("/enterprises/e/rulesets/84", func(w http.ResponseWriter, r *http.Request) {
  1844  		testMethod(t, r, "DELETE")
  1845  	})
  1846  
  1847  	ctx := context.Background()
  1848  	_, err := client.Enterprise.DeleteRepositoryRuleset(ctx, "e", 84)
  1849  	if err != nil {
  1850  		t.Errorf("Enterprise.DeleteRepositoryRuleset returned error: %v", err)
  1851  	}
  1852  
  1853  	const methodName = "DeleteRepositoryRuleset"
  1854  
  1855  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1856  		return client.Enterprise.DeleteRepositoryRuleset(ctx, "e", 84)
  1857  	})
  1858  }