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