github.com/google/go-github/v64@v64.0.0/github/repos_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 TestRepositoryRule_UnmarshalJSON(t *testing.T) {
    18  	tests := map[string]struct {
    19  		data    string
    20  		want    *RepositoryRule
    21  		wantErr bool
    22  	}{
    23  		"Invalid JSON": {
    24  			data: `{`,
    25  			want: &RepositoryRule{
    26  				Type:       "",
    27  				Parameters: nil,
    28  			},
    29  			wantErr: true,
    30  		},
    31  		"With Metadata": {
    32  			data: `{
    33                      "type": "creation",
    34  					"ruleset_source_type": "Repository",
    35  					"ruleset_source": "google",
    36  					"ruleset_id": 1984
    37             		   }`,
    38  			want: &RepositoryRule{
    39  				RulesetSource:     "google",
    40  				RulesetSourceType: "Repository",
    41  				RulesetID:         1984,
    42  				Type:              "creation",
    43  			},
    44  		},
    45  		"Valid creation": {
    46  			data: `{"type":"creation"}`,
    47  			want: NewCreationRule(),
    48  		},
    49  		"Valid deletion": {
    50  			data: `{"type":"deletion"}`,
    51  			want: &RepositoryRule{
    52  				Type:       "deletion",
    53  				Parameters: nil,
    54  			},
    55  		},
    56  		"Valid required_linear_history": {
    57  			data: `{"type":"required_linear_history"}`,
    58  			want: &RepositoryRule{
    59  				Type:       "required_linear_history",
    60  				Parameters: nil,
    61  			},
    62  		},
    63  		"Valid required_signatures": {
    64  			data: `{"type":"required_signatures"}`,
    65  			want: &RepositoryRule{
    66  				Type:       "required_signatures",
    67  				Parameters: nil,
    68  			},
    69  		},
    70  		"Valid merge_queue": {
    71  			data: `{"type":"merge_queue"}`,
    72  			want: &RepositoryRule{
    73  				Type:       "merge_queue",
    74  				Parameters: nil,
    75  			},
    76  		},
    77  		"Valid non_fast_forward": {
    78  			data: `{"type":"non_fast_forward"}`,
    79  			want: &RepositoryRule{
    80  				Type:       "non_fast_forward",
    81  				Parameters: nil,
    82  			},
    83  		},
    84  		"Valid update params": {
    85  			data: `{"type":"update","parameters":{"update_allows_fetch_and_merge":true}}`,
    86  			want: NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{UpdateAllowsFetchAndMerge: true}),
    87  		},
    88  		"Invalid update params": {
    89  			data: `{"type":"update","parameters":{"update_allows_fetch_and_merge":"true"}}`,
    90  			want: &RepositoryRule{
    91  				Type:       "update",
    92  				Parameters: nil,
    93  			},
    94  			wantErr: true,
    95  		},
    96  		"Valid required_deployments params": {
    97  			data: `{"type":"required_deployments","parameters":{"required_deployment_environments":["test"]}}`,
    98  			want: NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{
    99  				RequiredDeploymentEnvironments: []string{"test"},
   100  			}),
   101  		},
   102  		"Invalid required_deployments params": {
   103  			data: `{"type":"required_deployments","parameters":{"required_deployment_environments":true}}`,
   104  			want: &RepositoryRule{
   105  				Type:       "required_deployments",
   106  				Parameters: nil,
   107  			},
   108  			wantErr: true,
   109  		},
   110  		"Valid commit_message_pattern params": {
   111  			data: `{"type":"commit_message_pattern","parameters":{"operator":"starts_with","pattern":"github"}}`,
   112  			want: NewCommitMessagePatternRule(&RulePatternParameters{
   113  				Operator: "starts_with",
   114  				Pattern:  "github",
   115  			}),
   116  		},
   117  		"Invalid commit_message_pattern params": {
   118  			data: `{"type":"commit_message_pattern","parameters":{"operator":"starts_with","pattern":1}}`,
   119  			want: &RepositoryRule{
   120  				Type:       "commit_message_pattern",
   121  				Parameters: nil,
   122  			},
   123  			wantErr: true,
   124  		},
   125  		"Valid commit_author_email_pattern params": {
   126  			data: `{"type":"commit_author_email_pattern","parameters":{"operator":"starts_with","pattern":"github"}}`,
   127  			want: NewCommitAuthorEmailPatternRule(&RulePatternParameters{
   128  				Operator: "starts_with",
   129  				Pattern:  "github",
   130  			}),
   131  		},
   132  		"Invalid commit_author_email_pattern params": {
   133  			data: `{"type":"commit_author_email_pattern","parameters":{"operator":"starts_with","pattern":1}}`,
   134  			want: &RepositoryRule{
   135  				Type:       "commit_author_email_pattern",
   136  				Parameters: nil,
   137  			},
   138  			wantErr: true,
   139  		},
   140  		"Valid committer_email_pattern params": {
   141  			data: `{"type":"committer_email_pattern","parameters":{"operator":"starts_with","pattern":"github"}}`,
   142  			want: NewCommitterEmailPatternRule(&RulePatternParameters{
   143  				Operator: "starts_with",
   144  				Pattern:  "github",
   145  			}),
   146  		},
   147  		"Invalid committer_email_pattern params": {
   148  			data: `{"type":"committer_email_pattern","parameters":{"operator":"starts_with","pattern":1}}`,
   149  			want: &RepositoryRule{
   150  				Type:       "committer_email_pattern",
   151  				Parameters: nil,
   152  			},
   153  			wantErr: true,
   154  		},
   155  		"Valid branch_name_pattern params": {
   156  			data: `{"type":"branch_name_pattern","parameters":{"operator":"starts_with","pattern":"github"}}`,
   157  			want: NewBranchNamePatternRule(&RulePatternParameters{
   158  				Operator: "starts_with",
   159  				Pattern:  "github",
   160  			}),
   161  		},
   162  		"Invalid branch_name_pattern params": {
   163  			data: `{"type":"branch_name_pattern","parameters":{"operator":"starts_with","pattern":1}}`,
   164  			want: &RepositoryRule{
   165  				Type:       "branch_name_pattern",
   166  				Parameters: nil,
   167  			},
   168  			wantErr: true,
   169  		},
   170  		"Valid tag_name_pattern params": {
   171  			data: `{"type":"tag_name_pattern","parameters":{"operator":"starts_with","pattern":"github"}}`,
   172  			want: NewTagNamePatternRule(&RulePatternParameters{
   173  				Operator: "starts_with",
   174  				Pattern:  "github",
   175  			}),
   176  		},
   177  		"Invalid tag_name_pattern params": {
   178  			data: `{"type":"tag_name_pattern","parameters":{"operator":"starts_with","pattern":1}}`,
   179  			want: &RepositoryRule{
   180  				Type:       "tag_name_pattern",
   181  				Parameters: nil,
   182  			},
   183  			wantErr: true,
   184  		},
   185  		"Valid file_path_restriction params": {
   186  			data: `{"type":"file_path_restriction","parameters":{"restricted_file_paths":["/a/file"]}}`,
   187  			want: NewFilePathRestrictionRule(&RuleFileParameters{
   188  				RestrictedFilePaths: &[]string{"/a/file"},
   189  			}),
   190  		},
   191  		"Invalid file_path_restriction params": {
   192  			data: `{"type":"file_path_restriction","parameters":{"restricted_file_paths":true}}`,
   193  			want: &RepositoryRule{
   194  				Type:       "file_path_restriction",
   195  				Parameters: nil,
   196  			},
   197  			wantErr: true,
   198  		},
   199  		"Valid pull_request params": {
   200  			data: `{
   201  				"type":"pull_request",
   202  				"parameters":{
   203  					"dismiss_stale_reviews_on_push": true,
   204  					"require_code_owner_review": true,
   205  					"require_last_push_approval": true,
   206  					"required_approving_review_count": 1,
   207  					"required_review_thread_resolution":true
   208  				}
   209  			}`,
   210  			want: NewPullRequestRule(&PullRequestRuleParameters{
   211  				DismissStaleReviewsOnPush:      true,
   212  				RequireCodeOwnerReview:         true,
   213  				RequireLastPushApproval:        true,
   214  				RequiredApprovingReviewCount:   1,
   215  				RequiredReviewThreadResolution: true,
   216  			}),
   217  		},
   218  		"Invalid pull_request params": {
   219  			data: `{"type":"pull_request","parameters": {"dismiss_stale_reviews_on_push":"true"}}`,
   220  			want: &RepositoryRule{
   221  				Type:       "pull_request",
   222  				Parameters: nil,
   223  			},
   224  			wantErr: true,
   225  		},
   226  		"Valid required_status_checks params": {
   227  			data: `{"type":"required_status_checks","parameters":{"required_status_checks":[{"context":"test","integration_id":1}],"strict_required_status_checks_policy":true}}`,
   228  			want: NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{
   229  				RequiredStatusChecks: []RuleRequiredStatusChecks{
   230  					{
   231  						Context:       "test",
   232  						IntegrationID: Int64(1),
   233  					},
   234  				},
   235  				StrictRequiredStatusChecksPolicy: true,
   236  			}),
   237  		},
   238  		"Invalid required_status_checks params": {
   239  			data: `{"type":"required_status_checks",
   240  			"parameters": {
   241  				"required_status_checks": [
   242  				  {
   243  					"context": 1
   244  				  }
   245  				]
   246  			  }}`,
   247  			want: &RepositoryRule{
   248  				Type:       "required_status_checks",
   249  				Parameters: nil,
   250  			},
   251  			wantErr: true,
   252  		},
   253  		"Required workflows params": {
   254  			data: `{"type":"workflows","parameters":{"workflows":[{"path": ".github/workflows/test.yml", "repository_id": 1}]}}`,
   255  			want: NewRequiredWorkflowsRule(&RequiredWorkflowsRuleParameters{
   256  				RequiredWorkflows: []*RuleRequiredWorkflow{
   257  					{
   258  						Path:         ".github/workflows/test.yml",
   259  						RepositoryID: Int64(1),
   260  					},
   261  				},
   262  			}),
   263  		},
   264  		"Invalid type": {
   265  			data: `{"type":"unknown"}`,
   266  			want: &RepositoryRule{
   267  				Type:       "",
   268  				Parameters: nil,
   269  			},
   270  			wantErr: true,
   271  		},
   272  	}
   273  
   274  	for name, tc := range tests {
   275  		rule := &RepositoryRule{}
   276  
   277  		t.Run(name, func(t *testing.T) {
   278  			err := rule.UnmarshalJSON([]byte(tc.data))
   279  			if err == nil && tc.wantErr {
   280  				t.Errorf("RepositoryRule.UnmarshalJSON returned nil instead of an error")
   281  			}
   282  			if err != nil && !tc.wantErr {
   283  				t.Errorf("RepositoryRule.UnmarshalJSON returned an unexpected error: %+v", err)
   284  			}
   285  			if !cmp.Equal(tc.want, rule) {
   286  				t.Errorf("RepositoryRule.UnmarshalJSON expected rule %+v, got %+v", tc.want, rule)
   287  			}
   288  		})
   289  	}
   290  }
   291  
   292  func TestRepositoriesService_GetRulesForBranch(t *testing.T) {
   293  	client, mux, _, teardown := setup()
   294  	defer teardown()
   295  
   296  	mux.HandleFunc("/repos/o/repo/rules/branches/branch", func(w http.ResponseWriter, r *http.Request) {
   297  		testMethod(t, r, "GET")
   298  		fmt.Fprint(w, `[
   299  			{
   300  			  "ruleset_id": 42069,
   301  			  "ruleset_source_type": "Repository",
   302  			  "ruleset_source": "google",
   303  			  "type": "creation"
   304  			},
   305  			{
   306  			  "ruleset_id": 42069,
   307  			  "ruleset_source_type": "Organization",
   308  			  "ruleset_source": "google",
   309  			  "type": "update",
   310  			  "parameters": {
   311  			    "update_allows_fetch_and_merge": true
   312  			  }
   313  			}
   314  		]`)
   315  	})
   316  
   317  	ctx := context.Background()
   318  	rules, _, err := client.Repositories.GetRulesForBranch(ctx, "o", "repo", "branch")
   319  	if err != nil {
   320  		t.Errorf("Repositories.GetRulesForBranch returned error: %v", err)
   321  	}
   322  
   323  	creationRule := NewCreationRule()
   324  	creationRule.RulesetID = 42069
   325  	creationRule.RulesetSource = "google"
   326  	creationRule.RulesetSourceType = "Repository"
   327  	updateRule := NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{
   328  		UpdateAllowsFetchAndMerge: true,
   329  	})
   330  	updateRule.RulesetID = 42069
   331  	updateRule.RulesetSource = "google"
   332  	updateRule.RulesetSourceType = "Organization"
   333  
   334  	want := []*RepositoryRule{
   335  		creationRule,
   336  		updateRule,
   337  	}
   338  	if !cmp.Equal(rules, want) {
   339  		t.Errorf("Repositories.GetRulesForBranch returned %+v, want %+v", rules, want)
   340  	}
   341  
   342  	const methodName = "GetRulesForBranch"
   343  
   344  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   345  		got, resp, err := client.Repositories.GetRulesForBranch(ctx, "o", "repo", "branch")
   346  		if got != nil {
   347  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   348  		}
   349  		return resp, err
   350  	})
   351  }
   352  
   353  func TestRepositoriesService_GetRulesForBranchEmptyUpdateRule(t *testing.T) {
   354  	client, mux, _, teardown := setup()
   355  	defer teardown()
   356  
   357  	mux.HandleFunc("/repos/o/repo/rules/branches/branch", func(w http.ResponseWriter, r *http.Request) {
   358  		testMethod(t, r, "GET")
   359  		fmt.Fprint(w, `[
   360  			{
   361  			  "type": "update"
   362  			}
   363  		]`)
   364  	})
   365  
   366  	ctx := context.Background()
   367  	rules, _, err := client.Repositories.GetRulesForBranch(ctx, "o", "repo", "branch")
   368  	if err != nil {
   369  		t.Errorf("Repositories.GetRulesForBranch returned error: %v", err)
   370  	}
   371  
   372  	updateRule := NewUpdateRule(nil)
   373  
   374  	want := []*RepositoryRule{
   375  		updateRule,
   376  	}
   377  	if !cmp.Equal(rules, want) {
   378  		t.Errorf("Repositories.GetRulesForBranch returned %+v, want %+v", Stringify(rules), Stringify(want))
   379  	}
   380  
   381  	const methodName = "GetRulesForBranch"
   382  
   383  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   384  		got, resp, err := client.Repositories.GetRulesForBranch(ctx, "o", "repo", "branch")
   385  		if got != nil {
   386  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   387  		}
   388  		return resp, err
   389  	})
   390  }
   391  
   392  func TestRepositoriesService_GetAllRulesets(t *testing.T) {
   393  	client, mux, _, teardown := setup()
   394  	defer teardown()
   395  
   396  	mux.HandleFunc("/repos/o/repo/rulesets", func(w http.ResponseWriter, r *http.Request) {
   397  		testMethod(t, r, "GET")
   398  		fmt.Fprint(w, `[
   399  			{
   400  			  "id": 42,
   401  			  "name": "ruleset",
   402  			  "source_type": "Repository",
   403  			  "source": "o/repo",
   404  			  "enforcement": "enabled"
   405  			},
   406  			{
   407  			  "id": 314,
   408  			  "name": "Another ruleset",
   409  			  "source_type": "Repository",
   410  			  "source": "o/repo",
   411  			  "enforcement": "enabled"
   412  			}
   413  		]`)
   414  	})
   415  
   416  	ctx := context.Background()
   417  	ruleSet, _, err := client.Repositories.GetAllRulesets(ctx, "o", "repo", false)
   418  	if err != nil {
   419  		t.Errorf("Repositories.GetAllRulesets returned error: %v", err)
   420  	}
   421  
   422  	want := []*Ruleset{
   423  		{
   424  			ID:          Int64(42),
   425  			Name:        "ruleset",
   426  			SourceType:  String("Repository"),
   427  			Source:      "o/repo",
   428  			Enforcement: "enabled",
   429  		},
   430  		{
   431  			ID:          Int64(314),
   432  			Name:        "Another ruleset",
   433  			SourceType:  String("Repository"),
   434  			Source:      "o/repo",
   435  			Enforcement: "enabled",
   436  		},
   437  	}
   438  	if !cmp.Equal(ruleSet, want) {
   439  		t.Errorf("Repositories.GetAllRulesets returned %+v, want %+v", ruleSet, want)
   440  	}
   441  
   442  	const methodName = "GetAllRulesets"
   443  
   444  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   445  		got, resp, err := client.Repositories.GetAllRulesets(ctx, "o", "repo", false)
   446  		if got != nil {
   447  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   448  		}
   449  		return resp, err
   450  	})
   451  }
   452  
   453  func TestRepositoriesService_CreateRuleset(t *testing.T) {
   454  	client, mux, _, teardown := setup()
   455  	defer teardown()
   456  
   457  	mux.HandleFunc("/repos/o/repo/rulesets", func(w http.ResponseWriter, r *http.Request) {
   458  		testMethod(t, r, "POST")
   459  		fmt.Fprint(w, `{
   460  			"id": 42,
   461  			"name": "ruleset",
   462  			"source_type": "Repository",
   463  			"source": "o/repo",
   464  			"enforcement": "enabled"
   465  		}`)
   466  	})
   467  
   468  	ctx := context.Background()
   469  	ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{
   470  		Name:        "ruleset",
   471  		Enforcement: "enabled",
   472  	})
   473  	if err != nil {
   474  		t.Errorf("Repositories.CreateRuleset returned error: %v", err)
   475  	}
   476  
   477  	want := &Ruleset{
   478  		ID:          Int64(42),
   479  		Name:        "ruleset",
   480  		SourceType:  String("Repository"),
   481  		Source:      "o/repo",
   482  		Enforcement: "enabled",
   483  	}
   484  	if !cmp.Equal(ruleSet, want) {
   485  		t.Errorf("Repositories.CreateRuleset returned %+v, want %+v", ruleSet, want)
   486  	}
   487  
   488  	const methodName = "CreateRuleset"
   489  
   490  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   491  		got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{})
   492  		if got != nil {
   493  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   494  		}
   495  		return resp, err
   496  	})
   497  }
   498  
   499  func TestRepositoriesService_GetRuleset(t *testing.T) {
   500  	client, mux, _, teardown := setup()
   501  	defer teardown()
   502  
   503  	mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) {
   504  		testMethod(t, r, "GET")
   505  		fmt.Fprint(w, `{
   506  			"id": 42,
   507  			"name": "ruleset",
   508  			"source_type": "Organization",
   509  			"source": "o",
   510  			"enforcement": "enabled"
   511  		}`)
   512  	})
   513  
   514  	ctx := context.Background()
   515  	ruleSet, _, err := client.Repositories.GetRuleset(ctx, "o", "repo", 42, true)
   516  	if err != nil {
   517  		t.Errorf("Repositories.GetRuleset returned error: %v", err)
   518  	}
   519  
   520  	want := &Ruleset{
   521  		ID:          Int64(42),
   522  		Name:        "ruleset",
   523  		SourceType:  String("Organization"),
   524  		Source:      "o",
   525  		Enforcement: "enabled",
   526  	}
   527  	if !cmp.Equal(ruleSet, want) {
   528  		t.Errorf("Repositories.GetRuleset returned %+v, want %+v", ruleSet, want)
   529  	}
   530  
   531  	const methodName = "GetRuleset"
   532  
   533  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   534  		got, resp, err := client.Repositories.GetRuleset(ctx, "o", "repo", 42, true)
   535  		if got != nil {
   536  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   537  		}
   538  		return resp, err
   539  	})
   540  }
   541  
   542  func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) {
   543  	client, mux, _, teardown := setup()
   544  	defer teardown()
   545  
   546  	rs := &Ruleset{
   547  		Name:        "ruleset",
   548  		Source:      "o/repo",
   549  		Enforcement: "enabled",
   550  	}
   551  
   552  	mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) {
   553  		testMethod(t, r, "PUT")
   554  		fmt.Fprint(w, `{
   555  			"id": 42,
   556  			"name": "ruleset",
   557  			"source_type": "Repository",
   558  			"source": "o/repo",
   559  			"enforcement": "enabled"
   560  		}`)
   561  	})
   562  
   563  	ctx := context.Background()
   564  
   565  	ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, rs)
   566  
   567  	if err != nil {
   568  		t.Errorf("Repositories.UpdateRulesetNoBypassActor returned error: %v \n", err)
   569  	}
   570  
   571  	want := &Ruleset{
   572  		ID:          Int64(42),
   573  		Name:        "ruleset",
   574  		SourceType:  String("Repository"),
   575  		Source:      "o/repo",
   576  		Enforcement: "enabled",
   577  	}
   578  
   579  	if !cmp.Equal(ruleSet, want) {
   580  		t.Errorf("Repositories.UpdateRulesetNoBypassActor returned %+v, want %+v", ruleSet, want)
   581  	}
   582  
   583  	const methodName = "UpdateRulesetNoBypassActor"
   584  
   585  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   586  		got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, nil)
   587  		if got != nil {
   588  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   589  		}
   590  		return resp, err
   591  	})
   592  }
   593  
   594  func TestRepositoriesService_UpdateRuleset(t *testing.T) {
   595  	client, mux, _, teardown := setup()
   596  	defer teardown()
   597  
   598  	mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) {
   599  		testMethod(t, r, "PUT")
   600  		fmt.Fprint(w, `{
   601  			"id": 42,
   602  			"name": "ruleset",
   603  			"source_type": "Repository",
   604  			"source": "o/repo",
   605  			"enforcement": "enabled"
   606  		}`)
   607  	})
   608  
   609  	ctx := context.Background()
   610  	ruleSet, _, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, &Ruleset{
   611  		Name:        "ruleset",
   612  		Enforcement: "enabled",
   613  	})
   614  	if err != nil {
   615  		t.Errorf("Repositories.UpdateRuleset returned error: %v", err)
   616  	}
   617  
   618  	want := &Ruleset{
   619  		ID:          Int64(42),
   620  		Name:        "ruleset",
   621  		SourceType:  String("Repository"),
   622  		Source:      "o/repo",
   623  		Enforcement: "enabled",
   624  	}
   625  
   626  	if !cmp.Equal(ruleSet, want) {
   627  		t.Errorf("Repositories.UpdateRuleset returned %+v, want %+v", ruleSet, want)
   628  	}
   629  
   630  	const methodName = "UpdateRuleset"
   631  
   632  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   633  		got, resp, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, nil)
   634  		if got != nil {
   635  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   636  		}
   637  		return resp, err
   638  	})
   639  }
   640  
   641  func TestRepositoriesService_DeleteRuleset(t *testing.T) {
   642  	client, mux, _, teardown := setup()
   643  	defer teardown()
   644  
   645  	mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) {
   646  		testMethod(t, r, "DELETE")
   647  	})
   648  
   649  	ctx := context.Background()
   650  	_, err := client.Repositories.DeleteRuleset(ctx, "o", "repo", 42)
   651  	if err != nil {
   652  		t.Errorf("Repositories.DeleteRuleset returned error: %v", err)
   653  	}
   654  
   655  	const methodName = "DeleteRuleset"
   656  
   657  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   658  		return client.Repositories.DeleteRuleset(ctx, "o", "repo", 42)
   659  	})
   660  }