github.com/google/go-github/v68@v68.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(w 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 errpr: #{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 #{fixes}, want #{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/branch-50%"},
   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/branch-50%"},
   979  	}
   980  
   981  	for _, test := range tests {
   982  		test := test
   983  		t.Run(test.branch, func(t *testing.T) {
   984  			t.Parallel()
   985  			client, mux, _ := setup(t)
   986  
   987  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
   988  				testMethod(t, r, "GET")
   989  				fmt.Fprint(w, `{"name":"n", "commit":{"sha":...truncated`)
   990  			})
   991  
   992  			ctx := context.Background()
   993  			if _, _, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 0); err == nil {
   994  				t.Error("Repositories.GetBranch returned no error; wanted JSON error")
   995  			}
   996  		})
   997  	}
   998  }
   999  
  1000  func TestRepositoriesService_GetBranch_StatusMovedPermanently_followRedirects(t *testing.T) {
  1001  	t.Parallel()
  1002  	client, mux, serverURL := setup(t)
  1003  
  1004  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
  1005  		testMethod(t, r, "GET")
  1006  		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/repos/o/r/branches/br")
  1007  		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
  1008  	})
  1009  	mux.HandleFunc("/repos/o/r/branches/br", func(w http.ResponseWriter, r *http.Request) {
  1010  		testMethod(t, r, "GET")
  1011  		fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true, "protection":{"required_status_checks":{"contexts":["c"]}}}`)
  1012  	})
  1013  	ctx := context.Background()
  1014  	branch, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", 1)
  1015  	if err != nil {
  1016  		t.Errorf("Repositories.GetBranch returned error: %v", err)
  1017  	}
  1018  	if resp.StatusCode != http.StatusOK {
  1019  		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusOK)
  1020  	}
  1021  
  1022  	want := &Branch{
  1023  		Name: Ptr("n"),
  1024  		Commit: &RepositoryCommit{
  1025  			SHA: Ptr("s"),
  1026  			Commit: &Commit{
  1027  				Message: Ptr("m"),
  1028  			},
  1029  		},
  1030  		Protected: Ptr(true),
  1031  		Protection: &Protection{
  1032  			RequiredStatusChecks: &RequiredStatusChecks{
  1033  				Contexts: &[]string{"c"},
  1034  			},
  1035  		},
  1036  	}
  1037  	if !cmp.Equal(branch, want) {
  1038  		t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
  1039  	}
  1040  }
  1041  
  1042  func TestRepositoriesService_GetBranch_notFound(t *testing.T) {
  1043  	t.Parallel()
  1044  	tests := []struct {
  1045  		branch  string
  1046  		urlPath string
  1047  	}{
  1048  		{branch: "b", urlPath: "/repos/o/r/branches/b"},
  1049  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat-branch-50%"},
  1050  	}
  1051  
  1052  	for _, test := range tests {
  1053  		test := test
  1054  		t.Run(test.branch, func(t *testing.T) {
  1055  			t.Parallel()
  1056  			client, mux, _ := setup(t)
  1057  
  1058  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1059  				testMethod(t, r, "GET")
  1060  				http.Error(w, "branch not found", http.StatusNotFound)
  1061  			})
  1062  			ctx := context.Background()
  1063  			_, resp, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 1)
  1064  			if err == nil {
  1065  				t.Error("Repositories.GetBranch returned error: nil")
  1066  			}
  1067  			if resp.StatusCode != http.StatusNotFound {
  1068  				t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusNotFound)
  1069  			}
  1070  
  1071  			// Add custom round tripper
  1072  			client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
  1073  				return nil, errors.New("failed to get branch")
  1074  			})
  1075  
  1076  			const methodName = "GetBranch"
  1077  			testBadOptions(t, methodName, func() (err error) {
  1078  				_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", 1)
  1079  				return err
  1080  			})
  1081  		})
  1082  	}
  1083  }
  1084  
  1085  func TestRepositoriesService_RenameBranch(t *testing.T) {
  1086  	t.Parallel()
  1087  	tests := []struct {
  1088  		branch  string
  1089  		urlPath string
  1090  	}{
  1091  		{branch: "b", urlPath: "/repos/o/r/branches/b/rename"},
  1092  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/rename"},
  1093  	}
  1094  
  1095  	for _, test := range tests {
  1096  		test := test
  1097  		t.Run(test.branch, func(t *testing.T) {
  1098  			t.Parallel()
  1099  			client, mux, _ := setup(t)
  1100  
  1101  			renameBranchReq := "nn"
  1102  
  1103  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1104  				v := new(renameBranchRequest)
  1105  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1106  
  1107  				testMethod(t, r, "POST")
  1108  				want := &renameBranchRequest{NewName: renameBranchReq}
  1109  				if !cmp.Equal(v, want) {
  1110  					t.Errorf("Request body = %+v, want %+v", v, want)
  1111  				}
  1112  
  1113  				fmt.Fprint(w, `{"protected":true,"name":"nn"}`)
  1114  			})
  1115  
  1116  			ctx := context.Background()
  1117  			got, _, err := client.Repositories.RenameBranch(ctx, "o", "r", test.branch, renameBranchReq)
  1118  			if err != nil {
  1119  				t.Errorf("Repositories.RenameBranch returned error: %v", err)
  1120  			}
  1121  
  1122  			want := &Branch{Name: Ptr("nn"), Protected: Ptr(true)}
  1123  			if !cmp.Equal(got, want) {
  1124  				t.Errorf("Repositories.RenameBranch returned %+v, want %+v", got, want)
  1125  			}
  1126  
  1127  			const methodName = "RenameBranch"
  1128  			testBadOptions(t, methodName, func() (err error) {
  1129  				_, _, err = client.Repositories.RenameBranch(ctx, "\n", "\n", "\n", renameBranchReq)
  1130  				return err
  1131  			})
  1132  
  1133  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1134  				got, resp, err := client.Repositories.RenameBranch(ctx, "o", "r", test.branch, renameBranchReq)
  1135  				if got != nil {
  1136  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1137  				}
  1138  				return resp, err
  1139  			})
  1140  		})
  1141  	}
  1142  }
  1143  
  1144  func TestRepositoriesService_GetBranchProtection(t *testing.T) {
  1145  	t.Parallel()
  1146  	tests := []struct {
  1147  		branch               string
  1148  		urlPath              string
  1149  		enforceAdminsURLPath string
  1150  	}{
  1151  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection", enforceAdminsURLPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  1152  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection", enforceAdminsURLPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"},
  1153  	}
  1154  
  1155  	for _, test := range tests {
  1156  		test := test
  1157  		t.Run(test.branch, func(t *testing.T) {
  1158  			t.Parallel()
  1159  			client, mux, _ := setup(t)
  1160  
  1161  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1162  				testMethod(t, r, "GET")
  1163  				// TODO: remove custom Accept header when this API fully launches
  1164  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1165  				fmt.Fprintf(w, `{
  1166  						"required_status_checks":{
  1167  							"strict":true,
  1168  							"contexts":["continuous-integration"],
  1169  							"checks": [
  1170  								{
  1171  									"context": "continuous-integration",
  1172  									"app_id": null
  1173  								}
  1174  							]
  1175  						},
  1176  						"required_pull_request_reviews":{
  1177  							"dismissal_restrictions":{
  1178  								"users":[{
  1179  									"id":3,
  1180  									"login":"u"
  1181  								}],
  1182  								"teams":[{
  1183  									"id":4,
  1184  									"slug":"t"
  1185  								}],
  1186  								"apps":[{
  1187  									"id":5,
  1188  									"slug":"a"
  1189  								}]
  1190  							},
  1191  							"dismiss_stale_reviews":true,
  1192  							"require_code_owner_reviews":true,
  1193  							"require_last_push_approval":false,
  1194  							"required_approving_review_count":1
  1195  							},
  1196  							"enforce_admins":{
  1197  								"url":"%s",
  1198  								"enabled":true
  1199  							},
  1200  							"restrictions":{
  1201  								"users":[{"id":1,"login":"u"}],
  1202  								"teams":[{"id":2,"slug":"t"}],
  1203  								"apps":[{"id":3,"slug":"a"}]
  1204  							},
  1205  							"required_conversation_resolution": {
  1206  								"enabled": true
  1207  							},
  1208  							"block_creations": {
  1209  								"enabled": false
  1210  							},
  1211  							"lock_branch": {
  1212  								"enabled": false
  1213  							},
  1214  							"allow_fork_syncing": {
  1215  								"enabled": false
  1216  							}
  1217  						}`, test.enforceAdminsURLPath)
  1218  			})
  1219  
  1220  			ctx := context.Background()
  1221  			protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1222  			if err != nil {
  1223  				t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1224  			}
  1225  
  1226  			want := &Protection{
  1227  				RequiredStatusChecks: &RequiredStatusChecks{
  1228  					Strict:   true,
  1229  					Contexts: &[]string{"continuous-integration"},
  1230  					Checks: &[]*RequiredStatusCheck{
  1231  						{
  1232  							Context: "continuous-integration",
  1233  						},
  1234  					},
  1235  				},
  1236  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1237  					DismissStaleReviews: true,
  1238  					DismissalRestrictions: &DismissalRestrictions{
  1239  						Users: []*User{
  1240  							{Login: Ptr("u"), ID: Ptr(int64(3))},
  1241  						},
  1242  						Teams: []*Team{
  1243  							{Slug: Ptr("t"), ID: Ptr(int64(4))},
  1244  						},
  1245  						Apps: []*App{
  1246  							{Slug: Ptr("a"), ID: Ptr(int64(5))},
  1247  						},
  1248  					},
  1249  					RequireCodeOwnerReviews:      true,
  1250  					RequiredApprovingReviewCount: 1,
  1251  					RequireLastPushApproval:      false,
  1252  				},
  1253  				EnforceAdmins: &AdminEnforcement{
  1254  					URL:     Ptr(test.enforceAdminsURLPath),
  1255  					Enabled: true,
  1256  				},
  1257  				Restrictions: &BranchRestrictions{
  1258  					Users: []*User{
  1259  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1260  					},
  1261  					Teams: []*Team{
  1262  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1263  					},
  1264  					Apps: []*App{
  1265  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1266  					},
  1267  				},
  1268  				RequiredConversationResolution: &RequiredConversationResolution{
  1269  					Enabled: true,
  1270  				},
  1271  				BlockCreations: &BlockCreations{
  1272  					Enabled: Ptr(false),
  1273  				},
  1274  				LockBranch: &LockBranch{
  1275  					Enabled: Ptr(false),
  1276  				},
  1277  				AllowForkSyncing: &AllowForkSyncing{
  1278  					Enabled: Ptr(false),
  1279  				},
  1280  			}
  1281  			if !cmp.Equal(protection, want) {
  1282  				t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1283  			}
  1284  
  1285  			const methodName = "GetBranchProtection"
  1286  			testBadOptions(t, methodName, func() (err error) {
  1287  				_, _, err = client.Repositories.GetBranchProtection(ctx, "\n", "\n", "\n")
  1288  				return err
  1289  			})
  1290  
  1291  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1292  				got, resp, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1293  				if got != nil {
  1294  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1295  				}
  1296  				return resp, err
  1297  			})
  1298  		})
  1299  	}
  1300  }
  1301  
  1302  func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) {
  1303  	t.Parallel()
  1304  	client, mux, _ := setup(t)
  1305  
  1306  	tests := []struct {
  1307  		branch               string
  1308  		urlPath              string
  1309  		enforceAdminsURLPath string
  1310  	}{
  1311  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection", enforceAdminsURLPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  1312  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection", enforceAdminsURLPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"},
  1313  	}
  1314  
  1315  	for _, test := range tests {
  1316  		mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1317  			testMethod(t, r, "GET")
  1318  			// TODO: remove custom Accept header when this API fully launches
  1319  			testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1320  			fmt.Fprintf(w, `{
  1321  					"required_status_checks":{
  1322  						"strict":true,
  1323  						"contexts":["continuous-integration"],
  1324  						"checks": [
  1325  							{
  1326  								"context": "continuous-integration",
  1327  								"app_id": null
  1328  							}
  1329  						]
  1330  					},
  1331  					"required_pull_request_reviews":{
  1332  						"dismiss_stale_reviews":true,
  1333  						"require_code_owner_reviews":true,
  1334  						"required_approving_review_count":1
  1335  						},
  1336  						"enforce_admins":{
  1337  							"url":"%s",
  1338  							"enabled":true
  1339  						},
  1340  						"restrictions":{
  1341  							"users":[{"id":1,"login":"u"}],
  1342  							"teams":[{"id":2,"slug":"t"}]
  1343  						}
  1344  					}`, test.enforceAdminsURLPath)
  1345  		})
  1346  
  1347  		ctx := context.Background()
  1348  		protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1349  		if err != nil {
  1350  			t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1351  		}
  1352  
  1353  		want := &Protection{
  1354  			RequiredStatusChecks: &RequiredStatusChecks{
  1355  				Strict:   true,
  1356  				Contexts: &[]string{"continuous-integration"},
  1357  				Checks: &[]*RequiredStatusCheck{
  1358  					{
  1359  						Context: "continuous-integration",
  1360  					},
  1361  				},
  1362  			},
  1363  			RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1364  				DismissStaleReviews:          true,
  1365  				DismissalRestrictions:        nil,
  1366  				RequireCodeOwnerReviews:      true,
  1367  				RequiredApprovingReviewCount: 1,
  1368  			},
  1369  			EnforceAdmins: &AdminEnforcement{
  1370  				URL:     Ptr(test.enforceAdminsURLPath),
  1371  				Enabled: true,
  1372  			},
  1373  			Restrictions: &BranchRestrictions{
  1374  				Users: []*User{
  1375  					{Login: Ptr("u"), ID: Ptr(int64(1))},
  1376  				},
  1377  				Teams: []*Team{
  1378  					{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1379  				},
  1380  			},
  1381  		}
  1382  		if !cmp.Equal(protection, want) {
  1383  			t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1384  		}
  1385  	}
  1386  }
  1387  
  1388  func TestRepositoriesService_GetBranchProtection_branchNotProtected(t *testing.T) {
  1389  	t.Parallel()
  1390  	tests := []struct {
  1391  		branch  string
  1392  		urlPath string
  1393  	}{
  1394  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1395  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  1396  	}
  1397  
  1398  	for _, test := range tests {
  1399  		test := test
  1400  		t.Run(test.branch, func(t *testing.T) {
  1401  			t.Parallel()
  1402  			client, mux, _ := setup(t)
  1403  
  1404  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1405  				testMethod(t, r, "GET")
  1406  
  1407  				w.WriteHeader(http.StatusBadRequest)
  1408  				fmt.Fprintf(w, `{
  1409  					"message": %q,
  1410  					"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  1411  					}`, githubBranchNotProtected)
  1412  			})
  1413  
  1414  			ctx := context.Background()
  1415  			protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch)
  1416  
  1417  			if protection != nil {
  1418  				t.Errorf("Repositories.GetBranchProtection returned non-nil protection data")
  1419  			}
  1420  
  1421  			if err != ErrBranchNotProtected {
  1422  				t.Errorf("Repositories.GetBranchProtection returned an invalid error: %v", err)
  1423  			}
  1424  		})
  1425  	}
  1426  }
  1427  
  1428  func TestRepositoriesService_UpdateBranchProtection_Contexts(t *testing.T) {
  1429  	t.Parallel()
  1430  	tests := []struct {
  1431  		branch  string
  1432  		urlPath string
  1433  	}{
  1434  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1435  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  1436  	}
  1437  
  1438  	for _, test := range tests {
  1439  		test := test
  1440  		t.Run(test.branch, func(t *testing.T) {
  1441  			t.Parallel()
  1442  			client, mux, _ := setup(t)
  1443  
  1444  			input := &ProtectionRequest{
  1445  				RequiredStatusChecks: &RequiredStatusChecks{
  1446  					Strict:   true,
  1447  					Contexts: &[]string{"continuous-integration"},
  1448  				},
  1449  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1450  					DismissStaleReviews: true,
  1451  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1452  						Users: &[]string{"uu"},
  1453  						Teams: &[]string{"tt"},
  1454  						Apps:  &[]string{"aa"},
  1455  					},
  1456  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1457  						Users: []string{"uuu"},
  1458  						Teams: []string{"ttt"},
  1459  						Apps:  []string{"aaa"},
  1460  					},
  1461  				},
  1462  				Restrictions: &BranchRestrictionsRequest{
  1463  					Users: []string{"u"},
  1464  					Teams: []string{"t"},
  1465  					Apps:  []string{"a"},
  1466  				},
  1467  				BlockCreations:   Ptr(true),
  1468  				LockBranch:       Ptr(true),
  1469  				AllowForkSyncing: Ptr(true),
  1470  			}
  1471  
  1472  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1473  				v := new(ProtectionRequest)
  1474  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1475  
  1476  				testMethod(t, r, "PUT")
  1477  				if !cmp.Equal(v, input) {
  1478  					t.Errorf("Request body = %+v, want %+v", v, input)
  1479  				}
  1480  
  1481  				// TODO: remove custom Accept header when this API fully launches
  1482  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1483  				fmt.Fprintf(w, `{
  1484  					"required_status_checks":{
  1485  						"strict":true,
  1486  						"contexts":["continuous-integration"],
  1487  						"checks": [
  1488  							{
  1489  								"context": "continuous-integration",
  1490  								"app_id": null
  1491  							}
  1492  						]
  1493  					},
  1494  					"required_pull_request_reviews":{
  1495  						"dismissal_restrictions":{
  1496  							"users":[{
  1497  								"id":3,
  1498  								"login":"uu"
  1499  							}],
  1500  							"teams":[{
  1501  								"id":4,
  1502  								"slug":"tt"
  1503  							}],
  1504  							"apps":[{
  1505  								"id":5,
  1506  								"slug":"aa"
  1507  							}]
  1508  						},
  1509  						"dismiss_stale_reviews":true,
  1510  						"require_code_owner_reviews":true,
  1511  						"bypass_pull_request_allowances": {
  1512  							"users":[{"id":10,"login":"uuu"}],
  1513  							"teams":[{"id":20,"slug":"ttt"}],
  1514  							"apps":[{"id":30,"slug":"aaa"}]
  1515  						}
  1516  					},
  1517  					"restrictions":{
  1518  						"users":[{"id":1,"login":"u"}],
  1519  						"teams":[{"id":2,"slug":"t"}],
  1520  						"apps":[{"id":3,"slug":"a"}]
  1521  					},
  1522  					"block_creations": {
  1523  						"enabled": true
  1524  					},
  1525  					"lock_branch": {
  1526  						"enabled": true
  1527  					},
  1528  					"allow_fork_syncing": {
  1529  						"enabled": true
  1530  					}
  1531  				}`)
  1532  			})
  1533  
  1534  			ctx := context.Background()
  1535  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1536  			if err != nil {
  1537  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1538  			}
  1539  
  1540  			want := &Protection{
  1541  				RequiredStatusChecks: &RequiredStatusChecks{
  1542  					Strict:   true,
  1543  					Contexts: &[]string{"continuous-integration"},
  1544  					Checks: &[]*RequiredStatusCheck{
  1545  						{
  1546  							Context: "continuous-integration",
  1547  						},
  1548  					},
  1549  				},
  1550  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1551  					DismissStaleReviews: true,
  1552  					DismissalRestrictions: &DismissalRestrictions{
  1553  						Users: []*User{
  1554  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  1555  						},
  1556  						Teams: []*Team{
  1557  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  1558  						},
  1559  						Apps: []*App{
  1560  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  1561  						},
  1562  					},
  1563  					RequireCodeOwnerReviews: true,
  1564  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1565  						Users: []*User{
  1566  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  1567  						},
  1568  						Teams: []*Team{
  1569  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  1570  						},
  1571  						Apps: []*App{
  1572  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  1573  						},
  1574  					},
  1575  				},
  1576  				Restrictions: &BranchRestrictions{
  1577  					Users: []*User{
  1578  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1579  					},
  1580  					Teams: []*Team{
  1581  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1582  					},
  1583  					Apps: []*App{
  1584  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1585  					},
  1586  				},
  1587  				BlockCreations: &BlockCreations{
  1588  					Enabled: Ptr(true),
  1589  				},
  1590  				LockBranch: &LockBranch{
  1591  					Enabled: Ptr(true),
  1592  				},
  1593  				AllowForkSyncing: &AllowForkSyncing{
  1594  					Enabled: Ptr(true),
  1595  				},
  1596  			}
  1597  			if !cmp.Equal(protection, want) {
  1598  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1599  			}
  1600  
  1601  			const methodName = "UpdateBranchProtection"
  1602  			testBadOptions(t, methodName, func() (err error) {
  1603  				_, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input)
  1604  				return err
  1605  			})
  1606  
  1607  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1608  				got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1609  				if got != nil {
  1610  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1611  				}
  1612  				return resp, err
  1613  			})
  1614  		})
  1615  	}
  1616  }
  1617  
  1618  func TestRepositoriesService_UpdateBranchProtection_EmptyContexts(t *testing.T) {
  1619  	t.Parallel()
  1620  	tests := []struct {
  1621  		branch  string
  1622  		urlPath string
  1623  	}{
  1624  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1625  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  1626  	}
  1627  
  1628  	for _, test := range tests {
  1629  		test := test
  1630  		t.Run(test.branch, func(t *testing.T) {
  1631  			t.Parallel()
  1632  			client, mux, _ := setup(t)
  1633  
  1634  			input := &ProtectionRequest{
  1635  				RequiredStatusChecks: &RequiredStatusChecks{
  1636  					Strict:   true,
  1637  					Contexts: &[]string{},
  1638  				},
  1639  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1640  					DismissStaleReviews: true,
  1641  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1642  						Users: &[]string{"uu"},
  1643  						Teams: &[]string{"tt"},
  1644  						Apps:  &[]string{"aa"},
  1645  					},
  1646  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1647  						Users: []string{"uuu"},
  1648  						Teams: []string{"ttt"},
  1649  						Apps:  []string{"aaa"},
  1650  					},
  1651  				},
  1652  				Restrictions: &BranchRestrictionsRequest{
  1653  					Users: []string{"u"},
  1654  					Teams: []string{"t"},
  1655  					Apps:  []string{"a"},
  1656  				},
  1657  				BlockCreations:   Ptr(true),
  1658  				LockBranch:       Ptr(true),
  1659  				AllowForkSyncing: Ptr(true),
  1660  			}
  1661  
  1662  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1663  				v := new(ProtectionRequest)
  1664  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1665  
  1666  				testMethod(t, r, "PUT")
  1667  				if !cmp.Equal(v, input) {
  1668  					t.Errorf("Request body = %+v, want %+v", v, input)
  1669  				}
  1670  
  1671  				// TODO: remove custom Accept header when this API fully launches
  1672  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1673  				fmt.Fprintf(w, `{
  1674  					"required_status_checks":{
  1675  						"strict":true,
  1676  						"contexts":[],
  1677  						"checks": null
  1678  					},
  1679  					"required_pull_request_reviews":{
  1680  						"dismissal_restrictions":{
  1681  							"users":[{
  1682  								"id":3,
  1683  								"login":"uu"
  1684  							}],
  1685  							"teams":[{
  1686  								"id":4,
  1687  								"slug":"tt"
  1688  							}],
  1689  							"apps":[{
  1690  								"id":5,
  1691  								"slug":"aa"
  1692  							}]
  1693  						},
  1694  						"dismiss_stale_reviews":true,
  1695  						"require_code_owner_reviews":true,
  1696  						"bypass_pull_request_allowances": {
  1697  							"users":[{"id":10,"login":"uuu"}],
  1698  							"teams":[{"id":20,"slug":"ttt"}],
  1699  							"apps":[{"id":30,"slug":"aaa"}]
  1700  						}
  1701  					},
  1702  					"restrictions":{
  1703  						"users":[{"id":1,"login":"u"}],
  1704  						"teams":[{"id":2,"slug":"t"}],
  1705  						"apps":[{"id":3,"slug":"a"}]
  1706  					},
  1707  					"block_creations": {
  1708  						"enabled": true
  1709  					},
  1710  					"lock_branch": {
  1711  						"enabled": true
  1712  					},
  1713  					"allow_fork_syncing": {
  1714  						"enabled": true
  1715  					}
  1716  				}`)
  1717  			})
  1718  
  1719  			ctx := context.Background()
  1720  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1721  			if err != nil {
  1722  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1723  			}
  1724  
  1725  			want := &Protection{
  1726  				RequiredStatusChecks: &RequiredStatusChecks{
  1727  					Strict:   true,
  1728  					Contexts: &[]string{},
  1729  				},
  1730  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1731  					DismissStaleReviews: true,
  1732  					DismissalRestrictions: &DismissalRestrictions{
  1733  						Users: []*User{
  1734  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  1735  						},
  1736  						Teams: []*Team{
  1737  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  1738  						},
  1739  						Apps: []*App{
  1740  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  1741  						},
  1742  					},
  1743  					RequireCodeOwnerReviews: true,
  1744  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1745  						Users: []*User{
  1746  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  1747  						},
  1748  						Teams: []*Team{
  1749  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  1750  						},
  1751  						Apps: []*App{
  1752  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  1753  						},
  1754  					},
  1755  				},
  1756  				Restrictions: &BranchRestrictions{
  1757  					Users: []*User{
  1758  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1759  					},
  1760  					Teams: []*Team{
  1761  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1762  					},
  1763  					Apps: []*App{
  1764  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1765  					},
  1766  				},
  1767  				BlockCreations: &BlockCreations{
  1768  					Enabled: Ptr(true),
  1769  				},
  1770  				LockBranch: &LockBranch{
  1771  					Enabled: Ptr(true),
  1772  				},
  1773  				AllowForkSyncing: &AllowForkSyncing{
  1774  					Enabled: Ptr(true),
  1775  				},
  1776  			}
  1777  			if !cmp.Equal(protection, want) {
  1778  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1779  			}
  1780  
  1781  			const methodName = "UpdateBranchProtection"
  1782  			testBadOptions(t, methodName, func() (err error) {
  1783  				_, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input)
  1784  				return err
  1785  			})
  1786  
  1787  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1788  				got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1789  				if got != nil {
  1790  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1791  				}
  1792  				return resp, err
  1793  			})
  1794  		})
  1795  	}
  1796  }
  1797  
  1798  func TestRepositoriesService_UpdateBranchProtection_Checks(t *testing.T) {
  1799  	t.Parallel()
  1800  	tests := []struct {
  1801  		branch  string
  1802  		urlPath string
  1803  	}{
  1804  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1805  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  1806  	}
  1807  
  1808  	for _, test := range tests {
  1809  		test := test
  1810  		t.Run(test.branch, func(t *testing.T) {
  1811  			t.Parallel()
  1812  			client, mux, _ := setup(t)
  1813  
  1814  			input := &ProtectionRequest{
  1815  				RequiredStatusChecks: &RequiredStatusChecks{
  1816  					Strict: true,
  1817  					Checks: &[]*RequiredStatusCheck{
  1818  						{
  1819  							Context: "continuous-integration",
  1820  						},
  1821  					},
  1822  				},
  1823  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1824  					DismissStaleReviews: true,
  1825  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1826  						Users: &[]string{"uu"},
  1827  						Teams: &[]string{"tt"},
  1828  						Apps:  &[]string{"aa"},
  1829  					},
  1830  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1831  						Users: []string{"uuu"},
  1832  						Teams: []string{"ttt"},
  1833  						Apps:  []string{"aaa"},
  1834  					},
  1835  				},
  1836  				Restrictions: &BranchRestrictionsRequest{
  1837  					Users: []string{"u"},
  1838  					Teams: []string{"t"},
  1839  					Apps:  []string{"a"},
  1840  				},
  1841  			}
  1842  
  1843  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1844  				v := new(ProtectionRequest)
  1845  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  1846  
  1847  				testMethod(t, r, "PUT")
  1848  				if !cmp.Equal(v, input) {
  1849  					t.Errorf("Request body = %+v, want %+v", v, input)
  1850  				}
  1851  
  1852  				// TODO: remove custom Accept header when this API fully launches
  1853  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1854  				fmt.Fprintf(w, `{
  1855  					"required_status_checks":{
  1856  						"strict":true,
  1857  						"contexts":["continuous-integration"],
  1858  						"checks": [
  1859  							{
  1860  								"context": "continuous-integration",
  1861  								"app_id": null
  1862  							}
  1863  						]
  1864  					},
  1865  					"required_pull_request_reviews":{
  1866  						"dismissal_restrictions":{
  1867  							"users":[{
  1868  								"id":3,
  1869  								"login":"uu"
  1870  							}],
  1871  							"teams":[{
  1872  								"id":4,
  1873  								"slug":"tt"
  1874  							}],
  1875  							"apps":[{
  1876  								"id":5,
  1877  								"slug":"aa"
  1878  							}]
  1879  						},
  1880  						"dismiss_stale_reviews":true,
  1881  						"require_code_owner_reviews":true,
  1882  						"bypass_pull_request_allowances": {
  1883  							"users":[{"id":10,"login":"uuu"}],
  1884  							"teams":[{"id":20,"slug":"ttt"}],
  1885  							"apps":[{"id":30,"slug":"aaa"}]
  1886  						}
  1887  					},
  1888  					"restrictions":{
  1889  						"users":[{"id":1,"login":"u"}],
  1890  						"teams":[{"id":2,"slug":"t"}],
  1891  						"apps":[{"id":3,"slug":"a"}]
  1892  					}
  1893  				}`)
  1894  			})
  1895  
  1896  			ctx := context.Background()
  1897  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  1898  			if err != nil {
  1899  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1900  			}
  1901  
  1902  			want := &Protection{
  1903  				RequiredStatusChecks: &RequiredStatusChecks{
  1904  					Strict:   true,
  1905  					Contexts: &[]string{"continuous-integration"},
  1906  					Checks: &[]*RequiredStatusCheck{
  1907  						{
  1908  							Context: "continuous-integration",
  1909  						},
  1910  					},
  1911  				},
  1912  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1913  					DismissStaleReviews: true,
  1914  					DismissalRestrictions: &DismissalRestrictions{
  1915  						Users: []*User{
  1916  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  1917  						},
  1918  						Teams: []*Team{
  1919  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  1920  						},
  1921  						Apps: []*App{
  1922  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  1923  						},
  1924  					},
  1925  					RequireCodeOwnerReviews: true,
  1926  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1927  						Users: []*User{
  1928  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  1929  						},
  1930  						Teams: []*Team{
  1931  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  1932  						},
  1933  						Apps: []*App{
  1934  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  1935  						},
  1936  					},
  1937  				},
  1938  				Restrictions: &BranchRestrictions{
  1939  					Users: []*User{
  1940  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  1941  					},
  1942  					Teams: []*Team{
  1943  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  1944  					},
  1945  					Apps: []*App{
  1946  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  1947  					},
  1948  				},
  1949  			}
  1950  			if !cmp.Equal(protection, want) {
  1951  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1952  			}
  1953  		})
  1954  	}
  1955  }
  1956  
  1957  func TestRepositoriesService_UpdateBranchProtection_EmptyChecks(t *testing.T) {
  1958  	t.Parallel()
  1959  	tests := []struct {
  1960  		branch  string
  1961  		urlPath string
  1962  	}{
  1963  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  1964  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  1965  	}
  1966  
  1967  	for _, test := range tests {
  1968  		test := test
  1969  		t.Run(test.branch, func(t *testing.T) {
  1970  			t.Parallel()
  1971  			client, mux, _ := setup(t)
  1972  
  1973  			input := &ProtectionRequest{
  1974  				RequiredStatusChecks: &RequiredStatusChecks{
  1975  					Strict: true,
  1976  					Checks: &[]*RequiredStatusCheck{},
  1977  				},
  1978  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1979  					DismissStaleReviews: true,
  1980  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1981  						Users: &[]string{"uu"},
  1982  						Teams: &[]string{"tt"},
  1983  						Apps:  &[]string{"aa"},
  1984  					},
  1985  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1986  						Users: []string{"uuu"},
  1987  						Teams: []string{"ttt"},
  1988  						Apps:  []string{"aaa"},
  1989  					},
  1990  				},
  1991  				Restrictions: &BranchRestrictionsRequest{
  1992  					Users: []string{"u"},
  1993  					Teams: []string{"t"},
  1994  					Apps:  []string{"a"},
  1995  				},
  1996  			}
  1997  
  1998  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  1999  				v := new(ProtectionRequest)
  2000  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2001  
  2002  				testMethod(t, r, "PUT")
  2003  				if !cmp.Equal(v, input) {
  2004  					t.Errorf("Request body = %+v, want %+v", v, input)
  2005  				}
  2006  
  2007  				// TODO: remove custom Accept header when this API fully launches
  2008  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2009  				fmt.Fprintf(w, `{
  2010  					"required_status_checks":{
  2011  						"strict":true,
  2012  						"contexts":null,
  2013  						"checks": []
  2014  					},
  2015  					"required_pull_request_reviews":{
  2016  						"dismissal_restrictions":{
  2017  							"users":[{
  2018  								"id":3,
  2019  								"login":"uu"
  2020  							}],
  2021  							"teams":[{
  2022  								"id":4,
  2023  								"slug":"tt"
  2024  							}],
  2025  							"apps":[{
  2026  								"id":5,
  2027  								"slug":"aa"
  2028  							}]
  2029  						},
  2030  						"dismiss_stale_reviews":true,
  2031  						"require_code_owner_reviews":true,
  2032  						"bypass_pull_request_allowances": {
  2033  							"users":[{"id":10,"login":"uuu"}],
  2034  							"teams":[{"id":20,"slug":"ttt"}],
  2035  							"apps":[{"id":30,"slug":"aaa"}]
  2036  						}
  2037  					},
  2038  					"restrictions":{
  2039  						"users":[{"id":1,"login":"u"}],
  2040  						"teams":[{"id":2,"slug":"t"}],
  2041  						"apps":[{"id":3,"slug":"a"}]
  2042  					}
  2043  				}`)
  2044  			})
  2045  
  2046  			ctx := context.Background()
  2047  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  2048  			if err != nil {
  2049  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  2050  			}
  2051  
  2052  			want := &Protection{
  2053  				RequiredStatusChecks: &RequiredStatusChecks{
  2054  					Strict: true,
  2055  					Checks: &[]*RequiredStatusCheck{},
  2056  				},
  2057  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  2058  					DismissStaleReviews: true,
  2059  					DismissalRestrictions: &DismissalRestrictions{
  2060  						Users: []*User{
  2061  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  2062  						},
  2063  						Teams: []*Team{
  2064  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  2065  						},
  2066  						Apps: []*App{
  2067  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  2068  						},
  2069  					},
  2070  					RequireCodeOwnerReviews: true,
  2071  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  2072  						Users: []*User{
  2073  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  2074  						},
  2075  						Teams: []*Team{
  2076  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  2077  						},
  2078  						Apps: []*App{
  2079  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  2080  						},
  2081  					},
  2082  				},
  2083  				Restrictions: &BranchRestrictions{
  2084  					Users: []*User{
  2085  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2086  					},
  2087  					Teams: []*Team{
  2088  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2089  					},
  2090  					Apps: []*App{
  2091  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2092  					},
  2093  				},
  2094  			}
  2095  			if !cmp.Equal(protection, want) {
  2096  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  2097  			}
  2098  		})
  2099  	}
  2100  }
  2101  
  2102  func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T) {
  2103  	t.Parallel()
  2104  	tests := []struct {
  2105  		branch  string
  2106  		urlPath string
  2107  	}{
  2108  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  2109  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  2110  	}
  2111  
  2112  	for _, test := range tests {
  2113  		test := test
  2114  		t.Run(test.branch, func(t *testing.T) {
  2115  			t.Parallel()
  2116  			client, mux, _ := setup(t)
  2117  
  2118  			input := &ProtectionRequest{
  2119  				RequiredStatusChecks: &RequiredStatusChecks{
  2120  					Strict: true,
  2121  				},
  2122  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  2123  					DismissStaleReviews: true,
  2124  					DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  2125  						Users: &[]string{"uu"},
  2126  						Teams: &[]string{"tt"},
  2127  						Apps:  &[]string{"aa"},
  2128  					},
  2129  					BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  2130  						Users: []string{"uuu"},
  2131  						Teams: []string{"ttt"},
  2132  						Apps:  []string{"aaa"},
  2133  					},
  2134  				},
  2135  				Restrictions: &BranchRestrictionsRequest{
  2136  					Users: []string{"u"},
  2137  					Teams: []string{"t"},
  2138  					Apps:  []string{"a"},
  2139  				},
  2140  			}
  2141  
  2142  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2143  				v := new(ProtectionRequest)
  2144  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2145  
  2146  				testMethod(t, r, "PUT")
  2147  				if !cmp.Equal(v, input) {
  2148  					t.Errorf("Request body = %+v, want %+v", v, input)
  2149  				}
  2150  
  2151  				// TODO: remove custom Accept header when this API fully launches
  2152  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2153  				fmt.Fprintf(w, `{
  2154  					"required_status_checks":{
  2155  						"strict":true,
  2156  						"contexts":[]
  2157  					},
  2158  					"required_pull_request_reviews":{
  2159  						"dismissal_restrictions":{
  2160  							"users":[{
  2161  								"id":3,
  2162  								"login":"uu"
  2163  							}],
  2164  							"teams":[{
  2165  								"id":4,
  2166  								"slug":"tt"
  2167  							}],
  2168  							"apps":[{
  2169  								"id":5,
  2170  								"slug":"aa"
  2171  							}]
  2172  						},
  2173  						"dismiss_stale_reviews":true,
  2174  						"require_code_owner_reviews":true,
  2175  						"require_last_push_approval":false,
  2176  						"bypass_pull_request_allowances": {
  2177  							"users":[{"id":10,"login":"uuu"}],
  2178  							"teams":[{"id":20,"slug":"ttt"}],
  2179  							"apps":[{"id":30,"slug":"aaa"}]
  2180  						}
  2181  					},
  2182  					"restrictions":{
  2183  						"users":[{"id":1,"login":"u"}],
  2184  						"teams":[{"id":2,"slug":"t"}],
  2185  						"apps":[{"id":3,"slug":"a"}]
  2186  					}
  2187  				}`)
  2188  			})
  2189  
  2190  			ctx := context.Background()
  2191  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  2192  			if err != nil {
  2193  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  2194  			}
  2195  
  2196  			want := &Protection{
  2197  				RequiredStatusChecks: &RequiredStatusChecks{
  2198  					Strict:   true,
  2199  					Contexts: &[]string{},
  2200  				},
  2201  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  2202  					DismissStaleReviews: true,
  2203  					DismissalRestrictions: &DismissalRestrictions{
  2204  						Users: []*User{
  2205  							{Login: Ptr("uu"), ID: Ptr(int64(3))},
  2206  						},
  2207  						Teams: []*Team{
  2208  							{Slug: Ptr("tt"), ID: Ptr(int64(4))},
  2209  						},
  2210  						Apps: []*App{
  2211  							{Slug: Ptr("aa"), ID: Ptr(int64(5))},
  2212  						},
  2213  					},
  2214  					RequireCodeOwnerReviews: true,
  2215  					BypassPullRequestAllowances: &BypassPullRequestAllowances{
  2216  						Users: []*User{
  2217  							{Login: Ptr("uuu"), ID: Ptr(int64(10))},
  2218  						},
  2219  						Teams: []*Team{
  2220  							{Slug: Ptr("ttt"), ID: Ptr(int64(20))},
  2221  						},
  2222  						Apps: []*App{
  2223  							{Slug: Ptr("aaa"), ID: Ptr(int64(30))},
  2224  						},
  2225  					},
  2226  				},
  2227  				Restrictions: &BranchRestrictions{
  2228  					Users: []*User{
  2229  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2230  					},
  2231  					Teams: []*Team{
  2232  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2233  					},
  2234  					Apps: []*App{
  2235  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2236  					},
  2237  				},
  2238  			}
  2239  			if !cmp.Equal(protection, want) {
  2240  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  2241  			}
  2242  		})
  2243  	}
  2244  }
  2245  
  2246  func TestRepositoriesService_UpdateBranchProtection_RequireLastPushApproval(t *testing.T) {
  2247  	t.Parallel()
  2248  	tests := []struct {
  2249  		branch  string
  2250  		urlPath string
  2251  	}{
  2252  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  2253  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  2254  	}
  2255  
  2256  	for _, test := range tests {
  2257  		test := test
  2258  		t.Run(test.branch, func(t *testing.T) {
  2259  			t.Parallel()
  2260  			client, mux, _ := setup(t)
  2261  
  2262  			input := &ProtectionRequest{
  2263  				RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  2264  					RequireLastPushApproval: Ptr(true),
  2265  				},
  2266  			}
  2267  
  2268  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2269  				v := new(ProtectionRequest)
  2270  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2271  
  2272  				testMethod(t, r, "PUT")
  2273  				if !cmp.Equal(v, input) {
  2274  					t.Errorf("Request body = %+v, want %+v", v, input)
  2275  				}
  2276  
  2277  				fmt.Fprintf(w, `{
  2278  					"required_pull_request_reviews":{
  2279  						"require_last_push_approval":true
  2280  					}
  2281  				}`)
  2282  			})
  2283  
  2284  			ctx := context.Background()
  2285  			protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input)
  2286  			if err != nil {
  2287  				t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  2288  			}
  2289  
  2290  			want := &Protection{
  2291  				RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  2292  					RequireLastPushApproval: true,
  2293  				},
  2294  			}
  2295  			if !cmp.Equal(protection, want) {
  2296  				t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  2297  			}
  2298  		})
  2299  	}
  2300  }
  2301  
  2302  func TestRepositoriesService_RemoveBranchProtection(t *testing.T) {
  2303  	t.Parallel()
  2304  	tests := []struct {
  2305  		branch  string
  2306  		urlPath string
  2307  	}{
  2308  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection"},
  2309  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"},
  2310  	}
  2311  
  2312  	for _, test := range tests {
  2313  		test := test
  2314  		t.Run(test.branch, func(t *testing.T) {
  2315  			t.Parallel()
  2316  			client, mux, _ := setup(t)
  2317  
  2318  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2319  				testMethod(t, r, "DELETE")
  2320  				w.WriteHeader(http.StatusNoContent)
  2321  			})
  2322  
  2323  			ctx := context.Background()
  2324  			_, err := client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch)
  2325  			if err != nil {
  2326  				t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err)
  2327  			}
  2328  
  2329  			const methodName = "RemoveBranchProtection"
  2330  			testBadOptions(t, methodName, func() (err error) {
  2331  				_, err = client.Repositories.RemoveBranchProtection(ctx, "\n", "\n", "\n")
  2332  				return err
  2333  			})
  2334  
  2335  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2336  				return client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch)
  2337  			})
  2338  		})
  2339  	}
  2340  }
  2341  
  2342  func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) {
  2343  	t.Parallel()
  2344  	client, _, _ := setup(t)
  2345  
  2346  	ctx := context.Background()
  2347  	_, _, err := client.Repositories.ListLanguages(ctx, "%", "%")
  2348  	testURLParseError(t, err)
  2349  }
  2350  
  2351  func TestRepositoriesService_License(t *testing.T) {
  2352  	t.Parallel()
  2353  	client, mux, _ := setup(t)
  2354  
  2355  	mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) {
  2356  		testMethod(t, r, "GET")
  2357  		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}}`)
  2358  	})
  2359  
  2360  	ctx := context.Background()
  2361  	got, _, err := client.Repositories.License(ctx, "o", "r")
  2362  	if err != nil {
  2363  		t.Errorf("Repositories.License returned error: %v", err)
  2364  	}
  2365  
  2366  	want := &RepositoryLicense{
  2367  		Name: Ptr("LICENSE"),
  2368  		Path: Ptr("LICENSE"),
  2369  		License: &License{
  2370  			Name:     Ptr("MIT License"),
  2371  			Key:      Ptr("mit"),
  2372  			SPDXID:   Ptr("MIT"),
  2373  			URL:      Ptr("https://api.github.com/licenses/mit"),
  2374  			Featured: Ptr(true),
  2375  		},
  2376  	}
  2377  
  2378  	if !cmp.Equal(got, want) {
  2379  		t.Errorf("Repositories.License returned %+v, want %+v", got, want)
  2380  	}
  2381  
  2382  	const methodName = "License"
  2383  	testBadOptions(t, methodName, func() (err error) {
  2384  		_, _, err = client.Repositories.License(ctx, "\n", "\n")
  2385  		return err
  2386  	})
  2387  
  2388  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2389  		got, resp, err := client.Repositories.License(ctx, "o", "r")
  2390  		if got != nil {
  2391  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2392  		}
  2393  		return resp, err
  2394  	})
  2395  }
  2396  
  2397  func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) {
  2398  	t.Parallel()
  2399  	tests := []struct {
  2400  		branch  string
  2401  		urlPath string
  2402  	}{
  2403  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2404  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"},
  2405  	}
  2406  
  2407  	for _, test := range tests {
  2408  		test := test
  2409  		t.Run(test.branch, func(t *testing.T) {
  2410  			t.Parallel()
  2411  			client, mux, _ := setup(t)
  2412  
  2413  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2414  				testMethod(t, r, "GET")
  2415  				fmt.Fprint(w, `{
  2416  					"strict": true,
  2417  					"contexts": ["x","y","z"],
  2418  					"checks": [
  2419  						{
  2420  							"context": "x",
  2421  							"app_id": null
  2422  						},
  2423  						{
  2424  							"context": "y",
  2425  							"app_id": null
  2426  						},
  2427  						{
  2428  							"context": "z",
  2429  							"app_id": null
  2430  						}
  2431  					]
  2432  				}`)
  2433  			})
  2434  
  2435  			ctx := context.Background()
  2436  			checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch)
  2437  			if err != nil {
  2438  				t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err)
  2439  			}
  2440  
  2441  			want := &RequiredStatusChecks{
  2442  				Strict:   true,
  2443  				Contexts: &[]string{"x", "y", "z"},
  2444  				Checks: &[]*RequiredStatusCheck{
  2445  					{
  2446  						Context: "x",
  2447  					},
  2448  					{
  2449  						Context: "y",
  2450  					},
  2451  					{
  2452  						Context: "z",
  2453  					},
  2454  				},
  2455  			}
  2456  			if !cmp.Equal(checks, want) {
  2457  				t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want)
  2458  			}
  2459  
  2460  			const methodName = "GetRequiredStatusChecks"
  2461  			testBadOptions(t, methodName, func() (err error) {
  2462  				_, _, err = client.Repositories.GetRequiredStatusChecks(ctx, "\n", "\n", "\n")
  2463  				return err
  2464  			})
  2465  
  2466  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2467  				got, resp, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch)
  2468  				if got != nil {
  2469  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2470  				}
  2471  				return resp, err
  2472  			})
  2473  		})
  2474  	}
  2475  }
  2476  
  2477  func TestRepositoriesService_GetRequiredStatusChecks_branchNotProtected(t *testing.T) {
  2478  	t.Parallel()
  2479  	tests := []struct {
  2480  		branch  string
  2481  		urlPath string
  2482  	}{
  2483  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2484  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"},
  2485  	}
  2486  
  2487  	for _, test := range tests {
  2488  		test := test
  2489  		t.Run(test.branch, func(t *testing.T) {
  2490  			t.Parallel()
  2491  			client, mux, _ := setup(t)
  2492  
  2493  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2494  				testMethod(t, r, "GET")
  2495  
  2496  				w.WriteHeader(http.StatusBadRequest)
  2497  				fmt.Fprintf(w, `{
  2498  			"message": %q,
  2499  			"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  2500  			}`, githubBranchNotProtected)
  2501  			})
  2502  
  2503  			ctx := context.Background()
  2504  			checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch)
  2505  
  2506  			if checks != nil {
  2507  				t.Errorf("Repositories.GetRequiredStatusChecks returned non-nil status-checks data")
  2508  			}
  2509  
  2510  			if err != ErrBranchNotProtected {
  2511  				t.Errorf("Repositories.GetRequiredStatusChecks returned an invalid error: %v", err)
  2512  			}
  2513  		})
  2514  	}
  2515  }
  2516  
  2517  func TestRepositoriesService_UpdateRequiredStatusChecks_Contexts(t *testing.T) {
  2518  	t.Parallel()
  2519  	tests := []struct {
  2520  		branch  string
  2521  		urlPath string
  2522  	}{
  2523  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2524  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"},
  2525  	}
  2526  
  2527  	for _, test := range tests {
  2528  		test := test
  2529  		t.Run(test.branch, func(t *testing.T) {
  2530  			t.Parallel()
  2531  			client, mux, _ := setup(t)
  2532  
  2533  			input := &RequiredStatusChecksRequest{
  2534  				Strict:   Ptr(true),
  2535  				Contexts: []string{"continuous-integration"},
  2536  			}
  2537  
  2538  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2539  				v := new(RequiredStatusChecksRequest)
  2540  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2541  
  2542  				testMethod(t, r, "PATCH")
  2543  				if !cmp.Equal(v, input) {
  2544  					t.Errorf("Request body = %+v, want %+v", v, input)
  2545  				}
  2546  				testHeader(t, r, "Accept", mediaTypeV3)
  2547  				fmt.Fprintf(w, `{
  2548  					"strict":true,
  2549  					"contexts":["continuous-integration"],
  2550  					"checks": [
  2551  						{
  2552  							"context": "continuous-integration",
  2553  							"app_id": null
  2554  						}
  2555  					]
  2556  				}`)
  2557  			})
  2558  
  2559  			ctx := context.Background()
  2560  			statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input)
  2561  			if err != nil {
  2562  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err)
  2563  			}
  2564  
  2565  			want := &RequiredStatusChecks{
  2566  				Strict:   true,
  2567  				Contexts: &[]string{"continuous-integration"},
  2568  				Checks: &[]*RequiredStatusCheck{
  2569  					{
  2570  						Context: "continuous-integration",
  2571  					},
  2572  				},
  2573  			}
  2574  			if !cmp.Equal(statusChecks, want) {
  2575  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want)
  2576  			}
  2577  
  2578  			const methodName = "UpdateRequiredStatusChecks"
  2579  			testBadOptions(t, methodName, func() (err error) {
  2580  				_, _, err = client.Repositories.UpdateRequiredStatusChecks(ctx, "\n", "\n", "\n", input)
  2581  				return err
  2582  			})
  2583  
  2584  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2585  				got, resp, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input)
  2586  				if got != nil {
  2587  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2588  				}
  2589  				return resp, err
  2590  			})
  2591  		})
  2592  	}
  2593  }
  2594  
  2595  func TestRepositoriesService_UpdateRequiredStatusChecks_Checks(t *testing.T) {
  2596  	t.Parallel()
  2597  	tests := []struct {
  2598  		branch  string
  2599  		urlPath string
  2600  	}{
  2601  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2602  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"},
  2603  	}
  2604  
  2605  	for _, test := range tests {
  2606  		test := test
  2607  		t.Run(test.branch, func(t *testing.T) {
  2608  			t.Parallel()
  2609  			client, mux, _ := setup(t)
  2610  
  2611  			appID := int64(123)
  2612  			noAppID := int64(-1)
  2613  			input := &RequiredStatusChecksRequest{
  2614  				Strict: Ptr(true),
  2615  				Checks: []*RequiredStatusCheck{
  2616  					{
  2617  						Context: "continuous-integration",
  2618  					},
  2619  					{
  2620  						Context: "continuous-integration2",
  2621  						AppID:   &appID,
  2622  					},
  2623  					{
  2624  						Context: "continuous-integration3",
  2625  						AppID:   &noAppID,
  2626  					},
  2627  				},
  2628  			}
  2629  
  2630  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2631  				v := new(RequiredStatusChecksRequest)
  2632  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2633  
  2634  				testMethod(t, r, "PATCH")
  2635  				if !cmp.Equal(v, input) {
  2636  					t.Errorf("Request body = %+v, want %+v", v, input)
  2637  				}
  2638  				testHeader(t, r, "Accept", mediaTypeV3)
  2639  				fmt.Fprintf(w, `{
  2640  					"strict":true,
  2641  					"contexts":["continuous-integration"],
  2642  					"checks": [
  2643  						{
  2644  							"context": "continuous-integration",
  2645  							"app_id": null
  2646  						},
  2647  						{
  2648  							"context": "continuous-integration2",
  2649  							"app_id": 123
  2650  						},
  2651  						{
  2652  							"context": "continuous-integration3",
  2653  							"app_id": null
  2654  						}
  2655  					]
  2656  				}`)
  2657  			})
  2658  
  2659  			ctx := context.Background()
  2660  			statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input)
  2661  			if err != nil {
  2662  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err)
  2663  			}
  2664  
  2665  			want := &RequiredStatusChecks{
  2666  				Strict:   true,
  2667  				Contexts: &[]string{"continuous-integration"},
  2668  				Checks: &[]*RequiredStatusCheck{
  2669  					{
  2670  						Context: "continuous-integration",
  2671  					},
  2672  					{
  2673  						Context: "continuous-integration2",
  2674  						AppID:   &appID,
  2675  					},
  2676  					{
  2677  						Context: "continuous-integration3",
  2678  					},
  2679  				},
  2680  			}
  2681  			if !cmp.Equal(statusChecks, want) {
  2682  				t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want)
  2683  			}
  2684  		})
  2685  	}
  2686  }
  2687  
  2688  func TestRepositoriesService_RemoveRequiredStatusChecks(t *testing.T) {
  2689  	t.Parallel()
  2690  	tests := []struct {
  2691  		branch  string
  2692  		urlPath string
  2693  	}{
  2694  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"},
  2695  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"},
  2696  	}
  2697  
  2698  	for _, test := range tests {
  2699  		test := test
  2700  		t.Run(test.branch, func(t *testing.T) {
  2701  			t.Parallel()
  2702  			client, mux, _ := setup(t)
  2703  
  2704  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2705  				testMethod(t, r, "DELETE")
  2706  				testHeader(t, r, "Accept", mediaTypeV3)
  2707  				w.WriteHeader(http.StatusNoContent)
  2708  			})
  2709  
  2710  			ctx := context.Background()
  2711  			_, err := client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch)
  2712  			if err != nil {
  2713  				t.Errorf("Repositories.RemoveRequiredStatusChecks returned error: %v", err)
  2714  			}
  2715  
  2716  			const methodName = "RemoveRequiredStatusChecks"
  2717  			testBadOptions(t, methodName, func() (err error) {
  2718  				_, err = client.Repositories.RemoveRequiredStatusChecks(ctx, "\n", "\n", "\n")
  2719  				return err
  2720  			})
  2721  
  2722  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2723  				return client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch)
  2724  			})
  2725  		})
  2726  	}
  2727  }
  2728  
  2729  func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) {
  2730  	t.Parallel()
  2731  	tests := []struct {
  2732  		branch  string
  2733  		urlPath string
  2734  	}{
  2735  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"},
  2736  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks/contexts"},
  2737  	}
  2738  
  2739  	for _, test := range tests {
  2740  		test := test
  2741  		t.Run(test.branch, func(t *testing.T) {
  2742  			t.Parallel()
  2743  			client, mux, _ := setup(t)
  2744  
  2745  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2746  				testMethod(t, r, "GET")
  2747  				fmt.Fprint(w, `["x", "y", "z"]`)
  2748  			})
  2749  
  2750  			ctx := context.Background()
  2751  			contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch)
  2752  			if err != nil {
  2753  				t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err)
  2754  			}
  2755  
  2756  			want := []string{"x", "y", "z"}
  2757  			if !cmp.Equal(contexts, want) {
  2758  				t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want)
  2759  			}
  2760  
  2761  			const methodName = "ListRequiredStatusChecksContexts"
  2762  			testBadOptions(t, methodName, func() (err error) {
  2763  				_, _, err = client.Repositories.ListRequiredStatusChecksContexts(ctx, "\n", "\n", "\n")
  2764  				return err
  2765  			})
  2766  
  2767  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2768  				got, resp, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch)
  2769  				if got != nil {
  2770  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2771  				}
  2772  				return resp, err
  2773  			})
  2774  		})
  2775  	}
  2776  }
  2777  
  2778  func TestRepositoriesService_ListRequiredStatusChecksContexts_branchNotProtected(t *testing.T) {
  2779  	t.Parallel()
  2780  	tests := []struct {
  2781  		branch  string
  2782  		urlPath string
  2783  	}{
  2784  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"},
  2785  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks/contexts"},
  2786  	}
  2787  
  2788  	for _, test := range tests {
  2789  		test := test
  2790  		t.Run(test.branch, func(t *testing.T) {
  2791  			t.Parallel()
  2792  			client, mux, _ := setup(t)
  2793  
  2794  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2795  				testMethod(t, r, "GET")
  2796  
  2797  				w.WriteHeader(http.StatusBadRequest)
  2798  				fmt.Fprintf(w, `{
  2799  			"message": %q,
  2800  			"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  2801  			}`, githubBranchNotProtected)
  2802  			})
  2803  
  2804  			ctx := context.Background()
  2805  			contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch)
  2806  
  2807  			if contexts != nil {
  2808  				t.Errorf("Repositories.ListRequiredStatusChecksContexts returned non-nil contexts data")
  2809  			}
  2810  
  2811  			if err != ErrBranchNotProtected {
  2812  				t.Errorf("Repositories.ListRequiredStatusChecksContexts returned an invalid error: %v", err)
  2813  			}
  2814  		})
  2815  	}
  2816  }
  2817  
  2818  func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) {
  2819  	t.Parallel()
  2820  	tests := []struct {
  2821  		branch  string
  2822  		urlPath string
  2823  	}{
  2824  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  2825  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"},
  2826  	}
  2827  
  2828  	for _, test := range tests {
  2829  		test := test
  2830  		t.Run(test.branch, func(t *testing.T) {
  2831  			t.Parallel()
  2832  			client, mux, _ := setup(t)
  2833  
  2834  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2835  				testMethod(t, r, "GET")
  2836  				// TODO: remove custom Accept header when this API fully launches
  2837  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2838  				fmt.Fprintf(w, `{
  2839  			"dismissal_restrictions":{
  2840  				"users":[{"id":1,"login":"u"}],
  2841  				"teams":[{"id":2,"slug":"t"}],
  2842  				"apps":[{"id":3,"slug":"a"}]
  2843  			},
  2844  			"dismiss_stale_reviews":true,
  2845  			"require_code_owner_reviews":true,
  2846  			"required_approving_review_count":1
  2847  		}`)
  2848  			})
  2849  
  2850  			ctx := context.Background()
  2851  			enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  2852  			if err != nil {
  2853  				t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err)
  2854  			}
  2855  
  2856  			want := &PullRequestReviewsEnforcement{
  2857  				DismissStaleReviews: true,
  2858  				DismissalRestrictions: &DismissalRestrictions{
  2859  					Users: []*User{
  2860  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2861  					},
  2862  					Teams: []*Team{
  2863  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2864  					},
  2865  					Apps: []*App{
  2866  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2867  					},
  2868  				},
  2869  				RequireCodeOwnerReviews:      true,
  2870  				RequiredApprovingReviewCount: 1,
  2871  			}
  2872  
  2873  			if !cmp.Equal(enforcement, want) {
  2874  				t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  2875  			}
  2876  
  2877  			const methodName = "GetPullRequestReviewEnforcement"
  2878  			testBadOptions(t, methodName, func() (err error) {
  2879  				_, _, err = client.Repositories.GetPullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  2880  				return err
  2881  			})
  2882  
  2883  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2884  				got, resp, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  2885  				if got != nil {
  2886  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2887  				}
  2888  				return resp, err
  2889  			})
  2890  		})
  2891  	}
  2892  }
  2893  
  2894  func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) {
  2895  	t.Parallel()
  2896  	tests := []struct {
  2897  		branch  string
  2898  		urlPath string
  2899  	}{
  2900  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  2901  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"},
  2902  	}
  2903  
  2904  	for _, test := range tests {
  2905  		test := test
  2906  		t.Run(test.branch, func(t *testing.T) {
  2907  			t.Parallel()
  2908  			client, mux, _ := setup(t)
  2909  
  2910  			input := &PullRequestReviewsEnforcementUpdate{
  2911  				DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  2912  					Users: &[]string{"u"},
  2913  					Teams: &[]string{"t"},
  2914  					Apps:  &[]string{"a"},
  2915  				},
  2916  			}
  2917  
  2918  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  2919  				v := new(PullRequestReviewsEnforcementUpdate)
  2920  				assertNilError(t, json.NewDecoder(r.Body).Decode(v))
  2921  
  2922  				testMethod(t, r, "PATCH")
  2923  				if !cmp.Equal(v, input) {
  2924  					t.Errorf("Request body = %+v, want %+v", v, input)
  2925  				}
  2926  				// TODO: remove custom Accept header when this API fully launches
  2927  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2928  				fmt.Fprintf(w, `{
  2929  					"dismissal_restrictions":{
  2930  						"users":[{"id":1,"login":"u"}],
  2931  						"teams":[{"id":2,"slug":"t"}],
  2932  						"apps":[{"id":3,"slug":"a"}]
  2933  					},
  2934  					"dismiss_stale_reviews":true,
  2935  					"require_code_owner_reviews":true,
  2936  					"required_approving_review_count":3
  2937  				}`)
  2938  			})
  2939  
  2940  			ctx := context.Background()
  2941  			enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input)
  2942  			if err != nil {
  2943  				t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err)
  2944  			}
  2945  
  2946  			want := &PullRequestReviewsEnforcement{
  2947  				DismissStaleReviews: true,
  2948  				DismissalRestrictions: &DismissalRestrictions{
  2949  					Users: []*User{
  2950  						{Login: Ptr("u"), ID: Ptr(int64(1))},
  2951  					},
  2952  					Teams: []*Team{
  2953  						{Slug: Ptr("t"), ID: Ptr(int64(2))},
  2954  					},
  2955  					Apps: []*App{
  2956  						{Slug: Ptr("a"), ID: Ptr(int64(3))},
  2957  					},
  2958  				},
  2959  				RequireCodeOwnerReviews:      true,
  2960  				RequiredApprovingReviewCount: 3,
  2961  			}
  2962  			if !cmp.Equal(enforcement, want) {
  2963  				t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  2964  			}
  2965  
  2966  			const methodName = "UpdatePullRequestReviewEnforcement"
  2967  			testBadOptions(t, methodName, func() (err error) {
  2968  				_, _, err = client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "\n", "\n", "\n", input)
  2969  				return err
  2970  			})
  2971  
  2972  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2973  				got, resp, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input)
  2974  				if got != nil {
  2975  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2976  				}
  2977  				return resp, err
  2978  			})
  2979  		})
  2980  	}
  2981  }
  2982  
  2983  func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) {
  2984  	t.Parallel()
  2985  	tests := []struct {
  2986  		branch  string
  2987  		urlPath string
  2988  	}{
  2989  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  2990  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"},
  2991  	}
  2992  
  2993  	for _, test := range tests {
  2994  		test := test
  2995  		t.Run(test.branch, func(t *testing.T) {
  2996  			t.Parallel()
  2997  			client, mux, _ := setup(t)
  2998  
  2999  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3000  				testMethod(t, r, "PATCH")
  3001  				// TODO: remove custom Accept header when this API fully launches
  3002  				testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  3003  				testBody(t, r, `{"dismissal_restrictions":{}}`+"\n")
  3004  				fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`)
  3005  			})
  3006  
  3007  			ctx := context.Background()
  3008  			enforcement, _, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch)
  3009  			if err != nil {
  3010  				t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err)
  3011  			}
  3012  
  3013  			want := &PullRequestReviewsEnforcement{
  3014  				DismissStaleReviews:          true,
  3015  				DismissalRestrictions:        nil,
  3016  				RequireCodeOwnerReviews:      true,
  3017  				RequiredApprovingReviewCount: 1,
  3018  			}
  3019  			if !cmp.Equal(enforcement, want) {
  3020  				t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want)
  3021  			}
  3022  
  3023  			const methodName = "DisableDismissalRestrictions"
  3024  			testBadOptions(t, methodName, func() (err error) {
  3025  				_, _, err = client.Repositories.DisableDismissalRestrictions(ctx, "\n", "\n", "\n")
  3026  				return err
  3027  			})
  3028  
  3029  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3030  				got, resp, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch)
  3031  				if got != nil {
  3032  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3033  				}
  3034  				return resp, err
  3035  			})
  3036  		})
  3037  	}
  3038  }
  3039  
  3040  func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) {
  3041  	t.Parallel()
  3042  	tests := []struct {
  3043  		branch  string
  3044  		urlPath string
  3045  	}{
  3046  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"},
  3047  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"},
  3048  	}
  3049  
  3050  	for _, test := range tests {
  3051  		test := test
  3052  		t.Run(test.branch, func(t *testing.T) {
  3053  			t.Parallel()
  3054  			client, mux, _ := setup(t)
  3055  
  3056  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3057  				testMethod(t, r, "DELETE")
  3058  				w.WriteHeader(http.StatusNoContent)
  3059  			})
  3060  
  3061  			ctx := context.Background()
  3062  			_, err := client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  3063  			if err != nil {
  3064  				t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err)
  3065  			}
  3066  
  3067  			const methodName = "RemovePullRequestReviewEnforcement"
  3068  			testBadOptions(t, methodName, func() (err error) {
  3069  				_, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  3070  				return err
  3071  			})
  3072  
  3073  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3074  				return client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch)
  3075  			})
  3076  		})
  3077  	}
  3078  }
  3079  
  3080  func TestRepositoriesService_GetAdminEnforcement(t *testing.T) {
  3081  	t.Parallel()
  3082  	tests := []struct {
  3083  		branch  string
  3084  		urlPath string
  3085  	}{
  3086  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  3087  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"},
  3088  	}
  3089  
  3090  	for _, test := range tests {
  3091  		test := test
  3092  		t.Run(test.branch, func(t *testing.T) {
  3093  			t.Parallel()
  3094  			client, mux, _ := setup(t)
  3095  
  3096  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3097  				testMethod(t, r, "GET")
  3098  				fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  3099  			})
  3100  
  3101  			ctx := context.Background()
  3102  			enforcement, _, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch)
  3103  			if err != nil {
  3104  				t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err)
  3105  			}
  3106  
  3107  			want := &AdminEnforcement{
  3108  				URL:     Ptr("/repos/o/r/branches/b/protection/enforce_admins"),
  3109  				Enabled: true,
  3110  			}
  3111  
  3112  			if !cmp.Equal(enforcement, want) {
  3113  				t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want)
  3114  			}
  3115  
  3116  			const methodName = "GetAdminEnforcement"
  3117  			testBadOptions(t, methodName, func() (err error) {
  3118  				_, _, err = client.Repositories.GetAdminEnforcement(ctx, "\n", "\n", "\n")
  3119  				return err
  3120  			})
  3121  
  3122  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3123  				got, resp, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch)
  3124  				if got != nil {
  3125  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3126  				}
  3127  				return resp, err
  3128  			})
  3129  		})
  3130  	}
  3131  }
  3132  
  3133  func TestRepositoriesService_AddAdminEnforcement(t *testing.T) {
  3134  	t.Parallel()
  3135  	tests := []struct {
  3136  		branch  string
  3137  		urlPath string
  3138  	}{
  3139  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  3140  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"},
  3141  	}
  3142  
  3143  	for _, test := range tests {
  3144  		test := test
  3145  		t.Run(test.branch, func(t *testing.T) {
  3146  			t.Parallel()
  3147  			client, mux, _ := setup(t)
  3148  
  3149  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3150  				testMethod(t, r, "POST")
  3151  				fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  3152  			})
  3153  
  3154  			ctx := context.Background()
  3155  			enforcement, _, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch)
  3156  			if err != nil {
  3157  				t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err)
  3158  			}
  3159  
  3160  			want := &AdminEnforcement{
  3161  				URL:     Ptr("/repos/o/r/branches/b/protection/enforce_admins"),
  3162  				Enabled: true,
  3163  			}
  3164  			if !cmp.Equal(enforcement, want) {
  3165  				t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want)
  3166  			}
  3167  
  3168  			const methodName = "AddAdminEnforcement"
  3169  			testBadOptions(t, methodName, func() (err error) {
  3170  				_, _, err = client.Repositories.AddAdminEnforcement(ctx, "\n", "\n", "\n")
  3171  				return err
  3172  			})
  3173  
  3174  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3175  				got, resp, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch)
  3176  				if got != nil {
  3177  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3178  				}
  3179  				return resp, err
  3180  			})
  3181  		})
  3182  	}
  3183  }
  3184  
  3185  func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) {
  3186  	t.Parallel()
  3187  	tests := []struct {
  3188  		branch  string
  3189  		urlPath string
  3190  	}{
  3191  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"},
  3192  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"},
  3193  	}
  3194  
  3195  	for _, test := range tests {
  3196  		test := test
  3197  		t.Run(test.branch, func(t *testing.T) {
  3198  			t.Parallel()
  3199  			client, mux, _ := setup(t)
  3200  
  3201  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3202  				testMethod(t, r, "DELETE")
  3203  				w.WriteHeader(http.StatusNoContent)
  3204  			})
  3205  
  3206  			ctx := context.Background()
  3207  			_, err := client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch)
  3208  			if err != nil {
  3209  				t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err)
  3210  			}
  3211  
  3212  			const methodName = "RemoveAdminEnforcement"
  3213  			testBadOptions(t, methodName, func() (err error) {
  3214  				_, err = client.Repositories.RemoveAdminEnforcement(ctx, "\n", "\n", "\n")
  3215  				return err
  3216  			})
  3217  
  3218  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3219  				return client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch)
  3220  			})
  3221  		})
  3222  	}
  3223  }
  3224  
  3225  func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) {
  3226  	t.Parallel()
  3227  	tests := []struct {
  3228  		branch  string
  3229  		urlPath string
  3230  	}{
  3231  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"},
  3232  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"},
  3233  	}
  3234  
  3235  	for _, test := range tests {
  3236  		test := test
  3237  		t.Run(test.branch, func(t *testing.T) {
  3238  			t.Parallel()
  3239  			client, mux, _ := setup(t)
  3240  
  3241  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3242  				testMethod(t, r, "GET")
  3243  				testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  3244  				fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`)
  3245  			})
  3246  
  3247  			ctx := context.Background()
  3248  			signature, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch)
  3249  			if err != nil {
  3250  				t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err)
  3251  			}
  3252  
  3253  			want := &SignaturesProtectedBranch{
  3254  				URL:     Ptr("/repos/o/r/branches/b/protection/required_signatures"),
  3255  				Enabled: Ptr(false),
  3256  			}
  3257  
  3258  			if !cmp.Equal(signature, want) {
  3259  				t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want)
  3260  			}
  3261  
  3262  			const methodName = "GetSignaturesProtectedBranch"
  3263  			testBadOptions(t, methodName, func() (err error) {
  3264  				_, _, err = client.Repositories.GetSignaturesProtectedBranch(ctx, "\n", "\n", "\n")
  3265  				return err
  3266  			})
  3267  
  3268  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3269  				got, resp, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch)
  3270  				if got != nil {
  3271  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3272  				}
  3273  				return resp, err
  3274  			})
  3275  		})
  3276  	}
  3277  }
  3278  
  3279  func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) {
  3280  	t.Parallel()
  3281  	tests := []struct {
  3282  		branch  string
  3283  		urlPath string
  3284  	}{
  3285  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"},
  3286  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"},
  3287  	}
  3288  
  3289  	for _, test := range tests {
  3290  		test := test
  3291  		t.Run(test.branch, func(t *testing.T) {
  3292  			t.Parallel()
  3293  			client, mux, _ := setup(t)
  3294  
  3295  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3296  				testMethod(t, r, "POST")
  3297  				testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  3298  				fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`)
  3299  			})
  3300  
  3301  			ctx := context.Background()
  3302  			signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3303  			if err != nil {
  3304  				t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err)
  3305  			}
  3306  
  3307  			want := &SignaturesProtectedBranch{
  3308  				URL:     Ptr("/repos/o/r/branches/b/protection/required_signatures"),
  3309  				Enabled: Ptr(true),
  3310  			}
  3311  
  3312  			if !cmp.Equal(signature, want) {
  3313  				t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want)
  3314  			}
  3315  
  3316  			const methodName = "RequireSignaturesOnProtectedBranch"
  3317  			testBadOptions(t, methodName, func() (err error) {
  3318  				_, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  3319  				return err
  3320  			})
  3321  
  3322  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3323  				got, resp, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3324  				if got != nil {
  3325  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3326  				}
  3327  				return resp, err
  3328  			})
  3329  		})
  3330  	}
  3331  }
  3332  
  3333  func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) {
  3334  	t.Parallel()
  3335  	tests := []struct {
  3336  		branch  string
  3337  		urlPath string
  3338  	}{
  3339  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"},
  3340  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"},
  3341  	}
  3342  
  3343  	for _, test := range tests {
  3344  		test := test
  3345  		t.Run(test.branch, func(t *testing.T) {
  3346  			t.Parallel()
  3347  			client, mux, _ := setup(t)
  3348  
  3349  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3350  				testMethod(t, r, "DELETE")
  3351  				testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  3352  				w.WriteHeader(http.StatusNoContent)
  3353  			})
  3354  
  3355  			ctx := context.Background()
  3356  			_, err := client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3357  			if err != nil {
  3358  				t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err)
  3359  			}
  3360  
  3361  			const methodName = "OptionalSignaturesOnProtectedBranch"
  3362  			testBadOptions(t, methodName, func() (err error) {
  3363  				_, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  3364  				return err
  3365  			})
  3366  
  3367  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3368  				return client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch)
  3369  			})
  3370  		})
  3371  	}
  3372  }
  3373  
  3374  func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) {
  3375  	t.Parallel()
  3376  	req := PullRequestReviewsEnforcementRequest{}
  3377  
  3378  	got, err := json.Marshal(req)
  3379  	if err != nil {
  3380  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  3381  	}
  3382  
  3383  	want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  3384  	if want != string(got) {
  3385  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  3386  	}
  3387  
  3388  	req = PullRequestReviewsEnforcementRequest{
  3389  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{},
  3390  	}
  3391  
  3392  	got, err = json.Marshal(req)
  3393  	if err != nil {
  3394  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  3395  	}
  3396  
  3397  	want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  3398  	if want != string(got) {
  3399  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  3400  	}
  3401  
  3402  	req = PullRequestReviewsEnforcementRequest{
  3403  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  3404  			Users: &[]string{},
  3405  			Teams: &[]string{},
  3406  			Apps:  &[]string{},
  3407  		},
  3408  		RequireLastPushApproval: Ptr(true),
  3409  	}
  3410  
  3411  	got, err = json.Marshal(req)
  3412  	if err != nil {
  3413  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  3414  	}
  3415  
  3416  	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}`
  3417  	if want != string(got) {
  3418  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  3419  	}
  3420  }
  3421  
  3422  func TestRepositoriesService_ListAllTopics(t *testing.T) {
  3423  	t.Parallel()
  3424  	client, mux, _ := setup(t)
  3425  
  3426  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3427  		testMethod(t, r, "GET")
  3428  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3429  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  3430  	})
  3431  
  3432  	ctx := context.Background()
  3433  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  3434  	if err != nil {
  3435  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  3436  	}
  3437  
  3438  	want := []string{"go", "go-github", "github"}
  3439  	if !cmp.Equal(got, want) {
  3440  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  3441  	}
  3442  
  3443  	const methodName = "ListAllTopics"
  3444  	testBadOptions(t, methodName, func() (err error) {
  3445  		_, _, err = client.Repositories.ListAllTopics(ctx, "\n", "\n")
  3446  		return err
  3447  	})
  3448  
  3449  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3450  		got, resp, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  3451  		if got != nil {
  3452  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3453  		}
  3454  		return resp, err
  3455  	})
  3456  }
  3457  
  3458  func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) {
  3459  	t.Parallel()
  3460  	client, mux, _ := setup(t)
  3461  
  3462  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3463  		testMethod(t, r, "GET")
  3464  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3465  		fmt.Fprint(w, `{"names":[]}`)
  3466  	})
  3467  
  3468  	ctx := context.Background()
  3469  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  3470  	if err != nil {
  3471  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  3472  	}
  3473  
  3474  	want := []string{}
  3475  	if !cmp.Equal(got, want) {
  3476  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  3477  	}
  3478  }
  3479  
  3480  func TestRepositoriesService_ReplaceAllTopics(t *testing.T) {
  3481  	t.Parallel()
  3482  	client, mux, _ := setup(t)
  3483  
  3484  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3485  		testMethod(t, r, "PUT")
  3486  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3487  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  3488  	})
  3489  
  3490  	ctx := context.Background()
  3491  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  3492  	if err != nil {
  3493  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  3494  	}
  3495  
  3496  	want := []string{"go", "go-github", "github"}
  3497  	if !cmp.Equal(got, want) {
  3498  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  3499  	}
  3500  
  3501  	const methodName = "ReplaceAllTopics"
  3502  	testBadOptions(t, methodName, func() (err error) {
  3503  		_, _, err = client.Repositories.ReplaceAllTopics(ctx, "\n", "\n", []string{"\n", "\n", "\n"})
  3504  		return err
  3505  	})
  3506  
  3507  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3508  		got, resp, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  3509  		if got != nil {
  3510  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3511  		}
  3512  		return resp, err
  3513  	})
  3514  }
  3515  
  3516  func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) {
  3517  	t.Parallel()
  3518  	client, mux, _ := setup(t)
  3519  
  3520  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3521  		testMethod(t, r, "PUT")
  3522  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3523  		testBody(t, r, `{"names":[]}`+"\n")
  3524  		fmt.Fprint(w, `{"names":[]}`)
  3525  	})
  3526  
  3527  	ctx := context.Background()
  3528  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", nil)
  3529  	if err != nil {
  3530  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  3531  	}
  3532  
  3533  	want := []string{}
  3534  	if !cmp.Equal(got, want) {
  3535  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  3536  	}
  3537  }
  3538  
  3539  func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) {
  3540  	t.Parallel()
  3541  	client, mux, _ := setup(t)
  3542  
  3543  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  3544  		testMethod(t, r, "PUT")
  3545  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  3546  		testBody(t, r, `{"names":[]}`+"\n")
  3547  		fmt.Fprint(w, `{"names":[]}`)
  3548  	})
  3549  
  3550  	ctx := context.Background()
  3551  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{})
  3552  	if err != nil {
  3553  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  3554  	}
  3555  
  3556  	want := []string{}
  3557  	if !cmp.Equal(got, want) {
  3558  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  3559  	}
  3560  }
  3561  
  3562  func TestRepositoriesService_ListAppRestrictions(t *testing.T) {
  3563  	t.Parallel()
  3564  	tests := []struct {
  3565  		branch  string
  3566  		urlPath string
  3567  	}{
  3568  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3569  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"},
  3570  	}
  3571  
  3572  	for _, test := range tests {
  3573  		test := test
  3574  		t.Run(test.branch, func(t *testing.T) {
  3575  			t.Parallel()
  3576  			client, mux, _ := setup(t)
  3577  
  3578  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3579  				testMethod(t, r, "GET")
  3580  			})
  3581  
  3582  			ctx := context.Background()
  3583  			_, _, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch)
  3584  			if err != nil {
  3585  				t.Errorf("Repositories.ListAppRestrictions returned error: %v", err)
  3586  			}
  3587  
  3588  			const methodName = "ListAppRestrictions"
  3589  			testBadOptions(t, methodName, func() (err error) {
  3590  				_, _, err = client.Repositories.ListAppRestrictions(ctx, "\n", "\n", "\n")
  3591  				return err
  3592  			})
  3593  
  3594  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3595  				got, resp, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch)
  3596  				if got != nil {
  3597  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3598  				}
  3599  				return resp, err
  3600  			})
  3601  		})
  3602  	}
  3603  }
  3604  
  3605  func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) {
  3606  	t.Parallel()
  3607  	tests := []struct {
  3608  		branch  string
  3609  		urlPath string
  3610  	}{
  3611  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3612  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"},
  3613  	}
  3614  
  3615  	for _, test := range tests {
  3616  		test := test
  3617  		t.Run(test.branch, func(t *testing.T) {
  3618  			t.Parallel()
  3619  			client, mux, _ := setup(t)
  3620  
  3621  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3622  				testMethod(t, r, "PUT")
  3623  				fmt.Fprint(w, `[{
  3624  				"name": "octocat"
  3625  			}]`)
  3626  			})
  3627  			input := []string{"octocat"}
  3628  			ctx := context.Background()
  3629  			got, _, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input)
  3630  			if err != nil {
  3631  				t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err)
  3632  			}
  3633  			want := []*App{
  3634  				{Name: Ptr("octocat")},
  3635  			}
  3636  			if !cmp.Equal(got, want) {
  3637  				t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want)
  3638  			}
  3639  
  3640  			const methodName = "ReplaceAppRestrictions"
  3641  			testBadOptions(t, methodName, func() (err error) {
  3642  				_, _, err = client.Repositories.ReplaceAppRestrictions(ctx, "\n", "\n", "\n", input)
  3643  				return err
  3644  			})
  3645  
  3646  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3647  				got, resp, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input)
  3648  				if got != nil {
  3649  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3650  				}
  3651  				return resp, err
  3652  			})
  3653  		})
  3654  	}
  3655  }
  3656  
  3657  func TestRepositoriesService_AddAppRestrictions(t *testing.T) {
  3658  	t.Parallel()
  3659  	tests := []struct {
  3660  		branch  string
  3661  		urlPath string
  3662  	}{
  3663  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3664  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"},
  3665  	}
  3666  
  3667  	for _, test := range tests {
  3668  		test := test
  3669  		t.Run(test.branch, func(t *testing.T) {
  3670  			t.Parallel()
  3671  			client, mux, _ := setup(t)
  3672  
  3673  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3674  				testMethod(t, r, "POST")
  3675  				fmt.Fprint(w, `[{
  3676  				"name": "octocat"
  3677  			}]`)
  3678  			})
  3679  			input := []string{"octocat"}
  3680  			ctx := context.Background()
  3681  			got, _, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input)
  3682  			if err != nil {
  3683  				t.Errorf("Repositories.AddAppRestrictions returned error: %v", err)
  3684  			}
  3685  			want := []*App{
  3686  				{Name: Ptr("octocat")},
  3687  			}
  3688  			if !cmp.Equal(got, want) {
  3689  				t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want)
  3690  			}
  3691  
  3692  			const methodName = "AddAppRestrictions"
  3693  			testBadOptions(t, methodName, func() (err error) {
  3694  				_, _, err = client.Repositories.AddAppRestrictions(ctx, "\n", "\n", "\n", input)
  3695  				return err
  3696  			})
  3697  
  3698  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3699  				got, resp, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input)
  3700  				if got != nil {
  3701  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3702  				}
  3703  				return resp, err
  3704  			})
  3705  		})
  3706  	}
  3707  }
  3708  
  3709  func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) {
  3710  	t.Parallel()
  3711  	tests := []struct {
  3712  		branch  string
  3713  		urlPath string
  3714  	}{
  3715  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"},
  3716  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"},
  3717  	}
  3718  
  3719  	for _, test := range tests {
  3720  		test := test
  3721  		t.Run(test.branch, func(t *testing.T) {
  3722  			t.Parallel()
  3723  			client, mux, _ := setup(t)
  3724  
  3725  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3726  				testMethod(t, r, "DELETE")
  3727  				fmt.Fprint(w, `[]`)
  3728  			})
  3729  			input := []string{"octocat"}
  3730  			ctx := context.Background()
  3731  			got, _, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input)
  3732  			if err != nil {
  3733  				t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err)
  3734  			}
  3735  			want := []*App{}
  3736  			if !cmp.Equal(got, want) {
  3737  				t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want)
  3738  			}
  3739  
  3740  			const methodName = "RemoveAppRestrictions"
  3741  			testBadOptions(t, methodName, func() (err error) {
  3742  				_, _, err = client.Repositories.RemoveAppRestrictions(ctx, "\n", "\n", "\n", input)
  3743  				return err
  3744  			})
  3745  
  3746  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3747  				got, resp, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input)
  3748  				if got != nil {
  3749  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3750  				}
  3751  				return resp, err
  3752  			})
  3753  		})
  3754  	}
  3755  }
  3756  
  3757  func TestRepositoriesService_ListTeamRestrictions(t *testing.T) {
  3758  	t.Parallel()
  3759  	tests := []struct {
  3760  		branch  string
  3761  		urlPath string
  3762  	}{
  3763  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3764  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"},
  3765  	}
  3766  
  3767  	for _, test := range tests {
  3768  		test := test
  3769  		t.Run(test.branch, func(t *testing.T) {
  3770  			t.Parallel()
  3771  			client, mux, _ := setup(t)
  3772  
  3773  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3774  				testMethod(t, r, "GET")
  3775  			})
  3776  
  3777  			ctx := context.Background()
  3778  			_, _, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch)
  3779  			if err != nil {
  3780  				t.Errorf("Repositories.ListTeamRestrictions returned error: %v", err)
  3781  			}
  3782  
  3783  			const methodName = "ListTeamRestrictions"
  3784  			testBadOptions(t, methodName, func() (err error) {
  3785  				_, _, err = client.Repositories.ListTeamRestrictions(ctx, "\n", "\n", "\n")
  3786  				return err
  3787  			})
  3788  
  3789  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3790  				got, resp, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch)
  3791  				if got != nil {
  3792  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3793  				}
  3794  				return resp, err
  3795  			})
  3796  		})
  3797  	}
  3798  }
  3799  
  3800  func TestRepositoriesService_ReplaceTeamRestrictions(t *testing.T) {
  3801  	t.Parallel()
  3802  	tests := []struct {
  3803  		branch  string
  3804  		urlPath string
  3805  	}{
  3806  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3807  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"},
  3808  	}
  3809  
  3810  	for _, test := range tests {
  3811  		test := test
  3812  		t.Run(test.branch, func(t *testing.T) {
  3813  			t.Parallel()
  3814  			client, mux, _ := setup(t)
  3815  
  3816  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3817  				testMethod(t, r, "PUT")
  3818  				fmt.Fprint(w, `[{
  3819  				"name": "octocat"
  3820  			}]`)
  3821  			})
  3822  			input := []string{"octocat"}
  3823  			ctx := context.Background()
  3824  			got, _, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input)
  3825  			if err != nil {
  3826  				t.Errorf("Repositories.ReplaceTeamRestrictions returned error: %v", err)
  3827  			}
  3828  			want := []*Team{
  3829  				{Name: Ptr("octocat")},
  3830  			}
  3831  			if !cmp.Equal(got, want) {
  3832  				t.Errorf("Repositories.ReplaceTeamRestrictions returned %+v, want %+v", got, want)
  3833  			}
  3834  
  3835  			const methodName = "ReplaceTeamRestrictions"
  3836  			testBadOptions(t, methodName, func() (err error) {
  3837  				_, _, err = client.Repositories.ReplaceTeamRestrictions(ctx, "\n", "\n", "\n", input)
  3838  				return err
  3839  			})
  3840  
  3841  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3842  				got, resp, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input)
  3843  				if got != nil {
  3844  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3845  				}
  3846  				return resp, err
  3847  			})
  3848  		})
  3849  	}
  3850  }
  3851  
  3852  func TestRepositoriesService_AddTeamRestrictions(t *testing.T) {
  3853  	t.Parallel()
  3854  	tests := []struct {
  3855  		branch  string
  3856  		urlPath string
  3857  	}{
  3858  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3859  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"},
  3860  	}
  3861  
  3862  	for _, test := range tests {
  3863  		test := test
  3864  		t.Run(test.branch, func(t *testing.T) {
  3865  			t.Parallel()
  3866  			client, mux, _ := setup(t)
  3867  
  3868  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3869  				testMethod(t, r, "POST")
  3870  				fmt.Fprint(w, `[{
  3871  				"name": "octocat"
  3872  			}]`)
  3873  			})
  3874  			input := []string{"octocat"}
  3875  			ctx := context.Background()
  3876  			got, _, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input)
  3877  			if err != nil {
  3878  				t.Errorf("Repositories.AddTeamRestrictions returned error: %v", err)
  3879  			}
  3880  			want := []*Team{
  3881  				{Name: Ptr("octocat")},
  3882  			}
  3883  			if !cmp.Equal(got, want) {
  3884  				t.Errorf("Repositories.AddTeamRestrictions returned %+v, want %+v", got, want)
  3885  			}
  3886  
  3887  			const methodName = "AddTeamRestrictions"
  3888  			testBadOptions(t, methodName, func() (err error) {
  3889  				_, _, err = client.Repositories.AddTeamRestrictions(ctx, "\n", "\n", "\n", input)
  3890  				return err
  3891  			})
  3892  
  3893  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3894  				got, resp, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input)
  3895  				if got != nil {
  3896  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3897  				}
  3898  				return resp, err
  3899  			})
  3900  		})
  3901  	}
  3902  }
  3903  
  3904  func TestRepositoriesService_RemoveTeamRestrictions(t *testing.T) {
  3905  	t.Parallel()
  3906  	tests := []struct {
  3907  		branch  string
  3908  		urlPath string
  3909  	}{
  3910  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"},
  3911  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"},
  3912  	}
  3913  
  3914  	for _, test := range tests {
  3915  		test := test
  3916  		t.Run(test.branch, func(t *testing.T) {
  3917  			t.Parallel()
  3918  			client, mux, _ := setup(t)
  3919  
  3920  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3921  				testMethod(t, r, "DELETE")
  3922  				fmt.Fprint(w, `[]`)
  3923  			})
  3924  			input := []string{"octocat"}
  3925  			ctx := context.Background()
  3926  			got, _, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input)
  3927  			if err != nil {
  3928  				t.Errorf("Repositories.RemoveTeamRestrictions returned error: %v", err)
  3929  			}
  3930  			want := []*Team{}
  3931  			if !cmp.Equal(got, want) {
  3932  				t.Errorf("Repositories.RemoveTeamRestrictions returned %+v, want %+v", got, want)
  3933  			}
  3934  
  3935  			const methodName = "RemoveTeamRestrictions"
  3936  			testBadOptions(t, methodName, func() (err error) {
  3937  				_, _, err = client.Repositories.RemoveTeamRestrictions(ctx, "\n", "\n", "\n", input)
  3938  				return err
  3939  			})
  3940  
  3941  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3942  				got, resp, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input)
  3943  				if got != nil {
  3944  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3945  				}
  3946  				return resp, err
  3947  			})
  3948  		})
  3949  	}
  3950  }
  3951  
  3952  func TestRepositoriesService_ListUserRestrictions(t *testing.T) {
  3953  	t.Parallel()
  3954  	tests := []struct {
  3955  		branch  string
  3956  		urlPath string
  3957  	}{
  3958  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  3959  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"},
  3960  	}
  3961  
  3962  	for _, test := range tests {
  3963  		test := test
  3964  		t.Run(test.branch, func(t *testing.T) {
  3965  			t.Parallel()
  3966  			client, mux, _ := setup(t)
  3967  
  3968  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  3969  				testMethod(t, r, "GET")
  3970  			})
  3971  
  3972  			ctx := context.Background()
  3973  			_, _, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch)
  3974  			if err != nil {
  3975  				t.Errorf("Repositories.ListUserRestrictions returned error: %v", err)
  3976  			}
  3977  
  3978  			const methodName = "ListUserRestrictions"
  3979  			testBadOptions(t, methodName, func() (err error) {
  3980  				_, _, err = client.Repositories.ListUserRestrictions(ctx, "\n", "\n", "\n")
  3981  				return err
  3982  			})
  3983  
  3984  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  3985  				got, resp, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch)
  3986  				if got != nil {
  3987  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  3988  				}
  3989  				return resp, err
  3990  			})
  3991  		})
  3992  	}
  3993  }
  3994  
  3995  func TestRepositoriesService_ReplaceUserRestrictions(t *testing.T) {
  3996  	t.Parallel()
  3997  	tests := []struct {
  3998  		branch  string
  3999  		urlPath string
  4000  	}{
  4001  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  4002  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"},
  4003  	}
  4004  
  4005  	for _, test := range tests {
  4006  		test := test
  4007  		t.Run(test.branch, func(t *testing.T) {
  4008  			t.Parallel()
  4009  			client, mux, _ := setup(t)
  4010  
  4011  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  4012  				testMethod(t, r, "PUT")
  4013  				fmt.Fprint(w, `[{
  4014  				"name": "octocat"
  4015  			}]`)
  4016  			})
  4017  			input := []string{"octocat"}
  4018  			ctx := context.Background()
  4019  			got, _, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input)
  4020  			if err != nil {
  4021  				t.Errorf("Repositories.ReplaceUserRestrictions returned error: %v", err)
  4022  			}
  4023  			want := []*User{
  4024  				{Name: Ptr("octocat")},
  4025  			}
  4026  			if !cmp.Equal(got, want) {
  4027  				t.Errorf("Repositories.ReplaceUserRestrictions returned %+v, want %+v", got, want)
  4028  			}
  4029  
  4030  			const methodName = "ReplaceUserRestrictions"
  4031  			testBadOptions(t, methodName, func() (err error) {
  4032  				_, _, err = client.Repositories.ReplaceUserRestrictions(ctx, "\n", "\n", "\n", input)
  4033  				return err
  4034  			})
  4035  
  4036  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4037  				got, resp, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input)
  4038  				if got != nil {
  4039  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4040  				}
  4041  				return resp, err
  4042  			})
  4043  		})
  4044  	}
  4045  }
  4046  
  4047  func TestRepositoriesService_AddUserRestrictions(t *testing.T) {
  4048  	t.Parallel()
  4049  	tests := []struct {
  4050  		branch  string
  4051  		urlPath string
  4052  	}{
  4053  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  4054  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"},
  4055  	}
  4056  
  4057  	for _, test := range tests {
  4058  		test := test
  4059  		t.Run(test.branch, func(t *testing.T) {
  4060  			t.Parallel()
  4061  			client, mux, _ := setup(t)
  4062  
  4063  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  4064  				testMethod(t, r, "POST")
  4065  				fmt.Fprint(w, `[{
  4066  				"name": "octocat"
  4067  			}]`)
  4068  			})
  4069  			input := []string{"octocat"}
  4070  			ctx := context.Background()
  4071  			got, _, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input)
  4072  			if err != nil {
  4073  				t.Errorf("Repositories.AddUserRestrictions returned error: %v", err)
  4074  			}
  4075  			want := []*User{
  4076  				{Name: Ptr("octocat")},
  4077  			}
  4078  			if !cmp.Equal(got, want) {
  4079  				t.Errorf("Repositories.AddUserRestrictions returned %+v, want %+v", got, want)
  4080  			}
  4081  
  4082  			const methodName = "AddUserRestrictions"
  4083  			testBadOptions(t, methodName, func() (err error) {
  4084  				_, _, err = client.Repositories.AddUserRestrictions(ctx, "\n", "\n", "\n", input)
  4085  				return err
  4086  			})
  4087  
  4088  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4089  				got, resp, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input)
  4090  				if got != nil {
  4091  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4092  				}
  4093  				return resp, err
  4094  			})
  4095  		})
  4096  	}
  4097  }
  4098  
  4099  func TestRepositoriesService_RemoveUserRestrictions(t *testing.T) {
  4100  	t.Parallel()
  4101  	tests := []struct {
  4102  		branch  string
  4103  		urlPath string
  4104  	}{
  4105  		{branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"},
  4106  		{branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"},
  4107  	}
  4108  
  4109  	for _, test := range tests {
  4110  		test := test
  4111  		t.Run(test.branch, func(t *testing.T) {
  4112  			t.Parallel()
  4113  			client, mux, _ := setup(t)
  4114  
  4115  			mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) {
  4116  				testMethod(t, r, "DELETE")
  4117  				fmt.Fprint(w, `[]`)
  4118  			})
  4119  			input := []string{"octocat"}
  4120  			ctx := context.Background()
  4121  			got, _, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input)
  4122  			if err != nil {
  4123  				t.Errorf("Repositories.RemoveUserRestrictions returned error: %v", err)
  4124  			}
  4125  			want := []*User{}
  4126  			if !cmp.Equal(got, want) {
  4127  				t.Errorf("Repositories.RemoveUserRestrictions returned %+v, want %+v", got, want)
  4128  			}
  4129  
  4130  			const methodName = "RemoveUserRestrictions"
  4131  			testBadOptions(t, methodName, func() (err error) {
  4132  				_, _, err = client.Repositories.RemoveUserRestrictions(ctx, "\n", "\n", "\n", input)
  4133  				return err
  4134  			})
  4135  
  4136  			testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4137  				got, resp, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input)
  4138  				if got != nil {
  4139  					t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4140  				}
  4141  				return resp, err
  4142  			})
  4143  		})
  4144  	}
  4145  }
  4146  
  4147  func TestRepositoriesService_Transfer(t *testing.T) {
  4148  	t.Parallel()
  4149  	client, mux, _ := setup(t)
  4150  
  4151  	input := TransferRequest{NewOwner: "a", NewName: Ptr("b"), TeamID: []int64{123}}
  4152  
  4153  	mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) {
  4154  		var v TransferRequest
  4155  		assertNilError(t, json.NewDecoder(r.Body).Decode(&v))
  4156  
  4157  		testMethod(t, r, "POST")
  4158  		if !cmp.Equal(v, input) {
  4159  			t.Errorf("Request body = %+v, want %+v", v, input)
  4160  		}
  4161  
  4162  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  4163  	})
  4164  
  4165  	ctx := context.Background()
  4166  	got, _, err := client.Repositories.Transfer(ctx, "o", "r", input)
  4167  	if err != nil {
  4168  		t.Errorf("Repositories.Transfer returned error: %v", err)
  4169  	}
  4170  
  4171  	want := &Repository{Owner: &User{Login: Ptr("a")}}
  4172  	if !cmp.Equal(got, want) {
  4173  		t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want)
  4174  	}
  4175  
  4176  	const methodName = "Transfer"
  4177  	testBadOptions(t, methodName, func() (err error) {
  4178  		_, _, err = client.Repositories.Transfer(ctx, "\n", "\n", input)
  4179  		return err
  4180  	})
  4181  
  4182  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4183  		got, resp, err := client.Repositories.Transfer(ctx, "o", "r", input)
  4184  		if got != nil {
  4185  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4186  		}
  4187  		return resp, err
  4188  	})
  4189  }
  4190  
  4191  func TestRepositoriesService_Dispatch(t *testing.T) {
  4192  	t.Parallel()
  4193  	client, mux, _ := setup(t)
  4194  
  4195  	var input DispatchRequestOptions
  4196  
  4197  	mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) {
  4198  		var v DispatchRequestOptions
  4199  		assertNilError(t, json.NewDecoder(r.Body).Decode(&v))
  4200  
  4201  		testMethod(t, r, "POST")
  4202  		if !cmp.Equal(v, input) {
  4203  			t.Errorf("Request body = %+v, want %+v", v, input)
  4204  		}
  4205  
  4206  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  4207  	})
  4208  
  4209  	ctx := context.Background()
  4210  
  4211  	testCases := []interface{}{
  4212  		nil,
  4213  		struct {
  4214  			Foo string
  4215  		}{
  4216  			Foo: "test",
  4217  		},
  4218  		struct {
  4219  			Bar int
  4220  		}{
  4221  			Bar: 42,
  4222  		},
  4223  		struct {
  4224  			Foo string
  4225  			Bar int
  4226  			Baz bool
  4227  		}{
  4228  			Foo: "test",
  4229  			Bar: 42,
  4230  			Baz: false,
  4231  		},
  4232  	}
  4233  
  4234  	for _, tc := range testCases {
  4235  		if tc == nil {
  4236  			input = DispatchRequestOptions{EventType: "go"}
  4237  		} else {
  4238  			bytes, _ := json.Marshal(tc)
  4239  			payload := json.RawMessage(bytes)
  4240  			input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload}
  4241  		}
  4242  
  4243  		got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  4244  		if err != nil {
  4245  			t.Errorf("Repositories.Dispatch returned error: %v", err)
  4246  		}
  4247  
  4248  		want := &Repository{Owner: &User{Login: Ptr("a")}}
  4249  		if !cmp.Equal(got, want) {
  4250  			t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want)
  4251  		}
  4252  	}
  4253  
  4254  	const methodName = "Dispatch"
  4255  	testBadOptions(t, methodName, func() (err error) {
  4256  		_, _, err = client.Repositories.Dispatch(ctx, "\n", "\n", input)
  4257  		return err
  4258  	})
  4259  
  4260  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4261  		got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  4262  		if got != nil {
  4263  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  4264  		}
  4265  		return resp, err
  4266  	})
  4267  }
  4268  
  4269  func TestAdvancedSecurity_Marshal(t *testing.T) {
  4270  	t.Parallel()
  4271  	testJSONMarshal(t, &AdvancedSecurity{}, "{}")
  4272  
  4273  	u := &AdvancedSecurity{
  4274  		Status: Ptr("status"),
  4275  	}
  4276  
  4277  	want := `{
  4278  		"status": "status"
  4279  	}`
  4280  
  4281  	testJSONMarshal(t, u, want)
  4282  }
  4283  
  4284  func TestAuthorizedActorsOnly_Marshal(t *testing.T) {
  4285  	t.Parallel()
  4286  	testJSONMarshal(t, &AuthorizedActorsOnly{}, "{}")
  4287  
  4288  	u := &AuthorizedActorsOnly{
  4289  		From: Ptr(true),
  4290  	}
  4291  
  4292  	want := `{
  4293  		"from" : true
  4294  	}`
  4295  
  4296  	testJSONMarshal(t, u, want)
  4297  }
  4298  
  4299  func TestDispatchRequestOptions_Marshal(t *testing.T) {
  4300  	t.Parallel()
  4301  	testJSONMarshal(t, &DispatchRequestOptions{}, "{}")
  4302  
  4303  	cp := json.RawMessage(`{"testKey":"testValue"}`)
  4304  	u := &DispatchRequestOptions{
  4305  		EventType:     "test_event_type",
  4306  		ClientPayload: &cp,
  4307  	}
  4308  
  4309  	want := `{
  4310  		"event_type": "test_event_type",
  4311  		"client_payload": {
  4312  		  "testKey": "testValue"
  4313  		}
  4314  	  }`
  4315  
  4316  	testJSONMarshal(t, u, want)
  4317  }
  4318  
  4319  func TestTransferRequest_Marshal(t *testing.T) {
  4320  	t.Parallel()
  4321  	testJSONMarshal(t, &TransferRequest{}, "{}")
  4322  
  4323  	u := &TransferRequest{
  4324  		NewOwner: "testOwner",
  4325  		NewName:  Ptr("testName"),
  4326  		TeamID:   []int64{1, 2},
  4327  	}
  4328  
  4329  	want := `{
  4330  		"new_owner": "testOwner",
  4331  		"new_name": "testName",
  4332  		"team_ids": [1,2]
  4333  	}`
  4334  
  4335  	testJSONMarshal(t, u, want)
  4336  }
  4337  
  4338  func TestSignaturesProtectedBranch_Marshal(t *testing.T) {
  4339  	t.Parallel()
  4340  	testJSONMarshal(t, &SignaturesProtectedBranch{}, "{}")
  4341  
  4342  	u := &SignaturesProtectedBranch{
  4343  		URL:     Ptr("https://www.testURL.in"),
  4344  		Enabled: Ptr(false),
  4345  	}
  4346  
  4347  	want := `{
  4348  		"url": "https://www.testURL.in",
  4349  		"enabled": false
  4350  	}`
  4351  
  4352  	testJSONMarshal(t, u, want)
  4353  
  4354  	u2 := &SignaturesProtectedBranch{
  4355  		URL:     Ptr("testURL"),
  4356  		Enabled: Ptr(true),
  4357  	}
  4358  
  4359  	want2 := `{
  4360  		"url": "testURL",
  4361  		"enabled": true
  4362  	}`
  4363  
  4364  	testJSONMarshal(t, u2, want2)
  4365  }
  4366  
  4367  func TestDismissalRestrictionsRequest_Marshal(t *testing.T) {
  4368  	t.Parallel()
  4369  	testJSONMarshal(t, &DismissalRestrictionsRequest{}, "{}")
  4370  
  4371  	u := &DismissalRestrictionsRequest{
  4372  		Users: &[]string{"user1", "user2"},
  4373  		Teams: &[]string{"team1", "team2"},
  4374  		Apps:  &[]string{"app1", "app2"},
  4375  	}
  4376  
  4377  	want := `{
  4378  		"users": ["user1","user2"],
  4379  		"teams": ["team1","team2"],
  4380  		"apps": ["app1","app2"]
  4381  	}`
  4382  
  4383  	testJSONMarshal(t, u, want)
  4384  }
  4385  
  4386  func TestAdminEnforcement_Marshal(t *testing.T) {
  4387  	t.Parallel()
  4388  	testJSONMarshal(t, &AdminEnforcement{}, "{}")
  4389  
  4390  	u := &AdminEnforcement{
  4391  		URL:     Ptr("https://www.test-url.in"),
  4392  		Enabled: false,
  4393  	}
  4394  
  4395  	want := `{
  4396  		"url": "https://www.test-url.in",
  4397  		"enabled": false
  4398  	}`
  4399  
  4400  	testJSONMarshal(t, u, want)
  4401  }
  4402  
  4403  func TestPullRequestReviewsEnforcementUpdate_Marshal(t *testing.T) {
  4404  	t.Parallel()
  4405  	testJSONMarshal(t, &PullRequestReviewsEnforcementUpdate{}, "{}")
  4406  
  4407  	u := &PullRequestReviewsEnforcementUpdate{
  4408  		BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  4409  			Users: []string{"user1", "user2"},
  4410  			Teams: []string{"team1", "team2"},
  4411  			Apps:  []string{"app1", "app2"},
  4412  		},
  4413  		DismissStaleReviews:          Ptr(false),
  4414  		RequireCodeOwnerReviews:      Ptr(true),
  4415  		RequiredApprovingReviewCount: 2,
  4416  	}
  4417  
  4418  	want := `{
  4419  		"bypass_pull_request_allowances": {
  4420  			"users": ["user1","user2"],
  4421  			"teams": ["team1","team2"],
  4422  			"apps": ["app1","app2"]
  4423  		},
  4424  		"dismiss_stale_reviews": false,
  4425  		"require_code_owner_reviews": true,
  4426  		"required_approving_review_count": 2
  4427  	}`
  4428  
  4429  	testJSONMarshal(t, u, want)
  4430  }
  4431  
  4432  func TestRequiredStatusCheck_Marshal(t *testing.T) {
  4433  	t.Parallel()
  4434  	testJSONMarshal(t, &RequiredStatusCheck{}, "{}")
  4435  
  4436  	u := &RequiredStatusCheck{
  4437  		Context: "ctx",
  4438  		AppID:   Ptr(int64(1)),
  4439  	}
  4440  
  4441  	want := `{
  4442  		"context": "ctx",
  4443  		"app_id": 1
  4444  	}`
  4445  
  4446  	testJSONMarshal(t, u, want)
  4447  }
  4448  
  4449  func TestRepositoryTag_Marshal(t *testing.T) {
  4450  	t.Parallel()
  4451  	testJSONMarshal(t, &RepositoryTag{}, "{}")
  4452  
  4453  	u := &RepositoryTag{
  4454  		Name: Ptr("v0.1"),
  4455  		Commit: &Commit{
  4456  			SHA: Ptr("sha"),
  4457  			URL: Ptr("url"),
  4458  		},
  4459  		ZipballURL: Ptr("zball"),
  4460  		TarballURL: Ptr("tball"),
  4461  	}
  4462  
  4463  	want := `{
  4464  		"name": "v0.1",
  4465  		"commit": {
  4466  			"sha": "sha",
  4467  			"url": "url"
  4468  		},
  4469  		"zipball_url": "zball",
  4470  		"tarball_url": "tball"
  4471  	}`
  4472  
  4473  	testJSONMarshal(t, u, want)
  4474  }
  4475  
  4476  func TestRepositoriesService_EnablePrivateReporting(t *testing.T) {
  4477  	t.Parallel()
  4478  	client, mux, _ := setup(t)
  4479  
  4480  	mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) {
  4481  		testMethod(t, r, "PUT")
  4482  		w.WriteHeader(http.StatusNoContent)
  4483  	})
  4484  
  4485  	ctx := context.Background()
  4486  	_, err := client.Repositories.EnablePrivateReporting(ctx, "owner", "repo")
  4487  	if err != nil {
  4488  		t.Errorf("Repositories.EnablePrivateReporting returned error: %v", err)
  4489  	}
  4490  
  4491  	const methodName = "EnablePrivateReporting"
  4492  	testBadOptions(t, methodName, func() (err error) {
  4493  		_, err = client.Repositories.EnablePrivateReporting(ctx, "\n", "\n")
  4494  		return err
  4495  	})
  4496  
  4497  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4498  		return client.Repositories.EnablePrivateReporting(ctx, "owner", "repo")
  4499  	})
  4500  }
  4501  
  4502  func TestRepositoriesService_DisablePrivateReporting(t *testing.T) {
  4503  	t.Parallel()
  4504  	client, mux, _ := setup(t)
  4505  
  4506  	mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) {
  4507  		testMethod(t, r, "DELETE")
  4508  		w.WriteHeader(http.StatusNoContent)
  4509  	})
  4510  
  4511  	ctx := context.Background()
  4512  	_, err := client.Repositories.DisablePrivateReporting(ctx, "owner", "repo")
  4513  	if err != nil {
  4514  		t.Errorf("Repositories.DisablePrivateReporting returned error: %v", err)
  4515  	}
  4516  
  4517  	const methodName = "DisablePrivateReporting"
  4518  	testBadOptions(t, methodName, func() (err error) {
  4519  		_, err = client.Repositories.DisablePrivateReporting(ctx, "\n", "\n")
  4520  		return err
  4521  	})
  4522  
  4523  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4524  		return client.Repositories.DisablePrivateReporting(ctx, "owner", "repo")
  4525  	})
  4526  }
  4527  
  4528  func TestRepositoriesService_IsPrivateReportingEnabled(t *testing.T) {
  4529  	t.Parallel()
  4530  	client, mux, _ := setup(t)
  4531  
  4532  	mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) {
  4533  		testMethod(t, r, "GET")
  4534  		fmt.Fprint(w, `{"enabled": true}`)
  4535  	})
  4536  
  4537  	ctx := context.Background()
  4538  	enabled, _, err := client.Repositories.IsPrivateReportingEnabled(ctx, "owner", "repo")
  4539  	if err != nil {
  4540  		t.Errorf("Repositories.IsPrivateReportingEnabled returned error: %v", err)
  4541  	}
  4542  	if want := true; enabled != want {
  4543  		t.Errorf("Repositories.IsPrivateReportingEnabled returned %+v, want %+v", enabled, want)
  4544  	}
  4545  
  4546  	const methodName = "IsPrivateReportingEnabled"
  4547  	testBadOptions(t, methodName, func() (err error) {
  4548  		_, _, err = client.Repositories.IsPrivateReportingEnabled(ctx, "\n", "\n")
  4549  		return err
  4550  	})
  4551  
  4552  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  4553  		got, resp, err := client.Repositories.IsPrivateReportingEnabled(ctx, "owner", "repo")
  4554  		if got {
  4555  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want false", methodName, got)
  4556  		}
  4557  		return resp, err
  4558  	})
  4559  }
  4560  
  4561  func TestRepository_UnmarshalJSON(t *testing.T) {
  4562  	t.Parallel()
  4563  	var testCases = map[string]struct {
  4564  		data           []byte
  4565  		wantRepository Repository
  4566  		wantErr        bool
  4567  	}{
  4568  		"Empty": {
  4569  			data:           []byte("{}"),
  4570  			wantRepository: Repository{},
  4571  			wantErr:        false,
  4572  		},
  4573  		"Invalid JSON": {
  4574  			data:           []byte("{"),
  4575  			wantRepository: Repository{},
  4576  			wantErr:        true,
  4577  		},
  4578  		"Partial project": {
  4579  			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"}}`),
  4580  			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]interface{}{}, Organization: &Organization{Login: Ptr("google")}},
  4581  			wantErr:        false,
  4582  		},
  4583  		"With custom properties": {
  4584  			data:           []byte(`{"custom_properties":{"boolean":"false","text":"a","single-select":"a","multi-select":["a","b","c"]}}`),
  4585  			wantRepository: Repository{CustomProperties: map[string]interface{}{"boolean": "false", "text": "a", "single-select": "a", "multi-select": []interface{}{"a", "b", "c"}}},
  4586  			wantErr:        false,
  4587  		},
  4588  	}
  4589  
  4590  	for name, tt := range testCases {
  4591  		tt := tt
  4592  		t.Run(name, func(t *testing.T) {
  4593  			t.Parallel()
  4594  			pk := Repository{}
  4595  			err := json.Unmarshal(tt.data, &pk)
  4596  			if err == nil && tt.wantErr {
  4597  				t.Errorf("Repository.UnmarshalJSON returned nil instead of an error")
  4598  			}
  4599  			if err != nil && !tt.wantErr {
  4600  				t.Errorf("Repository.UnmarshalJSON returned an unexpected error: %+v", err)
  4601  			}
  4602  			if !cmp.Equal(tt.wantRepository, pk) {
  4603  				t.Errorf("Repository.UnmarshalJSON expected repository %+v, got %+v", tt.wantRepository, pk)
  4604  			}
  4605  		})
  4606  	}
  4607  }