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