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