github.com/google/go-github/v42@v42.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_List_authenticatedUser(t *testing.T) {
    22  	client, mux, _, teardown := setup()
    23  	defer teardown()
    24  
    25  	wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview}
    26  	mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) {
    27  		testMethod(t, r, "GET")
    28  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
    29  		fmt.Fprint(w, `[{"id":1},{"id":2}]`)
    30  	})
    31  
    32  	ctx := context.Background()
    33  	got, _, err := client.Repositories.List(ctx, "", nil)
    34  	if err != nil {
    35  		t.Errorf("Repositories.List returned error: %v", err)
    36  	}
    37  
    38  	want := []*Repository{{ID: Int64(1)}, {ID: Int64(2)}}
    39  	if !cmp.Equal(got, want) {
    40  		t.Errorf("Repositories.List returned %+v, want %+v", got, want)
    41  	}
    42  
    43  	const methodName = "List"
    44  	testBadOptions(t, methodName, func() (err error) {
    45  		_, _, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{})
    46  		return err
    47  	})
    48  
    49  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    50  		got, resp, err := client.Repositories.List(ctx, "", nil)
    51  		if got != nil {
    52  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    53  		}
    54  		return resp, err
    55  	})
    56  }
    57  
    58  func TestRepositoriesService_List_specifiedUser(t *testing.T) {
    59  	client, mux, _, teardown := setup()
    60  	defer teardown()
    61  
    62  	wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview}
    63  	mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) {
    64  		testMethod(t, r, "GET")
    65  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
    66  		testFormValues(t, r, values{
    67  			"visibility":  "public",
    68  			"affiliation": "owner,collaborator",
    69  			"sort":        "created",
    70  			"direction":   "asc",
    71  			"page":        "2",
    72  		})
    73  		fmt.Fprint(w, `[{"id":1}]`)
    74  	})
    75  
    76  	opt := &RepositoryListOptions{
    77  		Visibility:  "public",
    78  		Affiliation: "owner,collaborator",
    79  		Sort:        "created",
    80  		Direction:   "asc",
    81  		ListOptions: ListOptions{Page: 2},
    82  	}
    83  	ctx := context.Background()
    84  	repos, _, err := client.Repositories.List(ctx, "u", opt)
    85  	if err != nil {
    86  		t.Errorf("Repositories.List returned error: %v", err)
    87  	}
    88  
    89  	want := []*Repository{{ID: Int64(1)}}
    90  	if !cmp.Equal(repos, want) {
    91  		t.Errorf("Repositories.List returned %+v, want %+v", repos, want)
    92  	}
    93  }
    94  
    95  func TestRepositoriesService_List_specifiedUser_type(t *testing.T) {
    96  	client, mux, _, teardown := setup()
    97  	defer teardown()
    98  
    99  	wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview}
   100  	mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) {
   101  		testMethod(t, r, "GET")
   102  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   103  		testFormValues(t, r, values{
   104  			"type": "owner",
   105  		})
   106  		fmt.Fprint(w, `[{"id":1}]`)
   107  	})
   108  
   109  	opt := &RepositoryListOptions{
   110  		Type: "owner",
   111  	}
   112  	ctx := context.Background()
   113  	repos, _, err := client.Repositories.List(ctx, "u", opt)
   114  	if err != nil {
   115  		t.Errorf("Repositories.List returned error: %v", err)
   116  	}
   117  
   118  	want := []*Repository{{ID: Int64(1)}}
   119  	if !cmp.Equal(repos, want) {
   120  		t.Errorf("Repositories.List returned %+v, want %+v", repos, want)
   121  	}
   122  }
   123  
   124  func TestRepositoriesService_List_invalidUser(t *testing.T) {
   125  	client, _, _, teardown := setup()
   126  	defer teardown()
   127  
   128  	ctx := context.Background()
   129  	_, _, err := client.Repositories.List(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  		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  		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  		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"}}}`)
   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")}}}
   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/community/code_of_conduct", func(w http.ResponseWriter, r *http.Request) {
   397  		testMethod(t, r, "GET")
   398  		testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview)
   399  		fmt.Fprint(w, `{
   400  						"key": "key",
   401  						"name": "name",
   402  						"url": "url",
   403  						"body": "body"}`,
   404  		)
   405  	})
   406  
   407  	ctx := context.Background()
   408  	got, _, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
   409  	if err != nil {
   410  		t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err)
   411  	}
   412  
   413  	want := &CodeOfConduct{
   414  		Key:  String("key"),
   415  		Name: String("name"),
   416  		URL:  String("url"),
   417  		Body: String("body"),
   418  	}
   419  
   420  	if !cmp.Equal(got, want) {
   421  		t.Errorf("Repositories.GetCodeOfConduct returned %+v, want %+v", got, want)
   422  	}
   423  
   424  	const methodName = "GetCodeOfConduct"
   425  	testBadOptions(t, methodName, func() (err error) {
   426  		_, _, err = client.Repositories.GetCodeOfConduct(ctx, "\n", "\n")
   427  		return err
   428  	})
   429  
   430  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   431  		got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
   432  		if got != nil {
   433  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   434  		}
   435  		return resp, err
   436  	})
   437  }
   438  
   439  func TestRepositoriesService_GetByID(t *testing.T) {
   440  	client, mux, _, teardown := setup()
   441  	defer teardown()
   442  
   443  	mux.HandleFunc("/repositories/1", func(w http.ResponseWriter, r *http.Request) {
   444  		testMethod(t, r, "GET")
   445  		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`)
   446  	})
   447  
   448  	ctx := context.Background()
   449  	got, _, err := client.Repositories.GetByID(ctx, 1)
   450  	if err != nil {
   451  		t.Fatalf("Repositories.GetByID returned error: %v", err)
   452  	}
   453  
   454  	want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}}
   455  	if !cmp.Equal(got, want) {
   456  		t.Errorf("Repositories.GetByID returned %+v, want %+v", got, want)
   457  	}
   458  
   459  	const methodName = "GetByID"
   460  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   461  		got, resp, err := client.Repositories.GetByID(ctx, 1)
   462  		if got != nil {
   463  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   464  		}
   465  		return resp, err
   466  	})
   467  }
   468  
   469  func TestRepositoriesService_Edit(t *testing.T) {
   470  	client, mux, _, teardown := setup()
   471  	defer teardown()
   472  
   473  	i := true
   474  	input := &Repository{HasIssues: &i}
   475  
   476  	wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
   477  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   478  		v := new(Repository)
   479  		json.NewDecoder(r.Body).Decode(v)
   480  
   481  		testMethod(t, r, "PATCH")
   482  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   483  		if !cmp.Equal(v, input) {
   484  			t.Errorf("Request body = %+v, want %+v", v, input)
   485  		}
   486  		fmt.Fprint(w, `{"id":1}`)
   487  	})
   488  
   489  	ctx := context.Background()
   490  	got, _, err := client.Repositories.Edit(ctx, "o", "r", input)
   491  	if err != nil {
   492  		t.Errorf("Repositories.Edit returned error: %v", err)
   493  	}
   494  
   495  	want := &Repository{ID: Int64(1)}
   496  	if !cmp.Equal(got, want) {
   497  		t.Errorf("Repositories.Edit returned %+v, want %+v", got, want)
   498  	}
   499  
   500  	const methodName = "Edit"
   501  	testBadOptions(t, methodName, func() (err error) {
   502  		_, _, err = client.Repositories.Edit(ctx, "\n", "\n", input)
   503  		return err
   504  	})
   505  
   506  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   507  		got, resp, err := client.Repositories.Edit(ctx, "o", "r", input)
   508  		if got != nil {
   509  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   510  		}
   511  		return resp, err
   512  	})
   513  }
   514  
   515  func TestRepositoriesService_Delete(t *testing.T) {
   516  	client, mux, _, teardown := setup()
   517  	defer teardown()
   518  
   519  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   520  		testMethod(t, r, "DELETE")
   521  	})
   522  
   523  	ctx := context.Background()
   524  	_, err := client.Repositories.Delete(ctx, "o", "r")
   525  	if err != nil {
   526  		t.Errorf("Repositories.Delete returned error: %v", err)
   527  	}
   528  
   529  	const methodName = "Delete"
   530  	testBadOptions(t, methodName, func() (err error) {
   531  		_, err = client.Repositories.Delete(ctx, "\n", "\n")
   532  		return err
   533  	})
   534  
   535  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   536  		return client.Repositories.Delete(ctx, "o", "r")
   537  	})
   538  }
   539  
   540  func TestRepositoriesService_Get_invalidOwner(t *testing.T) {
   541  	client, _, _, teardown := setup()
   542  	defer teardown()
   543  
   544  	ctx := context.Background()
   545  	_, _, err := client.Repositories.Get(ctx, "%", "r")
   546  	testURLParseError(t, err)
   547  }
   548  
   549  func TestRepositoriesService_Edit_invalidOwner(t *testing.T) {
   550  	client, _, _, teardown := setup()
   551  	defer teardown()
   552  
   553  	ctx := context.Background()
   554  	_, _, err := client.Repositories.Edit(ctx, "%", "r", nil)
   555  	testURLParseError(t, err)
   556  }
   557  
   558  func TestRepositoriesService_GetVulnerabilityAlerts(t *testing.T) {
   559  	client, mux, _, teardown := setup()
   560  	defer teardown()
   561  
   562  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   563  		testMethod(t, r, "GET")
   564  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   565  
   566  		w.WriteHeader(http.StatusNoContent)
   567  	})
   568  
   569  	ctx := context.Background()
   570  	vulnerabilityAlertsEnabled, _, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r")
   571  	if err != nil {
   572  		t.Errorf("Repositories.GetVulnerabilityAlerts returned error: %v", err)
   573  	}
   574  
   575  	if want := true; vulnerabilityAlertsEnabled != want {
   576  		t.Errorf("Repositories.GetVulnerabilityAlerts returned %+v, want %+v", vulnerabilityAlertsEnabled, want)
   577  	}
   578  
   579  	const methodName = "GetVulnerabilityAlerts"
   580  	testBadOptions(t, methodName, func() (err error) {
   581  		_, _, err = client.Repositories.GetVulnerabilityAlerts(ctx, "\n", "\n")
   582  		return err
   583  	})
   584  
   585  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   586  		got, resp, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r")
   587  		if got {
   588  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want false", methodName, got)
   589  		}
   590  		return resp, err
   591  	})
   592  }
   593  
   594  func TestRepositoriesService_EnableVulnerabilityAlerts(t *testing.T) {
   595  	client, mux, _, teardown := setup()
   596  	defer teardown()
   597  
   598  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   599  		testMethod(t, r, "PUT")
   600  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   601  
   602  		w.WriteHeader(http.StatusNoContent)
   603  	})
   604  
   605  	ctx := context.Background()
   606  	if _, err := client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r"); err != nil {
   607  		t.Errorf("Repositories.EnableVulnerabilityAlerts returned error: %v", err)
   608  	}
   609  
   610  	const methodName = "EnableVulnerabilityAlerts"
   611  	testBadOptions(t, methodName, func() (err error) {
   612  		_, err = client.Repositories.EnableVulnerabilityAlerts(ctx, "\n", "\n")
   613  		return err
   614  	})
   615  
   616  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   617  		return client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r")
   618  	})
   619  }
   620  
   621  func TestRepositoriesService_DisableVulnerabilityAlerts(t *testing.T) {
   622  	client, mux, _, teardown := setup()
   623  	defer teardown()
   624  
   625  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   626  		testMethod(t, r, "DELETE")
   627  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   628  
   629  		w.WriteHeader(http.StatusNoContent)
   630  	})
   631  
   632  	ctx := context.Background()
   633  	if _, err := client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r"); err != nil {
   634  		t.Errorf("Repositories.DisableVulnerabilityAlerts returned error: %v", err)
   635  	}
   636  
   637  	const methodName = "DisableVulnerabilityAlerts"
   638  	testBadOptions(t, methodName, func() (err error) {
   639  		_, err = client.Repositories.DisableVulnerabilityAlerts(ctx, "\n", "\n")
   640  		return err
   641  	})
   642  
   643  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   644  		return client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r")
   645  	})
   646  }
   647  
   648  func TestRepositoriesService_EnableAutomatedSecurityFixes(t *testing.T) {
   649  	client, mux, _, teardown := setup()
   650  	defer teardown()
   651  
   652  	mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) {
   653  		testMethod(t, r, "PUT")
   654  		testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview)
   655  
   656  		w.WriteHeader(http.StatusNoContent)
   657  	})
   658  
   659  	ctx := context.Background()
   660  	if _, err := client.Repositories.EnableAutomatedSecurityFixes(ctx, "o", "r"); err != nil {
   661  		t.Errorf("Repositories.EnableAutomatedSecurityFixes returned error: %v", err)
   662  	}
   663  }
   664  
   665  func TestRepositoriesService_DisableAutomatedSecurityFixes(t *testing.T) {
   666  	client, mux, _, teardown := setup()
   667  	defer teardown()
   668  
   669  	mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) {
   670  		testMethod(t, r, "DELETE")
   671  		testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview)
   672  
   673  		w.WriteHeader(http.StatusNoContent)
   674  	})
   675  
   676  	ctx := context.Background()
   677  	if _, err := client.Repositories.DisableAutomatedSecurityFixes(ctx, "o", "r"); err != nil {
   678  		t.Errorf("Repositories.DisableAutomatedSecurityFixes returned error: %v", err)
   679  	}
   680  }
   681  
   682  func TestRepositoriesService_ListContributors(t *testing.T) {
   683  	client, mux, _, teardown := setup()
   684  	defer teardown()
   685  
   686  	mux.HandleFunc("/repos/o/r/contributors", func(w http.ResponseWriter, r *http.Request) {
   687  		testMethod(t, r, "GET")
   688  		testFormValues(t, r, values{
   689  			"anon": "true",
   690  			"page": "2",
   691  		})
   692  		fmt.Fprint(w, `[{"contributions":42}]`)
   693  	})
   694  
   695  	opts := &ListContributorsOptions{Anon: "true", ListOptions: ListOptions{Page: 2}}
   696  	ctx := context.Background()
   697  	contributors, _, err := client.Repositories.ListContributors(ctx, "o", "r", opts)
   698  	if err != nil {
   699  		t.Errorf("Repositories.ListContributors returned error: %v", err)
   700  	}
   701  
   702  	want := []*Contributor{{Contributions: Int(42)}}
   703  	if !cmp.Equal(contributors, want) {
   704  		t.Errorf("Repositories.ListContributors returned %+v, want %+v", contributors, want)
   705  	}
   706  
   707  	const methodName = "ListContributors"
   708  	testBadOptions(t, methodName, func() (err error) {
   709  		_, _, err = client.Repositories.ListContributors(ctx, "\n", "\n", opts)
   710  		return err
   711  	})
   712  
   713  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   714  		got, resp, err := client.Repositories.ListContributors(ctx, "o", "r", opts)
   715  		if got != nil {
   716  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   717  		}
   718  		return resp, err
   719  	})
   720  }
   721  
   722  func TestRepositoriesService_ListLanguages(t *testing.T) {
   723  	client, mux, _, teardown := setup()
   724  	defer teardown()
   725  
   726  	mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) {
   727  		testMethod(t, r, "GET")
   728  		fmt.Fprint(w, `{"go":1}`)
   729  	})
   730  
   731  	ctx := context.Background()
   732  	languages, _, err := client.Repositories.ListLanguages(ctx, "o", "r")
   733  	if err != nil {
   734  		t.Errorf("Repositories.ListLanguages returned error: %v", err)
   735  	}
   736  
   737  	want := map[string]int{"go": 1}
   738  	if !cmp.Equal(languages, want) {
   739  		t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want)
   740  	}
   741  
   742  	const methodName = "ListLanguages"
   743  	testBadOptions(t, methodName, func() (err error) {
   744  		_, _, err = client.Repositories.ListLanguages(ctx, "\n", "\n")
   745  		return err
   746  	})
   747  
   748  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   749  		got, resp, err := client.Repositories.ListLanguages(ctx, "o", "r")
   750  		if got != nil {
   751  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   752  		}
   753  		return resp, err
   754  	})
   755  }
   756  
   757  func TestRepositoriesService_ListTeams(t *testing.T) {
   758  	client, mux, _, teardown := setup()
   759  	defer teardown()
   760  
   761  	mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) {
   762  		testMethod(t, r, "GET")
   763  		testFormValues(t, r, values{"page": "2"})
   764  		fmt.Fprint(w, `[{"id":1}]`)
   765  	})
   766  
   767  	opt := &ListOptions{Page: 2}
   768  	ctx := context.Background()
   769  	teams, _, err := client.Repositories.ListTeams(ctx, "o", "r", opt)
   770  	if err != nil {
   771  		t.Errorf("Repositories.ListTeams returned error: %v", err)
   772  	}
   773  
   774  	want := []*Team{{ID: Int64(1)}}
   775  	if !cmp.Equal(teams, want) {
   776  		t.Errorf("Repositories.ListTeams returned %+v, want %+v", teams, want)
   777  	}
   778  
   779  	const methodName = "ListTeams"
   780  	testBadOptions(t, methodName, func() (err error) {
   781  		_, _, err = client.Repositories.ListTeams(ctx, "\n", "\n", opt)
   782  		return err
   783  	})
   784  
   785  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   786  		got, resp, err := client.Repositories.ListTeams(ctx, "o", "r", opt)
   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_ListTags(t *testing.T) {
   795  	client, mux, _, teardown := setup()
   796  	defer teardown()
   797  
   798  	mux.HandleFunc("/repos/o/r/tags", func(w http.ResponseWriter, r *http.Request) {
   799  		testMethod(t, r, "GET")
   800  		testFormValues(t, r, values{"page": "2"})
   801  		fmt.Fprint(w, `[{"name":"n", "commit" : {"sha" : "s", "url" : "u"}, "zipball_url": "z", "tarball_url": "t"}]`)
   802  	})
   803  
   804  	opt := &ListOptions{Page: 2}
   805  	ctx := context.Background()
   806  	tags, _, err := client.Repositories.ListTags(ctx, "o", "r", opt)
   807  	if err != nil {
   808  		t.Errorf("Repositories.ListTags returned error: %v", err)
   809  	}
   810  
   811  	want := []*RepositoryTag{
   812  		{
   813  			Name: String("n"),
   814  			Commit: &Commit{
   815  				SHA: String("s"),
   816  				URL: String("u"),
   817  			},
   818  			ZipballURL: String("z"),
   819  			TarballURL: String("t"),
   820  		},
   821  	}
   822  	if !cmp.Equal(tags, want) {
   823  		t.Errorf("Repositories.ListTags returned %+v, want %+v", tags, want)
   824  	}
   825  
   826  	const methodName = "ListTags"
   827  	testBadOptions(t, methodName, func() (err error) {
   828  		_, _, err = client.Repositories.ListTags(ctx, "\n", "\n", opt)
   829  		return err
   830  	})
   831  
   832  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   833  		got, resp, err := client.Repositories.ListTags(ctx, "o", "r", opt)
   834  		if got != nil {
   835  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   836  		}
   837  		return resp, err
   838  	})
   839  }
   840  
   841  func TestRepositoriesService_ListBranches(t *testing.T) {
   842  	client, mux, _, teardown := setup()
   843  	defer teardown()
   844  
   845  	mux.HandleFunc("/repos/o/r/branches", func(w http.ResponseWriter, r *http.Request) {
   846  		testMethod(t, r, "GET")
   847  		testFormValues(t, r, values{"page": "2"})
   848  		fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`)
   849  	})
   850  
   851  	opt := &BranchListOptions{
   852  		Protected:   nil,
   853  		ListOptions: ListOptions{Page: 2},
   854  	}
   855  	ctx := context.Background()
   856  	branches, _, err := client.Repositories.ListBranches(ctx, "o", "r", opt)
   857  	if err != nil {
   858  		t.Errorf("Repositories.ListBranches returned error: %v", err)
   859  	}
   860  
   861  	want := []*Branch{{Name: String("master"), Commit: &RepositoryCommit{SHA: String("a57781"), URL: String("https://api.github.com/repos/o/r/commits/a57781")}}}
   862  	if !cmp.Equal(branches, want) {
   863  		t.Errorf("Repositories.ListBranches returned %+v, want %+v", branches, want)
   864  	}
   865  
   866  	const methodName = "ListBranches"
   867  	testBadOptions(t, methodName, func() (err error) {
   868  		_, _, err = client.Repositories.ListBranches(ctx, "\n", "\n", opt)
   869  		return err
   870  	})
   871  
   872  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   873  		got, resp, err := client.Repositories.ListBranches(ctx, "o", "r", opt)
   874  		if got != nil {
   875  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   876  		}
   877  		return resp, err
   878  	})
   879  }
   880  
   881  func TestRepositoriesService_GetBranch(t *testing.T) {
   882  	client, mux, _, teardown := setup()
   883  	defer teardown()
   884  
   885  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
   886  		testMethod(t, r, "GET")
   887  		fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`)
   888  	})
   889  
   890  	ctx := context.Background()
   891  	branch, _, err := client.Repositories.GetBranch(ctx, "o", "r", "b", false)
   892  	if err != nil {
   893  		t.Errorf("Repositories.GetBranch returned error: %v", err)
   894  	}
   895  
   896  	want := &Branch{
   897  		Name: String("n"),
   898  		Commit: &RepositoryCommit{
   899  			SHA: String("s"),
   900  			Commit: &Commit{
   901  				Message: String("m"),
   902  			},
   903  		},
   904  		Protected: Bool(true),
   905  	}
   906  
   907  	if !cmp.Equal(branch, want) {
   908  		t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
   909  	}
   910  
   911  	const methodName = "GetBranch"
   912  	testBadOptions(t, methodName, func() (err error) {
   913  		_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", false)
   914  		return err
   915  	})
   916  }
   917  
   918  func TestRepositoriesService_GetBranch_StatusMovedPermanently_followRedirects(t *testing.T) {
   919  	client, mux, serverURL, teardown := setup()
   920  	defer teardown()
   921  
   922  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
   923  		testMethod(t, r, "GET")
   924  		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/repos/o/r/branches/br")
   925  		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
   926  	})
   927  	mux.HandleFunc("/repos/o/r/branches/br", func(w http.ResponseWriter, r *http.Request) {
   928  		testMethod(t, r, "GET")
   929  		fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`)
   930  	})
   931  	ctx := context.Background()
   932  	branch, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true)
   933  	if err != nil {
   934  		t.Errorf("Repositories.GetBranch returned error: %v", err)
   935  	}
   936  	if resp.StatusCode != http.StatusOK {
   937  		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusOK)
   938  	}
   939  
   940  	want := &Branch{
   941  		Name: String("n"),
   942  		Commit: &RepositoryCommit{
   943  			SHA: String("s"),
   944  			Commit: &Commit{
   945  				Message: String("m"),
   946  			},
   947  		},
   948  		Protected: Bool(true),
   949  	}
   950  	if !cmp.Equal(branch, want) {
   951  		t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
   952  	}
   953  }
   954  
   955  func TestRepositoriesService_GetBranch_notFound(t *testing.T) {
   956  	client, mux, _, teardown := setup()
   957  	defer teardown()
   958  
   959  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
   960  		testMethod(t, r, "GET")
   961  		http.Error(w, "branch not found", http.StatusNotFound)
   962  	})
   963  	ctx := context.Background()
   964  	_, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true)
   965  	if err == nil {
   966  		t.Error("Repositories.GetBranch returned error: nil")
   967  	}
   968  	if resp.StatusCode != http.StatusNotFound {
   969  		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusNotFound)
   970  	}
   971  
   972  	// Add custom round tripper
   973  	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
   974  		return nil, errors.New("failed to get branch")
   975  	})
   976  
   977  	const methodName = "GetBranch"
   978  	testBadOptions(t, methodName, func() (err error) {
   979  		_, _, err = client.Repositories.GetBranch(ctx, "o", "r", "b", true)
   980  		return err
   981  	})
   982  }
   983  
   984  func TestRepositoriesService_RenameBranch(t *testing.T) {
   985  	client, mux, _, teardown := setup()
   986  	defer teardown()
   987  
   988  	renameBranchReq := "nn"
   989  
   990  	mux.HandleFunc("/repos/o/r/branches/b/rename", func(w http.ResponseWriter, r *http.Request) {
   991  		v := new(renameBranchRequest)
   992  		json.NewDecoder(r.Body).Decode(v)
   993  
   994  		testMethod(t, r, "POST")
   995  		want := &renameBranchRequest{NewName: "nn"}
   996  		if !cmp.Equal(v, want) {
   997  			t.Errorf("Request body = %+v, want %+v", v, want)
   998  		}
   999  
  1000  		fmt.Fprint(w, `{"protected":true,"name":"nn"}`)
  1001  	})
  1002  
  1003  	ctx := context.Background()
  1004  	got, _, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq)
  1005  	if err != nil {
  1006  		t.Errorf("Repositories.RenameBranch returned error: %v", err)
  1007  	}
  1008  
  1009  	want := &Branch{Name: String("nn"), Protected: Bool(true)}
  1010  	if !cmp.Equal(got, want) {
  1011  		t.Errorf("Repositories.RenameBranch returned %+v, want %+v", got, want)
  1012  	}
  1013  
  1014  	const methodName = "RenameBranch"
  1015  	testBadOptions(t, methodName, func() (err error) {
  1016  		_, _, err = client.Repositories.RenameBranch(ctx, "\n", "\n", "\n", renameBranchReq)
  1017  		return err
  1018  	})
  1019  
  1020  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1021  		got, resp, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq)
  1022  		if got != nil {
  1023  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1024  		}
  1025  		return resp, err
  1026  	})
  1027  }
  1028  
  1029  func TestRepositoriesService_GetBranchProtection(t *testing.T) {
  1030  	client, mux, _, teardown := setup()
  1031  	defer teardown()
  1032  
  1033  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1034  		v := new(ProtectionRequest)
  1035  		json.NewDecoder(r.Body).Decode(v)
  1036  
  1037  		testMethod(t, r, "GET")
  1038  		// TODO: remove custom Accept header when this API fully launches
  1039  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1040  		fmt.Fprintf(w, `{
  1041  				"required_status_checks":{
  1042  					"strict":true,
  1043  					"contexts":["continuous-integration"]
  1044  				},
  1045  				"required_pull_request_reviews":{
  1046  					"dismissal_restrictions":{
  1047  						"users":[{
  1048  							"id":3,
  1049  							"login":"u"
  1050  						}],
  1051  						"teams":[{
  1052  							"id":4,
  1053  							"slug":"t"
  1054  						}]
  1055  					},
  1056  					"dismiss_stale_reviews":true,
  1057  					"require_code_owner_reviews":true,
  1058  					"required_approving_review_count":1
  1059  					},
  1060  					"enforce_admins":{
  1061  						"url":"/repos/o/r/branches/b/protection/enforce_admins",
  1062  						"enabled":true
  1063  					},
  1064  					"restrictions":{
  1065  						"users":[{"id":1,"login":"u"}],
  1066  						"teams":[{"id":2,"slug":"t"}]
  1067  					},
  1068  					"required_conversation_resolution": {
  1069  						"enabled": true
  1070  					}
  1071  				}`)
  1072  	})
  1073  
  1074  	ctx := context.Background()
  1075  	protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1076  	if err != nil {
  1077  		t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1078  	}
  1079  
  1080  	want := &Protection{
  1081  		RequiredStatusChecks: &RequiredStatusChecks{
  1082  			Strict:   true,
  1083  			Contexts: []string{"continuous-integration"},
  1084  		},
  1085  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1086  			DismissStaleReviews: true,
  1087  			DismissalRestrictions: &DismissalRestrictions{
  1088  				Users: []*User{
  1089  					{Login: String("u"), ID: Int64(3)},
  1090  				},
  1091  				Teams: []*Team{
  1092  					{Slug: String("t"), ID: Int64(4)},
  1093  				},
  1094  			},
  1095  			RequireCodeOwnerReviews:      true,
  1096  			RequiredApprovingReviewCount: 1,
  1097  		},
  1098  		EnforceAdmins: &AdminEnforcement{
  1099  			URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  1100  			Enabled: true,
  1101  		},
  1102  		Restrictions: &BranchRestrictions{
  1103  			Users: []*User{
  1104  				{Login: String("u"), ID: Int64(1)},
  1105  			},
  1106  			Teams: []*Team{
  1107  				{Slug: String("t"), ID: Int64(2)},
  1108  			},
  1109  		},
  1110  		RequiredConversationResolution: &RequiredConversationResolution{
  1111  			Enabled: true,
  1112  		},
  1113  	}
  1114  	if !cmp.Equal(protection, want) {
  1115  		t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1116  	}
  1117  
  1118  	const methodName = "GetBranchProtection"
  1119  	testBadOptions(t, methodName, func() (err error) {
  1120  		_, _, err = client.Repositories.GetBranchProtection(ctx, "\n", "\n", "\n")
  1121  		return err
  1122  	})
  1123  
  1124  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1125  		got, resp, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1126  		if got != nil {
  1127  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1128  		}
  1129  		return resp, err
  1130  	})
  1131  }
  1132  
  1133  func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) {
  1134  	client, mux, _, teardown := setup()
  1135  	defer teardown()
  1136  
  1137  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1138  		testMethod(t, r, "GET")
  1139  		// TODO: remove custom Accept header when this API fully launches
  1140  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1141  		fmt.Fprintf(w, `{
  1142  				"required_status_checks":{
  1143  					"strict":true,
  1144  					"contexts":["continuous-integration"]
  1145  				},
  1146  				"required_pull_request_reviews":{
  1147  					"dismiss_stale_reviews":true,
  1148  					"require_code_owner_reviews":true,
  1149  					"required_approving_review_count":1
  1150  					},
  1151  					"enforce_admins":{
  1152  						"url":"/repos/o/r/branches/b/protection/enforce_admins",
  1153  						"enabled":true
  1154  					},
  1155  					"restrictions":{
  1156  						"users":[{"id":1,"login":"u"}],
  1157  						"teams":[{"id":2,"slug":"t"}]
  1158  					}
  1159  				}`)
  1160  	})
  1161  
  1162  	ctx := context.Background()
  1163  	protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1164  	if err != nil {
  1165  		t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1166  	}
  1167  
  1168  	want := &Protection{
  1169  		RequiredStatusChecks: &RequiredStatusChecks{
  1170  			Strict:   true,
  1171  			Contexts: []string{"continuous-integration"},
  1172  		},
  1173  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1174  			DismissStaleReviews:          true,
  1175  			DismissalRestrictions:        nil,
  1176  			RequireCodeOwnerReviews:      true,
  1177  			RequiredApprovingReviewCount: 1,
  1178  		},
  1179  		EnforceAdmins: &AdminEnforcement{
  1180  			URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  1181  			Enabled: true,
  1182  		},
  1183  		Restrictions: &BranchRestrictions{
  1184  			Users: []*User{
  1185  				{Login: String("u"), ID: Int64(1)},
  1186  			},
  1187  			Teams: []*Team{
  1188  				{Slug: String("t"), ID: Int64(2)},
  1189  			},
  1190  		},
  1191  	}
  1192  	if !cmp.Equal(protection, want) {
  1193  		t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1194  	}
  1195  }
  1196  
  1197  func TestRepositoriesService_GetBranchProtection_branchNotProtected(t *testing.T) {
  1198  	client, mux, _, teardown := setup()
  1199  	defer teardown()
  1200  
  1201  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1202  		testMethod(t, r, "GET")
  1203  
  1204  		w.WriteHeader(http.StatusBadRequest)
  1205  		fmt.Fprintf(w, `{
  1206  			"message": %q,
  1207  			"documentation_url": "https://docs.github.com/rest/reference/repos#get-branch-protection"
  1208  			}`, githubBranchNotProtected)
  1209  	})
  1210  
  1211  	ctx := context.Background()
  1212  	protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1213  
  1214  	if protection != nil {
  1215  		t.Errorf("Repositories.GetBranchProtection returned non-nil protection data")
  1216  	}
  1217  
  1218  	if err != ErrBranchNotProtected {
  1219  		t.Errorf("Repositories.GetBranchProtection returned an invalid error: %v", err)
  1220  	}
  1221  }
  1222  
  1223  func TestRepositoriesService_UpdateBranchProtection(t *testing.T) {
  1224  	client, mux, _, teardown := setup()
  1225  	defer teardown()
  1226  
  1227  	input := &ProtectionRequest{
  1228  		RequiredStatusChecks: &RequiredStatusChecks{
  1229  			Strict:   true,
  1230  			Contexts: []string{"continuous-integration"},
  1231  		},
  1232  		RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1233  			DismissStaleReviews: true,
  1234  			DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1235  				Users: &[]string{"uu"},
  1236  				Teams: &[]string{"tt"},
  1237  			},
  1238  		},
  1239  		Restrictions: &BranchRestrictionsRequest{
  1240  			Users: []string{"u"},
  1241  			Teams: []string{"t"},
  1242  			Apps:  []string{"a"},
  1243  		},
  1244  	}
  1245  
  1246  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1247  		v := new(ProtectionRequest)
  1248  		json.NewDecoder(r.Body).Decode(v)
  1249  
  1250  		testMethod(t, r, "PUT")
  1251  		if !cmp.Equal(v, input) {
  1252  			t.Errorf("Request body = %+v, want %+v", v, input)
  1253  		}
  1254  
  1255  		// TODO: remove custom Accept header when this API fully launches
  1256  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1257  		fmt.Fprintf(w, `{
  1258  			"required_status_checks":{
  1259  				"strict":true,
  1260  				"contexts":["continuous-integration"]
  1261  			},
  1262  			"required_pull_request_reviews":{
  1263  				"dismissal_restrictions":{
  1264  					"users":[{
  1265  						"id":3,
  1266  						"login":"uu"
  1267  					}],
  1268  					"teams":[{
  1269  						"id":4,
  1270  						"slug":"tt"
  1271  					}]
  1272  				},
  1273  				"dismiss_stale_reviews":true,
  1274  				"require_code_owner_reviews":true
  1275  			},
  1276  			"restrictions":{
  1277  				"users":[{"id":1,"login":"u"}],
  1278  				"teams":[{"id":2,"slug":"t"}],
  1279  				"apps":[{"id":3,"slug":"a"}]
  1280  			}
  1281  		}`)
  1282  	})
  1283  
  1284  	ctx := context.Background()
  1285  	protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input)
  1286  	if err != nil {
  1287  		t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1288  	}
  1289  
  1290  	want := &Protection{
  1291  		RequiredStatusChecks: &RequiredStatusChecks{
  1292  			Strict:   true,
  1293  			Contexts: []string{"continuous-integration"},
  1294  		},
  1295  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1296  			DismissStaleReviews: true,
  1297  			DismissalRestrictions: &DismissalRestrictions{
  1298  				Users: []*User{
  1299  					{Login: String("uu"), ID: Int64(3)},
  1300  				},
  1301  				Teams: []*Team{
  1302  					{Slug: String("tt"), ID: Int64(4)},
  1303  				},
  1304  			},
  1305  			RequireCodeOwnerReviews: true,
  1306  		},
  1307  		Restrictions: &BranchRestrictions{
  1308  			Users: []*User{
  1309  				{Login: String("u"), ID: Int64(1)},
  1310  			},
  1311  			Teams: []*Team{
  1312  				{Slug: String("t"), ID: Int64(2)},
  1313  			},
  1314  			Apps: []*App{
  1315  				{Slug: String("a"), ID: Int64(3)},
  1316  			},
  1317  		},
  1318  	}
  1319  	if !cmp.Equal(protection, want) {
  1320  		t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1321  	}
  1322  
  1323  	const methodName = "UpdateBranchProtection"
  1324  	testBadOptions(t, methodName, func() (err error) {
  1325  		_, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input)
  1326  		return err
  1327  	})
  1328  
  1329  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1330  		got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input)
  1331  		if got != nil {
  1332  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1333  		}
  1334  		return resp, err
  1335  	})
  1336  }
  1337  
  1338  func TestRepositoriesService_RemoveBranchProtection(t *testing.T) {
  1339  	client, mux, _, teardown := setup()
  1340  	defer teardown()
  1341  
  1342  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1343  		testMethod(t, r, "DELETE")
  1344  		w.WriteHeader(http.StatusNoContent)
  1345  	})
  1346  
  1347  	ctx := context.Background()
  1348  	_, err := client.Repositories.RemoveBranchProtection(ctx, "o", "r", "b")
  1349  	if err != nil {
  1350  		t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err)
  1351  	}
  1352  
  1353  	const methodName = "RemoveBranchProtection"
  1354  	testBadOptions(t, methodName, func() (err error) {
  1355  		_, err = client.Repositories.RemoveBranchProtection(ctx, "\n", "\n", "\n")
  1356  		return err
  1357  	})
  1358  
  1359  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1360  		return client.Repositories.RemoveBranchProtection(ctx, "o", "r", "b")
  1361  	})
  1362  }
  1363  
  1364  func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) {
  1365  	client, _, _, teardown := setup()
  1366  	defer teardown()
  1367  
  1368  	ctx := context.Background()
  1369  	_, _, err := client.Repositories.ListLanguages(ctx, "%", "%")
  1370  	testURLParseError(t, err)
  1371  }
  1372  
  1373  func TestRepositoriesService_License(t *testing.T) {
  1374  	client, mux, _, teardown := setup()
  1375  	defer teardown()
  1376  
  1377  	mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) {
  1378  		testMethod(t, r, "GET")
  1379  		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}}`)
  1380  	})
  1381  
  1382  	ctx := context.Background()
  1383  	got, _, err := client.Repositories.License(ctx, "o", "r")
  1384  	if err != nil {
  1385  		t.Errorf("Repositories.License returned error: %v", err)
  1386  	}
  1387  
  1388  	want := &RepositoryLicense{
  1389  		Name: String("LICENSE"),
  1390  		Path: String("LICENSE"),
  1391  		License: &License{
  1392  			Name:     String("MIT License"),
  1393  			Key:      String("mit"),
  1394  			SPDXID:   String("MIT"),
  1395  			URL:      String("https://api.github.com/licenses/mit"),
  1396  			Featured: Bool(true),
  1397  		},
  1398  	}
  1399  
  1400  	if !cmp.Equal(got, want) {
  1401  		t.Errorf("Repositories.License returned %+v, want %+v", got, want)
  1402  	}
  1403  
  1404  	const methodName = "License"
  1405  	testBadOptions(t, methodName, func() (err error) {
  1406  		_, _, err = client.Repositories.License(ctx, "\n", "\n")
  1407  		return err
  1408  	})
  1409  
  1410  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1411  		got, resp, err := client.Repositories.License(ctx, "o", "r")
  1412  		if got != nil {
  1413  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1414  		}
  1415  		return resp, err
  1416  	})
  1417  }
  1418  
  1419  func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) {
  1420  	client, mux, _, teardown := setup()
  1421  	defer teardown()
  1422  
  1423  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1424  		v := new(ProtectionRequest)
  1425  		json.NewDecoder(r.Body).Decode(v)
  1426  
  1427  		testMethod(t, r, "GET")
  1428  		fmt.Fprint(w, `{"strict": true,"contexts": ["x","y","z"]}`)
  1429  	})
  1430  
  1431  	ctx := context.Background()
  1432  	checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b")
  1433  	if err != nil {
  1434  		t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err)
  1435  	}
  1436  
  1437  	want := &RequiredStatusChecks{
  1438  		Strict:   true,
  1439  		Contexts: []string{"x", "y", "z"},
  1440  	}
  1441  	if !cmp.Equal(checks, want) {
  1442  		t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want)
  1443  	}
  1444  
  1445  	const methodName = "GetRequiredStatusChecks"
  1446  	testBadOptions(t, methodName, func() (err error) {
  1447  		_, _, err = client.Repositories.GetRequiredStatusChecks(ctx, "\n", "\n", "\n")
  1448  		return err
  1449  	})
  1450  
  1451  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1452  		got, resp, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b")
  1453  		if got != nil {
  1454  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1455  		}
  1456  		return resp, err
  1457  	})
  1458  }
  1459  
  1460  func TestRepositoriesService_GetRequiredStatusChecks_branchNotProtected(t *testing.T) {
  1461  	client, mux, _, teardown := setup()
  1462  	defer teardown()
  1463  
  1464  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1465  		testMethod(t, r, "GET")
  1466  
  1467  		w.WriteHeader(http.StatusBadRequest)
  1468  		fmt.Fprintf(w, `{
  1469  			"message": %q,
  1470  			"documentation_url": "https://docs.github.com/rest/reference/repos#get-branch-protection"
  1471  			}`, githubBranchNotProtected)
  1472  	})
  1473  
  1474  	ctx := context.Background()
  1475  	checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b")
  1476  
  1477  	if checks != nil {
  1478  		t.Errorf("Repositories.GetRequiredStatusChecks returned non-nil status-checks data")
  1479  	}
  1480  
  1481  	if err != ErrBranchNotProtected {
  1482  		t.Errorf("Repositories.GetRequiredStatusChecks returned an invalid error: %v", err)
  1483  	}
  1484  }
  1485  
  1486  func TestRepositoriesService_UpdateRequiredStatusChecks(t *testing.T) {
  1487  	client, mux, _, teardown := setup()
  1488  	defer teardown()
  1489  
  1490  	input := &RequiredStatusChecksRequest{
  1491  		Strict:   Bool(true),
  1492  		Contexts: []string{"continuous-integration"},
  1493  	}
  1494  
  1495  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1496  		v := new(RequiredStatusChecksRequest)
  1497  		json.NewDecoder(r.Body).Decode(v)
  1498  
  1499  		testMethod(t, r, "PATCH")
  1500  		if !cmp.Equal(v, input) {
  1501  			t.Errorf("Request body = %+v, want %+v", v, input)
  1502  		}
  1503  		testHeader(t, r, "Accept", mediaTypeV3)
  1504  		fmt.Fprintf(w, `{"strict":true,"contexts":["continuous-integration"]}`)
  1505  	})
  1506  
  1507  	ctx := context.Background()
  1508  	statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input)
  1509  	if err != nil {
  1510  		t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err)
  1511  	}
  1512  
  1513  	want := &RequiredStatusChecks{
  1514  		Strict:   true,
  1515  		Contexts: []string{"continuous-integration"},
  1516  	}
  1517  	if !cmp.Equal(statusChecks, want) {
  1518  		t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want)
  1519  	}
  1520  
  1521  	const methodName = "UpdateRequiredStatusChecks"
  1522  	testBadOptions(t, methodName, func() (err error) {
  1523  		_, _, err = client.Repositories.UpdateRequiredStatusChecks(ctx, "\n", "\n", "\n", input)
  1524  		return err
  1525  	})
  1526  
  1527  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1528  		got, resp, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input)
  1529  		if got != nil {
  1530  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1531  		}
  1532  		return resp, err
  1533  	})
  1534  }
  1535  
  1536  func TestRepositoriesService_RemoveRequiredStatusChecks(t *testing.T) {
  1537  	client, mux, _, teardown := setup()
  1538  	defer teardown()
  1539  
  1540  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1541  		testMethod(t, r, "DELETE")
  1542  		testHeader(t, r, "Accept", mediaTypeV3)
  1543  		w.WriteHeader(http.StatusNoContent)
  1544  	})
  1545  
  1546  	ctx := context.Background()
  1547  	_, err := client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", "b")
  1548  	if err != nil {
  1549  		t.Errorf("Repositories.RemoveRequiredStatusChecks returned error: %v", err)
  1550  	}
  1551  
  1552  	const methodName = "RemoveRequiredStatusChecks"
  1553  	testBadOptions(t, methodName, func() (err error) {
  1554  		_, err = client.Repositories.RemoveRequiredStatusChecks(ctx, "\n", "\n", "\n")
  1555  		return err
  1556  	})
  1557  
  1558  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1559  		return client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", "b")
  1560  	})
  1561  }
  1562  
  1563  func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) {
  1564  	client, mux, _, teardown := setup()
  1565  	defer teardown()
  1566  
  1567  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks/contexts", func(w http.ResponseWriter, r *http.Request) {
  1568  		v := new(ProtectionRequest)
  1569  		json.NewDecoder(r.Body).Decode(v)
  1570  
  1571  		testMethod(t, r, "GET")
  1572  		fmt.Fprint(w, `["x", "y", "z"]`)
  1573  	})
  1574  
  1575  	ctx := context.Background()
  1576  	contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b")
  1577  	if err != nil {
  1578  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err)
  1579  	}
  1580  
  1581  	want := []string{"x", "y", "z"}
  1582  	if !cmp.Equal(contexts, want) {
  1583  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want)
  1584  	}
  1585  
  1586  	const methodName = "ListRequiredStatusChecksContexts"
  1587  	testBadOptions(t, methodName, func() (err error) {
  1588  		_, _, err = client.Repositories.ListRequiredStatusChecksContexts(ctx, "\n", "\n", "\n")
  1589  		return err
  1590  	})
  1591  
  1592  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1593  		got, resp, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b")
  1594  		if got != nil {
  1595  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1596  		}
  1597  		return resp, err
  1598  	})
  1599  }
  1600  
  1601  func TestRepositoriesService_ListRequiredStatusChecksContexts_branchNotProtected(t *testing.T) {
  1602  	client, mux, _, teardown := setup()
  1603  	defer teardown()
  1604  
  1605  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks/contexts", func(w http.ResponseWriter, r *http.Request) {
  1606  		testMethod(t, r, "GET")
  1607  
  1608  		w.WriteHeader(http.StatusBadRequest)
  1609  		fmt.Fprintf(w, `{
  1610  			"message": %q,
  1611  			"documentation_url": "https://docs.github.com/rest/reference/repos#get-branch-protection"
  1612  			}`, githubBranchNotProtected)
  1613  	})
  1614  
  1615  	ctx := context.Background()
  1616  	contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b")
  1617  
  1618  	if contexts != nil {
  1619  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned non-nil contexts data")
  1620  	}
  1621  
  1622  	if err != ErrBranchNotProtected {
  1623  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned an invalid error: %v", err)
  1624  	}
  1625  }
  1626  
  1627  func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) {
  1628  	client, mux, _, teardown := setup()
  1629  	defer teardown()
  1630  
  1631  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  1632  		testMethod(t, r, "GET")
  1633  		// TODO: remove custom Accept header when this API fully launches
  1634  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1635  		fmt.Fprintf(w, `{
  1636  			"dismissal_restrictions":{
  1637  				"users":[{"id":1,"login":"u"}],
  1638  				"teams":[{"id":2,"slug":"t"}]
  1639  			},
  1640  			"dismiss_stale_reviews":true,
  1641  			"require_code_owner_reviews":true,
  1642  			"required_approving_review_count":1
  1643  		}`)
  1644  	})
  1645  
  1646  	ctx := context.Background()
  1647  	enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", "b")
  1648  	if err != nil {
  1649  		t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err)
  1650  	}
  1651  
  1652  	want := &PullRequestReviewsEnforcement{
  1653  		DismissStaleReviews: true,
  1654  		DismissalRestrictions: &DismissalRestrictions{
  1655  			Users: []*User{
  1656  				{Login: String("u"), ID: Int64(1)},
  1657  			},
  1658  			Teams: []*Team{
  1659  				{Slug: String("t"), ID: Int64(2)},
  1660  			},
  1661  		},
  1662  		RequireCodeOwnerReviews:      true,
  1663  		RequiredApprovingReviewCount: 1,
  1664  	}
  1665  
  1666  	if !cmp.Equal(enforcement, want) {
  1667  		t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  1668  	}
  1669  
  1670  	const methodName = "GetPullRequestReviewEnforcement"
  1671  	testBadOptions(t, methodName, func() (err error) {
  1672  		_, _, err = client.Repositories.GetPullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  1673  		return err
  1674  	})
  1675  
  1676  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1677  		got, resp, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", "b")
  1678  		if got != nil {
  1679  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1680  		}
  1681  		return resp, err
  1682  	})
  1683  }
  1684  
  1685  func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) {
  1686  	client, mux, _, teardown := setup()
  1687  	defer teardown()
  1688  
  1689  	input := &PullRequestReviewsEnforcementUpdate{
  1690  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1691  			Users: &[]string{"u"},
  1692  			Teams: &[]string{"t"},
  1693  		},
  1694  	}
  1695  
  1696  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  1697  		v := new(PullRequestReviewsEnforcementUpdate)
  1698  		json.NewDecoder(r.Body).Decode(v)
  1699  
  1700  		testMethod(t, r, "PATCH")
  1701  		if !cmp.Equal(v, input) {
  1702  			t.Errorf("Request body = %+v, want %+v", v, input)
  1703  		}
  1704  		// TODO: remove custom Accept header when this API fully launches
  1705  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1706  		fmt.Fprintf(w, `{
  1707  			"dismissal_restrictions":{
  1708  				"users":[{"id":1,"login":"u"}],
  1709  				"teams":[{"id":2,"slug":"t"}]
  1710  			},
  1711  			"dismiss_stale_reviews":true,
  1712  			"require_code_owner_reviews":true,
  1713  			"required_approving_review_count":3
  1714  		}`)
  1715  	})
  1716  
  1717  	ctx := context.Background()
  1718  	enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", "b", input)
  1719  	if err != nil {
  1720  		t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err)
  1721  	}
  1722  
  1723  	want := &PullRequestReviewsEnforcement{
  1724  		DismissStaleReviews: true,
  1725  		DismissalRestrictions: &DismissalRestrictions{
  1726  			Users: []*User{
  1727  				{Login: String("u"), ID: Int64(1)},
  1728  			},
  1729  			Teams: []*Team{
  1730  				{Slug: String("t"), ID: Int64(2)},
  1731  			},
  1732  		},
  1733  		RequireCodeOwnerReviews:      true,
  1734  		RequiredApprovingReviewCount: 3,
  1735  	}
  1736  	if !cmp.Equal(enforcement, want) {
  1737  		t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  1738  	}
  1739  
  1740  	const methodName = "UpdatePullRequestReviewEnforcement"
  1741  	testBadOptions(t, methodName, func() (err error) {
  1742  		_, _, err = client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "\n", "\n", "\n", input)
  1743  		return err
  1744  	})
  1745  
  1746  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1747  		got, resp, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", "b", input)
  1748  		if got != nil {
  1749  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1750  		}
  1751  		return resp, err
  1752  	})
  1753  }
  1754  
  1755  func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) {
  1756  	client, mux, _, teardown := setup()
  1757  	defer teardown()
  1758  
  1759  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  1760  		testMethod(t, r, "PATCH")
  1761  		// TODO: remove custom Accept header when this API fully launches
  1762  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1763  		testBody(t, r, `{"dismissal_restrictions":{}}`+"\n")
  1764  		fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`)
  1765  	})
  1766  
  1767  	ctx := context.Background()
  1768  	enforcement, _, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", "b")
  1769  	if err != nil {
  1770  		t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err)
  1771  	}
  1772  
  1773  	want := &PullRequestReviewsEnforcement{
  1774  		DismissStaleReviews:          true,
  1775  		DismissalRestrictions:        nil,
  1776  		RequireCodeOwnerReviews:      true,
  1777  		RequiredApprovingReviewCount: 1,
  1778  	}
  1779  	if !cmp.Equal(enforcement, want) {
  1780  		t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want)
  1781  	}
  1782  
  1783  	const methodName = "DisableDismissalRestrictions"
  1784  	testBadOptions(t, methodName, func() (err error) {
  1785  		_, _, err = client.Repositories.DisableDismissalRestrictions(ctx, "\n", "\n", "\n")
  1786  		return err
  1787  	})
  1788  
  1789  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1790  		got, resp, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", "b")
  1791  		if got != nil {
  1792  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1793  		}
  1794  		return resp, err
  1795  	})
  1796  }
  1797  
  1798  func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) {
  1799  	client, mux, _, teardown := setup()
  1800  	defer teardown()
  1801  
  1802  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  1803  		testMethod(t, r, "DELETE")
  1804  		w.WriteHeader(http.StatusNoContent)
  1805  	})
  1806  
  1807  	ctx := context.Background()
  1808  	_, err := client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", "b")
  1809  	if err != nil {
  1810  		t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err)
  1811  	}
  1812  
  1813  	const methodName = "RemovePullRequestReviewEnforcement"
  1814  	testBadOptions(t, methodName, func() (err error) {
  1815  		_, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  1816  		return err
  1817  	})
  1818  
  1819  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1820  		return client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", "b")
  1821  	})
  1822  }
  1823  
  1824  func TestRepositoriesService_GetAdminEnforcement(t *testing.T) {
  1825  	client, mux, _, teardown := setup()
  1826  	defer teardown()
  1827  
  1828  	mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) {
  1829  		testMethod(t, r, "GET")
  1830  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  1831  	})
  1832  
  1833  	ctx := context.Background()
  1834  	enforcement, _, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", "b")
  1835  	if err != nil {
  1836  		t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err)
  1837  	}
  1838  
  1839  	want := &AdminEnforcement{
  1840  		URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  1841  		Enabled: true,
  1842  	}
  1843  
  1844  	if !cmp.Equal(enforcement, want) {
  1845  		t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want)
  1846  	}
  1847  
  1848  	const methodName = "GetAdminEnforcement"
  1849  	testBadOptions(t, methodName, func() (err error) {
  1850  		_, _, err = client.Repositories.GetAdminEnforcement(ctx, "\n", "\n", "\n")
  1851  		return err
  1852  	})
  1853  
  1854  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1855  		got, resp, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", "b")
  1856  		if got != nil {
  1857  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1858  		}
  1859  		return resp, err
  1860  	})
  1861  }
  1862  
  1863  func TestRepositoriesService_AddAdminEnforcement(t *testing.T) {
  1864  	client, mux, _, teardown := setup()
  1865  	defer teardown()
  1866  
  1867  	mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) {
  1868  		testMethod(t, r, "POST")
  1869  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  1870  	})
  1871  
  1872  	ctx := context.Background()
  1873  	enforcement, _, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", "b")
  1874  	if err != nil {
  1875  		t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err)
  1876  	}
  1877  
  1878  	want := &AdminEnforcement{
  1879  		URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  1880  		Enabled: true,
  1881  	}
  1882  	if !cmp.Equal(enforcement, want) {
  1883  		t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want)
  1884  	}
  1885  
  1886  	const methodName = "AddAdminEnforcement"
  1887  	testBadOptions(t, methodName, func() (err error) {
  1888  		_, _, err = client.Repositories.AddAdminEnforcement(ctx, "\n", "\n", "\n")
  1889  		return err
  1890  	})
  1891  
  1892  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1893  		got, resp, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", "b")
  1894  		if got != nil {
  1895  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1896  		}
  1897  		return resp, err
  1898  	})
  1899  }
  1900  
  1901  func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) {
  1902  	client, mux, _, teardown := setup()
  1903  	defer teardown()
  1904  
  1905  	mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) {
  1906  		testMethod(t, r, "DELETE")
  1907  		w.WriteHeader(http.StatusNoContent)
  1908  	})
  1909  
  1910  	ctx := context.Background()
  1911  	_, err := client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", "b")
  1912  	if err != nil {
  1913  		t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err)
  1914  	}
  1915  
  1916  	const methodName = "RemoveAdminEnforcement"
  1917  	testBadOptions(t, methodName, func() (err error) {
  1918  		_, err = client.Repositories.RemoveAdminEnforcement(ctx, "\n", "\n", "\n")
  1919  		return err
  1920  	})
  1921  
  1922  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1923  		return client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", "b")
  1924  	})
  1925  }
  1926  
  1927  func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) {
  1928  	client, mux, _, teardown := setup()
  1929  	defer teardown()
  1930  
  1931  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) {
  1932  		testMethod(t, r, "GET")
  1933  		testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  1934  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`)
  1935  	})
  1936  
  1937  	ctx := context.Background()
  1938  	signature, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", "b")
  1939  	if err != nil {
  1940  		t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err)
  1941  	}
  1942  
  1943  	want := &SignaturesProtectedBranch{
  1944  		URL:     String("/repos/o/r/branches/b/protection/required_signatures"),
  1945  		Enabled: Bool(false),
  1946  	}
  1947  
  1948  	if !cmp.Equal(signature, want) {
  1949  		t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want)
  1950  	}
  1951  
  1952  	const methodName = "GetSignaturesProtectedBranch"
  1953  	testBadOptions(t, methodName, func() (err error) {
  1954  		_, _, err = client.Repositories.GetSignaturesProtectedBranch(ctx, "\n", "\n", "\n")
  1955  		return err
  1956  	})
  1957  
  1958  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1959  		got, resp, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", "b")
  1960  		if got != nil {
  1961  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1962  		}
  1963  		return resp, err
  1964  	})
  1965  }
  1966  
  1967  func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) {
  1968  	client, mux, _, teardown := setup()
  1969  	defer teardown()
  1970  
  1971  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) {
  1972  		testMethod(t, r, "POST")
  1973  		testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  1974  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`)
  1975  	})
  1976  
  1977  	ctx := context.Background()
  1978  	signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  1979  	if err != nil {
  1980  		t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err)
  1981  	}
  1982  
  1983  	want := &SignaturesProtectedBranch{
  1984  		URL:     String("/repos/o/r/branches/b/protection/required_signatures"),
  1985  		Enabled: Bool(true),
  1986  	}
  1987  
  1988  	if !cmp.Equal(signature, want) {
  1989  		t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want)
  1990  	}
  1991  
  1992  	const methodName = "RequireSignaturesOnProtectedBranch"
  1993  	testBadOptions(t, methodName, func() (err error) {
  1994  		_, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  1995  		return err
  1996  	})
  1997  
  1998  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1999  		got, resp, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  2000  		if got != nil {
  2001  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2002  		}
  2003  		return resp, err
  2004  	})
  2005  }
  2006  
  2007  func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) {
  2008  	client, mux, _, teardown := setup()
  2009  	defer teardown()
  2010  
  2011  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) {
  2012  		testMethod(t, r, "DELETE")
  2013  		testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  2014  		w.WriteHeader(http.StatusNoContent)
  2015  	})
  2016  
  2017  	ctx := context.Background()
  2018  	_, err := client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  2019  	if err != nil {
  2020  		t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err)
  2021  	}
  2022  
  2023  	const methodName = "OptionalSignaturesOnProtectedBranch"
  2024  	testBadOptions(t, methodName, func() (err error) {
  2025  		_, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  2026  		return err
  2027  	})
  2028  
  2029  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2030  		return client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  2031  	})
  2032  }
  2033  
  2034  func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) {
  2035  	req := PullRequestReviewsEnforcementRequest{}
  2036  
  2037  	got, err := json.Marshal(req)
  2038  	if err != nil {
  2039  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  2040  	}
  2041  
  2042  	want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  2043  	if want != string(got) {
  2044  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  2045  	}
  2046  
  2047  	req = PullRequestReviewsEnforcementRequest{
  2048  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{},
  2049  	}
  2050  
  2051  	got, err = json.Marshal(req)
  2052  	if err != nil {
  2053  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  2054  	}
  2055  
  2056  	want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  2057  	if want != string(got) {
  2058  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  2059  	}
  2060  
  2061  	req = PullRequestReviewsEnforcementRequest{
  2062  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  2063  			Users: &[]string{},
  2064  			Teams: &[]string{},
  2065  		},
  2066  	}
  2067  
  2068  	got, err = json.Marshal(req)
  2069  	if err != nil {
  2070  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  2071  	}
  2072  
  2073  	want = `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  2074  	if want != string(got) {
  2075  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  2076  	}
  2077  }
  2078  
  2079  func TestRepositoriesService_ListAllTopics(t *testing.T) {
  2080  	client, mux, _, teardown := setup()
  2081  	defer teardown()
  2082  
  2083  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2084  		testMethod(t, r, "GET")
  2085  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2086  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  2087  	})
  2088  
  2089  	ctx := context.Background()
  2090  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  2091  	if err != nil {
  2092  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  2093  	}
  2094  
  2095  	want := []string{"go", "go-github", "github"}
  2096  	if !cmp.Equal(got, want) {
  2097  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  2098  	}
  2099  
  2100  	const methodName = "ListAllTopics"
  2101  	testBadOptions(t, methodName, func() (err error) {
  2102  		_, _, err = client.Repositories.ListAllTopics(ctx, "\n", "\n")
  2103  		return err
  2104  	})
  2105  
  2106  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2107  		got, resp, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  2108  		if got != nil {
  2109  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2110  		}
  2111  		return resp, err
  2112  	})
  2113  }
  2114  
  2115  func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) {
  2116  	client, mux, _, teardown := setup()
  2117  	defer teardown()
  2118  
  2119  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2120  		testMethod(t, r, "GET")
  2121  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2122  		fmt.Fprint(w, `{"names":[]}`)
  2123  	})
  2124  
  2125  	ctx := context.Background()
  2126  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  2127  	if err != nil {
  2128  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  2129  	}
  2130  
  2131  	want := []string{}
  2132  	if !cmp.Equal(got, want) {
  2133  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  2134  	}
  2135  }
  2136  
  2137  func TestRepositoriesService_ReplaceAllTopics(t *testing.T) {
  2138  	client, mux, _, teardown := setup()
  2139  	defer teardown()
  2140  
  2141  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2142  		testMethod(t, r, "PUT")
  2143  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2144  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  2145  	})
  2146  
  2147  	ctx := context.Background()
  2148  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  2149  	if err != nil {
  2150  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  2151  	}
  2152  
  2153  	want := []string{"go", "go-github", "github"}
  2154  	if !cmp.Equal(got, want) {
  2155  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  2156  	}
  2157  
  2158  	const methodName = "ReplaceAllTopics"
  2159  	testBadOptions(t, methodName, func() (err error) {
  2160  		_, _, err = client.Repositories.ReplaceAllTopics(ctx, "\n", "\n", []string{"\n", "\n", "\n"})
  2161  		return err
  2162  	})
  2163  
  2164  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2165  		got, resp, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  2166  		if got != nil {
  2167  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2168  		}
  2169  		return resp, err
  2170  	})
  2171  }
  2172  
  2173  func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) {
  2174  	client, mux, _, teardown := setup()
  2175  	defer teardown()
  2176  
  2177  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2178  		testMethod(t, r, "PUT")
  2179  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2180  		testBody(t, r, `{"names":[]}`+"\n")
  2181  		fmt.Fprint(w, `{"names":[]}`)
  2182  	})
  2183  
  2184  	ctx := context.Background()
  2185  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", nil)
  2186  	if err != nil {
  2187  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  2188  	}
  2189  
  2190  	want := []string{}
  2191  	if !cmp.Equal(got, want) {
  2192  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  2193  	}
  2194  }
  2195  
  2196  func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) {
  2197  	client, mux, _, teardown := setup()
  2198  	defer teardown()
  2199  
  2200  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2201  		testMethod(t, r, "PUT")
  2202  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2203  		testBody(t, r, `{"names":[]}`+"\n")
  2204  		fmt.Fprint(w, `{"names":[]}`)
  2205  	})
  2206  
  2207  	ctx := context.Background()
  2208  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{})
  2209  	if err != nil {
  2210  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  2211  	}
  2212  
  2213  	want := []string{}
  2214  	if !cmp.Equal(got, want) {
  2215  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  2216  	}
  2217  }
  2218  
  2219  func TestRepositoriesService_ListApps(t *testing.T) {
  2220  	client, mux, _, teardown := setup()
  2221  	defer teardown()
  2222  
  2223  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2224  		testMethod(t, r, "GET")
  2225  	})
  2226  
  2227  	ctx := context.Background()
  2228  	_, _, err := client.Repositories.ListApps(ctx, "o", "r", "b")
  2229  	if err != nil {
  2230  		t.Errorf("Repositories.ListApps returned error: %v", err)
  2231  	}
  2232  
  2233  	const methodName = "ListApps"
  2234  	testBadOptions(t, methodName, func() (err error) {
  2235  		_, _, err = client.Repositories.ListApps(ctx, "\n", "\n", "\n")
  2236  		return err
  2237  	})
  2238  
  2239  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2240  		got, resp, err := client.Repositories.ListApps(ctx, "o", "r", "b")
  2241  		if got != nil {
  2242  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2243  		}
  2244  		return resp, err
  2245  	})
  2246  }
  2247  
  2248  func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) {
  2249  	client, mux, _, teardown := setup()
  2250  	defer teardown()
  2251  
  2252  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2253  		testMethod(t, r, "PUT")
  2254  		fmt.Fprint(w, `[{
  2255  				"name": "octocat"
  2256  			}]`)
  2257  	})
  2258  	input := []string{"octocat"}
  2259  	ctx := context.Background()
  2260  	got, _, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", "b", input)
  2261  	if err != nil {
  2262  		t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err)
  2263  	}
  2264  	want := []*App{
  2265  		{Name: String("octocat")},
  2266  	}
  2267  	if !cmp.Equal(got, want) {
  2268  		t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want)
  2269  	}
  2270  
  2271  	const methodName = "ReplaceAppRestrictions"
  2272  	testBadOptions(t, methodName, func() (err error) {
  2273  		_, _, err = client.Repositories.ReplaceAppRestrictions(ctx, "\n", "\n", "\n", input)
  2274  		return err
  2275  	})
  2276  
  2277  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2278  		got, resp, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", "b", input)
  2279  		if got != nil {
  2280  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2281  		}
  2282  		return resp, err
  2283  	})
  2284  }
  2285  
  2286  func TestRepositoriesService_AddAppRestrictions(t *testing.T) {
  2287  	client, mux, _, teardown := setup()
  2288  	defer teardown()
  2289  
  2290  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2291  		testMethod(t, r, "POST")
  2292  		fmt.Fprint(w, `[{
  2293  				"name": "octocat"
  2294  			}]`)
  2295  	})
  2296  	input := []string{"octocat"}
  2297  	ctx := context.Background()
  2298  	got, _, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", "b", input)
  2299  	if err != nil {
  2300  		t.Errorf("Repositories.AddAppRestrictions returned error: %v", err)
  2301  	}
  2302  	want := []*App{
  2303  		{Name: String("octocat")},
  2304  	}
  2305  	if !cmp.Equal(got, want) {
  2306  		t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want)
  2307  	}
  2308  
  2309  	const methodName = "AddAppRestrictions"
  2310  	testBadOptions(t, methodName, func() (err error) {
  2311  		_, _, err = client.Repositories.AddAppRestrictions(ctx, "\n", "\n", "\n", input)
  2312  		return err
  2313  	})
  2314  
  2315  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2316  		got, resp, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", "b", input)
  2317  		if got != nil {
  2318  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2319  		}
  2320  		return resp, err
  2321  	})
  2322  }
  2323  
  2324  func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) {
  2325  	client, mux, _, teardown := setup()
  2326  	defer teardown()
  2327  
  2328  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2329  		testMethod(t, r, "DELETE")
  2330  		fmt.Fprint(w, `[]`)
  2331  	})
  2332  	input := []string{"octocat"}
  2333  	ctx := context.Background()
  2334  	got, _, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", "b", input)
  2335  	if err != nil {
  2336  		t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err)
  2337  	}
  2338  	want := []*App{}
  2339  	if !cmp.Equal(got, want) {
  2340  		t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want)
  2341  	}
  2342  
  2343  	const methodName = "RemoveAppRestrictions"
  2344  	testBadOptions(t, methodName, func() (err error) {
  2345  		_, _, err = client.Repositories.RemoveAppRestrictions(ctx, "\n", "\n", "\n", input)
  2346  		return err
  2347  	})
  2348  
  2349  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2350  		got, resp, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", "b", input)
  2351  		if got != nil {
  2352  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2353  		}
  2354  		return resp, err
  2355  	})
  2356  }
  2357  
  2358  func TestRepositoriesService_Transfer(t *testing.T) {
  2359  	client, mux, _, teardown := setup()
  2360  	defer teardown()
  2361  
  2362  	input := TransferRequest{NewOwner: "a", TeamID: []int64{123}}
  2363  
  2364  	mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) {
  2365  		var v TransferRequest
  2366  		json.NewDecoder(r.Body).Decode(&v)
  2367  
  2368  		testMethod(t, r, "POST")
  2369  		if !cmp.Equal(v, input) {
  2370  			t.Errorf("Request body = %+v, want %+v", v, input)
  2371  		}
  2372  
  2373  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  2374  	})
  2375  
  2376  	ctx := context.Background()
  2377  	got, _, err := client.Repositories.Transfer(ctx, "o", "r", input)
  2378  	if err != nil {
  2379  		t.Errorf("Repositories.Transfer returned error: %v", err)
  2380  	}
  2381  
  2382  	want := &Repository{Owner: &User{Login: String("a")}}
  2383  	if !cmp.Equal(got, want) {
  2384  		t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want)
  2385  	}
  2386  
  2387  	const methodName = "Transfer"
  2388  	testBadOptions(t, methodName, func() (err error) {
  2389  		_, _, err = client.Repositories.Transfer(ctx, "\n", "\n", input)
  2390  		return err
  2391  	})
  2392  
  2393  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2394  		got, resp, err := client.Repositories.Transfer(ctx, "o", "r", input)
  2395  		if got != nil {
  2396  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2397  		}
  2398  		return resp, err
  2399  	})
  2400  }
  2401  
  2402  func TestRepositoriesService_Dispatch(t *testing.T) {
  2403  	client, mux, _, teardown := setup()
  2404  	defer teardown()
  2405  
  2406  	var input DispatchRequestOptions
  2407  
  2408  	mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) {
  2409  		var v DispatchRequestOptions
  2410  		json.NewDecoder(r.Body).Decode(&v)
  2411  
  2412  		testMethod(t, r, "POST")
  2413  		if !cmp.Equal(v, input) {
  2414  			t.Errorf("Request body = %+v, want %+v", v, input)
  2415  		}
  2416  
  2417  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  2418  	})
  2419  
  2420  	ctx := context.Background()
  2421  
  2422  	testCases := []interface{}{
  2423  		nil,
  2424  		struct {
  2425  			Foo string
  2426  		}{
  2427  			Foo: "test",
  2428  		},
  2429  		struct {
  2430  			Bar int
  2431  		}{
  2432  			Bar: 42,
  2433  		},
  2434  		struct {
  2435  			Foo string
  2436  			Bar int
  2437  			Baz bool
  2438  		}{
  2439  			Foo: "test",
  2440  			Bar: 42,
  2441  			Baz: false,
  2442  		},
  2443  	}
  2444  
  2445  	for _, tc := range testCases {
  2446  		if tc == nil {
  2447  			input = DispatchRequestOptions{EventType: "go"}
  2448  		} else {
  2449  			bytes, _ := json.Marshal(tc)
  2450  			payload := json.RawMessage(bytes)
  2451  			input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload}
  2452  		}
  2453  
  2454  		got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  2455  		if err != nil {
  2456  			t.Errorf("Repositories.Dispatch returned error: %v", err)
  2457  		}
  2458  
  2459  		want := &Repository{Owner: &User{Login: String("a")}}
  2460  		if !cmp.Equal(got, want) {
  2461  			t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want)
  2462  		}
  2463  	}
  2464  
  2465  	const methodName = "Dispatch"
  2466  	testBadOptions(t, methodName, func() (err error) {
  2467  		_, _, err = client.Repositories.Dispatch(ctx, "\n", "\n", input)
  2468  		return err
  2469  	})
  2470  
  2471  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2472  		got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  2473  		if got != nil {
  2474  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2475  		}
  2476  		return resp, err
  2477  	})
  2478  }
  2479  
  2480  func TestAdvancedSecurity_Marshal(t *testing.T) {
  2481  	testJSONMarshal(t, &AdvancedSecurity{}, "{}")
  2482  
  2483  	u := &AdvancedSecurity{
  2484  		Status: String("status"),
  2485  	}
  2486  
  2487  	want := `{
  2488  		"status": "status"
  2489  	}`
  2490  
  2491  	testJSONMarshal(t, u, want)
  2492  }
  2493  
  2494  func TestAuthorizedActorsOnly_Marshal(t *testing.T) {
  2495  	testJSONMarshal(t, &AuthorizedActorsOnly{}, "{}")
  2496  
  2497  	u := &AuthorizedActorsOnly{
  2498  		From: Bool(true),
  2499  	}
  2500  
  2501  	want := `{
  2502  		"from" : true
  2503  	}`
  2504  
  2505  	testJSONMarshal(t, u, want)
  2506  }