github.com/google/go-github/v68@v68.0.0/github/orgs_rules_test.go (about)

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