github.com/google/go-github/v74@v74.0.0/github/repos_test.go (about)

     1  // Copyright 2013 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  	"encoding/json"
    11  	"errors"
    12  	"fmt"
    13  	"net/http"
    14  	"net/url"
    15  	"strings"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/google/go-cmp/cmp"
    20  )
    21  
    22  func TestRepositoriesService_ListByAuthenticatedUser(t *testing.T) {
    23  	t.Parallel()
    24  	client, mux, _ := setup(t)
    25  
    26  	mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) {
    27  		testMethod(t, r, "GET")
    28  		fmt.Fprint(w, `[{"id":1},{"id":2}]`)
    29  	})
    30  
    31  	ctx := context.Background()
    32  	got, _, err := client.Repositories.ListByAuthenticatedUser(ctx, nil)
    33  	if err != nil {
    34  		t.Errorf("Repositories.List returned error: %v", err)
    35  	}
    36  
    37  	want := []*Repository{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}
    38  	if !cmp.Equal(got, want) {
    39  		t.Errorf("Repositories.ListByAuthenticatedUser returned %+v, want %+v", got, want)
    40  	}
    41  
    42  	const methodName = "ListByAuthenticatedUser"
    43  
    44  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    45  		got, resp, err := client.Repositories.ListByAuthenticatedUser(ctx, nil)
    46  		if got != nil {
    47  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    48  		}
    49  		return resp, err
    50  	})
    51  }
    52  
    53  func TestRepositoriesService_ListByUser(t *testing.T) {
    54  	t.Parallel()
    55  	client, mux, _ := setup(t)
    56  
    57  	mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) {
    58  		testMethod(t, r, "GET")
    59  		testFormValues(t, r, values{
    60  			"sort":      "created",
    61  			"direction": "asc",
    62  			"page":      "2",
    63  		})
    64  		fmt.Fprint(w, `[{"id":1}]`)
    65  	})
    66  
    67  	opt := &RepositoryListByUserOptions{
    68  		Sort:        "created",
    69  		Direction:   "asc",
    70  		ListOptions: ListOptions{Page: 2},
    71  	}
    72  	ctx := context.Background()
    73  	repos, _, err := client.Repositories.ListByUser(ctx, "u", opt)
    74  	if err != nil {
    75  		t.Errorf("Repositories.List returned error: %v", err)
    76  	}
    77  
    78  	want := []*Repository{{ID: Ptr(int64(1))}}
    79  	if !cmp.Equal(repos, want) {
    80  		t.Errorf("Repositories.ListByUser returned %+v, want %+v", repos, want)
    81  	}
    82  
    83  	const methodName = "ListByUser"
    84  	testBadOptions(t, methodName, func() (err error) {
    85  		_, _, err = client.Repositories.ListByUser(ctx, "\n", &RepositoryListByUserOptions{})
    86  		return err
    87  	})
    88  
    89  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    90  		got, resp, err := client.Repositories.ListByUser(ctx, "u", nil)
    91  		if got != nil {
    92  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    93  		}
    94  		return resp, err
    95  	})
    96  }
    97  
    98  func TestRepositoriesService_ListByUser_type(t *testing.T) {
    99  	t.Parallel()
   100  	client, mux, _ := setup(t)
   101  
   102  	mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) {
   103  		testMethod(t, r, "GET")
   104  		testFormValues(t, r, values{
   105  			"type": "owner",
   106  		})
   107  		fmt.Fprint(w, `[{"id":1}]`)
   108  	})
   109  
   110  	opt := &RepositoryListByUserOptions{
   111  		Type: "owner",
   112  	}
   113  	ctx := context.Background()
   114  	repos, _, err := client.Repositories.ListByUser(ctx, "u", opt)
   115  	if err != nil {
   116  		t.Errorf("Repositories.ListByUser returned error: %v", err)
   117  	}
   118  
   119  	want := []*Repository{{ID: Ptr(int64(1))}}
   120  	if !cmp.Equal(repos, want) {
   121  		t.Errorf("Repositories.ListByUser returned %+v, want %+v", repos, want)
   122  	}
   123  }
   124  
   125  func TestRepositoriesService_ListByUser_invalidUser(t *testing.T) {
   126  	t.Parallel()
   127  	client, _, _ := setup(t)
   128  
   129  	ctx := context.Background()
   130  	_, _, err := client.Repositories.ListByUser(ctx, "%", nil)
   131  	testURLParseError(t, err)
   132  }
   133  
   134  func TestRepositoriesService_ListByOrg(t *testing.T) {
   135  	t.Parallel()
   136  	client, mux, _ := setup(t)
   137  
   138  	wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview}
   139  	mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) {
   140  		testMethod(t, r, "GET")
   141  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   142  		testFormValues(t, r, values{
   143  			"type": "forks",
   144  			"page": "2",
   145  		})
   146  		fmt.Fprint(w, `[{"id":1}]`)
   147  	})
   148  
   149  	ctx := context.Background()
   150  	opt := &RepositoryListByOrgOptions{
   151  		Type:        "forks",
   152  		ListOptions: ListOptions{Page: 2},
   153  	}
   154  	got, _, err := client.Repositories.ListByOrg(ctx, "o", opt)
   155  	if err != nil {
   156  		t.Errorf("Repositories.ListByOrg returned error: %v", err)
   157  	}
   158  
   159  	want := []*Repository{{ID: Ptr(int64(1))}}
   160  	if !cmp.Equal(got, want) {
   161  		t.Errorf("Repositories.ListByOrg returned %+v, want %+v", got, want)
   162  	}
   163  
   164  	const methodName = "ListByOrg"
   165  	testBadOptions(t, methodName, func() (err error) {
   166  		_, _, err = client.Repositories.ListByOrg(ctx, "\n", opt)
   167  		return err
   168  	})
   169  
   170  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   171  		got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt)
   172  		if got != nil {
   173  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   174  		}
   175  		return resp, err
   176  	})
   177  }
   178  
   179  func TestRepositoriesService_ListByOrg_invalidOrg(t *testing.T) {
   180  	t.Parallel()
   181  	client, _, _ := setup(t)
   182  
   183  	ctx := context.Background()
   184  	_, _, err := client.Repositories.ListByOrg(ctx, "%", nil)
   185  	testURLParseError(t, err)
   186  }
   187  
   188  func TestRepositoriesService_ListAll(t *testing.T) {
   189  	t.Parallel()
   190  	client, mux, _ := setup(t)
   191  
   192  	mux.HandleFunc("/repositories", func(w http.ResponseWriter, r *http.Request) {
   193  		testMethod(t, r, "GET")
   194  		testFormValues(t, r, values{
   195  			"since": "1",
   196  		})
   197  		fmt.Fprint(w, `[{"id":1}]`)
   198  	})
   199  
   200  	ctx := context.Background()
   201  	opt := &RepositoryListAllOptions{1}
   202  	got, _, err := client.Repositories.ListAll(ctx, opt)
   203  	if err != nil {
   204  		t.Errorf("Repositories.ListAll returned error: %v", err)
   205  	}
   206  
   207  	want := []*Repository{{ID: Ptr(int64(1))}}
   208  	if !cmp.Equal(got, want) {
   209  		t.Errorf("Repositories.ListAll returned %+v, want %+v", got, want)
   210  	}
   211  
   212  	const methodName = "ListAll"
   213  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   214  		got, resp, err := client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1})
   215  		if got != nil {
   216  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   217  		}
   218  		return resp, err
   219  	})
   220  }
   221  
   222  func TestRepositoriesService_Create_user(t *testing.T) {
   223  	t.Parallel()
   224  	client, mux, _ := setup(t)
   225  
   226  	input := &Repository{
   227  		Name:     Ptr("n"),
   228  		Archived: Ptr(true), // not passed along.
   229  	}
   230  
   231  	wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
   232  	mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) {
   233  		v := new(createRepoRequest)
   234  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
   235  
   236  		testMethod(t, r, "POST")
   237  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   238  		want := &createRepoRequest{Name: Ptr("n")}
   239  		if !cmp.Equal(v, want) {
   240  			t.Errorf("Request body = %+v, want %+v", v, want)
   241  		}
   242  
   243  		fmt.Fprint(w, `{"id":1}`)
   244  	})
   245  
   246  	ctx := context.Background()
   247  	got, _, err := client.Repositories.Create(ctx, "", input)
   248  	if err != nil {
   249  		t.Errorf("Repositories.Create returned error: %v", err)
   250  	}
   251  
   252  	want := &Repository{ID: Ptr(int64(1))}
   253  	if !cmp.Equal(got, want) {
   254  		t.Errorf("Repositories.Create returned %+v, want %+v", got, want)
   255  	}
   256  
   257  	const methodName = "Create"
   258  	testBadOptions(t, methodName, func() (err error) {
   259  		_, _, err = client.Repositories.Create(ctx, "\n", input)
   260  		return err
   261  	})
   262  
   263  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   264  		got, resp, err := client.Repositories.Create(ctx, "", input)
   265  		if got != nil {
   266  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   267  		}
   268  		return resp, err
   269  	})
   270  }
   271  
   272  func TestRepositoriesService_Create_org(t *testing.T) {
   273  	t.Parallel()
   274  	client, mux, _ := setup(t)
   275  
   276  	input := &Repository{
   277  		Name:     Ptr("n"),
   278  		Archived: Ptr(true), // not passed along.
   279  	}
   280  
   281  	wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
   282  	mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) {
   283  		v := new(createRepoRequest)
   284  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
   285  
   286  		testMethod(t, r, "POST")
   287  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   288  		want := &createRepoRequest{Name: Ptr("n")}
   289  		if !cmp.Equal(v, want) {
   290  			t.Errorf("Request body = %+v, want %+v", v, want)
   291  		}
   292  
   293  		fmt.Fprint(w, `{"id":1}`)
   294  	})
   295  
   296  	ctx := context.Background()
   297  	repo, _, err := client.Repositories.Create(ctx, "o", input)
   298  	if err != nil {
   299  		t.Errorf("Repositories.Create returned error: %v", err)
   300  	}
   301  
   302  	want := &Repository{ID: Ptr(int64(1))}
   303  	if !cmp.Equal(repo, want) {
   304  		t.Errorf("Repositories.Create returned %+v, want %+v", repo, want)
   305  	}
   306  }
   307  
   308  func TestRepositoriesService_CreateFromTemplate(t *testing.T) {
   309  	t.Parallel()
   310  	client, mux, _ := setup(t)
   311  
   312  	templateRepoReq := &TemplateRepoRequest{
   313  		Name: Ptr("n"),
   314  	}
   315  
   316  	mux.HandleFunc("/repos/to/tr/generate", func(w http.ResponseWriter, r *http.Request) {
   317  		v := new(TemplateRepoRequest)
   318  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
   319  
   320  		testMethod(t, r, "POST")
   321  		testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview)
   322  		want := &TemplateRepoRequest{Name: Ptr("n")}
   323  		if !cmp.Equal(v, want) {
   324  			t.Errorf("Request body = %+v, want %+v", v, want)
   325  		}
   326  
   327  		fmt.Fprint(w, `{"id":1,"name":"n"}`)
   328  	})
   329  
   330  	ctx := context.Background()
   331  	got, _, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq)
   332  	if err != nil {
   333  		t.Errorf("Repositories.CreateFromTemplate returned error: %v", err)
   334  	}
   335  
   336  	want := &Repository{ID: Ptr(int64(1)), Name: Ptr("n")}
   337  	if !cmp.Equal(got, want) {
   338  		t.Errorf("Repositories.CreateFromTemplate returned %+v, want %+v", got, want)
   339  	}
   340  
   341  	const methodName = "CreateFromTemplate"
   342  	testBadOptions(t, methodName, func() (err error) {
   343  		_, _, err = client.Repositories.CreateFromTemplate(ctx, "\n", "\n", templateRepoReq)
   344  		return err
   345  	})
   346  
   347  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   348  		got, resp, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq)
   349  		if got != nil {
   350  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   351  		}
   352  		return resp, err
   353  	})
   354  }
   355  
   356  func TestRepositoriesService_Get(t *testing.T) {
   357  	t.Parallel()
   358  	client, mux, _ := setup(t)
   359  
   360  	wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
   361  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   362  		testMethod(t, r, "GET")
   363  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   364  		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"},"dependabot_security_updates":{"status": "enabled"}, "secret_scanning_validity_checks":{"status":"enabled"}}}`)
   365  	})
   366  
   367  	ctx := context.Background()
   368  	got, _, err := client.Repositories.Get(ctx, "o", "r")
   369  	if err != nil {
   370  		t.Errorf("Repositories.Get returned error: %v", err)
   371  	}
   372  
   373  	want := &Repository{ID: Ptr(int64(1)), Name: Ptr("n"), Description: Ptr("d"), Owner: &User{Login: Ptr("l")}, License: &License{Key: Ptr("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: Ptr("enabled")}, SecretScanning: &SecretScanning{Ptr("enabled")}, SecretScanningPushProtection: &SecretScanningPushProtection{Ptr("enabled")}, DependabotSecurityUpdates: &DependabotSecurityUpdates{Ptr("enabled")}, SecretScanningValidityChecks: &SecretScanningValidityChecks{Ptr("enabled")}}}
   374  	if !cmp.Equal(got, want) {
   375  		t.Errorf("Repositories.Get returned %+v, want %+v", got, want)
   376  	}
   377  
   378  	const methodName = "Get"
   379  	testBadOptions(t, methodName, func() (err error) {
   380  		_, _, err = client.Repositories.Get(ctx, "\n", "\n")
   381  		return err
   382  	})
   383  
   384  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   385  		got, resp, err := client.Repositories.Get(ctx, "o", "r")
   386  		if got != nil {
   387  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   388  		}
   389  		return resp, err
   390  	})
   391  }
   392  
   393  func TestRepositoriesService_GetCodeOfConduct(t *testing.T) {
   394  	t.Parallel()
   395  	client, mux, _ := setup(t)
   396  
   397  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   398  		testMethod(t, r, "GET")
   399  		testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview)
   400  		fmt.Fprint(w, `{
   401              "code_of_conduct": {
   402    						"key": "key",
   403    						"name": "name",
   404    						"url": "url",
   405    						"body": "body"
   406              }}`,
   407  		)
   408  	})
   409  
   410  	ctx := context.Background()
   411  	got, _, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
   412  	if err != nil {
   413  		t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err)
   414  	}
   415  
   416  	want := &CodeOfConduct{
   417  		Key:  Ptr("key"),
   418  		Name: Ptr("name"),
   419  		URL:  Ptr("url"),
   420  		Body: Ptr("body"),
   421  	}
   422  
   423  	if !cmp.Equal(got, want) {
   424  		t.Errorf("Repositories.GetCodeOfConduct returned %+v, want %+v", got, want)
   425  	}
   426  
   427  	const methodName = "GetCodeOfConduct"
   428  	testBadOptions(t, methodName, func() (err error) {
   429  		_, _, err = client.Repositories.GetCodeOfConduct(ctx, "\n", "\n")
   430  		return err
   431  	})
   432  
   433  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   434  		got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
   435  		if got != nil {
   436  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   437  		}
   438  		return resp, err
   439  	})
   440  }
   441  
   442  func TestRepositoriesService_GetByID(t *testing.T) {
   443  	t.Parallel()
   444  	client, mux, _ := setup(t)
   445  
   446  	mux.HandleFunc("/repositories/1", func(w http.ResponseWriter, r *http.Request) {
   447  		testMethod(t, r, "GET")
   448  		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`)
   449  	})
   450  
   451  	ctx := context.Background()
   452  	got, _, err := client.Repositories.GetByID(ctx, 1)
   453  	if err != nil {
   454  		t.Fatalf("Repositories.GetByID returned error: %v", err)
   455  	}
   456  
   457  	want := &Repository{ID: Ptr(int64(1)), Name: Ptr("n"), Description: Ptr("d"), Owner: &User{Login: Ptr("l")}, License: &License{Key: Ptr("mit")}}
   458  	if !cmp.Equal(got, want) {
   459  		t.Errorf("Repositories.GetByID returned %+v, want %+v", got, want)
   460  	}
   461  
   462  	const methodName = "GetByID"
   463  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   464  		got, resp, err := client.Repositories.GetByID(ctx, 1)
   465  		if got != nil {
   466  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   467  		}
   468  		return resp, err
   469  	})
   470  }
   471  
   472  func TestRepositoriesService_Edit(t *testing.T) {
   473  	t.Parallel()
   474  	client, mux, _ := setup(t)
   475  
   476  	i := true
   477  	input := &Repository{HasIssues: &i}
   478  
   479  	wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
   480  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   481  		v := new(Repository)
   482  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
   483  
   484  		testMethod(t, r, "PATCH")
   485  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   486  		if !cmp.Equal(v, input) {
   487  			t.Errorf("Request body = %+v, want %+v", v, input)
   488  		}
   489  		fmt.Fprint(w, `{"id":1}`)
   490  	})
   491  
   492  	ctx := context.Background()
   493  	got, _, err := client.Repositories.Edit(ctx, "o", "r", input)
   494  	if err != nil {
   495  		t.Errorf("Repositories.Edit returned error: %v", err)
   496  	}
   497  
   498  	want := &Repository{ID: Ptr(int64(1))}
   499  	if !cmp.Equal(got, want) {
   500  		t.Errorf("Repositories.Edit returned %+v, want %+v", got, want)
   501  	}
   502  
   503  	const methodName = "Edit"
   504  	testBadOptions(t, methodName, func() (err error) {
   505  		_, _, err = client.Repositories.Edit(ctx, "\n", "\n", input)
   506  		return err
   507  	})
   508  
   509  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   510  		got, resp, err := client.Repositories.Edit(ctx, "o", "r", input)
   511  		if got != nil {
   512  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   513  		}
   514  		return resp, err
   515  	})
   516  }
   517  
   518  func TestRepositoriesService_Delete(t *testing.T) {
   519  	t.Parallel()
   520  	client, mux, _ := setup(t)
   521  
   522  	mux.HandleFunc("/repos/o/r", func(_ http.ResponseWriter, r *http.Request) {
   523  		testMethod(t, r, "DELETE")
   524  	})
   525  
   526  	ctx := context.Background()
   527  	_, err := client.Repositories.Delete(ctx, "o", "r")
   528  	if err != nil {
   529  		t.Errorf("Repositories.Delete returned error: %v", err)
   530  	}
   531  
   532  	const methodName = "Delete"
   533  	testBadOptions(t, methodName, func() (err error) {
   534  		_, err = client.Repositories.Delete(ctx, "\n", "\n")
   535  		return err
   536  	})
   537  
   538  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   539  		return client.Repositories.Delete(ctx, "o", "r")
   540  	})
   541  }
   542  
   543  func TestRepositoriesService_Get_invalidOwner(t *testing.T) {
   544  	t.Parallel()
   545  	client, _, _ := setup(t)
   546  
   547  	ctx := context.Background()
   548  	_, _, err := client.Repositories.Get(ctx, "%", "r")
   549  	testURLParseError(t, err)
   550  }
   551  
   552  func TestRepositoriesService_Edit_invalidOwner(t *testing.T) {
   553  	t.Parallel()
   554  	client, _, _ := setup(t)
   555  
   556  	ctx := context.Background()
   557  	_, _, err := client.Repositories.Edit(ctx, "%", "r", nil)
   558  	testURLParseError(t, err)
   559  }
   560  
   561  func TestRepositoriesService_GetVulnerabilityAlerts(t *testing.T) {
   562  	t.Parallel()
   563  	client, mux, _ := setup(t)
   564  
   565  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   566  		testMethod(t, r, "GET")
   567  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   568  
   569  		w.WriteHeader(http.StatusNoContent)
   570  	})
   571  
   572  	ctx := context.Background()
   573  	vulnerabilityAlertsEnabled, _, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r")
   574  	if err != nil {
   575  		t.Errorf("Repositories.GetVulnerabilityAlerts returned error: %v", err)
   576  	}
   577  
   578  	if want := true; vulnerabilityAlertsEnabled != want {
   579  		t.Errorf("Repositories.GetVulnerabilityAlerts returned %+v, want %+v", vulnerabilityAlertsEnabled, want)
   580  	}
   581  
   582  	const methodName = "GetVulnerabilityAlerts"
   583  	testBadOptions(t, methodName, func() (err error) {
   584  		_, _, err = client.Repositories.GetVulnerabilityAlerts(ctx, "\n", "\n")
   585  		return err
   586  	})
   587  
   588  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   589  		got, resp, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r")
   590  		if got {
   591  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want false", methodName, got)
   592  		}
   593  		return resp, err
   594  	})
   595  }
   596  
   597  func TestRepositoriesService_EnableVulnerabilityAlerts(t *testing.T) {
   598  	t.Parallel()
   599  	client, mux, _ := setup(t)
   600  
   601  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   602  		testMethod(t, r, "PUT")
   603  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   604  
   605  		w.WriteHeader(http.StatusNoContent)
   606  	})
   607  
   608  	ctx := context.Background()
   609  	if _, err := client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r"); err != nil {
   610  		t.Errorf("Repositories.EnableVulnerabilityAlerts returned error: %v", err)
   611  	}
   612  
   613  	const methodName = "EnableVulnerabilityAlerts"
   614  	testBadOptions(t, methodName, func() (err error) {
   615  		_, err = client.Repositories.EnableVulnerabilityAlerts(ctx, "\n", "\n")
   616  		return err
   617  	})
   618  
   619  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   620  		return client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r")
   621  	})
   622  }
   623  
   624  func TestRepositoriesService_DisableVulnerabilityAlerts(t *testing.T) {
   625  	t.Parallel()
   626  	client, mux, _ := setup(t)
   627  
   628  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   629  		testMethod(t, r, "DELETE")
   630  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   631  
   632  		w.WriteHeader(http.StatusNoContent)
   633  	})
   634  
   635  	ctx := context.Background()
   636  	if _, err := client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r"); err != nil {
   637  		t.Errorf("Repositories.DisableVulnerabilityAlerts returned error: %v", err)
   638  	}
   639  
   640  	const methodName = "DisableVulnerabilityAlerts"
   641  	testBadOptions(t, methodName, func() (err error) {
   642  		_, err = client.Repositories.DisableVulnerabilityAlerts(ctx, "\n", "\n")
   643  		return err
   644  	})
   645  
   646  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   647  		return client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r")
   648  	})
   649  }
   650  
   651  func TestRepositoriesService_EnableAutomatedSecurityFixes(t *testing.T) {
   652  	t.Parallel()
   653  	client, mux, _ := setup(t)
   654  
   655  	mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) {
   656  		testMethod(t, r, "PUT")
   657  
   658  		w.WriteHeader(http.StatusNoContent)
   659  	})
   660  
   661  	ctx := context.Background()
   662  	if _, err := client.Repositories.EnableAutomatedSecurityFixes(ctx, "o", "r"); err != nil {
   663  		t.Errorf("Repositories.EnableAutomatedSecurityFixes returned error: %v", err)
   664  	}
   665  }
   666  
   667  func TestRepositoriesService_GetAutomatedSecurityFixes(t *testing.T) {
   668  	t.Parallel()
   669  	client, mux, _ := setup(t)
   670  
   671  	mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) {
   672  		testMethod(t, r, "GET")
   673  		fmt.Fprint(w, `{"enabled": true, "paused": false}`)
   674  	})
   675  
   676  	ctx := context.Background()
   677  	fixes, _, err := client.Repositories.GetAutomatedSecurityFixes(ctx, "o", "r")
   678  	if err != nil {
   679  		t.Errorf("Repositories.GetAutomatedSecurityFixes returned error: %v", err)
   680  	}
   681  
   682  	want := &AutomatedSecurityFixes{
   683  		Enabled: Ptr(true),
   684  		Paused:  Ptr(false),
   685  	}
   686  	if !cmp.Equal(fixes, want) {
   687  		t.Errorf("Repositories.GetAutomatedSecurityFixes returned %#v, want %#v", fixes, want)
   688  	}
   689  
   690  	const methodName = "GetAutomatedSecurityFixes"
   691  	testBadOptions(t, methodName, func() (err error) {
   692  		_, _, err = client.Repositories.GetAutomatedSecurityFixes(ctx, "\n", "\n")
   693  		return err
   694  	})
   695  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   696  		got, resp, err := client.Repositories.GetAutomatedSecurityFixes(ctx, "o", "r")
   697  		if got != nil {
   698  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   699  		}
   700  		return resp, err
   701  	})
   702  }
   703  
   704  func TestRepositoriesService_DisableAutomatedSecurityFixes(t *testing.T) {
   705  	t.Parallel()
   706  	client, mux, _ := setup(t)
   707  
   708  	mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) {
   709  		testMethod(t, r, "DELETE")
   710  
   711  		w.WriteHeader(http.StatusNoContent)
   712  	})
   713  
   714  	ctx := context.Background()
   715  	if _, err := client.Repositories.DisableAutomatedSecurityFixes(ctx, "o", "r"); err != nil {
   716  		t.Errorf("Repositories.DisableAutomatedSecurityFixes returned error: %v", err)
   717  	}
   718  }
   719  
   720  func TestRepositoriesService_ListContributors(t *testing.T) {
   721  	t.Parallel()
   722  	client, mux, _ := setup(t)
   723  
   724  	mux.HandleFunc("/repos/o/r/contributors", func(w http.ResponseWriter, r *http.Request) {
   725  		testMethod(t, r, "GET")
   726  		testFormValues(t, r, values{
   727  			"anon": "true",
   728  			"page": "2",
   729  		})
   730  		fmt.Fprint(w, `[{"contributions":42}]`)
   731  	})
   732  
   733  	opts := &ListContributorsOptions{Anon: "true", ListOptions: ListOptions{Page: 2}}
   734  	ctx := context.Background()
   735  	contributors, _, err := client.Repositories.ListContributors(ctx, "o", "r", opts)
   736  	if err != nil {
   737  		t.Errorf("Repositories.ListContributors returned error: %v", err)
   738  	}
   739  
   740  	want := []*Contributor{{Contributions: Ptr(42)}}
   741  	if !cmp.Equal(contributors, want) {
   742  		t.Errorf("Repositories.ListContributors returned %+v, want %+v", contributors, want)
   743  	}
   744  
   745  	const methodName = "ListContributors"
   746  	testBadOptions(t, methodName, func() (err error) {
   747  		_, _, err = client.Repositories.ListContributors(ctx, "\n", "\n", opts)
   748  		return err
   749  	})
   750  
   751  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   752  		got, resp, err := client.Repositories.ListContributors(ctx, "o", "r", opts)
   753  		if got != nil {
   754  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   755  		}
   756  		return resp, err
   757  	})
   758  }
   759  
   760  func TestRepositoriesService_ListLanguages(t *testing.T) {
   761  	t.Parallel()
   762  	client, mux, _ := setup(t)
   763  
   764  	mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) {
   765  		testMethod(t, r, "GET")
   766  		fmt.Fprint(w, `{"go":1}`)
   767  	})
   768  
   769  	ctx := context.Background()
   770  	languages, _, err := client.Repositories.ListLanguages(ctx, "o", "r")
   771  	if err != nil {
   772  		t.Errorf("Repositories.ListLanguages returned error: %v", err)
   773  	}
   774  
   775  	want := map[string]int{"go": 1}
   776  	if !cmp.Equal(languages, want) {
   777  		t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want)
   778  	}
   779  
   780  	const methodName = "ListLanguages"
   781  	testBadOptions(t, methodName, func() (err error) {
   782  		_, _, err = client.Repositories.ListLanguages(ctx, "\n", "\n")
   783  		return err
   784  	})
   785  
   786  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   787  		got, resp, err := client.Repositories.ListLanguages(ctx, "o", "r")
   788  		if got != nil {
   789  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   790  		}
   791  		return resp, err
   792  	})
   793  }
   794  
   795  func TestRepositoriesService_ListTeams(t *testing.T) {
   796  	t.Parallel()
   797  	client, mux, _ := setup(t)
   798  
   799  	mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) {
   800  		testMethod(t, r, "GET")
   801  		testFormValues(t, r, values{"page": "2"})
   802  		fmt.Fprint(w, `[{"id":1}]`)
   803  	})
   804  
   805  	opt := &ListOptions{Page: 2}
   806  	ctx := context.Background()
   807  	teams, _, err := client.Repositories.ListTeams(ctx, "o", "r", opt)
   808  	if err != nil {
   809  		t.Errorf("Repositories.ListTeams returned error: %v", err)
   810  	}
   811  
   812  	want := []*Team{{ID: Ptr(int64(1))}}
   813  	if !cmp.Equal(teams, want) {
   814  		t.Errorf("Repositories.ListTeams returned %+v, want %+v", teams, want)
   815  	}
   816  
   817  	const methodName = "ListTeams"
   818  	testBadOptions(t, methodName, func() (err error) {
   819  		_, _, err = client.Repositories.ListTeams(ctx, "\n", "\n", opt)
   820  		return err
   821  	})
   822  
   823  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   824  		got, resp, err := client.Repositories.ListTeams(ctx, "o", "r", opt)
   825  		if got != nil {
   826  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   827  		}
   828  		return resp, err
   829  	})
   830  }
   831  
   832  func TestRepositoriesService_ListTags(t *testing.T) {
   833  	t.Parallel()
   834  	client, mux, _ := setup(t)
   835  
   836  	mux.HandleFunc("/repos/o/r/tags", func(w http.ResponseWriter, r *http.Request) {
   837  		testMethod(t, r, "GET")
   838  		testFormValues(t, r, values{"page": "2"})
   839  		fmt.Fprint(w, `[{"name":"n", "commit" : {"sha" : "s", "url" : "u"}, "zipball_url": "z", "tarball_url": "t"}]`)
   840  	})
   841  
   842  	opt := &ListOptions{Page: 2}
   843  	ctx := context.Background()
   844  	tags, _, err := client.Repositories.ListTags(ctx, "o", "r", opt)
   845  	if err != nil {
   846  		t.Errorf("Repositories.ListTags returned error: %v", err)
   847  	}
   848  
   849  	want := []*RepositoryTag{
   850  		{
   851  			Name: Ptr("n"),
   852  			Commit: &Commit{
   853  				SHA: Ptr("s"),
   854  				URL: Ptr("u"),
   855  			},
   856  			ZipballURL: Ptr("z"),
   857  			TarballURL: Ptr("t"),
   858  		},
   859  	}
   860  	if !cmp.Equal(tags, want) {
   861  		t.Errorf("Repositories.ListTags returned %+v, want %+v", tags, want)
   862  	}
   863  
   864  	const methodName = "ListTags"
   865  	testBadOptions(t, methodName, func() (err error) {
   866  		_, _, err = client.Repositories.ListTags(ctx, "\n", "\n", opt)
   867  		return err
   868  	})
   869  
   870  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   871  		got, resp, err := client.Repositories.ListTags(ctx, "o", "r", opt)
   872  		if got != nil {
   873  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   874  		}
   875  		return resp, err
   876  	})
   877  }
   878  
   879  func TestRepositoriesService_ListBranches(t *testing.T) {
   880  	t.Parallel()
   881  	client, mux, _ := setup(t)
   882  
   883  	mux.HandleFunc("/repos/o/r/branches", func(w http.ResponseWriter, r *http.Request) {
   884  		testMethod(t, r, "GET")
   885  		testFormValues(t, r, values{"page": "2"})
   886  		fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`)
   887  	})
   888  
   889  	opt := &BranchListOptions{
   890  		Protected:   nil,
   891  		ListOptions: ListOptions{Page: 2},
   892  	}
   893  	ctx := context.Background()
   894  	branches, _, err := client.Repositories.ListBranches(ctx, "o", "r", opt)
   895  	if err != nil {
   896  		t.Errorf("Repositories.ListBranches returned error: %v", err)
   897  	}
   898  
   899  	want := []*Branch{{Name: Ptr("master"), Commit: &RepositoryCommit{SHA: Ptr("a57781"), URL: Ptr("https://api.github.com/repos/o/r/commits/a57781")}}}
   900  	if !cmp.Equal(branches, want) {
   901  		t.Errorf("Repositories.ListBranches returned %+v, want %+v", branches, want)
   902  	}
   903  
   904  	const methodName = "ListBranches"
   905  	testBadOptions(t, methodName, func() (err error) {
   906  		_, _, err = client.Repositories.ListBranches(ctx, "\n", "\n", opt)
   907  		return err
   908  	})
   909  
   910  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   911  		got, resp, err := client.Repositories.ListBranches(ctx, "o", "r", opt)
   912  		if got != nil {
   913  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   914  		}
   915  		return resp, err
   916  	})
   917  }
   918  
   919  func TestRepositoriesService_GetBranch(t *testing.T) {
   920  	t.Parallel()
   921  	client, mux, _ := setup(t)
   922  
   923  	tests := []struct {
   924  		branch  string
   925  		urlPath string
   926  	}{
   927  		{branch: "b", urlPath: "/repos/o/r/branches/b"},
   928  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25"},
   929  	}
   930  
   931  	for _, test := range tests {
   932  		mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
   933  			testMethod(t, r, "GET")
   934  			fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true, "protection":{"required_status_checks":{"contexts":["c"]}}}`)
   935  		})
   936  
   937  		ctx := context.Background()
   938  		branch, _, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 0)
   939  		if err != nil {
   940  			t.Errorf("Repositories.GetBranch returned error: %v", err)
   941  		}
   942  
   943  		want := &Branch{
   944  			Name: Ptr("n"),
   945  			Commit: &RepositoryCommit{
   946  				SHA: Ptr("s"),
   947  				Commit: &Commit{
   948  					Message: Ptr("m"),
   949  				},
   950  			},
   951  			Protected: Ptr(true),
   952  			Protection: &Protection{
   953  				RequiredStatusChecks: &RequiredStatusChecks{
   954  					Contexts: &[]string{"c"},
   955  				},
   956  			},
   957  		}
   958  
   959  		if !cmp.Equal(branch, want) {
   960  			t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
   961  		}
   962  
   963  		const methodName = "GetBranch"
   964  		testBadOptions(t, methodName, func() (err error) {
   965  			_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", 0)
   966  			return err
   967  		})
   968  	}
   969  }
   970  
   971  func TestRepositoriesService_GetBranch_BadJSONResponse(t *testing.T) {
   972  	t.Parallel()
   973  	tests := []struct {
   974  		branch  string
   975  		urlPath string
   976  	}{
   977  		{branch: "b", urlPath: "/repos/o/r/branches/b"},
   978  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25"},
   979  	}
   980  
   981  	for _, test := range tests {
   982  		t.Run(test.branch, func(t *testing.T) {
   983  			t.Parallel()
   984  			client, mux, _ := setup(t)
   985  
   986  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
   987  				testMethod(t, r, "GET")
   988  				fmt.Fprint(w, `{"name":"n", "commit":{"sha":...truncated`)
   989  			})
   990  
   991  			ctx := context.Background()
   992  			if _, _, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 0); err == nil {
   993  				t.Error("Repositories.GetBranch returned no error; wanted JSON error")
   994  			}
   995  		})
   996  	}
   997  }
   998  
   999  func TestRepositoriesService_GetBranch_StatusMovedPermanently_followRedirects(t *testing.T) {
  1000  	t.Parallel()
  1001  	client, mux, serverURL := setup(t)
  1002  
  1003  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
  1004  		testMethod(t, r, "GET")
  1005  		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/repos/o/r/branches/br")
  1006  		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
  1007  	})
  1008  	mux.HandleFunc("/repos/o/r/branches/br", func(w http.ResponseWriter, r *http.Request) {
  1009  		testMethod(t, r, "GET")
  1010  		fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true, "protection":{"required_status_checks":{"contexts":["c"]}}}`)
  1011  	})
  1012  	ctx := context.Background()
  1013  	branch, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", 1)
  1014  	if err != nil {
  1015  		t.Errorf("Repositories.GetBranch returned error: %v", err)
  1016  	}
  1017  	if resp.StatusCode != http.StatusOK {
  1018  		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusOK)
  1019  	}
  1020  
  1021  	want := &Branch{
  1022  		Name: Ptr("n"),
  1023  		Commit: &RepositoryCommit{
  1024  			SHA: Ptr("s"),
  1025  			Commit: &Commit{
  1026  				Message: Ptr("m"),
  1027  			},
  1028  		},
  1029  		Protected: Ptr(true),
  1030  		Protection: &Protection{
  1031  			RequiredStatusChecks: &RequiredStatusChecks{
  1032  				Contexts: &[]string{"c"},
  1033  			},
  1034  		},
  1035  	}
  1036  	if !cmp.Equal(branch, want) {
  1037  		t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
  1038  	}
  1039  }
  1040  
  1041  func TestRepositoriesService_GetBranch_notFound(t *testing.T) {
  1042  	t.Parallel()
  1043  	tests := []struct {
  1044  		branch  string
  1045  		urlPath string
  1046  	}{
  1047  		{branch: "b", urlPath: "/repos/o/r/branches/b"},
  1048  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat-branch-50%"},
  1049  	}
  1050  
  1051  	for _, test := range tests {
  1052  		t.Run(test.branch, func(t *testing.T) {
  1053  			t.Parallel()
  1054  			client, mux, _ := setup(t)
  1055  
  1056  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1057  				testMethod(t, r, "GET")
  1058  				http.Error(w, "branch not found", http.StatusNotFound)
  1059  			})
  1060  			ctx := context.Background()
  1061  			_, resp, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 1)
  1062  			if err == nil {
  1063  				t.Error("Repositories.GetBranch returned error: nil")
  1064  			}
  1065  			if resp.StatusCode != http.StatusNotFound {
  1066  				t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusNotFound)
  1067  			}
  1068  
  1069  			// Add custom round tripper
  1070  			client.client.Transport = roundTripperFunc(func(*http.Request) (*http.Response, error) {
  1071  				return nil, errors.New("failed to get branch")
  1072  			})
  1073  
  1074  			const methodName = "GetBranch"
  1075  			testBadOptions(t, methodName, func() (err error) {
  1076  				_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", 1)
  1077  				return err
  1078  			})
  1079  		})
  1080  	}
  1081  }
  1082  
  1083  func TestRepositoriesService_RenameBranch(t *testing.T) {
  1084  	t.Parallel()
  1085  	tests := []struct {
  1086  		branch  string
  1087  		urlPath string
  1088  	}{
  1089  		{branch: "b", urlPath: "/repos/o/r/branches/b/rename"},
  1090  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/rename"},
  1091  	}
  1092  
  1093  	for _, test := range tests {
  1094  		t.Run(test.branch, func(t *testing.T) {
  1095  			t.Parallel()
  1096  			client, mux, _ := setup(t)
  1097  
  1098  			renameBranchReq := "nn"
  1099  
  1100  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1101  				v := new(renameBranchRequest)
  1102  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1103  
  1104  				testMethod(t, r, "POST")
  1105  				want := &renameBranchRequest{NewName: renameBranchReq}
  1106  				if !cmp.Equal(v, want) {
  1107  					t.Errorf("Request body = %+v, want %+v", v, want)
  1108  				}
  1109  
  1110  				fmt.Fprint(w, `{"protected":true,"name":"nn"}`)
  1111  			})
  1112  
  1113  			ctx := context.Background()
  1114  			got, _, err := client.Repositories.RenameBranch(ctx, "o", "r", test.branch, renameBranchReq)
  1115  			if err != nil {
  1116  				t.Errorf("Repositories.RenameBranch returned error: %v", err)
  1117  			}
  1118  
  1119  			want := &Branch{Name: Ptr("nn"), Protected: Ptr(true)}
  1120  			if !cmp.Equal(got, want) {
  1121  				t.Errorf("Repositories.RenameBranch returned %+v, want %+v", got, want)
  1122  			}
  1123  
  1124  			const methodName = "RenameBranch"
  1125  			testBadOptions(t, methodName, func() (err error) {
  1126  				_, _, err = client.Repositories.RenameBranch(ctx, "\n", "\n", "\n", renameBranchReq)
  1127  				return err
  1128  			})
  1129  
  1130  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1131  				got, resp, err := client.Repositories.RenameBranch(ctx, "o", "r", test.branch, renameBranchReq)
  1132  				if got != nil {
  1133  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1134  				}
  1135  				return resp, err
  1136  			})
  1137  		})
  1138  	}
  1139  }
  1140  
  1141  func TestRepositoriesService_GetBranchProtection(t *testing.T) {
  1142  	t.Parallel()
  1143  	tests := []struct {
  1144  		branch               string
  1145  		urlPath              string
  1146  		enforceAdminsURLPath string
  1147  	}{
  1148  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection", enforceAdminsURLPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  1149  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection", enforceAdminsURLPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/enforce_admins"},
  1150  	}
  1151  
  1152  	for _, test := range tests {
  1153  		t.Run(test.branch, func(t *testing.T) {
  1154  			t.Parallel()
  1155  			client, mux, _ := setup(t)
  1156  
  1157  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1158  				testMethod(t, r, "GET")
  1159  				// TODO: remove custom Accept header when this API fully launches
  1160  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1161  				fmt.Fprintf(w, `{
  1162  						"required_status_checks":{
  1163  							"strict":true,
  1164  							"contexts":["continuous-integration"],
  1165  							"checks": [
  1166  								{
  1167  									"context": "continuous-integration",
  1168  									"app_id": null
  1169  								}
  1170  							]
  1171  						},
  1172  						"required_pull_request_reviews":{
  1173  							"dismissal_restrictions":{
  1174  								"users":[{
  1175  									"id":3,
  1176  									"login":"u"
  1177  								}],
  1178  								"teams":[{
  1179  									"id":4,
  1180  									"slug":"t"
  1181  								}],
  1182  								"apps":[{
  1183  									"id":5,
  1184  									"slug":"a"
  1185  								}]
  1186  							},
  1187  							"dismiss_stale_reviews":true,
  1188  							"require_code_owner_reviews":true,
  1189  							"require_last_push_approval":false,
  1190  							"required_approving_review_count":1
  1191  							},
  1192  							"enforce_admins":{
  1193  								"url":"%s",
  1194  								"enabled":true
  1195  							},
  1196  							"restrictions":{
  1197  								"users":[{"id":1,"login":"u"}],
  1198  								"teams":[{"id":2,"slug":"t"}],
  1199  								"apps":[{"id":3,"slug":"a"}]
  1200  							},
  1201  							"required_conversation_resolution": {
  1202  								"enabled": true
  1203  							},
  1204  							"block_creations": {
  1205  								"enabled": false
  1206  							},
  1207  							"lock_branch": {
  1208  								"enabled": false
  1209  							},
  1210  							"allow_fork_syncing": {
  1211  								"enabled": false
  1212  							}
  1213  						}`, test.enforceAdminsURLPath)
  1214  			})
  1215  
  1216  			ctx := context.Background()
  1217  			protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1218  			if err != nil {
  1219  				t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1220  			}
  1221  
  1222  			want := &Protection{
  1223  				RequiredStatusChecks: &RequiredStatusChecks{
  1224  					Strict:   true,
  1225  					Contexts: &[]string{"continuous-integration"},
  1226  					Checks: &[]*RequiredStatusCheck{
  1227  						{
  1228  							Context: "continuous-integration",
  1229  						},
  1230  					},
  1231  				},
  1232  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1233  					DismissStaleReviews: true,
  1234  					DismissalRestrictions: &DismissalRestrictions{
  1235  						Users: []*User{
  1236  							{Login: Ptr("u"), ID: Ptr(int64(3))},
  1237  						},
  1238  						Teams: []*Team{
  1239  							{Slug: Ptr("t"), ID: Ptr(int64(4))},
  1240  						},
  1241  						Apps: []*App{
  1242  							{Slug: Ptr("a"), ID: Ptr(int64(5))},
  1243  						},
  1244  					},
  1245  					RequireCodeOwnerReviews:      true,
  1246  					RequiredApprovingReviewCount: 1,
  1247  					RequireLastPushApproval:      false,
  1248  				},
  1249  				EnforceAdmins: &AdminEnforcement{
  1250  					URL:     Ptr(test.enforceAdminsURLPath),
  1251  					Enabled: true,
  1252  				},
  1253  				Restrictions: &BranchRestrictions{
  1254  					Users: []*User{
  1255  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1256  					},
  1257  					Teams: []*Team{
  1258  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1259  					},
  1260  					Apps: []*App{
  1261  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1262  					},
  1263  				},
  1264  				RequiredConversationResolution: &RequiredConversationResolution{
  1265  					Enabled: true,
  1266  				},
  1267  				BlockCreations: &BlockCreations{
  1268  					Enabled: Ptr(false),
  1269  				},
  1270  				LockBranch: &LockBranch{
  1271  					Enabled: Ptr(false),
  1272  				},
  1273  				AllowForkSyncing: &AllowForkSyncing{
  1274  					Enabled: Ptr(false),
  1275  				},
  1276  			}
  1277  			if !cmp.Equal(protection, want) {
  1278  				t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1279  			}
  1280  
  1281  			const methodName = "GetBranchProtection"
  1282  			testBadOptions(t, methodName, func() (err error) {
  1283  				_, _, err = client.Repositories.GetBranchProtection(ctx, "\n", "\n", "\n")
  1284  				return err
  1285  			})
  1286  
  1287  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1288  				got, resp, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1289  				if got != nil {
  1290  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1291  				}
  1292  				return resp, err
  1293  			})
  1294  		})
  1295  	}
  1296  }
  1297  
  1298  func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) {
  1299  	t.Parallel()
  1300  	client, mux, _ := setup(t)
  1301  
  1302  	tests := []struct {
  1303  		branch               string
  1304  		urlPath              string
  1305  		enforceAdminsURLPath string
  1306  	}{
  1307  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection", enforceAdminsURLPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  1308  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection", enforceAdminsURLPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/enforce_admins"},
  1309  	}
  1310  
  1311  	for _, test := range tests {
  1312  		mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1313  			testMethod(t, r, "GET")
  1314  			// TODO: remove custom Accept header when this API fully launches
  1315  			testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1316  			fmt.Fprintf(w, `{
  1317  					"required_status_checks":{
  1318  						"strict":true,
  1319  						"contexts":["continuous-integration"],
  1320  						"checks": [
  1321  							{
  1322  								"context": "continuous-integration",
  1323  								"app_id": null
  1324  							}
  1325  						]
  1326  					},
  1327  					"required_pull_request_reviews":{
  1328  						"dismiss_stale_reviews":true,
  1329  						"require_code_owner_reviews":true,
  1330  						"required_approving_review_count":1
  1331  						},
  1332  						"enforce_admins":{
  1333  							"url":"%s",
  1334  							"enabled":true
  1335  						},
  1336  						"restrictions":{
  1337  							"users":[{"id":1,"login":"u"}],
  1338  							"teams":[{"id":2,"slug":"t"}]
  1339  						}
  1340  					}`, test.enforceAdminsURLPath)
  1341  		})
  1342  
  1343  		ctx := context.Background()
  1344  		protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1345  		if err != nil {
  1346  			t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1347  		}
  1348  
  1349  		want := &Protection{
  1350  			RequiredStatusChecks: &RequiredStatusChecks{
  1351  				Strict:   true,
  1352  				Contexts: &[]string{"continuous-integration"},
  1353  				Checks: &[]*RequiredStatusCheck{
  1354  					{
  1355  						Context: "continuous-integration",
  1356  					},
  1357  				},
  1358  			},
  1359  			RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1360  				DismissStaleReviews:          true,
  1361  				DismissalRestrictions:        nil,
  1362  				RequireCodeOwnerReviews:      true,
  1363  				RequiredApprovingReviewCount: 1,
  1364  			},
  1365  			EnforceAdmins: &AdminEnforcement{
  1366  				URL:     Ptr(test.enforceAdminsURLPath),
  1367  				Enabled: true,
  1368  			},
  1369  			Restrictions: &BranchRestrictions{
  1370  				Users: []*User{
  1371  					{Login: Ptr("u"), ID: Ptr(int64(1))},
  1372  				},
  1373  				Teams: []*Team{
  1374  					{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1375  				},
  1376  			},
  1377  		}
  1378  		if !cmp.Equal(protection, want) {
  1379  			t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1380  		}
  1381  	}
  1382  }
  1383  
  1384  func TestRepositoriesService_GetBranchProtection_branchNotProtected(t *testing.T) {
  1385  	t.Parallel()
  1386  	tests := []struct {
  1387  		branch  string
  1388  		urlPath string
  1389  	}{
  1390  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1391  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  1392  	}
  1393  
  1394  	for _, test := range tests {
  1395  		t.Run(test.branch, func(t *testing.T) {
  1396  			t.Parallel()
  1397  			client, mux, _ := setup(t)
  1398  
  1399  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1400  				testMethod(t, r, "GET")
  1401  
  1402  				w.WriteHeader(http.StatusBadRequest)
  1403  				fmt.Fprintf(w, `{
  1404  					"message": %q,
  1405  					"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  1406  					}`, githubBranchNotProtected)
  1407  			})
  1408  
  1409  			ctx := context.Background()
  1410  			protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1411  
  1412  			if protection != nil {
  1413  				t.Error("Repositories.GetBranchProtection returned non-nil protection data")
  1414  			}
  1415  
  1416  			if err != ErrBranchNotProtected {
  1417  				t.Errorf("Repositories.GetBranchProtection returned an invalid error: %v", err)
  1418  			}
  1419  		})
  1420  	}
  1421  }
  1422  
  1423  func TestRepositoriesService_UpdateBranchProtection_Contexts(t *testing.T) {
  1424  	t.Parallel()
  1425  	tests := []struct {
  1426  		branch  string
  1427  		urlPath string
  1428  	}{
  1429  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1430  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  1431  	}
  1432  
  1433  	for _, test := range tests {
  1434  		t.Run(test.branch, func(t *testing.T) {
  1435  			t.Parallel()
  1436  			client, mux, _ := setup(t)
  1437  
  1438  			input := &ProtectionRequest{
  1439  				RequiredStatusChecks: &RequiredStatusChecks{
  1440  					Strict:   true,
  1441  					Contexts: &[]string{"continuous-integration"},
  1442  				},
  1443  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1444  					DismissStaleReviews: true,
  1445  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1446  						Users: &[]string{"uu"},
  1447  						Teams: &[]string{"tt"},
  1448  						Apps:  &[]string{"aa"},
  1449  					},
  1450  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1451  						Users: []string{"uuu"},
  1452  						Teams: []string{"ttt"},
  1453  						Apps:  []string{"aaa"},
  1454  					},
  1455  				},
  1456  				Restrictions: &BranchRestrictionsRequest{
  1457  					Users: []string{"u"},
  1458  					Teams: []string{"t"},
  1459  					Apps:  []string{"a"},
  1460  				},
  1461  				BlockCreations:   Ptr(true),
  1462  				LockBranch:       Ptr(true),
  1463  				AllowForkSyncing: Ptr(true),
  1464  			}
  1465  
  1466  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1467  				v := new(ProtectionRequest)
  1468  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1469  
  1470  				testMethod(t, r, "PUT")
  1471  				if !cmp.Equal(v, input) {
  1472  					t.Errorf("Request body = %+v, want %+v", v, input)
  1473  				}
  1474  
  1475  				// TODO: remove custom Accept header when this API fully launches
  1476  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1477  				fmt.Fprint(w, `{
  1478  					"required_status_checks":{
  1479  						"strict":true,
  1480  						"contexts":["continuous-integration"],
  1481  						"checks": [
  1482  							{
  1483  								"context": "continuous-integration",
  1484  								"app_id": null
  1485  							}
  1486  						]
  1487  					},
  1488  					"required_pull_request_reviews":{
  1489  						"dismissal_restrictions":{
  1490  							"users":[{
  1491  								"id":3,
  1492  								"login":"uu"
  1493  							}],
  1494  							"teams":[{
  1495  								"id":4,
  1496  								"slug":"tt"
  1497  							}],
  1498  							"apps":[{
  1499  								"id":5,
  1500  								"slug":"aa"
  1501  							}]
  1502  						},
  1503  						"dismiss_stale_reviews":true,
  1504  						"require_code_owner_reviews":true,
  1505  						"bypass_pull_request_allowances": {
  1506  							"users":[{"id":10,"login":"uuu"}],
  1507  							"teams":[{"id":20,"slug":"ttt"}],
  1508  							"apps":[{"id":30,"slug":"aaa"}]
  1509  						}
  1510  					},
  1511  					"restrictions":{
  1512  						"users":[{"id":1,"login":"u"}],
  1513  						"teams":[{"id":2,"slug":"t"}],
  1514  						"apps":[{"id":3,"slug":"a"}]
  1515  					},
  1516  					"block_creations": {
  1517  						"enabled": true
  1518  					},
  1519  					"lock_branch": {
  1520  						"enabled": true
  1521  					},
  1522  					"allow_fork_syncing": {
  1523  						"enabled": true
  1524  					}
  1525  				}`)
  1526  			})
  1527  
  1528  			ctx := context.Background()
  1529  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1530  			if err != nil {
  1531  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1532  			}
  1533  
  1534  			want := &Protection{
  1535  				RequiredStatusChecks: &RequiredStatusChecks{
  1536  					Strict:   true,
  1537  					Contexts: &[]string{"continuous-integration"},
  1538  					Checks: &[]*RequiredStatusCheck{
  1539  						{
  1540  							Context: "continuous-integration",
  1541  						},
  1542  					},
  1543  				},
  1544  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1545  					DismissStaleReviews: true,
  1546  					DismissalRestrictions: &DismissalRestrictions{
  1547  						Users: []*User{
  1548  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  1549  						},
  1550  						Teams: []*Team{
  1551  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  1552  						},
  1553  						Apps: []*App{
  1554  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  1555  						},
  1556  					},
  1557  					RequireCodeOwnerReviews: true,
  1558  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1559  						Users: []*User{
  1560  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  1561  						},
  1562  						Teams: []*Team{
  1563  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  1564  						},
  1565  						Apps: []*App{
  1566  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  1567  						},
  1568  					},
  1569  				},
  1570  				Restrictions: &BranchRestrictions{
  1571  					Users: []*User{
  1572  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1573  					},
  1574  					Teams: []*Team{
  1575  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1576  					},
  1577  					Apps: []*App{
  1578  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1579  					},
  1580  				},
  1581  				BlockCreations: &BlockCreations{
  1582  					Enabled: Ptr(true),
  1583  				},
  1584  				LockBranch: &LockBranch{
  1585  					Enabled: Ptr(true),
  1586  				},
  1587  				AllowForkSyncing: &AllowForkSyncing{
  1588  					Enabled: Ptr(true),
  1589  				},
  1590  			}
  1591  			if !cmp.Equal(protection, want) {
  1592  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1593  			}
  1594  
  1595  			const methodName = "UpdateBranchProtection"
  1596  			testBadOptions(t, methodName, func() (err error) {
  1597  				_, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input)
  1598  				return err
  1599  			})
  1600  
  1601  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1602  				got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1603  				if got != nil {
  1604  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1605  				}
  1606  				return resp, err
  1607  			})
  1608  		})
  1609  	}
  1610  }
  1611  
  1612  func TestRepositoriesService_UpdateBranchProtection_EmptyContexts(t *testing.T) {
  1613  	t.Parallel()
  1614  	tests := []struct {
  1615  		branch  string
  1616  		urlPath string
  1617  	}{
  1618  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1619  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  1620  	}
  1621  
  1622  	for _, test := range tests {
  1623  		t.Run(test.branch, func(t *testing.T) {
  1624  			t.Parallel()
  1625  			client, mux, _ := setup(t)
  1626  
  1627  			input := &ProtectionRequest{
  1628  				RequiredStatusChecks: &RequiredStatusChecks{
  1629  					Strict:   true,
  1630  					Contexts: &[]string{},
  1631  				},
  1632  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1633  					DismissStaleReviews: true,
  1634  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1635  						Users: &[]string{"uu"},
  1636  						Teams: &[]string{"tt"},
  1637  						Apps:  &[]string{"aa"},
  1638  					},
  1639  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1640  						Users: []string{"uuu"},
  1641  						Teams: []string{"ttt"},
  1642  						Apps:  []string{"aaa"},
  1643  					},
  1644  				},
  1645  				Restrictions: &BranchRestrictionsRequest{
  1646  					Users: []string{"u"},
  1647  					Teams: []string{"t"},
  1648  					Apps:  []string{"a"},
  1649  				},
  1650  				BlockCreations:   Ptr(true),
  1651  				LockBranch:       Ptr(true),
  1652  				AllowForkSyncing: Ptr(true),
  1653  			}
  1654  
  1655  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1656  				v := new(ProtectionRequest)
  1657  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1658  
  1659  				testMethod(t, r, "PUT")
  1660  				if !cmp.Equal(v, input) {
  1661  					t.Errorf("Request body = %+v, want %+v", v, input)
  1662  				}
  1663  
  1664  				// TODO: remove custom Accept header when this API fully launches
  1665  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1666  				fmt.Fprint(w, `{
  1667  					"required_status_checks":{
  1668  						"strict":true,
  1669  						"contexts":[],
  1670  						"checks": null
  1671  					},
  1672  					"required_pull_request_reviews":{
  1673  						"dismissal_restrictions":{
  1674  							"users":[{
  1675  								"id":3,
  1676  								"login":"uu"
  1677  							}],
  1678  							"teams":[{
  1679  								"id":4,
  1680  								"slug":"tt"
  1681  							}],
  1682  							"apps":[{
  1683  								"id":5,
  1684  								"slug":"aa"
  1685  							}]
  1686  						},
  1687  						"dismiss_stale_reviews":true,
  1688  						"require_code_owner_reviews":true,
  1689  						"bypass_pull_request_allowances": {
  1690  							"users":[{"id":10,"login":"uuu"}],
  1691  							"teams":[{"id":20,"slug":"ttt"}],
  1692  							"apps":[{"id":30,"slug":"aaa"}]
  1693  						}
  1694  					},
  1695  					"restrictions":{
  1696  						"users":[{"id":1,"login":"u"}],
  1697  						"teams":[{"id":2,"slug":"t"}],
  1698  						"apps":[{"id":3,"slug":"a"}]
  1699  					},
  1700  					"block_creations": {
  1701  						"enabled": true
  1702  					},
  1703  					"lock_branch": {
  1704  						"enabled": true
  1705  					},
  1706  					"allow_fork_syncing": {
  1707  						"enabled": true
  1708  					}
  1709  				}`)
  1710  			})
  1711  
  1712  			ctx := context.Background()
  1713  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1714  			if err != nil {
  1715  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1716  			}
  1717  
  1718  			want := &Protection{
  1719  				RequiredStatusChecks: &RequiredStatusChecks{
  1720  					Strict:   true,
  1721  					Contexts: &[]string{},
  1722  				},
  1723  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1724  					DismissStaleReviews: true,
  1725  					DismissalRestrictions: &DismissalRestrictions{
  1726  						Users: []*User{
  1727  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  1728  						},
  1729  						Teams: []*Team{
  1730  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  1731  						},
  1732  						Apps: []*App{
  1733  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  1734  						},
  1735  					},
  1736  					RequireCodeOwnerReviews: true,
  1737  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1738  						Users: []*User{
  1739  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  1740  						},
  1741  						Teams: []*Team{
  1742  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  1743  						},
  1744  						Apps: []*App{
  1745  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  1746  						},
  1747  					},
  1748  				},
  1749  				Restrictions: &BranchRestrictions{
  1750  					Users: []*User{
  1751  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1752  					},
  1753  					Teams: []*Team{
  1754  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1755  					},
  1756  					Apps: []*App{
  1757  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1758  					},
  1759  				},
  1760  				BlockCreations: &BlockCreations{
  1761  					Enabled: Ptr(true),
  1762  				},
  1763  				LockBranch: &LockBranch{
  1764  					Enabled: Ptr(true),
  1765  				},
  1766  				AllowForkSyncing: &AllowForkSyncing{
  1767  					Enabled: Ptr(true),
  1768  				},
  1769  			}
  1770  			if !cmp.Equal(protection, want) {
  1771  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1772  			}
  1773  
  1774  			const methodName = "UpdateBranchProtection"
  1775  			testBadOptions(t, methodName, func() (err error) {
  1776  				_, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input)
  1777  				return err
  1778  			})
  1779  
  1780  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1781  				got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1782  				if got != nil {
  1783  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1784  				}
  1785  				return resp, err
  1786  			})
  1787  		})
  1788  	}
  1789  }
  1790  
  1791  func TestRepositoriesService_UpdateBranchProtection_Checks(t *testing.T) {
  1792  	t.Parallel()
  1793  	tests := []struct {
  1794  		branch  string
  1795  		urlPath string
  1796  	}{
  1797  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1798  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  1799  	}
  1800  
  1801  	for _, test := range tests {
  1802  		t.Run(test.branch, func(t *testing.T) {
  1803  			t.Parallel()
  1804  			client, mux, _ := setup(t)
  1805  
  1806  			input := &ProtectionRequest{
  1807  				RequiredStatusChecks: &RequiredStatusChecks{
  1808  					Strict: true,
  1809  					Checks: &[]*RequiredStatusCheck{
  1810  						{
  1811  							Context: "continuous-integration",
  1812  						},
  1813  					},
  1814  				},
  1815  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1816  					DismissStaleReviews: true,
  1817  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1818  						Users: &[]string{"uu"},
  1819  						Teams: &[]string{"tt"},
  1820  						Apps:  &[]string{"aa"},
  1821  					},
  1822  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1823  						Users: []string{"uuu"},
  1824  						Teams: []string{"ttt"},
  1825  						Apps:  []string{"aaa"},
  1826  					},
  1827  				},
  1828  				Restrictions: &BranchRestrictionsRequest{
  1829  					Users: []string{"u"},
  1830  					Teams: []string{"t"},
  1831  					Apps:  []string{"a"},
  1832  				},
  1833  			}
  1834  
  1835  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1836  				v := new(ProtectionRequest)
  1837  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1838  
  1839  				testMethod(t, r, "PUT")
  1840  				if !cmp.Equal(v, input) {
  1841  					t.Errorf("Request body = %+v, want %+v", v, input)
  1842  				}
  1843  
  1844  				// TODO: remove custom Accept header when this API fully launches
  1845  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1846  				fmt.Fprint(w, `{
  1847  					"required_status_checks":{
  1848  						"strict":true,
  1849  						"contexts":["continuous-integration"],
  1850  						"checks": [
  1851  							{
  1852  								"context": "continuous-integration",
  1853  								"app_id": null
  1854  							}
  1855  						]
  1856  					},
  1857  					"required_pull_request_reviews":{
  1858  						"dismissal_restrictions":{
  1859  							"users":[{
  1860  								"id":3,
  1861  								"login":"uu"
  1862  							}],
  1863  							"teams":[{
  1864  								"id":4,
  1865  								"slug":"tt"
  1866  							}],
  1867  							"apps":[{
  1868  								"id":5,
  1869  								"slug":"aa"
  1870  							}]
  1871  						},
  1872  						"dismiss_stale_reviews":true,
  1873  						"require_code_owner_reviews":true,
  1874  						"bypass_pull_request_allowances": {
  1875  							"users":[{"id":10,"login":"uuu"}],
  1876  							"teams":[{"id":20,"slug":"ttt"}],
  1877  							"apps":[{"id":30,"slug":"aaa"}]
  1878  						}
  1879  					},
  1880  					"restrictions":{
  1881  						"users":[{"id":1,"login":"u"}],
  1882  						"teams":[{"id":2,"slug":"t"}],
  1883  						"apps":[{"id":3,"slug":"a"}]
  1884  					}
  1885  				}`)
  1886  			})
  1887  
  1888  			ctx := context.Background()
  1889  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1890  			if err != nil {
  1891  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1892  			}
  1893  
  1894  			want := &Protection{
  1895  				RequiredStatusChecks: &RequiredStatusChecks{
  1896  					Strict:   true,
  1897  					Contexts: &[]string{"continuous-integration"},
  1898  					Checks: &[]*RequiredStatusCheck{
  1899  						{
  1900  							Context: "continuous-integration",
  1901  						},
  1902  					},
  1903  				},
  1904  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1905  					DismissStaleReviews: true,
  1906  					DismissalRestrictions: &DismissalRestrictions{
  1907  						Users: []*User{
  1908  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  1909  						},
  1910  						Teams: []*Team{
  1911  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  1912  						},
  1913  						Apps: []*App{
  1914  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  1915  						},
  1916  					},
  1917  					RequireCodeOwnerReviews: true,
  1918  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1919  						Users: []*User{
  1920  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  1921  						},
  1922  						Teams: []*Team{
  1923  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  1924  						},
  1925  						Apps: []*App{
  1926  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  1927  						},
  1928  					},
  1929  				},
  1930  				Restrictions: &BranchRestrictions{
  1931  					Users: []*User{
  1932  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1933  					},
  1934  					Teams: []*Team{
  1935  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1936  					},
  1937  					Apps: []*App{
  1938  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1939  					},
  1940  				},
  1941  			}
  1942  			if !cmp.Equal(protection, want) {
  1943  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1944  			}
  1945  		})
  1946  	}
  1947  }
  1948  
  1949  func TestRepositoriesService_UpdateBranchProtection_EmptyChecks(t *testing.T) {
  1950  	t.Parallel()
  1951  	tests := []struct {
  1952  		branch  string
  1953  		urlPath string
  1954  	}{
  1955  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1956  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  1957  	}
  1958  
  1959  	for _, test := range tests {
  1960  		t.Run(test.branch, func(t *testing.T) {
  1961  			t.Parallel()
  1962  			client, mux, _ := setup(t)
  1963  
  1964  			input := &ProtectionRequest{
  1965  				RequiredStatusChecks: &RequiredStatusChecks{
  1966  					Strict: true,
  1967  					Checks: &[]*RequiredStatusCheck{},
  1968  				},
  1969  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1970  					DismissStaleReviews: true,
  1971  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1972  						Users: &[]string{"uu"},
  1973  						Teams: &[]string{"tt"},
  1974  						Apps:  &[]string{"aa"},
  1975  					},
  1976  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1977  						Users: []string{"uuu"},
  1978  						Teams: []string{"ttt"},
  1979  						Apps:  []string{"aaa"},
  1980  					},
  1981  				},
  1982  				Restrictions: &BranchRestrictionsRequest{
  1983  					Users: []string{"u"},
  1984  					Teams: []string{"t"},
  1985  					Apps:  []string{"a"},
  1986  				},
  1987  			}
  1988  
  1989  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1990  				v := new(ProtectionRequest)
  1991  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1992  
  1993  				testMethod(t, r, "PUT")
  1994  				if !cmp.Equal(v, input) {
  1995  					t.Errorf("Request body = %+v, want %+v", v, input)
  1996  				}
  1997  
  1998  				// TODO: remove custom Accept header when this API fully launches
  1999  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2000  				fmt.Fprint(w, `{
  2001  					"required_status_checks":{
  2002  						"strict":true,
  2003  						"contexts":null,
  2004  						"checks": []
  2005  					},
  2006  					"required_pull_request_reviews":{
  2007  						"dismissal_restrictions":{
  2008  							"users":[{
  2009  								"id":3,
  2010  								"login":"uu"
  2011  							}],
  2012  							"teams":[{
  2013  								"id":4,
  2014  								"slug":"tt"
  2015  							}],
  2016  							"apps":[{
  2017  								"id":5,
  2018  								"slug":"aa"
  2019  							}]
  2020  						},
  2021  						"dismiss_stale_reviews":true,
  2022  						"require_code_owner_reviews":true,
  2023  						"bypass_pull_request_allowances": {
  2024  							"users":[{"id":10,"login":"uuu"}],
  2025  							"teams":[{"id":20,"slug":"ttt"}],
  2026  							"apps":[{"id":30,"slug":"aaa"}]
  2027  						}
  2028  					},
  2029  					"restrictions":{
  2030  						"users":[{"id":1,"login":"u"}],
  2031  						"teams":[{"id":2,"slug":"t"}],
  2032  						"apps":[{"id":3,"slug":"a"}]
  2033  					}
  2034  				}`)
  2035  			})
  2036  
  2037  			ctx := context.Background()
  2038  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  2039  			if err != nil {
  2040  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  2041  			}
  2042  
  2043  			want := &Protection{
  2044  				RequiredStatusChecks: &RequiredStatusChecks{
  2045  					Strict: true,
  2046  					Checks: &[]*RequiredStatusCheck{},
  2047  				},
  2048  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  2049  					DismissStaleReviews: true,
  2050  					DismissalRestrictions: &DismissalRestrictions{
  2051  						Users: []*User{
  2052  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  2053  						},
  2054  						Teams: []*Team{
  2055  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  2056  						},
  2057  						Apps: []*App{
  2058  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  2059  						},
  2060  					},
  2061  					RequireCodeOwnerReviews: true,
  2062  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  2063  						Users: []*User{
  2064  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  2065  						},
  2066  						Teams: []*Team{
  2067  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  2068  						},
  2069  						Apps: []*App{
  2070  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  2071  						},
  2072  					},
  2073  				},
  2074  				Restrictions: &BranchRestrictions{
  2075  					Users: []*User{
  2076  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2077  					},
  2078  					Teams: []*Team{
  2079  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2080  					},
  2081  					Apps: []*App{
  2082  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2083  					},
  2084  				},
  2085  			}
  2086  			if !cmp.Equal(protection, want) {
  2087  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  2088  			}
  2089  		})
  2090  	}
  2091  }
  2092  
  2093  func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T) {
  2094  	t.Parallel()
  2095  	tests := []struct {
  2096  		branch  string
  2097  		urlPath string
  2098  	}{
  2099  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  2100  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  2101  	}
  2102  
  2103  	for _, test := range tests {
  2104  		t.Run(test.branch, func(t *testing.T) {
  2105  			t.Parallel()
  2106  			client, mux, _ := setup(t)
  2107  
  2108  			input := &ProtectionRequest{
  2109  				RequiredStatusChecks: &RequiredStatusChecks{
  2110  					Strict: true,
  2111  				},
  2112  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  2113  					DismissStaleReviews: true,
  2114  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  2115  						Users: &[]string{"uu"},
  2116  						Teams: &[]string{"tt"},
  2117  						Apps:  &[]string{"aa"},
  2118  					},
  2119  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  2120  						Users: []string{"uuu"},
  2121  						Teams: []string{"ttt"},
  2122  						Apps:  []string{"aaa"},
  2123  					},
  2124  				},
  2125  				Restrictions: &BranchRestrictionsRequest{
  2126  					Users: []string{"u"},
  2127  					Teams: []string{"t"},
  2128  					Apps:  []string{"a"},
  2129  				},
  2130  			}
  2131  
  2132  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2133  				v := new(ProtectionRequest)
  2134  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2135  
  2136  				testMethod(t, r, "PUT")
  2137  				if !cmp.Equal(v, input) {
  2138  					t.Errorf("Request body = %+v, want %+v", v, input)
  2139  				}
  2140  
  2141  				// TODO: remove custom Accept header when this API fully launches
  2142  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2143  				fmt.Fprint(w, `{
  2144  					"required_status_checks":{
  2145  						"strict":true,
  2146  						"contexts":[]
  2147  					},
  2148  					"required_pull_request_reviews":{
  2149  						"dismissal_restrictions":{
  2150  							"users":[{
  2151  								"id":3,
  2152  								"login":"uu"
  2153  							}],
  2154  							"teams":[{
  2155  								"id":4,
  2156  								"slug":"tt"
  2157  							}],
  2158  							"apps":[{
  2159  								"id":5,
  2160  								"slug":"aa"
  2161  							}]
  2162  						},
  2163  						"dismiss_stale_reviews":true,
  2164  						"require_code_owner_reviews":true,
  2165  						"require_last_push_approval":false,
  2166  						"bypass_pull_request_allowances": {
  2167  							"users":[{"id":10,"login":"uuu"}],
  2168  							"teams":[{"id":20,"slug":"ttt"}],
  2169  							"apps":[{"id":30,"slug":"aaa"}]
  2170  						}
  2171  					},
  2172  					"restrictions":{
  2173  						"users":[{"id":1,"login":"u"}],
  2174  						"teams":[{"id":2,"slug":"t"}],
  2175  						"apps":[{"id":3,"slug":"a"}]
  2176  					}
  2177  				}`)
  2178  			})
  2179  
  2180  			ctx := context.Background()
  2181  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  2182  			if err != nil {
  2183  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  2184  			}
  2185  
  2186  			want := &Protection{
  2187  				RequiredStatusChecks: &RequiredStatusChecks{
  2188  					Strict:   true,
  2189  					Contexts: &[]string{},
  2190  				},
  2191  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  2192  					DismissStaleReviews: true,
  2193  					DismissalRestrictions: &DismissalRestrictions{
  2194  						Users: []*User{
  2195  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  2196  						},
  2197  						Teams: []*Team{
  2198  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  2199  						},
  2200  						Apps: []*App{
  2201  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  2202  						},
  2203  					},
  2204  					RequireCodeOwnerReviews: true,
  2205  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  2206  						Users: []*User{
  2207  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  2208  						},
  2209  						Teams: []*Team{
  2210  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  2211  						},
  2212  						Apps: []*App{
  2213  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  2214  						},
  2215  					},
  2216  				},
  2217  				Restrictions: &BranchRestrictions{
  2218  					Users: []*User{
  2219  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2220  					},
  2221  					Teams: []*Team{
  2222  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2223  					},
  2224  					Apps: []*App{
  2225  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2226  					},
  2227  				},
  2228  			}
  2229  			if !cmp.Equal(protection, want) {
  2230  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  2231  			}
  2232  		})
  2233  	}
  2234  }
  2235  
  2236  func TestRepositoriesService_UpdateBranchProtection_RequireLastPushApproval(t *testing.T) {
  2237  	t.Parallel()
  2238  	tests := []struct {
  2239  		branch  string
  2240  		urlPath string
  2241  	}{
  2242  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  2243  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  2244  	}
  2245  
  2246  	for _, test := range tests {
  2247  		t.Run(test.branch, func(t *testing.T) {
  2248  			t.Parallel()
  2249  			client, mux, _ := setup(t)
  2250  
  2251  			input := &ProtectionRequest{
  2252  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  2253  					RequireLastPushApproval: Ptr(true),
  2254  				},
  2255  			}
  2256  
  2257  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2258  				v := new(ProtectionRequest)
  2259  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2260  
  2261  				testMethod(t, r, "PUT")
  2262  				if !cmp.Equal(v, input) {
  2263  					t.Errorf("Request body = %+v, want %+v", v, input)
  2264  				}
  2265  
  2266  				fmt.Fprint(w, `{
  2267  					"required_pull_request_reviews":{
  2268  						"require_last_push_approval":true
  2269  					}
  2270  				}`)
  2271  			})
  2272  
  2273  			ctx := context.Background()
  2274  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  2275  			if err != nil {
  2276  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  2277  			}
  2278  
  2279  			want := &Protection{
  2280  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  2281  					RequireLastPushApproval: true,
  2282  				},
  2283  			}
  2284  			if !cmp.Equal(protection, want) {
  2285  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  2286  			}
  2287  		})
  2288  	}
  2289  }
  2290  
  2291  func TestRepositoriesService_RemoveBranchProtection(t *testing.T) {
  2292  	t.Parallel()
  2293  	tests := []struct {
  2294  		branch  string
  2295  		urlPath string
  2296  	}{
  2297  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  2298  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection"},
  2299  	}
  2300  
  2301  	for _, test := range tests {
  2302  		t.Run(test.branch, func(t *testing.T) {
  2303  			t.Parallel()
  2304  			client, mux, _ := setup(t)
  2305  
  2306  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2307  				testMethod(t, r, "DELETE")
  2308  				w.WriteHeader(http.StatusNoContent)
  2309  			})
  2310  
  2311  			ctx := context.Background()
  2312  			_, err := client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch)
  2313  			if err != nil {
  2314  				t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err)
  2315  			}
  2316  
  2317  			const methodName = "RemoveBranchProtection"
  2318  			testBadOptions(t, methodName, func() (err error) {
  2319  				_, err = client.Repositories.RemoveBranchProtection(ctx, "\n", "\n", "\n")
  2320  				return err
  2321  			})
  2322  
  2323  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2324  				return client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch)
  2325  			})
  2326  		})
  2327  	}
  2328  }
  2329  
  2330  func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) {
  2331  	t.Parallel()
  2332  	client, _, _ := setup(t)
  2333  
  2334  	ctx := context.Background()
  2335  	_, _, err := client.Repositories.ListLanguages(ctx, "%", "%")
  2336  	testURLParseError(t, err)
  2337  }
  2338  
  2339  func TestRepositoriesService_License(t *testing.T) {
  2340  	t.Parallel()
  2341  	client, mux, _ := setup(t)
  2342  
  2343  	mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) {
  2344  		testMethod(t, r, "GET")
  2345  		fmt.Fprint(w, `{"name": "LICENSE", "path": "LICENSE", "license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","featured":true}}`)
  2346  	})
  2347  
  2348  	ctx := context.Background()
  2349  	got, _, err := client.Repositories.License(ctx, "o", "r")
  2350  	if err != nil {
  2351  		t.Errorf("Repositories.License returned error: %v", err)
  2352  	}
  2353  
  2354  	want := &RepositoryLicense{
  2355  		Name: Ptr("LICENSE"),
  2356  		Path: Ptr("LICENSE"),
  2357  		License: &License{
  2358  			Name:     Ptr("MIT License"),
  2359  			Key:      Ptr("mit"),
  2360  			SPDXID:   Ptr("MIT"),
  2361  			URL:      Ptr("https://api.github.com/licenses/mit"),
  2362  			Featured: Ptr(true),
  2363  		},
  2364  	}
  2365  
  2366  	if !cmp.Equal(got, want) {
  2367  		t.Errorf("Repositories.License returned %+v, want %+v", got, want)
  2368  	}
  2369  
  2370  	const methodName = "License"
  2371  	testBadOptions(t, methodName, func() (err error) {
  2372  		_, _, err = client.Repositories.License(ctx, "\n", "\n")
  2373  		return err
  2374  	})
  2375  
  2376  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2377  		got, resp, err := client.Repositories.License(ctx, "o", "r")
  2378  		if got != nil {
  2379  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2380  		}
  2381  		return resp, err
  2382  	})
  2383  }
  2384  
  2385  func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) {
  2386  	t.Parallel()
  2387  	tests := []struct {
  2388  		branch  string
  2389  		urlPath string
  2390  	}{
  2391  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2392  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_status_checks"},
  2393  	}
  2394  
  2395  	for _, test := range tests {
  2396  		t.Run(test.branch, func(t *testing.T) {
  2397  			t.Parallel()
  2398  			client, mux, _ := setup(t)
  2399  
  2400  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2401  				testMethod(t, r, "GET")
  2402  				fmt.Fprint(w, `{
  2403  					"strict": true,
  2404  					"contexts": ["x","y","z"],
  2405  					"checks": [
  2406  						{
  2407  							"context": "x",
  2408  							"app_id": null
  2409  						},
  2410  						{
  2411  							"context": "y",
  2412  							"app_id": null
  2413  						},
  2414  						{
  2415  							"context": "z",
  2416  							"app_id": null
  2417  						}
  2418  					]
  2419  				}`)
  2420  			})
  2421  
  2422  			ctx := context.Background()
  2423  			checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch)
  2424  			if err != nil {
  2425  				t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err)
  2426  			}
  2427  
  2428  			want := &RequiredStatusChecks{
  2429  				Strict:   true,
  2430  				Contexts: &[]string{"x", "y", "z"},
  2431  				Checks: &[]*RequiredStatusCheck{
  2432  					{
  2433  						Context: "x",
  2434  					},
  2435  					{
  2436  						Context: "y",
  2437  					},
  2438  					{
  2439  						Context: "z",
  2440  					},
  2441  				},
  2442  			}
  2443  			if !cmp.Equal(checks, want) {
  2444  				t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want)
  2445  			}
  2446  
  2447  			const methodName = "GetRequiredStatusChecks"
  2448  			testBadOptions(t, methodName, func() (err error) {
  2449  				_, _, err = client.Repositories.GetRequiredStatusChecks(ctx, "\n", "\n", "\n")
  2450  				return err
  2451  			})
  2452  
  2453  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2454  				got, resp, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch)
  2455  				if got != nil {
  2456  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2457  				}
  2458  				return resp, err
  2459  			})
  2460  		})
  2461  	}
  2462  }
  2463  
  2464  func TestRepositoriesService_GetRequiredStatusChecks_branchNotProtected(t *testing.T) {
  2465  	t.Parallel()
  2466  	tests := []struct {
  2467  		branch  string
  2468  		urlPath string
  2469  	}{
  2470  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2471  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_status_checks"},
  2472  	}
  2473  
  2474  	for _, test := range tests {
  2475  		t.Run(test.branch, func(t *testing.T) {
  2476  			t.Parallel()
  2477  			client, mux, _ := setup(t)
  2478  
  2479  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2480  				testMethod(t, r, "GET")
  2481  
  2482  				w.WriteHeader(http.StatusBadRequest)
  2483  				fmt.Fprintf(w, `{
  2484  			"message": %q,
  2485  			"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  2486  			}`, githubBranchNotProtected)
  2487  			})
  2488  
  2489  			ctx := context.Background()
  2490  			checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch)
  2491  
  2492  			if checks != nil {
  2493  				t.Error("Repositories.GetRequiredStatusChecks returned non-nil status-checks data")
  2494  			}
  2495  
  2496  			if err != ErrBranchNotProtected {
  2497  				t.Errorf("Repositories.GetRequiredStatusChecks returned an invalid error: %v", err)
  2498  			}
  2499  		})
  2500  	}
  2501  }
  2502  
  2503  func TestRepositoriesService_UpdateRequiredStatusChecks_Contexts(t *testing.T) {
  2504  	t.Parallel()
  2505  	tests := []struct {
  2506  		branch  string
  2507  		urlPath string
  2508  	}{
  2509  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2510  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_status_checks"},
  2511  	}
  2512  
  2513  	for _, test := range tests {
  2514  		t.Run(test.branch, func(t *testing.T) {
  2515  			t.Parallel()
  2516  			client, mux, _ := setup(t)
  2517  
  2518  			input := &RequiredStatusChecksRequest{
  2519  				Strict:   Ptr(true),
  2520  				Contexts: []string{"continuous-integration"},
  2521  			}
  2522  
  2523  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2524  				v := new(RequiredStatusChecksRequest)
  2525  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2526  
  2527  				testMethod(t, r, "PATCH")
  2528  				if !cmp.Equal(v, input) {
  2529  					t.Errorf("Request body = %+v, want %+v", v, input)
  2530  				}
  2531  				testHeader(t, r, "Accept", mediaTypeV3)
  2532  				fmt.Fprint(w, `{
  2533  					"strict":true,
  2534  					"contexts":["continuous-integration"],
  2535  					"checks": [
  2536  						{
  2537  							"context": "continuous-integration",
  2538  							"app_id": null
  2539  						}
  2540  					]
  2541  				}`)
  2542  			})
  2543  
  2544  			ctx := context.Background()
  2545  			statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input)
  2546  			if err != nil {
  2547  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err)
  2548  			}
  2549  
  2550  			want := &RequiredStatusChecks{
  2551  				Strict:   true,
  2552  				Contexts: &[]string{"continuous-integration"},
  2553  				Checks: &[]*RequiredStatusCheck{
  2554  					{
  2555  						Context: "continuous-integration",
  2556  					},
  2557  				},
  2558  			}
  2559  			if !cmp.Equal(statusChecks, want) {
  2560  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want)
  2561  			}
  2562  
  2563  			const methodName = "UpdateRequiredStatusChecks"
  2564  			testBadOptions(t, methodName, func() (err error) {
  2565  				_, _, err = client.Repositories.UpdateRequiredStatusChecks(ctx, "\n", "\n", "\n", input)
  2566  				return err
  2567  			})
  2568  
  2569  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2570  				got, resp, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input)
  2571  				if got != nil {
  2572  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2573  				}
  2574  				return resp, err
  2575  			})
  2576  		})
  2577  	}
  2578  }
  2579  
  2580  func TestRepositoriesService_UpdateRequiredStatusChecks_Checks(t *testing.T) {
  2581  	t.Parallel()
  2582  	tests := []struct {
  2583  		branch  string
  2584  		urlPath string
  2585  	}{
  2586  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2587  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_status_checks"},
  2588  	}
  2589  
  2590  	for _, test := range tests {
  2591  		t.Run(test.branch, func(t *testing.T) {
  2592  			t.Parallel()
  2593  			client, mux, _ := setup(t)
  2594  
  2595  			appID := int64(123)
  2596  			noAppID := int64(-1)
  2597  			input := &RequiredStatusChecksRequest{
  2598  				Strict: Ptr(true),
  2599  				Checks: []*RequiredStatusCheck{
  2600  					{
  2601  						Context: "continuous-integration",
  2602  					},
  2603  					{
  2604  						Context: "continuous-integration2",
  2605  						AppID:   &appID,
  2606  					},
  2607  					{
  2608  						Context: "continuous-integration3",
  2609  						AppID:   &noAppID,
  2610  					},
  2611  				},
  2612  			}
  2613  
  2614  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2615  				v := new(RequiredStatusChecksRequest)
  2616  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2617  
  2618  				testMethod(t, r, "PATCH")
  2619  				if !cmp.Equal(v, input) {
  2620  					t.Errorf("Request body = %+v, want %+v", v, input)
  2621  				}
  2622  				testHeader(t, r, "Accept", mediaTypeV3)
  2623  				fmt.Fprint(w, `{
  2624  					"strict":true,
  2625  					"contexts":["continuous-integration"],
  2626  					"checks": [
  2627  						{
  2628  							"context": "continuous-integration",
  2629  							"app_id": null
  2630  						},
  2631  						{
  2632  							"context": "continuous-integration2",
  2633  							"app_id": 123
  2634  						},
  2635  						{
  2636  							"context": "continuous-integration3",
  2637  							"app_id": null
  2638  						}
  2639  					]
  2640  				}`)
  2641  			})
  2642  
  2643  			ctx := context.Background()
  2644  			statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input)
  2645  			if err != nil {
  2646  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err)
  2647  			}
  2648  
  2649  			want := &RequiredStatusChecks{
  2650  				Strict:   true,
  2651  				Contexts: &[]string{"continuous-integration"},
  2652  				Checks: &[]*RequiredStatusCheck{
  2653  					{
  2654  						Context: "continuous-integration",
  2655  					},
  2656  					{
  2657  						Context: "continuous-integration2",
  2658  						AppID:   &appID,
  2659  					},
  2660  					{
  2661  						Context: "continuous-integration3",
  2662  					},
  2663  				},
  2664  			}
  2665  			if !cmp.Equal(statusChecks, want) {
  2666  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want)
  2667  			}
  2668  		})
  2669  	}
  2670  }
  2671  
  2672  func TestRepositoriesService_RemoveRequiredStatusChecks(t *testing.T) {
  2673  	t.Parallel()
  2674  	tests := []struct {
  2675  		branch  string
  2676  		urlPath string
  2677  	}{
  2678  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2679  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_status_checks"},
  2680  	}
  2681  
  2682  	for _, test := range tests {
  2683  		t.Run(test.branch, func(t *testing.T) {
  2684  			t.Parallel()
  2685  			client, mux, _ := setup(t)
  2686  
  2687  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2688  				testMethod(t, r, "DELETE")
  2689  				testHeader(t, r, "Accept", mediaTypeV3)
  2690  				w.WriteHeader(http.StatusNoContent)
  2691  			})
  2692  
  2693  			ctx := context.Background()
  2694  			_, err := client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch)
  2695  			if err != nil {
  2696  				t.Errorf("Repositories.RemoveRequiredStatusChecks returned error: %v", err)
  2697  			}
  2698  
  2699  			const methodName = "RemoveRequiredStatusChecks"
  2700  			testBadOptions(t, methodName, func() (err error) {
  2701  				_, err = client.Repositories.RemoveRequiredStatusChecks(ctx, "\n", "\n", "\n")
  2702  				return err
  2703  			})
  2704  
  2705  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2706  				return client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch)
  2707  			})
  2708  		})
  2709  	}
  2710  }
  2711  
  2712  func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) {
  2713  	t.Parallel()
  2714  	tests := []struct {
  2715  		branch  string
  2716  		urlPath string
  2717  	}{
  2718  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"},
  2719  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_status_checks/contexts"},
  2720  	}
  2721  
  2722  	for _, test := range tests {
  2723  		t.Run(test.branch, func(t *testing.T) {
  2724  			t.Parallel()
  2725  			client, mux, _ := setup(t)
  2726  
  2727  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2728  				testMethod(t, r, "GET")
  2729  				fmt.Fprint(w, `["x", "y", "z"]`)
  2730  			})
  2731  
  2732  			ctx := context.Background()
  2733  			contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch)
  2734  			if err != nil {
  2735  				t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err)
  2736  			}
  2737  
  2738  			want := []string{"x", "y", "z"}
  2739  			if !cmp.Equal(contexts, want) {
  2740  				t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want)
  2741  			}
  2742  
  2743  			const methodName = "ListRequiredStatusChecksContexts"
  2744  			testBadOptions(t, methodName, func() (err error) {
  2745  				_, _, err = client.Repositories.ListRequiredStatusChecksContexts(ctx, "\n", "\n", "\n")
  2746  				return err
  2747  			})
  2748  
  2749  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2750  				got, resp, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch)
  2751  				if got != nil {
  2752  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2753  				}
  2754  				return resp, err
  2755  			})
  2756  		})
  2757  	}
  2758  }
  2759  
  2760  func TestRepositoriesService_ListRequiredStatusChecksContexts_branchNotProtected(t *testing.T) {
  2761  	t.Parallel()
  2762  	tests := []struct {
  2763  		branch  string
  2764  		urlPath string
  2765  	}{
  2766  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"},
  2767  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_status_checks/contexts"},
  2768  	}
  2769  
  2770  	for _, test := range tests {
  2771  		t.Run(test.branch, func(t *testing.T) {
  2772  			t.Parallel()
  2773  			client, mux, _ := setup(t)
  2774  
  2775  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2776  				testMethod(t, r, "GET")
  2777  
  2778  				w.WriteHeader(http.StatusBadRequest)
  2779  				fmt.Fprintf(w, `{
  2780  			"message": %q,
  2781  			"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  2782  			}`, githubBranchNotProtected)
  2783  			})
  2784  
  2785  			ctx := context.Background()
  2786  			contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch)
  2787  
  2788  			if contexts != nil {
  2789  				t.Error("Repositories.ListRequiredStatusChecksContexts returned non-nil contexts data")
  2790  			}
  2791  
  2792  			if err != ErrBranchNotProtected {
  2793  				t.Errorf("Repositories.ListRequiredStatusChecksContexts returned an invalid error: %v", err)
  2794  			}
  2795  		})
  2796  	}
  2797  }
  2798  
  2799  func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) {
  2800  	t.Parallel()
  2801  	tests := []struct {
  2802  		branch  string
  2803  		urlPath string
  2804  	}{
  2805  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  2806  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_pull_request_reviews"},
  2807  	}
  2808  
  2809  	for _, test := range tests {
  2810  		t.Run(test.branch, func(t *testing.T) {
  2811  			t.Parallel()
  2812  			client, mux, _ := setup(t)
  2813  
  2814  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2815  				testMethod(t, r, "GET")
  2816  				// TODO: remove custom Accept header when this API fully launches
  2817  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2818  				fmt.Fprint(w, `{
  2819  			"dismissal_restrictions":{
  2820  				"users":[{"id":1,"login":"u"}],
  2821  				"teams":[{"id":2,"slug":"t"}],
  2822  				"apps":[{"id":3,"slug":"a"}]
  2823  			},
  2824  			"dismiss_stale_reviews":true,
  2825  			"require_code_owner_reviews":true,
  2826  			"required_approving_review_count":1
  2827  		}`)
  2828  			})
  2829  
  2830  			ctx := context.Background()
  2831  			enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  2832  			if err != nil {
  2833  				t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err)
  2834  			}
  2835  
  2836  			want := &PullRequestReviewsEnforcement{
  2837  				DismissStaleReviews: true,
  2838  				DismissalRestrictions: &DismissalRestrictions{
  2839  					Users: []*User{
  2840  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2841  					},
  2842  					Teams: []*Team{
  2843  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2844  					},
  2845  					Apps: []*App{
  2846  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2847  					},
  2848  				},
  2849  				RequireCodeOwnerReviews:      true,
  2850  				RequiredApprovingReviewCount: 1,
  2851  			}
  2852  
  2853  			if !cmp.Equal(enforcement, want) {
  2854  				t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  2855  			}
  2856  
  2857  			const methodName = "GetPullRequestReviewEnforcement"
  2858  			testBadOptions(t, methodName, func() (err error) {
  2859  				_, _, err = client.Repositories.GetPullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  2860  				return err
  2861  			})
  2862  
  2863  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2864  				got, resp, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  2865  				if got != nil {
  2866  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2867  				}
  2868  				return resp, err
  2869  			})
  2870  		})
  2871  	}
  2872  }
  2873  
  2874  func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) {
  2875  	t.Parallel()
  2876  	tests := []struct {
  2877  		branch  string
  2878  		urlPath string
  2879  	}{
  2880  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  2881  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_pull_request_reviews"},
  2882  	}
  2883  
  2884  	for _, test := range tests {
  2885  		t.Run(test.branch, func(t *testing.T) {
  2886  			t.Parallel()
  2887  			client, mux, _ := setup(t)
  2888  
  2889  			input := &PullRequestReviewsEnforcementUpdate{
  2890  				DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  2891  					Users: &[]string{"u"},
  2892  					Teams: &[]string{"t"},
  2893  					Apps:  &[]string{"a"},
  2894  				},
  2895  			}
  2896  
  2897  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2898  				v := new(PullRequestReviewsEnforcementUpdate)
  2899  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2900  
  2901  				testMethod(t, r, "PATCH")
  2902  				if !cmp.Equal(v, input) {
  2903  					t.Errorf("Request body = %+v, want %+v", v, input)
  2904  				}
  2905  				// TODO: remove custom Accept header when this API fully launches
  2906  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2907  				fmt.Fprint(w, `{
  2908  					"dismissal_restrictions":{
  2909  						"users":[{"id":1,"login":"u"}],
  2910  						"teams":[{"id":2,"slug":"t"}],
  2911  						"apps":[{"id":3,"slug":"a"}]
  2912  					},
  2913  					"dismiss_stale_reviews":true,
  2914  					"require_code_owner_reviews":true,
  2915  					"required_approving_review_count":3
  2916  				}`)
  2917  			})
  2918  
  2919  			ctx := context.Background()
  2920  			enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input)
  2921  			if err != nil {
  2922  				t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err)
  2923  			}
  2924  
  2925  			want := &PullRequestReviewsEnforcement{
  2926  				DismissStaleReviews: true,
  2927  				DismissalRestrictions: &DismissalRestrictions{
  2928  					Users: []*User{
  2929  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2930  					},
  2931  					Teams: []*Team{
  2932  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2933  					},
  2934  					Apps: []*App{
  2935  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2936  					},
  2937  				},
  2938  				RequireCodeOwnerReviews:      true,
  2939  				RequiredApprovingReviewCount: 3,
  2940  			}
  2941  			if !cmp.Equal(enforcement, want) {
  2942  				t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  2943  			}
  2944  
  2945  			const methodName = "UpdatePullRequestReviewEnforcement"
  2946  			testBadOptions(t, methodName, func() (err error) {
  2947  				_, _, err = client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "\n", "\n", "\n", input)
  2948  				return err
  2949  			})
  2950  
  2951  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2952  				got, resp, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input)
  2953  				if got != nil {
  2954  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2955  				}
  2956  				return resp, err
  2957  			})
  2958  		})
  2959  	}
  2960  }
  2961  
  2962  func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) {
  2963  	t.Parallel()
  2964  	tests := []struct {
  2965  		branch  string
  2966  		urlPath string
  2967  	}{
  2968  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  2969  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_pull_request_reviews"},
  2970  	}
  2971  
  2972  	for _, test := range tests {
  2973  		t.Run(test.branch, func(t *testing.T) {
  2974  			t.Parallel()
  2975  			client, mux, _ := setup(t)
  2976  
  2977  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2978  				testMethod(t, r, "PATCH")
  2979  				// TODO: remove custom Accept header when this API fully launches
  2980  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2981  				testBody(t, r, `{"dismissal_restrictions":{}}`+"\n")
  2982  				fmt.Fprint(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`)
  2983  			})
  2984  
  2985  			ctx := context.Background()
  2986  			enforcement, _, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch)
  2987  			if err != nil {
  2988  				t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err)
  2989  			}
  2990  
  2991  			want := &PullRequestReviewsEnforcement{
  2992  				DismissStaleReviews:          true,
  2993  				DismissalRestrictions:        nil,
  2994  				RequireCodeOwnerReviews:      true,
  2995  				RequiredApprovingReviewCount: 1,
  2996  			}
  2997  			if !cmp.Equal(enforcement, want) {
  2998  				t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want)
  2999  			}
  3000  
  3001  			const methodName = "DisableDismissalRestrictions"
  3002  			testBadOptions(t, methodName, func() (err error) {
  3003  				_, _, err = client.Repositories.DisableDismissalRestrictions(ctx, "\n", "\n", "\n")
  3004  				return err
  3005  			})
  3006  
  3007  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3008  				got, resp, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch)
  3009  				if got != nil {
  3010  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3011  				}
  3012  				return resp, err
  3013  			})
  3014  		})
  3015  	}
  3016  }
  3017  
  3018  func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) {
  3019  	t.Parallel()
  3020  	tests := []struct {
  3021  		branch  string
  3022  		urlPath string
  3023  	}{
  3024  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  3025  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_pull_request_reviews"},
  3026  	}
  3027  
  3028  	for _, test := range tests {
  3029  		t.Run(test.branch, func(t *testing.T) {
  3030  			t.Parallel()
  3031  			client, mux, _ := setup(t)
  3032  
  3033  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3034  				testMethod(t, r, "DELETE")
  3035  				w.WriteHeader(http.StatusNoContent)
  3036  			})
  3037  
  3038  			ctx := context.Background()
  3039  			_, err := client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  3040  			if err != nil {
  3041  				t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err)
  3042  			}
  3043  
  3044  			const methodName = "RemovePullRequestReviewEnforcement"
  3045  			testBadOptions(t, methodName, func() (err error) {
  3046  				_, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  3047  				return err
  3048  			})
  3049  
  3050  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3051  				return client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  3052  			})
  3053  		})
  3054  	}
  3055  }
  3056  
  3057  func TestRepositoriesService_GetAdminEnforcement(t *testing.T) {
  3058  	t.Parallel()
  3059  	tests := []struct {
  3060  		branch  string
  3061  		urlPath string
  3062  	}{
  3063  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  3064  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/enforce_admins"},
  3065  	}
  3066  
  3067  	for _, test := range tests {
  3068  		t.Run(test.branch, func(t *testing.T) {
  3069  			t.Parallel()
  3070  			client, mux, _ := setup(t)
  3071  
  3072  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3073  				testMethod(t, r, "GET")
  3074  				fmt.Fprint(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  3075  			})
  3076  
  3077  			ctx := context.Background()
  3078  			enforcement, _, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch)
  3079  			if err != nil {
  3080  				t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err)
  3081  			}
  3082  
  3083  			want := &AdminEnforcement{
  3084  				URL:     Ptr("/repos/o/r/branches/b/protection/enforce_admins"),
  3085  				Enabled: true,
  3086  			}
  3087  
  3088  			if !cmp.Equal(enforcement, want) {
  3089  				t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want)
  3090  			}
  3091  
  3092  			const methodName = "GetAdminEnforcement"
  3093  			testBadOptions(t, methodName, func() (err error) {
  3094  				_, _, err = client.Repositories.GetAdminEnforcement(ctx, "\n", "\n", "\n")
  3095  				return err
  3096  			})
  3097  
  3098  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3099  				got, resp, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch)
  3100  				if got != nil {
  3101  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3102  				}
  3103  				return resp, err
  3104  			})
  3105  		})
  3106  	}
  3107  }
  3108  
  3109  func TestRepositoriesService_AddAdminEnforcement(t *testing.T) {
  3110  	t.Parallel()
  3111  	tests := []struct {
  3112  		branch  string
  3113  		urlPath string
  3114  	}{
  3115  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  3116  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/enforce_admins"},
  3117  	}
  3118  
  3119  	for _, test := range tests {
  3120  		t.Run(test.branch, func(t *testing.T) {
  3121  			t.Parallel()
  3122  			client, mux, _ := setup(t)
  3123  
  3124  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3125  				testMethod(t, r, "POST")
  3126  				fmt.Fprint(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  3127  			})
  3128  
  3129  			ctx := context.Background()
  3130  			enforcement, _, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch)
  3131  			if err != nil {
  3132  				t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err)
  3133  			}
  3134  
  3135  			want := &AdminEnforcement{
  3136  				URL:     Ptr("/repos/o/r/branches/b/protection/enforce_admins"),
  3137  				Enabled: true,
  3138  			}
  3139  			if !cmp.Equal(enforcement, want) {
  3140  				t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want)
  3141  			}
  3142  
  3143  			const methodName = "AddAdminEnforcement"
  3144  			testBadOptions(t, methodName, func() (err error) {
  3145  				_, _, err = client.Repositories.AddAdminEnforcement(ctx, "\n", "\n", "\n")
  3146  				return err
  3147  			})
  3148  
  3149  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3150  				got, resp, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch)
  3151  				if got != nil {
  3152  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3153  				}
  3154  				return resp, err
  3155  			})
  3156  		})
  3157  	}
  3158  }
  3159  
  3160  func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) {
  3161  	t.Parallel()
  3162  	tests := []struct {
  3163  		branch  string
  3164  		urlPath string
  3165  	}{
  3166  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  3167  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/enforce_admins"},
  3168  	}
  3169  
  3170  	for _, test := range tests {
  3171  		t.Run(test.branch, func(t *testing.T) {
  3172  			t.Parallel()
  3173  			client, mux, _ := setup(t)
  3174  
  3175  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3176  				testMethod(t, r, "DELETE")
  3177  				w.WriteHeader(http.StatusNoContent)
  3178  			})
  3179  
  3180  			ctx := context.Background()
  3181  			_, err := client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch)
  3182  			if err != nil {
  3183  				t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err)
  3184  			}
  3185  
  3186  			const methodName = "RemoveAdminEnforcement"
  3187  			testBadOptions(t, methodName, func() (err error) {
  3188  				_, err = client.Repositories.RemoveAdminEnforcement(ctx, "\n", "\n", "\n")
  3189  				return err
  3190  			})
  3191  
  3192  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3193  				return client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch)
  3194  			})
  3195  		})
  3196  	}
  3197  }
  3198  
  3199  func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) {
  3200  	t.Parallel()
  3201  	tests := []struct {
  3202  		branch  string
  3203  		urlPath string
  3204  	}{
  3205  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"},
  3206  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_signatures"},
  3207  	}
  3208  
  3209  	for _, test := range tests {
  3210  		t.Run(test.branch, func(t *testing.T) {
  3211  			t.Parallel()
  3212  			client, mux, _ := setup(t)
  3213  
  3214  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3215  				testMethod(t, r, "GET")
  3216  				testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  3217  				fmt.Fprint(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`)
  3218  			})
  3219  
  3220  			ctx := context.Background()
  3221  			signature, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch)
  3222  			if err != nil {
  3223  				t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err)
  3224  			}
  3225  
  3226  			want := &SignaturesProtectedBranch{
  3227  				URL:     Ptr("/repos/o/r/branches/b/protection/required_signatures"),
  3228  				Enabled: Ptr(false),
  3229  			}
  3230  
  3231  			if !cmp.Equal(signature, want) {
  3232  				t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want)
  3233  			}
  3234  
  3235  			const methodName = "GetSignaturesProtectedBranch"
  3236  			testBadOptions(t, methodName, func() (err error) {
  3237  				_, _, err = client.Repositories.GetSignaturesProtectedBranch(ctx, "\n", "\n", "\n")
  3238  				return err
  3239  			})
  3240  
  3241  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3242  				got, resp, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch)
  3243  				if got != nil {
  3244  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3245  				}
  3246  				return resp, err
  3247  			})
  3248  		})
  3249  	}
  3250  }
  3251  
  3252  func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) {
  3253  	t.Parallel()
  3254  	tests := []struct {
  3255  		branch  string
  3256  		urlPath string
  3257  	}{
  3258  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"},
  3259  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_signatures"},
  3260  	}
  3261  
  3262  	for _, test := range tests {
  3263  		t.Run(test.branch, func(t *testing.T) {
  3264  			t.Parallel()
  3265  			client, mux, _ := setup(t)
  3266  
  3267  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3268  				testMethod(t, r, "POST")
  3269  				testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  3270  				fmt.Fprint(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`)
  3271  			})
  3272  
  3273  			ctx := context.Background()
  3274  			signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3275  			if err != nil {
  3276  				t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err)
  3277  			}
  3278  
  3279  			want := &SignaturesProtectedBranch{
  3280  				URL:     Ptr("/repos/o/r/branches/b/protection/required_signatures"),
  3281  				Enabled: Ptr(true),
  3282  			}
  3283  
  3284  			if !cmp.Equal(signature, want) {
  3285  				t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want)
  3286  			}
  3287  
  3288  			const methodName = "RequireSignaturesOnProtectedBranch"
  3289  			testBadOptions(t, methodName, func() (err error) {
  3290  				_, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  3291  				return err
  3292  			})
  3293  
  3294  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3295  				got, resp, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3296  				if got != nil {
  3297  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3298  				}
  3299  				return resp, err
  3300  			})
  3301  		})
  3302  	}
  3303  }
  3304  
  3305  func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) {
  3306  	t.Parallel()
  3307  	tests := []struct {
  3308  		branch  string
  3309  		urlPath string
  3310  	}{
  3311  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"},
  3312  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/required_signatures"},
  3313  	}
  3314  
  3315  	for _, test := range tests {
  3316  		t.Run(test.branch, func(t *testing.T) {
  3317  			t.Parallel()
  3318  			client, mux, _ := setup(t)
  3319  
  3320  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3321  				testMethod(t, r, "DELETE")
  3322  				testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  3323  				w.WriteHeader(http.StatusNoContent)
  3324  			})
  3325  
  3326  			ctx := context.Background()
  3327  			_, err := client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3328  			if err != nil {
  3329  				t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err)
  3330  			}
  3331  
  3332  			const methodName = "OptionalSignaturesOnProtectedBranch"
  3333  			testBadOptions(t, methodName, func() (err error) {
  3334  				_, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  3335  				return err
  3336  			})
  3337  
  3338  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3339  				return client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3340  			})
  3341  		})
  3342  	}
  3343  }
  3344  
  3345  func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestrictions(t *testing.T) {
  3346  	t.Parallel()
  3347  	req := PullRequestReviewsEnforcementRequest{}
  3348  
  3349  	got, err := json.Marshal(req)
  3350  	if err != nil {
  3351  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  3352  	}
  3353  
  3354  	want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  3355  	if want != string(got) {
  3356  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  3357  	}
  3358  
  3359  	req = PullRequestReviewsEnforcementRequest{
  3360  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{},
  3361  	}
  3362  
  3363  	got, err = json.Marshal(req)
  3364  	if err != nil {
  3365  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  3366  	}
  3367  
  3368  	want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  3369  	if want != string(got) {
  3370  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  3371  	}
  3372  
  3373  	req = PullRequestReviewsEnforcementRequest{
  3374  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  3375  			Users: &[]string{},
  3376  			Teams: &[]string{},
  3377  			Apps:  &[]string{},
  3378  		},
  3379  		RequireLastPushApproval: Ptr(true),
  3380  	}
  3381  
  3382  	got, err = json.Marshal(req)
  3383  	if err != nil {
  3384  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  3385  	}
  3386  
  3387  	want = `{"dismissal_restrictions":{"users":[],"teams":[],"apps":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0,"require_last_push_approval":true}`
  3388  	if want != string(got) {
  3389  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  3390  	}
  3391  }
  3392  
  3393  func TestRepositoriesService_ListAllTopics(t *testing.T) {
  3394  	t.Parallel()
  3395  	client, mux, _ := setup(t)
  3396  
  3397  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3398  		testMethod(t, r, "GET")
  3399  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3400  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  3401  	})
  3402  
  3403  	ctx := context.Background()
  3404  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  3405  	if err != nil {
  3406  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  3407  	}
  3408  
  3409  	want := []string{"go", "go-github", "github"}
  3410  	if !cmp.Equal(got, want) {
  3411  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  3412  	}
  3413  
  3414  	const methodName = "ListAllTopics"
  3415  	testBadOptions(t, methodName, func() (err error) {
  3416  		_, _, err = client.Repositories.ListAllTopics(ctx, "\n", "\n")
  3417  		return err
  3418  	})
  3419  
  3420  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3421  		got, resp, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  3422  		if got != nil {
  3423  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3424  		}
  3425  		return resp, err
  3426  	})
  3427  }
  3428  
  3429  func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) {
  3430  	t.Parallel()
  3431  	client, mux, _ := setup(t)
  3432  
  3433  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3434  		testMethod(t, r, "GET")
  3435  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3436  		fmt.Fprint(w, `{"names":[]}`)
  3437  	})
  3438  
  3439  	ctx := context.Background()
  3440  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  3441  	if err != nil {
  3442  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  3443  	}
  3444  
  3445  	want := []string{}
  3446  	if !cmp.Equal(got, want) {
  3447  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  3448  	}
  3449  }
  3450  
  3451  func TestRepositoriesService_ReplaceAllTopics(t *testing.T) {
  3452  	t.Parallel()
  3453  	client, mux, _ := setup(t)
  3454  
  3455  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3456  		testMethod(t, r, "PUT")
  3457  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3458  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  3459  	})
  3460  
  3461  	ctx := context.Background()
  3462  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  3463  	if err != nil {
  3464  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  3465  	}
  3466  
  3467  	want := []string{"go", "go-github", "github"}
  3468  	if !cmp.Equal(got, want) {
  3469  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  3470  	}
  3471  
  3472  	const methodName = "ReplaceAllTopics"
  3473  	testBadOptions(t, methodName, func() (err error) {
  3474  		_, _, err = client.Repositories.ReplaceAllTopics(ctx, "\n", "\n", []string{"\n", "\n", "\n"})
  3475  		return err
  3476  	})
  3477  
  3478  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3479  		got, resp, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  3480  		if got != nil {
  3481  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3482  		}
  3483  		return resp, err
  3484  	})
  3485  }
  3486  
  3487  func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) {
  3488  	t.Parallel()
  3489  	client, mux, _ := setup(t)
  3490  
  3491  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3492  		testMethod(t, r, "PUT")
  3493  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3494  		testBody(t, r, `{"names":[]}`+"\n")
  3495  		fmt.Fprint(w, `{"names":[]}`)
  3496  	})
  3497  
  3498  	ctx := context.Background()
  3499  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", nil)
  3500  	if err != nil {
  3501  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  3502  	}
  3503  
  3504  	want := []string{}
  3505  	if !cmp.Equal(got, want) {
  3506  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  3507  	}
  3508  }
  3509  
  3510  func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) {
  3511  	t.Parallel()
  3512  	client, mux, _ := setup(t)
  3513  
  3514  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3515  		testMethod(t, r, "PUT")
  3516  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3517  		testBody(t, r, `{"names":[]}`+"\n")
  3518  		fmt.Fprint(w, `{"names":[]}`)
  3519  	})
  3520  
  3521  	ctx := context.Background()
  3522  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{})
  3523  	if err != nil {
  3524  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  3525  	}
  3526  
  3527  	want := []string{}
  3528  	if !cmp.Equal(got, want) {
  3529  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  3530  	}
  3531  }
  3532  
  3533  func TestRepositoriesService_ListAppRestrictions(t *testing.T) {
  3534  	t.Parallel()
  3535  	tests := []struct {
  3536  		branch  string
  3537  		urlPath string
  3538  	}{
  3539  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3540  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/apps"},
  3541  	}
  3542  
  3543  	for _, test := range tests {
  3544  		t.Run(test.branch, func(t *testing.T) {
  3545  			t.Parallel()
  3546  			client, mux, _ := setup(t)
  3547  
  3548  			mux.HandleFunc(test.urlPath, func(_ http.ResponseWriter, r *http.Request) {
  3549  				testMethod(t, r, "GET")
  3550  			})
  3551  
  3552  			ctx := context.Background()
  3553  			_, _, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch)
  3554  			if err != nil {
  3555  				t.Errorf("Repositories.ListAppRestrictions returned error: %v", err)
  3556  			}
  3557  
  3558  			const methodName = "ListAppRestrictions"
  3559  			testBadOptions(t, methodName, func() (err error) {
  3560  				_, _, err = client.Repositories.ListAppRestrictions(ctx, "\n", "\n", "\n")
  3561  				return err
  3562  			})
  3563  
  3564  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3565  				got, resp, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch)
  3566  				if got != nil {
  3567  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3568  				}
  3569  				return resp, err
  3570  			})
  3571  		})
  3572  	}
  3573  }
  3574  
  3575  func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) {
  3576  	t.Parallel()
  3577  	tests := []struct {
  3578  		branch  string
  3579  		urlPath string
  3580  	}{
  3581  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3582  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/apps"},
  3583  	}
  3584  
  3585  	for _, test := range tests {
  3586  		t.Run(test.branch, func(t *testing.T) {
  3587  			t.Parallel()
  3588  			client, mux, _ := setup(t)
  3589  
  3590  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3591  				testMethod(t, r, "PUT")
  3592  				fmt.Fprint(w, `[{
  3593  				"name": "octocat"
  3594  			}]`)
  3595  			})
  3596  			input := []string{"octocat"}
  3597  			ctx := context.Background()
  3598  			got, _, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input)
  3599  			if err != nil {
  3600  				t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err)
  3601  			}
  3602  			want := []*App{
  3603  				{Name: Ptr("octocat")},
  3604  			}
  3605  			if !cmp.Equal(got, want) {
  3606  				t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want)
  3607  			}
  3608  
  3609  			const methodName = "ReplaceAppRestrictions"
  3610  			testBadOptions(t, methodName, func() (err error) {
  3611  				_, _, err = client.Repositories.ReplaceAppRestrictions(ctx, "\n", "\n", "\n", input)
  3612  				return err
  3613  			})
  3614  
  3615  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3616  				got, resp, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input)
  3617  				if got != nil {
  3618  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3619  				}
  3620  				return resp, err
  3621  			})
  3622  		})
  3623  	}
  3624  }
  3625  
  3626  func TestRepositoriesService_AddAppRestrictions(t *testing.T) {
  3627  	t.Parallel()
  3628  	tests := []struct {
  3629  		branch  string
  3630  		urlPath string
  3631  	}{
  3632  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3633  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/apps"},
  3634  	}
  3635  
  3636  	for _, test := range tests {
  3637  		t.Run(test.branch, func(t *testing.T) {
  3638  			t.Parallel()
  3639  			client, mux, _ := setup(t)
  3640  
  3641  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3642  				testMethod(t, r, "POST")
  3643  				fmt.Fprint(w, `[{
  3644  				"name": "octocat"
  3645  			}]`)
  3646  			})
  3647  			input := []string{"octocat"}
  3648  			ctx := context.Background()
  3649  			got, _, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input)
  3650  			if err != nil {
  3651  				t.Errorf("Repositories.AddAppRestrictions returned error: %v", err)
  3652  			}
  3653  			want := []*App{
  3654  				{Name: Ptr("octocat")},
  3655  			}
  3656  			if !cmp.Equal(got, want) {
  3657  				t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want)
  3658  			}
  3659  
  3660  			const methodName = "AddAppRestrictions"
  3661  			testBadOptions(t, methodName, func() (err error) {
  3662  				_, _, err = client.Repositories.AddAppRestrictions(ctx, "\n", "\n", "\n", input)
  3663  				return err
  3664  			})
  3665  
  3666  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3667  				got, resp, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input)
  3668  				if got != nil {
  3669  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3670  				}
  3671  				return resp, err
  3672  			})
  3673  		})
  3674  	}
  3675  }
  3676  
  3677  func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) {
  3678  	t.Parallel()
  3679  	tests := []struct {
  3680  		branch  string
  3681  		urlPath string
  3682  	}{
  3683  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3684  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/apps"},
  3685  	}
  3686  
  3687  	for _, test := range tests {
  3688  		t.Run(test.branch, func(t *testing.T) {
  3689  			t.Parallel()
  3690  			client, mux, _ := setup(t)
  3691  
  3692  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3693  				testMethod(t, r, "DELETE")
  3694  				fmt.Fprint(w, `[]`)
  3695  			})
  3696  			input := []string{"octocat"}
  3697  			ctx := context.Background()
  3698  			got, _, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input)
  3699  			if err != nil {
  3700  				t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err)
  3701  			}
  3702  			want := []*App{}
  3703  			if !cmp.Equal(got, want) {
  3704  				t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want)
  3705  			}
  3706  
  3707  			const methodName = "RemoveAppRestrictions"
  3708  			testBadOptions(t, methodName, func() (err error) {
  3709  				_, _, err = client.Repositories.RemoveAppRestrictions(ctx, "\n", "\n", "\n", input)
  3710  				return err
  3711  			})
  3712  
  3713  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3714  				got, resp, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input)
  3715  				if got != nil {
  3716  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3717  				}
  3718  				return resp, err
  3719  			})
  3720  		})
  3721  	}
  3722  }
  3723  
  3724  func TestRepositoriesService_ListTeamRestrictions(t *testing.T) {
  3725  	t.Parallel()
  3726  	tests := []struct {
  3727  		branch  string
  3728  		urlPath string
  3729  	}{
  3730  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3731  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/teams"},
  3732  	}
  3733  
  3734  	for _, test := range tests {
  3735  		t.Run(test.branch, func(t *testing.T) {
  3736  			t.Parallel()
  3737  			client, mux, _ := setup(t)
  3738  
  3739  			mux.HandleFunc(test.urlPath, func(_ http.ResponseWriter, r *http.Request) {
  3740  				testMethod(t, r, "GET")
  3741  			})
  3742  
  3743  			ctx := context.Background()
  3744  			_, _, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch)
  3745  			if err != nil {
  3746  				t.Errorf("Repositories.ListTeamRestrictions returned error: %v", err)
  3747  			}
  3748  
  3749  			const methodName = "ListTeamRestrictions"
  3750  			testBadOptions(t, methodName, func() (err error) {
  3751  				_, _, err = client.Repositories.ListTeamRestrictions(ctx, "\n", "\n", "\n")
  3752  				return err
  3753  			})
  3754  
  3755  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3756  				got, resp, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch)
  3757  				if got != nil {
  3758  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3759  				}
  3760  				return resp, err
  3761  			})
  3762  		})
  3763  	}
  3764  }
  3765  
  3766  func TestRepositoriesService_ReplaceTeamRestrictions(t *testing.T) {
  3767  	t.Parallel()
  3768  	tests := []struct {
  3769  		branch  string
  3770  		urlPath string
  3771  	}{
  3772  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3773  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/teams"},
  3774  	}
  3775  
  3776  	for _, test := range tests {
  3777  		t.Run(test.branch, func(t *testing.T) {
  3778  			t.Parallel()
  3779  			client, mux, _ := setup(t)
  3780  
  3781  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3782  				testMethod(t, r, "PUT")
  3783  				fmt.Fprint(w, `[{
  3784  				"name": "octocat"
  3785  			}]`)
  3786  			})
  3787  			input := []string{"octocat"}
  3788  			ctx := context.Background()
  3789  			got, _, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input)
  3790  			if err != nil {
  3791  				t.Errorf("Repositories.ReplaceTeamRestrictions returned error: %v", err)
  3792  			}
  3793  			want := []*Team{
  3794  				{Name: Ptr("octocat")},
  3795  			}
  3796  			if !cmp.Equal(got, want) {
  3797  				t.Errorf("Repositories.ReplaceTeamRestrictions returned %+v, want %+v", got, want)
  3798  			}
  3799  
  3800  			const methodName = "ReplaceTeamRestrictions"
  3801  			testBadOptions(t, methodName, func() (err error) {
  3802  				_, _, err = client.Repositories.ReplaceTeamRestrictions(ctx, "\n", "\n", "\n", input)
  3803  				return err
  3804  			})
  3805  
  3806  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3807  				got, resp, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input)
  3808  				if got != nil {
  3809  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3810  				}
  3811  				return resp, err
  3812  			})
  3813  		})
  3814  	}
  3815  }
  3816  
  3817  func TestRepositoriesService_AddTeamRestrictions(t *testing.T) {
  3818  	t.Parallel()
  3819  	tests := []struct {
  3820  		branch  string
  3821  		urlPath string
  3822  	}{
  3823  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3824  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/teams"},
  3825  	}
  3826  
  3827  	for _, test := range tests {
  3828  		t.Run(test.branch, func(t *testing.T) {
  3829  			t.Parallel()
  3830  			client, mux, _ := setup(t)
  3831  
  3832  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3833  				testMethod(t, r, "POST")
  3834  				fmt.Fprint(w, `[{
  3835  				"name": "octocat"
  3836  			}]`)
  3837  			})
  3838  			input := []string{"octocat"}
  3839  			ctx := context.Background()
  3840  			got, _, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input)
  3841  			if err != nil {
  3842  				t.Errorf("Repositories.AddTeamRestrictions returned error: %v", err)
  3843  			}
  3844  			want := []*Team{
  3845  				{Name: Ptr("octocat")},
  3846  			}
  3847  			if !cmp.Equal(got, want) {
  3848  				t.Errorf("Repositories.AddTeamRestrictions returned %+v, want %+v", got, want)
  3849  			}
  3850  
  3851  			const methodName = "AddTeamRestrictions"
  3852  			testBadOptions(t, methodName, func() (err error) {
  3853  				_, _, err = client.Repositories.AddTeamRestrictions(ctx, "\n", "\n", "\n", input)
  3854  				return err
  3855  			})
  3856  
  3857  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3858  				got, resp, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input)
  3859  				if got != nil {
  3860  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3861  				}
  3862  				return resp, err
  3863  			})
  3864  		})
  3865  	}
  3866  }
  3867  
  3868  func TestRepositoriesService_RemoveTeamRestrictions(t *testing.T) {
  3869  	t.Parallel()
  3870  	tests := []struct {
  3871  		branch  string
  3872  		urlPath string
  3873  	}{
  3874  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3875  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/teams"},
  3876  	}
  3877  
  3878  	for _, test := range tests {
  3879  		t.Run(test.branch, func(t *testing.T) {
  3880  			t.Parallel()
  3881  			client, mux, _ := setup(t)
  3882  
  3883  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3884  				testMethod(t, r, "DELETE")
  3885  				fmt.Fprint(w, `[]`)
  3886  			})
  3887  			input := []string{"octocat"}
  3888  			ctx := context.Background()
  3889  			got, _, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input)
  3890  			if err != nil {
  3891  				t.Errorf("Repositories.RemoveTeamRestrictions returned error: %v", err)
  3892  			}
  3893  			want := []*Team{}
  3894  			if !cmp.Equal(got, want) {
  3895  				t.Errorf("Repositories.RemoveTeamRestrictions returned %+v, want %+v", got, want)
  3896  			}
  3897  
  3898  			const methodName = "RemoveTeamRestrictions"
  3899  			testBadOptions(t, methodName, func() (err error) {
  3900  				_, _, err = client.Repositories.RemoveTeamRestrictions(ctx, "\n", "\n", "\n", input)
  3901  				return err
  3902  			})
  3903  
  3904  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3905  				got, resp, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input)
  3906  				if got != nil {
  3907  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3908  				}
  3909  				return resp, err
  3910  			})
  3911  		})
  3912  	}
  3913  }
  3914  
  3915  func TestRepositoriesService_ListUserRestrictions(t *testing.T) {
  3916  	t.Parallel()
  3917  	tests := []struct {
  3918  		branch  string
  3919  		urlPath string
  3920  	}{
  3921  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  3922  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/users"},
  3923  	}
  3924  
  3925  	for _, test := range tests {
  3926  		t.Run(test.branch, func(t *testing.T) {
  3927  			t.Parallel()
  3928  			client, mux, _ := setup(t)
  3929  
  3930  			mux.HandleFunc(test.urlPath, func(_ http.ResponseWriter, r *http.Request) {
  3931  				testMethod(t, r, "GET")
  3932  			})
  3933  
  3934  			ctx := context.Background()
  3935  			_, _, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch)
  3936  			if err != nil {
  3937  				t.Errorf("Repositories.ListUserRestrictions returned error: %v", err)
  3938  			}
  3939  
  3940  			const methodName = "ListUserRestrictions"
  3941  			testBadOptions(t, methodName, func() (err error) {
  3942  				_, _, err = client.Repositories.ListUserRestrictions(ctx, "\n", "\n", "\n")
  3943  				return err
  3944  			})
  3945  
  3946  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3947  				got, resp, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch)
  3948  				if got != nil {
  3949  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3950  				}
  3951  				return resp, err
  3952  			})
  3953  		})
  3954  	}
  3955  }
  3956  
  3957  func TestRepositoriesService_ReplaceUserRestrictions(t *testing.T) {
  3958  	t.Parallel()
  3959  	tests := []struct {
  3960  		branch  string
  3961  		urlPath string
  3962  	}{
  3963  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  3964  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/users"},
  3965  	}
  3966  
  3967  	for _, test := range tests {
  3968  		t.Run(test.branch, func(t *testing.T) {
  3969  			t.Parallel()
  3970  			client, mux, _ := setup(t)
  3971  
  3972  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3973  				testMethod(t, r, "PUT")
  3974  				fmt.Fprint(w, `[{
  3975  				"name": "octocat"
  3976  			}]`)
  3977  			})
  3978  			input := []string{"octocat"}
  3979  			ctx := context.Background()
  3980  			got, _, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input)
  3981  			if err != nil {
  3982  				t.Errorf("Repositories.ReplaceUserRestrictions returned error: %v", err)
  3983  			}
  3984  			want := []*User{
  3985  				{Name: Ptr("octocat")},
  3986  			}
  3987  			if !cmp.Equal(got, want) {
  3988  				t.Errorf("Repositories.ReplaceUserRestrictions returned %+v, want %+v", got, want)
  3989  			}
  3990  
  3991  			const methodName = "ReplaceUserRestrictions"
  3992  			testBadOptions(t, methodName, func() (err error) {
  3993  				_, _, err = client.Repositories.ReplaceUserRestrictions(ctx, "\n", "\n", "\n", input)
  3994  				return err
  3995  			})
  3996  
  3997  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3998  				got, resp, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input)
  3999  				if got != nil {
  4000  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4001  				}
  4002  				return resp, err
  4003  			})
  4004  		})
  4005  	}
  4006  }
  4007  
  4008  func TestRepositoriesService_AddUserRestrictions(t *testing.T) {
  4009  	t.Parallel()
  4010  	tests := []struct {
  4011  		branch  string
  4012  		urlPath string
  4013  	}{
  4014  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  4015  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/users"},
  4016  	}
  4017  
  4018  	for _, test := range tests {
  4019  		t.Run(test.branch, func(t *testing.T) {
  4020  			t.Parallel()
  4021  			client, mux, _ := setup(t)
  4022  
  4023  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  4024  				testMethod(t, r, "POST")
  4025  				fmt.Fprint(w, `[{
  4026  				"name": "octocat"
  4027  			}]`)
  4028  			})
  4029  			input := []string{"octocat"}
  4030  			ctx := context.Background()
  4031  			got, _, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input)
  4032  			if err != nil {
  4033  				t.Errorf("Repositories.AddUserRestrictions returned error: %v", err)
  4034  			}
  4035  			want := []*User{
  4036  				{Name: Ptr("octocat")},
  4037  			}
  4038  			if !cmp.Equal(got, want) {
  4039  				t.Errorf("Repositories.AddUserRestrictions returned %+v, want %+v", got, want)
  4040  			}
  4041  
  4042  			const methodName = "AddUserRestrictions"
  4043  			testBadOptions(t, methodName, func() (err error) {
  4044  				_, _, err = client.Repositories.AddUserRestrictions(ctx, "\n", "\n", "\n", input)
  4045  				return err
  4046  			})
  4047  
  4048  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4049  				got, resp, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input)
  4050  				if got != nil {
  4051  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4052  				}
  4053  				return resp, err
  4054  			})
  4055  		})
  4056  	}
  4057  }
  4058  
  4059  func TestRepositoriesService_RemoveUserRestrictions(t *testing.T) {
  4060  	t.Parallel()
  4061  	tests := []struct {
  4062  		branch  string
  4063  		urlPath string
  4064  	}{
  4065  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  4066  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat%2fbranch-50%25/protection/restrictions/users"},
  4067  	}
  4068  
  4069  	for _, test := range tests {
  4070  		t.Run(test.branch, func(t *testing.T) {
  4071  			t.Parallel()
  4072  			client, mux, _ := setup(t)
  4073  
  4074  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  4075  				testMethod(t, r, "DELETE")
  4076  				fmt.Fprint(w, `[]`)
  4077  			})
  4078  			input := []string{"octocat"}
  4079  			ctx := context.Background()
  4080  			got, _, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input)
  4081  			if err != nil {
  4082  				t.Errorf("Repositories.RemoveUserRestrictions returned error: %v", err)
  4083  			}
  4084  			want := []*User{}
  4085  			if !cmp.Equal(got, want) {
  4086  				t.Errorf("Repositories.RemoveUserRestrictions returned %+v, want %+v", got, want)
  4087  			}
  4088  
  4089  			const methodName = "RemoveUserRestrictions"
  4090  			testBadOptions(t, methodName, func() (err error) {
  4091  				_, _, err = client.Repositories.RemoveUserRestrictions(ctx, "\n", "\n", "\n", input)
  4092  				return err
  4093  			})
  4094  
  4095  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4096  				got, resp, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input)
  4097  				if got != nil {
  4098  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4099  				}
  4100  				return resp, err
  4101  			})
  4102  		})
  4103  	}
  4104  }
  4105  
  4106  func TestRepositoriesService_Transfer(t *testing.T) {
  4107  	t.Parallel()
  4108  	client, mux, _ := setup(t)
  4109  
  4110  	input := TransferRequest{NewOwner: "a", NewName: Ptr("b"), TeamID: []int64{123}}
  4111  
  4112  	mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) {
  4113  		var v TransferRequest
  4114  		assertNilError(t, json.NewDecoder(r.Body).Decode(&v))
  4115  
  4116  		testMethod(t, r, "POST")
  4117  		if !cmp.Equal(v, input) {
  4118  			t.Errorf("Request body = %+v, want %+v", v, input)
  4119  		}
  4120  
  4121  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  4122  	})
  4123  
  4124  	ctx := context.Background()
  4125  	got, _, err := client.Repositories.Transfer(ctx, "o", "r", input)
  4126  	if err != nil {
  4127  		t.Errorf("Repositories.Transfer returned error: %v", err)
  4128  	}
  4129  
  4130  	want := &Repository{Owner: &User{Login: Ptr("a")}}
  4131  	if !cmp.Equal(got, want) {
  4132  		t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want)
  4133  	}
  4134  
  4135  	const methodName = "Transfer"
  4136  	testBadOptions(t, methodName, func() (err error) {
  4137  		_, _, err = client.Repositories.Transfer(ctx, "\n", "\n", input)
  4138  		return err
  4139  	})
  4140  
  4141  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4142  		got, resp, err := client.Repositories.Transfer(ctx, "o", "r", input)
  4143  		if got != nil {
  4144  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4145  		}
  4146  		return resp, err
  4147  	})
  4148  }
  4149  
  4150  func TestRepositoriesService_Dispatch(t *testing.T) {
  4151  	t.Parallel()
  4152  	client, mux, _ := setup(t)
  4153  
  4154  	var input DispatchRequestOptions
  4155  
  4156  	mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) {
  4157  		var v DispatchRequestOptions
  4158  		assertNilError(t, json.NewDecoder(r.Body).Decode(&v))
  4159  
  4160  		testMethod(t, r, "POST")
  4161  		if !cmp.Equal(v, input) {
  4162  			t.Errorf("Request body = %+v, want %+v", v, input)
  4163  		}
  4164  
  4165  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  4166  	})
  4167  
  4168  	ctx := context.Background()
  4169  
  4170  	testCases := []any{
  4171  		nil,
  4172  		struct {
  4173  			Foo string
  4174  		}{
  4175  			Foo: "test",
  4176  		},
  4177  		struct {
  4178  			Bar int
  4179  		}{
  4180  			Bar: 42,
  4181  		},
  4182  		struct {
  4183  			Foo string
  4184  			Bar int
  4185  			Baz bool
  4186  		}{
  4187  			Foo: "test",
  4188  			Bar: 42,
  4189  			Baz: false,
  4190  		},
  4191  	}
  4192  
  4193  	for _, tc := range testCases {
  4194  		if tc == nil {
  4195  			input = DispatchRequestOptions{EventType: "go"}
  4196  		} else {
  4197  			bytes, _ := json.Marshal(tc)
  4198  			payload := json.RawMessage(bytes)
  4199  			input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload}
  4200  		}
  4201  
  4202  		got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  4203  		if err != nil {
  4204  			t.Errorf("Repositories.Dispatch returned error: %v", err)
  4205  		}
  4206  
  4207  		want := &Repository{Owner: &User{Login: Ptr("a")}}
  4208  		if !cmp.Equal(got, want) {
  4209  			t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want)
  4210  		}
  4211  	}
  4212  
  4213  	const methodName = "Dispatch"
  4214  	testBadOptions(t, methodName, func() (err error) {
  4215  		_, _, err = client.Repositories.Dispatch(ctx, "\n", "\n", input)
  4216  		return err
  4217  	})
  4218  
  4219  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4220  		got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  4221  		if got != nil {
  4222  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4223  		}
  4224  		return resp, err
  4225  	})
  4226  }
  4227  
  4228  func TestAdvancedSecurity_Marshal(t *testing.T) {
  4229  	t.Parallel()
  4230  	testJSONMarshal(t, &AdvancedSecurity{}, "{}")
  4231  
  4232  	u := &AdvancedSecurity{
  4233  		Status: Ptr("status"),
  4234  	}
  4235  
  4236  	want := `{
  4237  		"status": "status"
  4238  	}`
  4239  
  4240  	testJSONMarshal(t, u, want)
  4241  }
  4242  
  4243  func TestAuthorizedActorsOnly_Marshal(t *testing.T) {
  4244  	t.Parallel()
  4245  	testJSONMarshal(t, &AuthorizedActorsOnly{}, "{}")
  4246  
  4247  	u := &AuthorizedActorsOnly{
  4248  		From: Ptr(true),
  4249  	}
  4250  
  4251  	want := `{
  4252  		"from" : true
  4253  	}`
  4254  
  4255  	testJSONMarshal(t, u, want)
  4256  }
  4257  
  4258  func TestDispatchRequestOptions_Marshal(t *testing.T) {
  4259  	t.Parallel()
  4260  	testJSONMarshal(t, &DispatchRequestOptions{}, "{}")
  4261  
  4262  	cp := json.RawMessage(`{"testKey":"testValue"}`)
  4263  	u := &DispatchRequestOptions{
  4264  		EventType:     "test_event_type",
  4265  		ClientPayload: &cp,
  4266  	}
  4267  
  4268  	want := `{
  4269  		"event_type": "test_event_type",
  4270  		"client_payload": {
  4271  		  "testKey": "testValue"
  4272  		}
  4273  	  }`
  4274  
  4275  	testJSONMarshal(t, u, want)
  4276  }
  4277  
  4278  func TestTransferRequest_Marshal(t *testing.T) {
  4279  	t.Parallel()
  4280  	testJSONMarshal(t, &TransferRequest{}, "{}")
  4281  
  4282  	u := &TransferRequest{
  4283  		NewOwner: "testOwner",
  4284  		NewName:  Ptr("testName"),
  4285  		TeamID:   []int64{1, 2},
  4286  	}
  4287  
  4288  	want := `{
  4289  		"new_owner": "testOwner",
  4290  		"new_name": "testName",
  4291  		"team_ids": [1,2]
  4292  	}`
  4293  
  4294  	testJSONMarshal(t, u, want)
  4295  }
  4296  
  4297  func TestSignaturesProtectedBranch_Marshal(t *testing.T) {
  4298  	t.Parallel()
  4299  	testJSONMarshal(t, &SignaturesProtectedBranch{}, "{}")
  4300  
  4301  	u := &SignaturesProtectedBranch{
  4302  		URL:     Ptr("https://www.testURL.in"),
  4303  		Enabled: Ptr(false),
  4304  	}
  4305  
  4306  	want := `{
  4307  		"url": "https://www.testURL.in",
  4308  		"enabled": false
  4309  	}`
  4310  
  4311  	testJSONMarshal(t, u, want)
  4312  
  4313  	u2 := &SignaturesProtectedBranch{
  4314  		URL:     Ptr("testURL"),
  4315  		Enabled: Ptr(true),
  4316  	}
  4317  
  4318  	want2 := `{
  4319  		"url": "testURL",
  4320  		"enabled": true
  4321  	}`
  4322  
  4323  	testJSONMarshal(t, u2, want2)
  4324  }
  4325  
  4326  func TestDismissalRestrictionsRequest_Marshal(t *testing.T) {
  4327  	t.Parallel()
  4328  	testJSONMarshal(t, &DismissalRestrictionsRequest{}, "{}")
  4329  
  4330  	u := &DismissalRestrictionsRequest{
  4331  		Users: &[]string{"user1", "user2"},
  4332  		Teams: &[]string{"team1", "team2"},
  4333  		Apps:  &[]string{"app1", "app2"},
  4334  	}
  4335  
  4336  	want := `{
  4337  		"users": ["user1","user2"],
  4338  		"teams": ["team1","team2"],
  4339  		"apps": ["app1","app2"]
  4340  	}`
  4341  
  4342  	testJSONMarshal(t, u, want)
  4343  }
  4344  
  4345  func TestAdminEnforcement_Marshal(t *testing.T) {
  4346  	t.Parallel()
  4347  	testJSONMarshal(t, &AdminEnforcement{}, "{}")
  4348  
  4349  	u := &AdminEnforcement{
  4350  		URL:     Ptr("https://www.test-url.in"),
  4351  		Enabled: false,
  4352  	}
  4353  
  4354  	want := `{
  4355  		"url": "https://www.test-url.in",
  4356  		"enabled": false
  4357  	}`
  4358  
  4359  	testJSONMarshal(t, u, want)
  4360  }
  4361  
  4362  func TestPullRequestReviewsEnforcementUpdate_Marshal(t *testing.T) {
  4363  	t.Parallel()
  4364  	testJSONMarshal(t, &PullRequestReviewsEnforcementUpdate{}, "{}")
  4365  
  4366  	u := &PullRequestReviewsEnforcementUpdate{
  4367  		BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  4368  			Users: []string{"user1", "user2"},
  4369  			Teams: []string{"team1", "team2"},
  4370  			Apps:  []string{"app1", "app2"},
  4371  		},
  4372  		DismissStaleReviews:          Ptr(false),
  4373  		RequireCodeOwnerReviews:      Ptr(true),
  4374  		RequiredApprovingReviewCount: 2,
  4375  	}
  4376  
  4377  	want := `{
  4378  		"bypass_pull_request_allowances": {
  4379  			"users": ["user1","user2"],
  4380  			"teams": ["team1","team2"],
  4381  			"apps": ["app1","app2"]
  4382  		},
  4383  		"dismiss_stale_reviews": false,
  4384  		"require_code_owner_reviews": true,
  4385  		"required_approving_review_count": 2
  4386  	}`
  4387  
  4388  	testJSONMarshal(t, u, want)
  4389  }
  4390  
  4391  func TestRequiredStatusCheck_Marshal(t *testing.T) {
  4392  	t.Parallel()
  4393  	testJSONMarshal(t, &RequiredStatusCheck{}, "{}")
  4394  
  4395  	u := &RequiredStatusCheck{
  4396  		Context: "ctx",
  4397  		AppID:   Ptr(int64(1)),
  4398  	}
  4399  
  4400  	want := `{
  4401  		"context": "ctx",
  4402  		"app_id": 1
  4403  	}`
  4404  
  4405  	testJSONMarshal(t, u, want)
  4406  }
  4407  
  4408  func TestRepositoryTag_Marshal(t *testing.T) {
  4409  	t.Parallel()
  4410  	testJSONMarshal(t, &RepositoryTag{}, "{}")
  4411  
  4412  	u := &RepositoryTag{
  4413  		Name: Ptr("v0.1"),
  4414  		Commit: &Commit{
  4415  			SHA: Ptr("sha"),
  4416  			URL: Ptr("url"),
  4417  		},
  4418  		ZipballURL: Ptr("zball"),
  4419  		TarballURL: Ptr("tball"),
  4420  	}
  4421  
  4422  	want := `{
  4423  		"name": "v0.1",
  4424  		"commit": {
  4425  			"sha": "sha",
  4426  			"url": "url"
  4427  		},
  4428  		"zipball_url": "zball",
  4429  		"tarball_url": "tball"
  4430  	}`
  4431  
  4432  	testJSONMarshal(t, u, want)
  4433  }
  4434  
  4435  func TestRepositoriesService_EnablePrivateReporting(t *testing.T) {
  4436  	t.Parallel()
  4437  	client, mux, _ := setup(t)
  4438  
  4439  	mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) {
  4440  		testMethod(t, r, "PUT")
  4441  		w.WriteHeader(http.StatusNoContent)
  4442  	})
  4443  
  4444  	ctx := context.Background()
  4445  	_, err := client.Repositories.EnablePrivateReporting(ctx, "owner", "repo")
  4446  	if err != nil {
  4447  		t.Errorf("Repositories.EnablePrivateReporting returned error: %v", err)
  4448  	}
  4449  
  4450  	const methodName = "EnablePrivateReporting"
  4451  	testBadOptions(t, methodName, func() (err error) {
  4452  		_, err = client.Repositories.EnablePrivateReporting(ctx, "\n", "\n")
  4453  		return err
  4454  	})
  4455  
  4456  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4457  		return client.Repositories.EnablePrivateReporting(ctx, "owner", "repo")
  4458  	})
  4459  }
  4460  
  4461  func TestRepositoriesService_DisablePrivateReporting(t *testing.T) {
  4462  	t.Parallel()
  4463  	client, mux, _ := setup(t)
  4464  
  4465  	mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) {
  4466  		testMethod(t, r, "DELETE")
  4467  		w.WriteHeader(http.StatusNoContent)
  4468  	})
  4469  
  4470  	ctx := context.Background()
  4471  	_, err := client.Repositories.DisablePrivateReporting(ctx, "owner", "repo")
  4472  	if err != nil {
  4473  		t.Errorf("Repositories.DisablePrivateReporting returned error: %v", err)
  4474  	}
  4475  
  4476  	const methodName = "DisablePrivateReporting"
  4477  	testBadOptions(t, methodName, func() (err error) {
  4478  		_, err = client.Repositories.DisablePrivateReporting(ctx, "\n", "\n")
  4479  		return err
  4480  	})
  4481  
  4482  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4483  		return client.Repositories.DisablePrivateReporting(ctx, "owner", "repo")
  4484  	})
  4485  }
  4486  
  4487  func TestRepositoriesService_IsPrivateReportingEnabled(t *testing.T) {
  4488  	t.Parallel()
  4489  	client, mux, _ := setup(t)
  4490  
  4491  	mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) {
  4492  		testMethod(t, r, "GET")
  4493  		fmt.Fprint(w, `{"enabled": true}`)
  4494  	})
  4495  
  4496  	ctx := context.Background()
  4497  	enabled, _, err := client.Repositories.IsPrivateReportingEnabled(ctx, "owner", "repo")
  4498  	if err != nil {
  4499  		t.Errorf("Repositories.IsPrivateReportingEnabled returned error: %v", err)
  4500  	}
  4501  	if want := true; enabled != want {
  4502  		t.Errorf("Repositories.IsPrivateReportingEnabled returned %+v, want %+v", enabled, want)
  4503  	}
  4504  
  4505  	const methodName = "IsPrivateReportingEnabled"
  4506  	testBadOptions(t, methodName, func() (err error) {
  4507  		_, _, err = client.Repositories.IsPrivateReportingEnabled(ctx, "\n", "\n")
  4508  		return err
  4509  	})
  4510  
  4511  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4512  		got, resp, err := client.Repositories.IsPrivateReportingEnabled(ctx, "owner", "repo")
  4513  		if got {
  4514  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want false", methodName, got)
  4515  		}
  4516  		return resp, err
  4517  	})
  4518  }
  4519  
  4520  func TestRepository_UnmarshalJSON(t *testing.T) {
  4521  	t.Parallel()
  4522  	var testCases = map[string]struct {
  4523  		data           []byte
  4524  		wantRepository Repository
  4525  		wantErr        bool
  4526  	}{
  4527  		"Empty": {
  4528  			data:           []byte("{}"),
  4529  			wantRepository: Repository{},
  4530  			wantErr:        false,
  4531  		},
  4532  		"Invalid JSON": {
  4533  			data:           []byte("{"),
  4534  			wantRepository: Repository{},
  4535  			wantErr:        true,
  4536  		},
  4537  		"Partial project": {
  4538  			data:           []byte(`{"id":10270722,"name":"go-github","private":false,"owner":{"login":"google"},"created_at":"2013-05-24T16:42:58Z","license":{},"topics":["github"],"permissions":{"pull":true},"custom_properties":{},"organization":{"login":"google"}}`),
  4539  			wantRepository: Repository{ID: Ptr(int64(10270722)), Name: Ptr("go-github"), Private: Ptr(false), Owner: &User{Login: Ptr("google")}, CreatedAt: &Timestamp{time.Date(2013, 5, 24, 16, 42, 58, 0, time.UTC)}, License: &License{}, Topics: []string{"github"}, Permissions: map[string]bool{"pull": true}, CustomProperties: map[string]any{}, Organization: &Organization{Login: Ptr("google")}},
  4540  			wantErr:        false,
  4541  		},
  4542  		"With custom properties": {
  4543  			data:           []byte(`{"custom_properties":{"boolean":"false","text":"a","single-select":"a","multi-select":["a","b","c"]}}`),
  4544  			wantRepository: Repository{CustomProperties: map[string]any{"boolean": "false", "text": "a", "single-select": "a", "multi-select": []any{"a", "b", "c"}}},
  4545  			wantErr:        false,
  4546  		},
  4547  	}
  4548  
  4549  	for name, tt := range testCases {
  4550  		t.Run(name, func(t *testing.T) {
  4551  			t.Parallel()
  4552  			pk := Repository{}
  4553  			err := json.Unmarshal(tt.data, &pk)
  4554  			if err == nil && tt.wantErr {
  4555  				t.Error("Repository.UnmarshalJSON returned nil instead of an error")
  4556  			}
  4557  			if err != nil && !tt.wantErr {
  4558  				t.Errorf("Repository.UnmarshalJSON returned an unexpected error: %+v", err)
  4559  			}
  4560  			if !cmp.Equal(tt.wantRepository, pk) {
  4561  				t.Errorf("Repository.UnmarshalJSON expected repository %+v, got %+v", tt.wantRepository, pk)
  4562  			}
  4563  		})
  4564  	}
  4565  }