github.com/google/go-github/v49@v49.1.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"},"secret_scanning_push_protection":{"status":"enabled"}}}`)
   364  	})
   365  
   366  	ctx := context.Background()
   367  	got, _, err := client.Repositories.Get(ctx, "o", "r")
   368  	if err != nil {
   369  		t.Errorf("Repositories.Get returned error: %v", err)
   370  	}
   371  
   372  	want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: String("enabled")}, SecretScanning: &SecretScanning{String("enabled")}, SecretScanningPushProtection: &SecretScanningPushProtection{String("enabled")}}}
   373  	if !cmp.Equal(got, want) {
   374  		t.Errorf("Repositories.Get returned %+v, want %+v", got, want)
   375  	}
   376  
   377  	const methodName = "Get"
   378  	testBadOptions(t, methodName, func() (err error) {
   379  		_, _, err = client.Repositories.Get(ctx, "\n", "\n")
   380  		return err
   381  	})
   382  
   383  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   384  		got, resp, err := client.Repositories.Get(ctx, "o", "r")
   385  		if got != nil {
   386  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   387  		}
   388  		return resp, err
   389  	})
   390  }
   391  
   392  func TestRepositoriesService_GetCodeOfConduct(t *testing.T) {
   393  	client, mux, _, teardown := setup()
   394  	defer teardown()
   395  
   396  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   397  		testMethod(t, r, "GET")
   398  		testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview)
   399  		fmt.Fprint(w, `{
   400              "code_of_conduct": {
   401    						"key": "key",
   402    						"name": "name",
   403    						"url": "url",
   404    						"body": "body"
   405              }}`,
   406  		)
   407  	})
   408  
   409  	ctx := context.Background()
   410  	got, _, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
   411  	if err != nil {
   412  		t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err)
   413  	}
   414  
   415  	want := &CodeOfConduct{
   416  		Key:  String("key"),
   417  		Name: String("name"),
   418  		URL:  String("url"),
   419  		Body: String("body"),
   420  	}
   421  
   422  	if !cmp.Equal(got, want) {
   423  		t.Errorf("Repositories.GetCodeOfConduct returned %+v, want %+v", got, want)
   424  	}
   425  
   426  	const methodName = "GetCodeOfConduct"
   427  	testBadOptions(t, methodName, func() (err error) {
   428  		_, _, err = client.Repositories.GetCodeOfConduct(ctx, "\n", "\n")
   429  		return err
   430  	})
   431  
   432  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   433  		got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r")
   434  		if got != nil {
   435  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   436  		}
   437  		return resp, err
   438  	})
   439  }
   440  
   441  func TestRepositoriesService_GetByID(t *testing.T) {
   442  	client, mux, _, teardown := setup()
   443  	defer teardown()
   444  
   445  	mux.HandleFunc("/repositories/1", func(w http.ResponseWriter, r *http.Request) {
   446  		testMethod(t, r, "GET")
   447  		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`)
   448  	})
   449  
   450  	ctx := context.Background()
   451  	got, _, err := client.Repositories.GetByID(ctx, 1)
   452  	if err != nil {
   453  		t.Fatalf("Repositories.GetByID returned error: %v", err)
   454  	}
   455  
   456  	want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}}
   457  	if !cmp.Equal(got, want) {
   458  		t.Errorf("Repositories.GetByID returned %+v, want %+v", got, want)
   459  	}
   460  
   461  	const methodName = "GetByID"
   462  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   463  		got, resp, err := client.Repositories.GetByID(ctx, 1)
   464  		if got != nil {
   465  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   466  		}
   467  		return resp, err
   468  	})
   469  }
   470  
   471  func TestRepositoriesService_Edit(t *testing.T) {
   472  	client, mux, _, teardown := setup()
   473  	defer teardown()
   474  
   475  	i := true
   476  	input := &Repository{HasIssues: &i}
   477  
   478  	wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview}
   479  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   480  		v := new(Repository)
   481  		json.NewDecoder(r.Body).Decode(v)
   482  
   483  		testMethod(t, r, "PATCH")
   484  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   485  		if !cmp.Equal(v, input) {
   486  			t.Errorf("Request body = %+v, want %+v", v, input)
   487  		}
   488  		fmt.Fprint(w, `{"id":1}`)
   489  	})
   490  
   491  	ctx := context.Background()
   492  	got, _, err := client.Repositories.Edit(ctx, "o", "r", input)
   493  	if err != nil {
   494  		t.Errorf("Repositories.Edit returned error: %v", err)
   495  	}
   496  
   497  	want := &Repository{ID: Int64(1)}
   498  	if !cmp.Equal(got, want) {
   499  		t.Errorf("Repositories.Edit returned %+v, want %+v", got, want)
   500  	}
   501  
   502  	const methodName = "Edit"
   503  	testBadOptions(t, methodName, func() (err error) {
   504  		_, _, err = client.Repositories.Edit(ctx, "\n", "\n", input)
   505  		return err
   506  	})
   507  
   508  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   509  		got, resp, err := client.Repositories.Edit(ctx, "o", "r", input)
   510  		if got != nil {
   511  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   512  		}
   513  		return resp, err
   514  	})
   515  }
   516  
   517  func TestRepositoriesService_Delete(t *testing.T) {
   518  	client, mux, _, teardown := setup()
   519  	defer teardown()
   520  
   521  	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
   522  		testMethod(t, r, "DELETE")
   523  	})
   524  
   525  	ctx := context.Background()
   526  	_, err := client.Repositories.Delete(ctx, "o", "r")
   527  	if err != nil {
   528  		t.Errorf("Repositories.Delete returned error: %v", err)
   529  	}
   530  
   531  	const methodName = "Delete"
   532  	testBadOptions(t, methodName, func() (err error) {
   533  		_, err = client.Repositories.Delete(ctx, "\n", "\n")
   534  		return err
   535  	})
   536  
   537  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   538  		return client.Repositories.Delete(ctx, "o", "r")
   539  	})
   540  }
   541  
   542  func TestRepositoriesService_Get_invalidOwner(t *testing.T) {
   543  	client, _, _, teardown := setup()
   544  	defer teardown()
   545  
   546  	ctx := context.Background()
   547  	_, _, err := client.Repositories.Get(ctx, "%", "r")
   548  	testURLParseError(t, err)
   549  }
   550  
   551  func TestRepositoriesService_Edit_invalidOwner(t *testing.T) {
   552  	client, _, _, teardown := setup()
   553  	defer teardown()
   554  
   555  	ctx := context.Background()
   556  	_, _, err := client.Repositories.Edit(ctx, "%", "r", nil)
   557  	testURLParseError(t, err)
   558  }
   559  
   560  func TestRepositoriesService_GetVulnerabilityAlerts(t *testing.T) {
   561  	client, mux, _, teardown := setup()
   562  	defer teardown()
   563  
   564  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   565  		testMethod(t, r, "GET")
   566  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   567  
   568  		w.WriteHeader(http.StatusNoContent)
   569  	})
   570  
   571  	ctx := context.Background()
   572  	vulnerabilityAlertsEnabled, _, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r")
   573  	if err != nil {
   574  		t.Errorf("Repositories.GetVulnerabilityAlerts returned error: %v", err)
   575  	}
   576  
   577  	if want := true; vulnerabilityAlertsEnabled != want {
   578  		t.Errorf("Repositories.GetVulnerabilityAlerts returned %+v, want %+v", vulnerabilityAlertsEnabled, want)
   579  	}
   580  
   581  	const methodName = "GetVulnerabilityAlerts"
   582  	testBadOptions(t, methodName, func() (err error) {
   583  		_, _, err = client.Repositories.GetVulnerabilityAlerts(ctx, "\n", "\n")
   584  		return err
   585  	})
   586  
   587  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   588  		got, resp, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r")
   589  		if got {
   590  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want false", methodName, got)
   591  		}
   592  		return resp, err
   593  	})
   594  }
   595  
   596  func TestRepositoriesService_EnableVulnerabilityAlerts(t *testing.T) {
   597  	client, mux, _, teardown := setup()
   598  	defer teardown()
   599  
   600  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   601  		testMethod(t, r, "PUT")
   602  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   603  
   604  		w.WriteHeader(http.StatusNoContent)
   605  	})
   606  
   607  	ctx := context.Background()
   608  	if _, err := client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r"); err != nil {
   609  		t.Errorf("Repositories.EnableVulnerabilityAlerts returned error: %v", err)
   610  	}
   611  
   612  	const methodName = "EnableVulnerabilityAlerts"
   613  	testBadOptions(t, methodName, func() (err error) {
   614  		_, err = client.Repositories.EnableVulnerabilityAlerts(ctx, "\n", "\n")
   615  		return err
   616  	})
   617  
   618  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   619  		return client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r")
   620  	})
   621  }
   622  
   623  func TestRepositoriesService_DisableVulnerabilityAlerts(t *testing.T) {
   624  	client, mux, _, teardown := setup()
   625  	defer teardown()
   626  
   627  	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
   628  		testMethod(t, r, "DELETE")
   629  		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
   630  
   631  		w.WriteHeader(http.StatusNoContent)
   632  	})
   633  
   634  	ctx := context.Background()
   635  	if _, err := client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r"); err != nil {
   636  		t.Errorf("Repositories.DisableVulnerabilityAlerts returned error: %v", err)
   637  	}
   638  
   639  	const methodName = "DisableVulnerabilityAlerts"
   640  	testBadOptions(t, methodName, func() (err error) {
   641  		_, err = client.Repositories.DisableVulnerabilityAlerts(ctx, "\n", "\n")
   642  		return err
   643  	})
   644  
   645  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   646  		return client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r")
   647  	})
   648  }
   649  
   650  func TestRepositoriesService_EnableAutomatedSecurityFixes(t *testing.T) {
   651  	client, mux, _, teardown := setup()
   652  	defer teardown()
   653  
   654  	mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) {
   655  		testMethod(t, r, "PUT")
   656  		testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview)
   657  
   658  		w.WriteHeader(http.StatusNoContent)
   659  	})
   660  
   661  	ctx := context.Background()
   662  	if _, err := client.Repositories.EnableAutomatedSecurityFixes(ctx, "o", "r"); err != nil {
   663  		t.Errorf("Repositories.EnableAutomatedSecurityFixes returned error: %v", err)
   664  	}
   665  }
   666  
   667  func TestRepositoriesService_DisableAutomatedSecurityFixes(t *testing.T) {
   668  	client, mux, _, teardown := setup()
   669  	defer teardown()
   670  
   671  	mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) {
   672  		testMethod(t, r, "DELETE")
   673  		testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview)
   674  
   675  		w.WriteHeader(http.StatusNoContent)
   676  	})
   677  
   678  	ctx := context.Background()
   679  	if _, err := client.Repositories.DisableAutomatedSecurityFixes(ctx, "o", "r"); err != nil {
   680  		t.Errorf("Repositories.DisableAutomatedSecurityFixes returned error: %v", err)
   681  	}
   682  }
   683  
   684  func TestRepositoriesService_ListContributors(t *testing.T) {
   685  	client, mux, _, teardown := setup()
   686  	defer teardown()
   687  
   688  	mux.HandleFunc("/repos/o/r/contributors", func(w http.ResponseWriter, r *http.Request) {
   689  		testMethod(t, r, "GET")
   690  		testFormValues(t, r, values{
   691  			"anon": "true",
   692  			"page": "2",
   693  		})
   694  		fmt.Fprint(w, `[{"contributions":42}]`)
   695  	})
   696  
   697  	opts := &ListContributorsOptions{Anon: "true", ListOptions: ListOptions{Page: 2}}
   698  	ctx := context.Background()
   699  	contributors, _, err := client.Repositories.ListContributors(ctx, "o", "r", opts)
   700  	if err != nil {
   701  		t.Errorf("Repositories.ListContributors returned error: %v", err)
   702  	}
   703  
   704  	want := []*Contributor{{Contributions: Int(42)}}
   705  	if !cmp.Equal(contributors, want) {
   706  		t.Errorf("Repositories.ListContributors returned %+v, want %+v", contributors, want)
   707  	}
   708  
   709  	const methodName = "ListContributors"
   710  	testBadOptions(t, methodName, func() (err error) {
   711  		_, _, err = client.Repositories.ListContributors(ctx, "\n", "\n", opts)
   712  		return err
   713  	})
   714  
   715  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   716  		got, resp, err := client.Repositories.ListContributors(ctx, "o", "r", opts)
   717  		if got != nil {
   718  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   719  		}
   720  		return resp, err
   721  	})
   722  }
   723  
   724  func TestRepositoriesService_ListLanguages(t *testing.T) {
   725  	client, mux, _, teardown := setup()
   726  	defer teardown()
   727  
   728  	mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) {
   729  		testMethod(t, r, "GET")
   730  		fmt.Fprint(w, `{"go":1}`)
   731  	})
   732  
   733  	ctx := context.Background()
   734  	languages, _, err := client.Repositories.ListLanguages(ctx, "o", "r")
   735  	if err != nil {
   736  		t.Errorf("Repositories.ListLanguages returned error: %v", err)
   737  	}
   738  
   739  	want := map[string]int{"go": 1}
   740  	if !cmp.Equal(languages, want) {
   741  		t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want)
   742  	}
   743  
   744  	const methodName = "ListLanguages"
   745  	testBadOptions(t, methodName, func() (err error) {
   746  		_, _, err = client.Repositories.ListLanguages(ctx, "\n", "\n")
   747  		return err
   748  	})
   749  
   750  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   751  		got, resp, err := client.Repositories.ListLanguages(ctx, "o", "r")
   752  		if got != nil {
   753  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   754  		}
   755  		return resp, err
   756  	})
   757  }
   758  
   759  func TestRepositoriesService_ListTeams(t *testing.T) {
   760  	client, mux, _, teardown := setup()
   761  	defer teardown()
   762  
   763  	mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) {
   764  		testMethod(t, r, "GET")
   765  		testFormValues(t, r, values{"page": "2"})
   766  		fmt.Fprint(w, `[{"id":1}]`)
   767  	})
   768  
   769  	opt := &ListOptions{Page: 2}
   770  	ctx := context.Background()
   771  	teams, _, err := client.Repositories.ListTeams(ctx, "o", "r", opt)
   772  	if err != nil {
   773  		t.Errorf("Repositories.ListTeams returned error: %v", err)
   774  	}
   775  
   776  	want := []*Team{{ID: Int64(1)}}
   777  	if !cmp.Equal(teams, want) {
   778  		t.Errorf("Repositories.ListTeams returned %+v, want %+v", teams, want)
   779  	}
   780  
   781  	const methodName = "ListTeams"
   782  	testBadOptions(t, methodName, func() (err error) {
   783  		_, _, err = client.Repositories.ListTeams(ctx, "\n", "\n", opt)
   784  		return err
   785  	})
   786  
   787  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   788  		got, resp, err := client.Repositories.ListTeams(ctx, "o", "r", opt)
   789  		if got != nil {
   790  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   791  		}
   792  		return resp, err
   793  	})
   794  }
   795  
   796  func TestRepositoriesService_ListTags(t *testing.T) {
   797  	client, mux, _, teardown := setup()
   798  	defer teardown()
   799  
   800  	mux.HandleFunc("/repos/o/r/tags", func(w http.ResponseWriter, r *http.Request) {
   801  		testMethod(t, r, "GET")
   802  		testFormValues(t, r, values{"page": "2"})
   803  		fmt.Fprint(w, `[{"name":"n", "commit" : {"sha" : "s", "url" : "u"}, "zipball_url": "z", "tarball_url": "t"}]`)
   804  	})
   805  
   806  	opt := &ListOptions{Page: 2}
   807  	ctx := context.Background()
   808  	tags, _, err := client.Repositories.ListTags(ctx, "o", "r", opt)
   809  	if err != nil {
   810  		t.Errorf("Repositories.ListTags returned error: %v", err)
   811  	}
   812  
   813  	want := []*RepositoryTag{
   814  		{
   815  			Name: String("n"),
   816  			Commit: &Commit{
   817  				SHA: String("s"),
   818  				URL: String("u"),
   819  			},
   820  			ZipballURL: String("z"),
   821  			TarballURL: String("t"),
   822  		},
   823  	}
   824  	if !cmp.Equal(tags, want) {
   825  		t.Errorf("Repositories.ListTags returned %+v, want %+v", tags, want)
   826  	}
   827  
   828  	const methodName = "ListTags"
   829  	testBadOptions(t, methodName, func() (err error) {
   830  		_, _, err = client.Repositories.ListTags(ctx, "\n", "\n", opt)
   831  		return err
   832  	})
   833  
   834  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   835  		got, resp, err := client.Repositories.ListTags(ctx, "o", "r", opt)
   836  		if got != nil {
   837  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   838  		}
   839  		return resp, err
   840  	})
   841  }
   842  
   843  func TestRepositoriesService_ListBranches(t *testing.T) {
   844  	client, mux, _, teardown := setup()
   845  	defer teardown()
   846  
   847  	mux.HandleFunc("/repos/o/r/branches", func(w http.ResponseWriter, r *http.Request) {
   848  		testMethod(t, r, "GET")
   849  		testFormValues(t, r, values{"page": "2"})
   850  		fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`)
   851  	})
   852  
   853  	opt := &BranchListOptions{
   854  		Protected:   nil,
   855  		ListOptions: ListOptions{Page: 2},
   856  	}
   857  	ctx := context.Background()
   858  	branches, _, err := client.Repositories.ListBranches(ctx, "o", "r", opt)
   859  	if err != nil {
   860  		t.Errorf("Repositories.ListBranches returned error: %v", err)
   861  	}
   862  
   863  	want := []*Branch{{Name: String("master"), Commit: &RepositoryCommit{SHA: String("a57781"), URL: String("https://api.github.com/repos/o/r/commits/a57781")}}}
   864  	if !cmp.Equal(branches, want) {
   865  		t.Errorf("Repositories.ListBranches returned %+v, want %+v", branches, want)
   866  	}
   867  
   868  	const methodName = "ListBranches"
   869  	testBadOptions(t, methodName, func() (err error) {
   870  		_, _, err = client.Repositories.ListBranches(ctx, "\n", "\n", opt)
   871  		return err
   872  	})
   873  
   874  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   875  		got, resp, err := client.Repositories.ListBranches(ctx, "o", "r", opt)
   876  		if got != nil {
   877  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   878  		}
   879  		return resp, err
   880  	})
   881  }
   882  
   883  func TestRepositoriesService_GetBranch(t *testing.T) {
   884  	client, mux, _, teardown := setup()
   885  	defer teardown()
   886  
   887  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
   888  		testMethod(t, r, "GET")
   889  		fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`)
   890  	})
   891  
   892  	ctx := context.Background()
   893  	branch, _, err := client.Repositories.GetBranch(ctx, "o", "r", "b", false)
   894  	if err != nil {
   895  		t.Errorf("Repositories.GetBranch returned error: %v", err)
   896  	}
   897  
   898  	want := &Branch{
   899  		Name: String("n"),
   900  		Commit: &RepositoryCommit{
   901  			SHA: String("s"),
   902  			Commit: &Commit{
   903  				Message: String("m"),
   904  			},
   905  		},
   906  		Protected: Bool(true),
   907  	}
   908  
   909  	if !cmp.Equal(branch, want) {
   910  		t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
   911  	}
   912  
   913  	const methodName = "GetBranch"
   914  	testBadOptions(t, methodName, func() (err error) {
   915  		_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", false)
   916  		return err
   917  	})
   918  }
   919  
   920  func TestRepositoriesService_GetBranch_BadJSONResponse(t *testing.T) {
   921  	client, mux, _, teardown := setup()
   922  	defer teardown()
   923  
   924  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
   925  		testMethod(t, r, "GET")
   926  		fmt.Fprint(w, `{"name":"n", "commit":{"sha":...truncated`)
   927  	})
   928  
   929  	ctx := context.Background()
   930  	if _, _, err := client.Repositories.GetBranch(ctx, "o", "r", "b", false); err == nil {
   931  		t.Error("Repositories.GetBranch returned no error; wanted JSON error")
   932  	}
   933  }
   934  
   935  func TestRepositoriesService_GetBranch_StatusMovedPermanently_followRedirects(t *testing.T) {
   936  	client, mux, serverURL, teardown := setup()
   937  	defer teardown()
   938  
   939  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
   940  		testMethod(t, r, "GET")
   941  		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/repos/o/r/branches/br")
   942  		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
   943  	})
   944  	mux.HandleFunc("/repos/o/r/branches/br", func(w http.ResponseWriter, r *http.Request) {
   945  		testMethod(t, r, "GET")
   946  		fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`)
   947  	})
   948  	ctx := context.Background()
   949  	branch, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true)
   950  	if err != nil {
   951  		t.Errorf("Repositories.GetBranch returned error: %v", err)
   952  	}
   953  	if resp.StatusCode != http.StatusOK {
   954  		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusOK)
   955  	}
   956  
   957  	want := &Branch{
   958  		Name: String("n"),
   959  		Commit: &RepositoryCommit{
   960  			SHA: String("s"),
   961  			Commit: &Commit{
   962  				Message: String("m"),
   963  			},
   964  		},
   965  		Protected: Bool(true),
   966  	}
   967  	if !cmp.Equal(branch, want) {
   968  		t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
   969  	}
   970  }
   971  
   972  func TestRepositoriesService_GetBranch_notFound(t *testing.T) {
   973  	client, mux, _, teardown := setup()
   974  	defer teardown()
   975  
   976  	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
   977  		testMethod(t, r, "GET")
   978  		http.Error(w, "branch not found", http.StatusNotFound)
   979  	})
   980  	ctx := context.Background()
   981  	_, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true)
   982  	if err == nil {
   983  		t.Error("Repositories.GetBranch returned error: nil")
   984  	}
   985  	if resp.StatusCode != http.StatusNotFound {
   986  		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusNotFound)
   987  	}
   988  
   989  	// Add custom round tripper
   990  	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
   991  		return nil, errors.New("failed to get branch")
   992  	})
   993  
   994  	const methodName = "GetBranch"
   995  	testBadOptions(t, methodName, func() (err error) {
   996  		_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", true)
   997  		return err
   998  	})
   999  }
  1000  
  1001  func TestRepositoriesService_RenameBranch(t *testing.T) {
  1002  	client, mux, _, teardown := setup()
  1003  	defer teardown()
  1004  
  1005  	renameBranchReq := "nn"
  1006  
  1007  	mux.HandleFunc("/repos/o/r/branches/b/rename", func(w http.ResponseWriter, r *http.Request) {
  1008  		v := new(renameBranchRequest)
  1009  		json.NewDecoder(r.Body).Decode(v)
  1010  
  1011  		testMethod(t, r, "POST")
  1012  		want := &renameBranchRequest{NewName: "nn"}
  1013  		if !cmp.Equal(v, want) {
  1014  			t.Errorf("Request body = %+v, want %+v", v, want)
  1015  		}
  1016  
  1017  		fmt.Fprint(w, `{"protected":true,"name":"nn"}`)
  1018  	})
  1019  
  1020  	ctx := context.Background()
  1021  	got, _, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq)
  1022  	if err != nil {
  1023  		t.Errorf("Repositories.RenameBranch returned error: %v", err)
  1024  	}
  1025  
  1026  	want := &Branch{Name: String("nn"), Protected: Bool(true)}
  1027  	if !cmp.Equal(got, want) {
  1028  		t.Errorf("Repositories.RenameBranch returned %+v, want %+v", got, want)
  1029  	}
  1030  
  1031  	const methodName = "RenameBranch"
  1032  	testBadOptions(t, methodName, func() (err error) {
  1033  		_, _, err = client.Repositories.RenameBranch(ctx, "\n", "\n", "\n", renameBranchReq)
  1034  		return err
  1035  	})
  1036  
  1037  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1038  		got, resp, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq)
  1039  		if got != nil {
  1040  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1041  		}
  1042  		return resp, err
  1043  	})
  1044  }
  1045  
  1046  func TestRepositoriesService_GetBranchProtection(t *testing.T) {
  1047  	client, mux, _, teardown := setup()
  1048  	defer teardown()
  1049  
  1050  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1051  		v := new(ProtectionRequest)
  1052  		json.NewDecoder(r.Body).Decode(v)
  1053  
  1054  		testMethod(t, r, "GET")
  1055  		// TODO: remove custom Accept header when this API fully launches
  1056  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1057  		fmt.Fprintf(w, `{
  1058  				"required_status_checks":{
  1059  					"strict":true,
  1060  					"contexts":["continuous-integration"],
  1061  					"checks": [
  1062  						{
  1063  							"context": "continuous-integration",
  1064  							"app_id": null
  1065  						}
  1066  					]
  1067  				},
  1068  				"required_pull_request_reviews":{
  1069  					"dismissal_restrictions":{
  1070  						"users":[{
  1071  							"id":3,
  1072  							"login":"u"
  1073  						}],
  1074  						"teams":[{
  1075  							"id":4,
  1076  							"slug":"t"
  1077  						}],
  1078  						"apps":[{
  1079  							"id":5,
  1080  							"slug":"a"
  1081  						}]
  1082  					},
  1083  					"dismiss_stale_reviews":true,
  1084  					"require_code_owner_reviews":true,
  1085  					"required_approving_review_count":1
  1086  					},
  1087  					"enforce_admins":{
  1088  						"url":"/repos/o/r/branches/b/protection/enforce_admins",
  1089  						"enabled":true
  1090  					},
  1091  					"restrictions":{
  1092  						"users":[{"id":1,"login":"u"}],
  1093  						"teams":[{"id":2,"slug":"t"}],
  1094  						"apps":[{"id":3,"slug":"a"}]
  1095  					},
  1096  					"required_conversation_resolution": {
  1097  						"enabled": true
  1098  					}
  1099  				}`)
  1100  	})
  1101  
  1102  	ctx := context.Background()
  1103  	protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1104  	if err != nil {
  1105  		t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1106  	}
  1107  
  1108  	want := &Protection{
  1109  		RequiredStatusChecks: &RequiredStatusChecks{
  1110  			Strict:   true,
  1111  			Contexts: []string{"continuous-integration"},
  1112  			Checks: []*RequiredStatusCheck{
  1113  				{
  1114  					Context: "continuous-integration",
  1115  				},
  1116  			},
  1117  		},
  1118  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1119  			DismissStaleReviews: true,
  1120  			DismissalRestrictions: &DismissalRestrictions{
  1121  				Users: []*User{
  1122  					{Login: String("u"), ID: Int64(3)},
  1123  				},
  1124  				Teams: []*Team{
  1125  					{Slug: String("t"), ID: Int64(4)},
  1126  				},
  1127  				Apps: []*App{
  1128  					{Slug: String("a"), ID: Int64(5)},
  1129  				},
  1130  			},
  1131  			RequireCodeOwnerReviews:      true,
  1132  			RequiredApprovingReviewCount: 1,
  1133  		},
  1134  		EnforceAdmins: &AdminEnforcement{
  1135  			URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  1136  			Enabled: true,
  1137  		},
  1138  		Restrictions: &BranchRestrictions{
  1139  			Users: []*User{
  1140  				{Login: String("u"), ID: Int64(1)},
  1141  			},
  1142  			Teams: []*Team{
  1143  				{Slug: String("t"), ID: Int64(2)},
  1144  			},
  1145  			Apps: []*App{
  1146  				{Slug: String("a"), ID: Int64(3)},
  1147  			},
  1148  		},
  1149  		RequiredConversationResolution: &RequiredConversationResolution{
  1150  			Enabled: true,
  1151  		},
  1152  	}
  1153  	if !cmp.Equal(protection, want) {
  1154  		t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1155  	}
  1156  
  1157  	const methodName = "GetBranchProtection"
  1158  	testBadOptions(t, methodName, func() (err error) {
  1159  		_, _, err = client.Repositories.GetBranchProtection(ctx, "\n", "\n", "\n")
  1160  		return err
  1161  	})
  1162  
  1163  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1164  		got, resp, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1165  		if got != nil {
  1166  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1167  		}
  1168  		return resp, err
  1169  	})
  1170  }
  1171  
  1172  func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) {
  1173  	client, mux, _, teardown := setup()
  1174  	defer teardown()
  1175  
  1176  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1177  		testMethod(t, r, "GET")
  1178  		// TODO: remove custom Accept header when this API fully launches
  1179  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1180  		fmt.Fprintf(w, `{
  1181  				"required_status_checks":{
  1182  					"strict":true,
  1183  					"contexts":["continuous-integration"],
  1184  					"checks": [
  1185  						{
  1186  							"context": "continuous-integration",
  1187  							"app_id": null
  1188  						}
  1189  					]
  1190  				},
  1191  				"required_pull_request_reviews":{
  1192  					"dismiss_stale_reviews":true,
  1193  					"require_code_owner_reviews":true,
  1194  					"required_approving_review_count":1
  1195  					},
  1196  					"enforce_admins":{
  1197  						"url":"/repos/o/r/branches/b/protection/enforce_admins",
  1198  						"enabled":true
  1199  					},
  1200  					"restrictions":{
  1201  						"users":[{"id":1,"login":"u"}],
  1202  						"teams":[{"id":2,"slug":"t"}]
  1203  					}
  1204  				}`)
  1205  	})
  1206  
  1207  	ctx := context.Background()
  1208  	protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1209  	if err != nil {
  1210  		t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
  1211  	}
  1212  
  1213  	want := &Protection{
  1214  		RequiredStatusChecks: &RequiredStatusChecks{
  1215  			Strict:   true,
  1216  			Contexts: []string{"continuous-integration"},
  1217  			Checks: []*RequiredStatusCheck{
  1218  				{
  1219  					Context: "continuous-integration",
  1220  				},
  1221  			},
  1222  		},
  1223  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1224  			DismissStaleReviews:          true,
  1225  			DismissalRestrictions:        nil,
  1226  			RequireCodeOwnerReviews:      true,
  1227  			RequiredApprovingReviewCount: 1,
  1228  		},
  1229  		EnforceAdmins: &AdminEnforcement{
  1230  			URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  1231  			Enabled: true,
  1232  		},
  1233  		Restrictions: &BranchRestrictions{
  1234  			Users: []*User{
  1235  				{Login: String("u"), ID: Int64(1)},
  1236  			},
  1237  			Teams: []*Team{
  1238  				{Slug: String("t"), ID: Int64(2)},
  1239  			},
  1240  		},
  1241  	}
  1242  	if !cmp.Equal(protection, want) {
  1243  		t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
  1244  	}
  1245  }
  1246  
  1247  func TestRepositoriesService_GetBranchProtection_branchNotProtected(t *testing.T) {
  1248  	client, mux, _, teardown := setup()
  1249  	defer teardown()
  1250  
  1251  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1252  		testMethod(t, r, "GET")
  1253  
  1254  		w.WriteHeader(http.StatusBadRequest)
  1255  		fmt.Fprintf(w, `{
  1256  			"message": %q,
  1257  			"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  1258  			}`, githubBranchNotProtected)
  1259  	})
  1260  
  1261  	ctx := context.Background()
  1262  	protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b")
  1263  
  1264  	if protection != nil {
  1265  		t.Errorf("Repositories.GetBranchProtection returned non-nil protection data")
  1266  	}
  1267  
  1268  	if err != ErrBranchNotProtected {
  1269  		t.Errorf("Repositories.GetBranchProtection returned an invalid error: %v", err)
  1270  	}
  1271  }
  1272  
  1273  func TestRepositoriesService_UpdateBranchProtection_Contexts(t *testing.T) {
  1274  	client, mux, _, teardown := setup()
  1275  	defer teardown()
  1276  
  1277  	input := &ProtectionRequest{
  1278  		RequiredStatusChecks: &RequiredStatusChecks{
  1279  			Strict:   true,
  1280  			Contexts: []string{"continuous-integration"},
  1281  		},
  1282  		RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1283  			DismissStaleReviews: true,
  1284  			DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1285  				Users: &[]string{"uu"},
  1286  				Teams: &[]string{"tt"},
  1287  				Apps:  &[]string{"aa"},
  1288  			},
  1289  			BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1290  				Users: []string{"uuu"},
  1291  				Teams: []string{"ttt"},
  1292  				Apps:  []string{"aaa"},
  1293  			},
  1294  		},
  1295  		Restrictions: &BranchRestrictionsRequest{
  1296  			Users: []string{"u"},
  1297  			Teams: []string{"t"},
  1298  			Apps:  []string{"a"},
  1299  		},
  1300  	}
  1301  
  1302  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1303  		v := new(ProtectionRequest)
  1304  		json.NewDecoder(r.Body).Decode(v)
  1305  
  1306  		testMethod(t, r, "PUT")
  1307  		if !cmp.Equal(v, input) {
  1308  			t.Errorf("Request body = %+v, want %+v", v, input)
  1309  		}
  1310  
  1311  		// TODO: remove custom Accept header when this API fully launches
  1312  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1313  		fmt.Fprintf(w, `{
  1314  			"required_status_checks":{
  1315  				"strict":true,
  1316  				"contexts":["continuous-integration"],
  1317  				"checks": [
  1318  					{
  1319  						"context": "continuous-integration",
  1320  						"app_id": null
  1321  					}
  1322  				]
  1323  			},
  1324  			"required_pull_request_reviews":{
  1325  				"dismissal_restrictions":{
  1326  					"users":[{
  1327  						"id":3,
  1328  						"login":"uu"
  1329  					}],
  1330  					"teams":[{
  1331  						"id":4,
  1332  						"slug":"tt"
  1333  					}],
  1334  					"apps":[{
  1335  						"id":5,
  1336  						"slug":"aa"
  1337  					}]
  1338  				},
  1339  				"dismiss_stale_reviews":true,
  1340  				"require_code_owner_reviews":true,
  1341  				"bypass_pull_request_allowances": {
  1342  					"users":[{"id":10,"login":"uuu"}],
  1343  					"teams":[{"id":20,"slug":"ttt"}],
  1344  					"apps":[{"id":30,"slug":"aaa"}]
  1345  				}
  1346  			},
  1347  			"restrictions":{
  1348  				"users":[{"id":1,"login":"u"}],
  1349  				"teams":[{"id":2,"slug":"t"}],
  1350  				"apps":[{"id":3,"slug":"a"}]
  1351  			}
  1352  		}`)
  1353  	})
  1354  
  1355  	ctx := context.Background()
  1356  	protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input)
  1357  	if err != nil {
  1358  		t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1359  	}
  1360  
  1361  	want := &Protection{
  1362  		RequiredStatusChecks: &RequiredStatusChecks{
  1363  			Strict:   true,
  1364  			Contexts: []string{"continuous-integration"},
  1365  			Checks: []*RequiredStatusCheck{
  1366  				{
  1367  					Context: "continuous-integration",
  1368  				},
  1369  			},
  1370  		},
  1371  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1372  			DismissStaleReviews: true,
  1373  			DismissalRestrictions: &DismissalRestrictions{
  1374  				Users: []*User{
  1375  					{Login: String("uu"), ID: Int64(3)},
  1376  				},
  1377  				Teams: []*Team{
  1378  					{Slug: String("tt"), ID: Int64(4)},
  1379  				},
  1380  				Apps: []*App{
  1381  					{Slug: String("aa"), ID: Int64(5)},
  1382  				},
  1383  			},
  1384  			RequireCodeOwnerReviews: true,
  1385  			BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1386  				Users: []*User{
  1387  					{Login: String("uuu"), ID: Int64(10)},
  1388  				},
  1389  				Teams: []*Team{
  1390  					{Slug: String("ttt"), ID: Int64(20)},
  1391  				},
  1392  				Apps: []*App{
  1393  					{Slug: String("aaa"), ID: Int64(30)},
  1394  				},
  1395  			},
  1396  		},
  1397  		Restrictions: &BranchRestrictions{
  1398  			Users: []*User{
  1399  				{Login: String("u"), ID: Int64(1)},
  1400  			},
  1401  			Teams: []*Team{
  1402  				{Slug: String("t"), ID: Int64(2)},
  1403  			},
  1404  			Apps: []*App{
  1405  				{Slug: String("a"), ID: Int64(3)},
  1406  			},
  1407  		},
  1408  	}
  1409  	if !cmp.Equal(protection, want) {
  1410  		t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1411  	}
  1412  
  1413  	const methodName = "UpdateBranchProtection"
  1414  	testBadOptions(t, methodName, func() (err error) {
  1415  		_, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input)
  1416  		return err
  1417  	})
  1418  
  1419  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1420  		got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input)
  1421  		if got != nil {
  1422  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1423  		}
  1424  		return resp, err
  1425  	})
  1426  }
  1427  
  1428  func TestRepositoriesService_UpdateBranchProtection_Checks(t *testing.T) {
  1429  	client, mux, _, teardown := setup()
  1430  	defer teardown()
  1431  
  1432  	input := &ProtectionRequest{
  1433  		RequiredStatusChecks: &RequiredStatusChecks{
  1434  			Strict: true,
  1435  			Checks: []*RequiredStatusCheck{
  1436  				{
  1437  					Context: "continuous-integration",
  1438  				},
  1439  			},
  1440  		},
  1441  		RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1442  			DismissStaleReviews: true,
  1443  			DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1444  				Users: &[]string{"uu"},
  1445  				Teams: &[]string{"tt"},
  1446  				Apps:  &[]string{"aa"},
  1447  			},
  1448  			BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1449  				Users: []string{"uuu"},
  1450  				Teams: []string{"ttt"},
  1451  				Apps:  []string{"aaa"},
  1452  			},
  1453  		},
  1454  		Restrictions: &BranchRestrictionsRequest{
  1455  			Users: []string{"u"},
  1456  			Teams: []string{"t"},
  1457  			Apps:  []string{"a"},
  1458  		},
  1459  	}
  1460  
  1461  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1462  		v := new(ProtectionRequest)
  1463  		json.NewDecoder(r.Body).Decode(v)
  1464  
  1465  		testMethod(t, r, "PUT")
  1466  		if !cmp.Equal(v, input) {
  1467  			t.Errorf("Request body = %+v, want %+v", v, input)
  1468  		}
  1469  
  1470  		// TODO: remove custom Accept header when this API fully launches
  1471  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1472  		fmt.Fprintf(w, `{
  1473  			"required_status_checks":{
  1474  				"strict":true,
  1475  				"contexts":["continuous-integration"],
  1476  				"checks": [
  1477  					{
  1478  						"context": "continuous-integration",
  1479  						"app_id": null
  1480  					}
  1481  				]
  1482  			},
  1483  			"required_pull_request_reviews":{
  1484  				"dismissal_restrictions":{
  1485  					"users":[{
  1486  						"id":3,
  1487  						"login":"uu"
  1488  					}],
  1489  					"teams":[{
  1490  						"id":4,
  1491  						"slug":"tt"
  1492  					}],
  1493  					"apps":[{
  1494  						"id":5,
  1495  						"slug":"aa"
  1496  					}]
  1497  				},
  1498  				"dismiss_stale_reviews":true,
  1499  				"require_code_owner_reviews":true,
  1500  				"bypass_pull_request_allowances": {
  1501  					"users":[{"id":10,"login":"uuu"}],
  1502  					"teams":[{"id":20,"slug":"ttt"}],
  1503  					"apps":[{"id":30,"slug":"aaa"}]
  1504  				}
  1505  			},
  1506  			"restrictions":{
  1507  				"users":[{"id":1,"login":"u"}],
  1508  				"teams":[{"id":2,"slug":"t"}],
  1509  				"apps":[{"id":3,"slug":"a"}]
  1510  			}
  1511  		}`)
  1512  	})
  1513  
  1514  	ctx := context.Background()
  1515  	protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input)
  1516  	if err != nil {
  1517  		t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1518  	}
  1519  
  1520  	want := &Protection{
  1521  		RequiredStatusChecks: &RequiredStatusChecks{
  1522  			Strict:   true,
  1523  			Contexts: []string{"continuous-integration"},
  1524  			Checks: []*RequiredStatusCheck{
  1525  				{
  1526  					Context: "continuous-integration",
  1527  				},
  1528  			},
  1529  		},
  1530  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1531  			DismissStaleReviews: true,
  1532  			DismissalRestrictions: &DismissalRestrictions{
  1533  				Users: []*User{
  1534  					{Login: String("uu"), ID: Int64(3)},
  1535  				},
  1536  				Teams: []*Team{
  1537  					{Slug: String("tt"), ID: Int64(4)},
  1538  				},
  1539  				Apps: []*App{
  1540  					{Slug: String("aa"), ID: Int64(5)},
  1541  				},
  1542  			},
  1543  			RequireCodeOwnerReviews: true,
  1544  			BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1545  				Users: []*User{
  1546  					{Login: String("uuu"), ID: Int64(10)},
  1547  				},
  1548  				Teams: []*Team{
  1549  					{Slug: String("ttt"), ID: Int64(20)},
  1550  				},
  1551  				Apps: []*App{
  1552  					{Slug: String("aaa"), ID: Int64(30)},
  1553  				},
  1554  			},
  1555  		},
  1556  		Restrictions: &BranchRestrictions{
  1557  			Users: []*User{
  1558  				{Login: String("u"), ID: Int64(1)},
  1559  			},
  1560  			Teams: []*Team{
  1561  				{Slug: String("t"), ID: Int64(2)},
  1562  			},
  1563  			Apps: []*App{
  1564  				{Slug: String("a"), ID: Int64(3)},
  1565  			},
  1566  		},
  1567  	}
  1568  	if !cmp.Equal(protection, want) {
  1569  		t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1570  	}
  1571  }
  1572  
  1573  func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T) {
  1574  	client, mux, _, teardown := setup()
  1575  	defer teardown()
  1576  
  1577  	input := &ProtectionRequest{
  1578  		RequiredStatusChecks: &RequiredStatusChecks{
  1579  			Strict: true,
  1580  			Checks: []*RequiredStatusCheck{},
  1581  		},
  1582  		RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
  1583  			DismissStaleReviews: true,
  1584  			DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  1585  				Users: &[]string{"uu"},
  1586  				Teams: &[]string{"tt"},
  1587  				Apps:  &[]string{"aa"},
  1588  			},
  1589  			BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  1590  				Users: []string{"uuu"},
  1591  				Teams: []string{"ttt"},
  1592  				Apps:  []string{"aaa"},
  1593  			},
  1594  		},
  1595  		Restrictions: &BranchRestrictionsRequest{
  1596  			Users: []string{"u"},
  1597  			Teams: []string{"t"},
  1598  			Apps:  []string{"a"},
  1599  		},
  1600  	}
  1601  
  1602  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1603  		v := new(ProtectionRequest)
  1604  		json.NewDecoder(r.Body).Decode(v)
  1605  
  1606  		testMethod(t, r, "PUT")
  1607  		if !cmp.Equal(v, input) {
  1608  			t.Errorf("Request body = %+v, want %+v", v, input)
  1609  		}
  1610  
  1611  		// TODO: remove custom Accept header when this API fully launches
  1612  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  1613  		fmt.Fprintf(w, `{
  1614  			"required_status_checks":{
  1615  				"strict":true,
  1616  				"contexts":[],
  1617  				"checks": []
  1618  			},
  1619  			"required_pull_request_reviews":{
  1620  				"dismissal_restrictions":{
  1621  					"users":[{
  1622  						"id":3,
  1623  						"login":"uu"
  1624  					}],
  1625  					"teams":[{
  1626  						"id":4,
  1627  						"slug":"tt"
  1628  					}],
  1629  					"apps":[{
  1630  						"id":5,
  1631  						"slug":"aa"
  1632  					}]
  1633  				},
  1634  				"dismiss_stale_reviews":true,
  1635  				"require_code_owner_reviews":true,
  1636  				"bypass_pull_request_allowances": {
  1637  					"users":[{"id":10,"login":"uuu"}],
  1638  					"teams":[{"id":20,"slug":"ttt"}],
  1639  					"apps":[{"id":30,"slug":"aaa"}]
  1640  				}
  1641  			},
  1642  			"restrictions":{
  1643  				"users":[{"id":1,"login":"u"}],
  1644  				"teams":[{"id":2,"slug":"t"}],
  1645  				"apps":[{"id":3,"slug":"a"}]
  1646  			}
  1647  		}`)
  1648  	})
  1649  
  1650  	ctx := context.Background()
  1651  	protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input)
  1652  	if err != nil {
  1653  		t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
  1654  	}
  1655  
  1656  	want := &Protection{
  1657  		RequiredStatusChecks: &RequiredStatusChecks{
  1658  			Strict:   true,
  1659  			Contexts: []string{},
  1660  			Checks:   []*RequiredStatusCheck{},
  1661  		},
  1662  		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
  1663  			DismissStaleReviews: true,
  1664  			DismissalRestrictions: &DismissalRestrictions{
  1665  				Users: []*User{
  1666  					{Login: String("uu"), ID: Int64(3)},
  1667  				},
  1668  				Teams: []*Team{
  1669  					{Slug: String("tt"), ID: Int64(4)},
  1670  				},
  1671  				Apps: []*App{
  1672  					{Slug: String("aa"), ID: Int64(5)},
  1673  				},
  1674  			},
  1675  			RequireCodeOwnerReviews: true,
  1676  			BypassPullRequestAllowances: &BypassPullRequestAllowances{
  1677  				Users: []*User{
  1678  					{Login: String("uuu"), ID: Int64(10)},
  1679  				},
  1680  				Teams: []*Team{
  1681  					{Slug: String("ttt"), ID: Int64(20)},
  1682  				},
  1683  				Apps: []*App{
  1684  					{Slug: String("aaa"), ID: Int64(30)},
  1685  				},
  1686  			},
  1687  		},
  1688  		Restrictions: &BranchRestrictions{
  1689  			Users: []*User{
  1690  				{Login: String("u"), ID: Int64(1)},
  1691  			},
  1692  			Teams: []*Team{
  1693  				{Slug: String("t"), ID: Int64(2)},
  1694  			},
  1695  			Apps: []*App{
  1696  				{Slug: String("a"), ID: Int64(3)},
  1697  			},
  1698  		},
  1699  	}
  1700  	if !cmp.Equal(protection, want) {
  1701  		t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
  1702  	}
  1703  }
  1704  
  1705  func TestRepositoriesService_RemoveBranchProtection(t *testing.T) {
  1706  	client, mux, _, teardown := setup()
  1707  	defer teardown()
  1708  
  1709  	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
  1710  		testMethod(t, r, "DELETE")
  1711  		w.WriteHeader(http.StatusNoContent)
  1712  	})
  1713  
  1714  	ctx := context.Background()
  1715  	_, err := client.Repositories.RemoveBranchProtection(ctx, "o", "r", "b")
  1716  	if err != nil {
  1717  		t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err)
  1718  	}
  1719  
  1720  	const methodName = "RemoveBranchProtection"
  1721  	testBadOptions(t, methodName, func() (err error) {
  1722  		_, err = client.Repositories.RemoveBranchProtection(ctx, "\n", "\n", "\n")
  1723  		return err
  1724  	})
  1725  
  1726  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1727  		return client.Repositories.RemoveBranchProtection(ctx, "o", "r", "b")
  1728  	})
  1729  }
  1730  
  1731  func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) {
  1732  	client, _, _, teardown := setup()
  1733  	defer teardown()
  1734  
  1735  	ctx := context.Background()
  1736  	_, _, err := client.Repositories.ListLanguages(ctx, "%", "%")
  1737  	testURLParseError(t, err)
  1738  }
  1739  
  1740  func TestRepositoriesService_License(t *testing.T) {
  1741  	client, mux, _, teardown := setup()
  1742  	defer teardown()
  1743  
  1744  	mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) {
  1745  		testMethod(t, r, "GET")
  1746  		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}}`)
  1747  	})
  1748  
  1749  	ctx := context.Background()
  1750  	got, _, err := client.Repositories.License(ctx, "o", "r")
  1751  	if err != nil {
  1752  		t.Errorf("Repositories.License returned error: %v", err)
  1753  	}
  1754  
  1755  	want := &RepositoryLicense{
  1756  		Name: String("LICENSE"),
  1757  		Path: String("LICENSE"),
  1758  		License: &License{
  1759  			Name:     String("MIT License"),
  1760  			Key:      String("mit"),
  1761  			SPDXID:   String("MIT"),
  1762  			URL:      String("https://api.github.com/licenses/mit"),
  1763  			Featured: Bool(true),
  1764  		},
  1765  	}
  1766  
  1767  	if !cmp.Equal(got, want) {
  1768  		t.Errorf("Repositories.License returned %+v, want %+v", got, want)
  1769  	}
  1770  
  1771  	const methodName = "License"
  1772  	testBadOptions(t, methodName, func() (err error) {
  1773  		_, _, err = client.Repositories.License(ctx, "\n", "\n")
  1774  		return err
  1775  	})
  1776  
  1777  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1778  		got, resp, err := client.Repositories.License(ctx, "o", "r")
  1779  		if got != nil {
  1780  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1781  		}
  1782  		return resp, err
  1783  	})
  1784  }
  1785  
  1786  func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) {
  1787  	client, mux, _, teardown := setup()
  1788  	defer teardown()
  1789  
  1790  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1791  		v := new(ProtectionRequest)
  1792  		json.NewDecoder(r.Body).Decode(v)
  1793  
  1794  		testMethod(t, r, "GET")
  1795  		fmt.Fprint(w, `{
  1796  			"strict": true,
  1797  			"contexts": ["x","y","z"],
  1798  			"checks": [
  1799  				{
  1800  					"context": "x",
  1801  					"app_id": null
  1802  				},
  1803  				{
  1804  					"context": "y",
  1805  					"app_id": null
  1806  				},
  1807  				{
  1808  					"context": "z",
  1809  					"app_id": null
  1810  				}
  1811  			]
  1812  		}`)
  1813  	})
  1814  
  1815  	ctx := context.Background()
  1816  	checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b")
  1817  	if err != nil {
  1818  		t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err)
  1819  	}
  1820  
  1821  	want := &RequiredStatusChecks{
  1822  		Strict:   true,
  1823  		Contexts: []string{"x", "y", "z"},
  1824  		Checks: []*RequiredStatusCheck{
  1825  			{
  1826  				Context: "x",
  1827  			},
  1828  			{
  1829  				Context: "y",
  1830  			},
  1831  			{
  1832  				Context: "z",
  1833  			},
  1834  		},
  1835  	}
  1836  	if !cmp.Equal(checks, want) {
  1837  		t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want)
  1838  	}
  1839  
  1840  	const methodName = "GetRequiredStatusChecks"
  1841  	testBadOptions(t, methodName, func() (err error) {
  1842  		_, _, err = client.Repositories.GetRequiredStatusChecks(ctx, "\n", "\n", "\n")
  1843  		return err
  1844  	})
  1845  
  1846  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1847  		got, resp, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b")
  1848  		if got != nil {
  1849  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1850  		}
  1851  		return resp, err
  1852  	})
  1853  }
  1854  
  1855  func TestRepositoriesService_GetRequiredStatusChecks_branchNotProtected(t *testing.T) {
  1856  	client, mux, _, teardown := setup()
  1857  	defer teardown()
  1858  
  1859  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1860  		testMethod(t, r, "GET")
  1861  
  1862  		w.WriteHeader(http.StatusBadRequest)
  1863  		fmt.Fprintf(w, `{
  1864  			"message": %q,
  1865  			"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  1866  			}`, githubBranchNotProtected)
  1867  	})
  1868  
  1869  	ctx := context.Background()
  1870  	checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b")
  1871  
  1872  	if checks != nil {
  1873  		t.Errorf("Repositories.GetRequiredStatusChecks returned non-nil status-checks data")
  1874  	}
  1875  
  1876  	if err != ErrBranchNotProtected {
  1877  		t.Errorf("Repositories.GetRequiredStatusChecks returned an invalid error: %v", err)
  1878  	}
  1879  }
  1880  
  1881  func TestRepositoriesService_UpdateRequiredStatusChecks_Contexts(t *testing.T) {
  1882  	client, mux, _, teardown := setup()
  1883  	defer teardown()
  1884  
  1885  	input := &RequiredStatusChecksRequest{
  1886  		Strict:   Bool(true),
  1887  		Contexts: []string{"continuous-integration"},
  1888  	}
  1889  
  1890  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1891  		v := new(RequiredStatusChecksRequest)
  1892  		json.NewDecoder(r.Body).Decode(v)
  1893  
  1894  		testMethod(t, r, "PATCH")
  1895  		if !cmp.Equal(v, input) {
  1896  			t.Errorf("Request body = %+v, want %+v", v, input)
  1897  		}
  1898  		testHeader(t, r, "Accept", mediaTypeV3)
  1899  		fmt.Fprintf(w, `{
  1900  			"strict":true,
  1901  			"contexts":["continuous-integration"],
  1902  			"checks": [
  1903  				{
  1904  					"context": "continuous-integration",
  1905  					"app_id": null
  1906  				}
  1907  			]
  1908  		}`)
  1909  	})
  1910  
  1911  	ctx := context.Background()
  1912  	statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input)
  1913  	if err != nil {
  1914  		t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err)
  1915  	}
  1916  
  1917  	want := &RequiredStatusChecks{
  1918  		Strict:   true,
  1919  		Contexts: []string{"continuous-integration"},
  1920  		Checks: []*RequiredStatusCheck{
  1921  			{
  1922  				Context: "continuous-integration",
  1923  			},
  1924  		},
  1925  	}
  1926  	if !cmp.Equal(statusChecks, want) {
  1927  		t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want)
  1928  	}
  1929  
  1930  	const methodName = "UpdateRequiredStatusChecks"
  1931  	testBadOptions(t, methodName, func() (err error) {
  1932  		_, _, err = client.Repositories.UpdateRequiredStatusChecks(ctx, "\n", "\n", "\n", input)
  1933  		return err
  1934  	})
  1935  
  1936  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1937  		got, resp, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input)
  1938  		if got != nil {
  1939  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  1940  		}
  1941  		return resp, err
  1942  	})
  1943  }
  1944  
  1945  func TestRepositoriesService_UpdateRequiredStatusChecks_Checks(t *testing.T) {
  1946  	client, mux, _, teardown := setup()
  1947  	defer teardown()
  1948  
  1949  	appID := int64(123)
  1950  	noAppID := int64(-1)
  1951  	input := &RequiredStatusChecksRequest{
  1952  		Strict: Bool(true),
  1953  		Checks: []*RequiredStatusCheck{
  1954  			{
  1955  				Context: "continuous-integration",
  1956  			},
  1957  			{
  1958  				Context: "continuous-integration2",
  1959  				AppID:   &appID,
  1960  			},
  1961  			{
  1962  				Context: "continuous-integration3",
  1963  				AppID:   &noAppID,
  1964  			},
  1965  		},
  1966  	}
  1967  
  1968  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  1969  		v := new(RequiredStatusChecksRequest)
  1970  		json.NewDecoder(r.Body).Decode(v)
  1971  
  1972  		testMethod(t, r, "PATCH")
  1973  		if !cmp.Equal(v, input) {
  1974  			t.Errorf("Request body = %+v, want %+v", v, input)
  1975  		}
  1976  		testHeader(t, r, "Accept", mediaTypeV3)
  1977  		fmt.Fprintf(w, `{
  1978  			"strict":true,
  1979  			"contexts":["continuous-integration"],
  1980  			"checks": [
  1981  				{
  1982  					"context": "continuous-integration",
  1983  					"app_id": null
  1984  				},
  1985  				{
  1986  					"context": "continuous-integration2",
  1987  					"app_id": 123
  1988  				},
  1989  				{
  1990  					"context": "continuous-integration3",
  1991  					"app_id": null
  1992  				}
  1993  			]
  1994  		}`)
  1995  	})
  1996  
  1997  	ctx := context.Background()
  1998  	statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input)
  1999  	if err != nil {
  2000  		t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err)
  2001  	}
  2002  
  2003  	want := &RequiredStatusChecks{
  2004  		Strict:   true,
  2005  		Contexts: []string{"continuous-integration"},
  2006  		Checks: []*RequiredStatusCheck{
  2007  			{
  2008  				Context: "continuous-integration",
  2009  			},
  2010  			{
  2011  				Context: "continuous-integration2",
  2012  				AppID:   &appID,
  2013  			},
  2014  			{
  2015  				Context: "continuous-integration3",
  2016  			},
  2017  		},
  2018  	}
  2019  	if !cmp.Equal(statusChecks, want) {
  2020  		t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want)
  2021  	}
  2022  }
  2023  
  2024  func TestRepositoriesService_RemoveRequiredStatusChecks(t *testing.T) {
  2025  	client, mux, _, teardown := setup()
  2026  	defer teardown()
  2027  
  2028  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) {
  2029  		testMethod(t, r, "DELETE")
  2030  		testHeader(t, r, "Accept", mediaTypeV3)
  2031  		w.WriteHeader(http.StatusNoContent)
  2032  	})
  2033  
  2034  	ctx := context.Background()
  2035  	_, err := client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", "b")
  2036  	if err != nil {
  2037  		t.Errorf("Repositories.RemoveRequiredStatusChecks returned error: %v", err)
  2038  	}
  2039  
  2040  	const methodName = "RemoveRequiredStatusChecks"
  2041  	testBadOptions(t, methodName, func() (err error) {
  2042  		_, err = client.Repositories.RemoveRequiredStatusChecks(ctx, "\n", "\n", "\n")
  2043  		return err
  2044  	})
  2045  
  2046  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2047  		return client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", "b")
  2048  	})
  2049  }
  2050  
  2051  func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) {
  2052  	client, mux, _, teardown := setup()
  2053  	defer teardown()
  2054  
  2055  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks/contexts", func(w http.ResponseWriter, r *http.Request) {
  2056  		v := new(ProtectionRequest)
  2057  		json.NewDecoder(r.Body).Decode(v)
  2058  
  2059  		testMethod(t, r, "GET")
  2060  		fmt.Fprint(w, `["x", "y", "z"]`)
  2061  	})
  2062  
  2063  	ctx := context.Background()
  2064  	contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b")
  2065  	if err != nil {
  2066  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err)
  2067  	}
  2068  
  2069  	want := []string{"x", "y", "z"}
  2070  	if !cmp.Equal(contexts, want) {
  2071  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want)
  2072  	}
  2073  
  2074  	const methodName = "ListRequiredStatusChecksContexts"
  2075  	testBadOptions(t, methodName, func() (err error) {
  2076  		_, _, err = client.Repositories.ListRequiredStatusChecksContexts(ctx, "\n", "\n", "\n")
  2077  		return err
  2078  	})
  2079  
  2080  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2081  		got, resp, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b")
  2082  		if got != nil {
  2083  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2084  		}
  2085  		return resp, err
  2086  	})
  2087  }
  2088  
  2089  func TestRepositoriesService_ListRequiredStatusChecksContexts_branchNotProtected(t *testing.T) {
  2090  	client, mux, _, teardown := setup()
  2091  	defer teardown()
  2092  
  2093  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks/contexts", func(w http.ResponseWriter, r *http.Request) {
  2094  		testMethod(t, r, "GET")
  2095  
  2096  		w.WriteHeader(http.StatusBadRequest)
  2097  		fmt.Fprintf(w, `{
  2098  			"message": %q,
  2099  			"documentation_url": "https://docs.github.com/rest/repos#get-branch-protection"
  2100  			}`, githubBranchNotProtected)
  2101  	})
  2102  
  2103  	ctx := context.Background()
  2104  	contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b")
  2105  
  2106  	if contexts != nil {
  2107  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned non-nil contexts data")
  2108  	}
  2109  
  2110  	if err != ErrBranchNotProtected {
  2111  		t.Errorf("Repositories.ListRequiredStatusChecksContexts returned an invalid error: %v", err)
  2112  	}
  2113  }
  2114  
  2115  func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) {
  2116  	client, mux, _, teardown := setup()
  2117  	defer teardown()
  2118  
  2119  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  2120  		testMethod(t, r, "GET")
  2121  		// TODO: remove custom Accept header when this API fully launches
  2122  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2123  		fmt.Fprintf(w, `{
  2124  			"dismissal_restrictions":{
  2125  				"users":[{"id":1,"login":"u"}],
  2126  				"teams":[{"id":2,"slug":"t"}],
  2127  				"apps":[{"id":3,"slug":"a"}]
  2128  			},
  2129  			"dismiss_stale_reviews":true,
  2130  			"require_code_owner_reviews":true,
  2131  			"required_approving_review_count":1
  2132  		}`)
  2133  	})
  2134  
  2135  	ctx := context.Background()
  2136  	enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", "b")
  2137  	if err != nil {
  2138  		t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err)
  2139  	}
  2140  
  2141  	want := &PullRequestReviewsEnforcement{
  2142  		DismissStaleReviews: true,
  2143  		DismissalRestrictions: &DismissalRestrictions{
  2144  			Users: []*User{
  2145  				{Login: String("u"), ID: Int64(1)},
  2146  			},
  2147  			Teams: []*Team{
  2148  				{Slug: String("t"), ID: Int64(2)},
  2149  			},
  2150  			Apps: []*App{
  2151  				{Slug: String("a"), ID: Int64(3)},
  2152  			},
  2153  		},
  2154  		RequireCodeOwnerReviews:      true,
  2155  		RequiredApprovingReviewCount: 1,
  2156  	}
  2157  
  2158  	if !cmp.Equal(enforcement, want) {
  2159  		t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  2160  	}
  2161  
  2162  	const methodName = "GetPullRequestReviewEnforcement"
  2163  	testBadOptions(t, methodName, func() (err error) {
  2164  		_, _, err = client.Repositories.GetPullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  2165  		return err
  2166  	})
  2167  
  2168  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2169  		got, resp, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", "b")
  2170  		if got != nil {
  2171  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2172  		}
  2173  		return resp, err
  2174  	})
  2175  }
  2176  
  2177  func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) {
  2178  	client, mux, _, teardown := setup()
  2179  	defer teardown()
  2180  
  2181  	input := &PullRequestReviewsEnforcementUpdate{
  2182  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  2183  			Users: &[]string{"u"},
  2184  			Teams: &[]string{"t"},
  2185  			Apps:  &[]string{"a"},
  2186  		},
  2187  	}
  2188  
  2189  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  2190  		v := new(PullRequestReviewsEnforcementUpdate)
  2191  		json.NewDecoder(r.Body).Decode(v)
  2192  
  2193  		testMethod(t, r, "PATCH")
  2194  		if !cmp.Equal(v, input) {
  2195  			t.Errorf("Request body = %+v, want %+v", v, input)
  2196  		}
  2197  		// TODO: remove custom Accept header when this API fully launches
  2198  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2199  		fmt.Fprintf(w, `{
  2200  			"dismissal_restrictions":{
  2201  				"users":[{"id":1,"login":"u"}],
  2202  				"teams":[{"id":2,"slug":"t"}],
  2203  				"apps":[{"id":3,"slug":"a"}]
  2204  			},
  2205  			"dismiss_stale_reviews":true,
  2206  			"require_code_owner_reviews":true,
  2207  			"required_approving_review_count":3
  2208  		}`)
  2209  	})
  2210  
  2211  	ctx := context.Background()
  2212  	enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", "b", input)
  2213  	if err != nil {
  2214  		t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err)
  2215  	}
  2216  
  2217  	want := &PullRequestReviewsEnforcement{
  2218  		DismissStaleReviews: true,
  2219  		DismissalRestrictions: &DismissalRestrictions{
  2220  			Users: []*User{
  2221  				{Login: String("u"), ID: Int64(1)},
  2222  			},
  2223  			Teams: []*Team{
  2224  				{Slug: String("t"), ID: Int64(2)},
  2225  			},
  2226  			Apps: []*App{
  2227  				{Slug: String("a"), ID: Int64(3)},
  2228  			},
  2229  		},
  2230  		RequireCodeOwnerReviews:      true,
  2231  		RequiredApprovingReviewCount: 3,
  2232  	}
  2233  	if !cmp.Equal(enforcement, want) {
  2234  		t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want)
  2235  	}
  2236  
  2237  	const methodName = "UpdatePullRequestReviewEnforcement"
  2238  	testBadOptions(t, methodName, func() (err error) {
  2239  		_, _, err = client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "\n", "\n", "\n", input)
  2240  		return err
  2241  	})
  2242  
  2243  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2244  		got, resp, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", "b", input)
  2245  		if got != nil {
  2246  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2247  		}
  2248  		return resp, err
  2249  	})
  2250  }
  2251  
  2252  func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) {
  2253  	client, mux, _, teardown := setup()
  2254  	defer teardown()
  2255  
  2256  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  2257  		testMethod(t, r, "PATCH")
  2258  		// TODO: remove custom Accept header when this API fully launches
  2259  		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
  2260  		testBody(t, r, `{"dismissal_restrictions":{}}`+"\n")
  2261  		fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`)
  2262  	})
  2263  
  2264  	ctx := context.Background()
  2265  	enforcement, _, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", "b")
  2266  	if err != nil {
  2267  		t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err)
  2268  	}
  2269  
  2270  	want := &PullRequestReviewsEnforcement{
  2271  		DismissStaleReviews:          true,
  2272  		DismissalRestrictions:        nil,
  2273  		RequireCodeOwnerReviews:      true,
  2274  		RequiredApprovingReviewCount: 1,
  2275  	}
  2276  	if !cmp.Equal(enforcement, want) {
  2277  		t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want)
  2278  	}
  2279  
  2280  	const methodName = "DisableDismissalRestrictions"
  2281  	testBadOptions(t, methodName, func() (err error) {
  2282  		_, _, err = client.Repositories.DisableDismissalRestrictions(ctx, "\n", "\n", "\n")
  2283  		return err
  2284  	})
  2285  
  2286  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2287  		got, resp, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", "b")
  2288  		if got != nil {
  2289  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2290  		}
  2291  		return resp, err
  2292  	})
  2293  }
  2294  
  2295  func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) {
  2296  	client, mux, _, teardown := setup()
  2297  	defer teardown()
  2298  
  2299  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) {
  2300  		testMethod(t, r, "DELETE")
  2301  		w.WriteHeader(http.StatusNoContent)
  2302  	})
  2303  
  2304  	ctx := context.Background()
  2305  	_, err := client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", "b")
  2306  	if err != nil {
  2307  		t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err)
  2308  	}
  2309  
  2310  	const methodName = "RemovePullRequestReviewEnforcement"
  2311  	testBadOptions(t, methodName, func() (err error) {
  2312  		_, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, "\n", "\n", "\n")
  2313  		return err
  2314  	})
  2315  
  2316  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2317  		return client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", "b")
  2318  	})
  2319  }
  2320  
  2321  func TestRepositoriesService_GetAdminEnforcement(t *testing.T) {
  2322  	client, mux, _, teardown := setup()
  2323  	defer teardown()
  2324  
  2325  	mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) {
  2326  		testMethod(t, r, "GET")
  2327  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  2328  	})
  2329  
  2330  	ctx := context.Background()
  2331  	enforcement, _, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", "b")
  2332  	if err != nil {
  2333  		t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err)
  2334  	}
  2335  
  2336  	want := &AdminEnforcement{
  2337  		URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  2338  		Enabled: true,
  2339  	}
  2340  
  2341  	if !cmp.Equal(enforcement, want) {
  2342  		t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want)
  2343  	}
  2344  
  2345  	const methodName = "GetAdminEnforcement"
  2346  	testBadOptions(t, methodName, func() (err error) {
  2347  		_, _, err = client.Repositories.GetAdminEnforcement(ctx, "\n", "\n", "\n")
  2348  		return err
  2349  	})
  2350  
  2351  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2352  		got, resp, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", "b")
  2353  		if got != nil {
  2354  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2355  		}
  2356  		return resp, err
  2357  	})
  2358  }
  2359  
  2360  func TestRepositoriesService_AddAdminEnforcement(t *testing.T) {
  2361  	client, mux, _, teardown := setup()
  2362  	defer teardown()
  2363  
  2364  	mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) {
  2365  		testMethod(t, r, "POST")
  2366  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`)
  2367  	})
  2368  
  2369  	ctx := context.Background()
  2370  	enforcement, _, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", "b")
  2371  	if err != nil {
  2372  		t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err)
  2373  	}
  2374  
  2375  	want := &AdminEnforcement{
  2376  		URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
  2377  		Enabled: true,
  2378  	}
  2379  	if !cmp.Equal(enforcement, want) {
  2380  		t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want)
  2381  	}
  2382  
  2383  	const methodName = "AddAdminEnforcement"
  2384  	testBadOptions(t, methodName, func() (err error) {
  2385  		_, _, err = client.Repositories.AddAdminEnforcement(ctx, "\n", "\n", "\n")
  2386  		return err
  2387  	})
  2388  
  2389  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2390  		got, resp, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", "b")
  2391  		if got != nil {
  2392  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2393  		}
  2394  		return resp, err
  2395  	})
  2396  }
  2397  
  2398  func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) {
  2399  	client, mux, _, teardown := setup()
  2400  	defer teardown()
  2401  
  2402  	mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) {
  2403  		testMethod(t, r, "DELETE")
  2404  		w.WriteHeader(http.StatusNoContent)
  2405  	})
  2406  
  2407  	ctx := context.Background()
  2408  	_, err := client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", "b")
  2409  	if err != nil {
  2410  		t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err)
  2411  	}
  2412  
  2413  	const methodName = "RemoveAdminEnforcement"
  2414  	testBadOptions(t, methodName, func() (err error) {
  2415  		_, err = client.Repositories.RemoveAdminEnforcement(ctx, "\n", "\n", "\n")
  2416  		return err
  2417  	})
  2418  
  2419  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2420  		return client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", "b")
  2421  	})
  2422  }
  2423  
  2424  func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) {
  2425  	client, mux, _, teardown := setup()
  2426  	defer teardown()
  2427  
  2428  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) {
  2429  		testMethod(t, r, "GET")
  2430  		testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  2431  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`)
  2432  	})
  2433  
  2434  	ctx := context.Background()
  2435  	signature, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", "b")
  2436  	if err != nil {
  2437  		t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err)
  2438  	}
  2439  
  2440  	want := &SignaturesProtectedBranch{
  2441  		URL:     String("/repos/o/r/branches/b/protection/required_signatures"),
  2442  		Enabled: Bool(false),
  2443  	}
  2444  
  2445  	if !cmp.Equal(signature, want) {
  2446  		t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want)
  2447  	}
  2448  
  2449  	const methodName = "GetSignaturesProtectedBranch"
  2450  	testBadOptions(t, methodName, func() (err error) {
  2451  		_, _, err = client.Repositories.GetSignaturesProtectedBranch(ctx, "\n", "\n", "\n")
  2452  		return err
  2453  	})
  2454  
  2455  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2456  		got, resp, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", "b")
  2457  		if got != nil {
  2458  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2459  		}
  2460  		return resp, err
  2461  	})
  2462  }
  2463  
  2464  func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) {
  2465  	client, mux, _, teardown := setup()
  2466  	defer teardown()
  2467  
  2468  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) {
  2469  		testMethod(t, r, "POST")
  2470  		testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  2471  		fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`)
  2472  	})
  2473  
  2474  	ctx := context.Background()
  2475  	signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  2476  	if err != nil {
  2477  		t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err)
  2478  	}
  2479  
  2480  	want := &SignaturesProtectedBranch{
  2481  		URL:     String("/repos/o/r/branches/b/protection/required_signatures"),
  2482  		Enabled: Bool(true),
  2483  	}
  2484  
  2485  	if !cmp.Equal(signature, want) {
  2486  		t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want)
  2487  	}
  2488  
  2489  	const methodName = "RequireSignaturesOnProtectedBranch"
  2490  	testBadOptions(t, methodName, func() (err error) {
  2491  		_, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  2492  		return err
  2493  	})
  2494  
  2495  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2496  		got, resp, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  2497  		if got != nil {
  2498  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2499  		}
  2500  		return resp, err
  2501  	})
  2502  }
  2503  
  2504  func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) {
  2505  	client, mux, _, teardown := setup()
  2506  	defer teardown()
  2507  
  2508  	mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) {
  2509  		testMethod(t, r, "DELETE")
  2510  		testHeader(t, r, "Accept", mediaTypeSignaturePreview)
  2511  		w.WriteHeader(http.StatusNoContent)
  2512  	})
  2513  
  2514  	ctx := context.Background()
  2515  	_, err := client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  2516  	if err != nil {
  2517  		t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err)
  2518  	}
  2519  
  2520  	const methodName = "OptionalSignaturesOnProtectedBranch"
  2521  	testBadOptions(t, methodName, func() (err error) {
  2522  		_, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n")
  2523  		return err
  2524  	})
  2525  
  2526  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2527  		return client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", "b")
  2528  	})
  2529  }
  2530  
  2531  func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) {
  2532  	req := PullRequestReviewsEnforcementRequest{}
  2533  
  2534  	got, err := json.Marshal(req)
  2535  	if err != nil {
  2536  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  2537  	}
  2538  
  2539  	want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  2540  	if want != string(got) {
  2541  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  2542  	}
  2543  
  2544  	req = PullRequestReviewsEnforcementRequest{
  2545  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{},
  2546  	}
  2547  
  2548  	got, err = json.Marshal(req)
  2549  	if err != nil {
  2550  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  2551  	}
  2552  
  2553  	want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  2554  	if want != string(got) {
  2555  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  2556  	}
  2557  
  2558  	req = PullRequestReviewsEnforcementRequest{
  2559  		DismissalRestrictionsRequest: &DismissalRestrictionsRequest{
  2560  			Users: &[]string{},
  2561  			Teams: &[]string{},
  2562  			Apps:  &[]string{},
  2563  		},
  2564  	}
  2565  
  2566  	got, err = json.Marshal(req)
  2567  	if err != nil {
  2568  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
  2569  	}
  2570  
  2571  	want = `{"dismissal_restrictions":{"users":[],"teams":[],"apps":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
  2572  	if want != string(got) {
  2573  		t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
  2574  	}
  2575  }
  2576  
  2577  func TestRepositoriesService_ListAllTopics(t *testing.T) {
  2578  	client, mux, _, teardown := setup()
  2579  	defer teardown()
  2580  
  2581  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2582  		testMethod(t, r, "GET")
  2583  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2584  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  2585  	})
  2586  
  2587  	ctx := context.Background()
  2588  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  2589  	if err != nil {
  2590  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  2591  	}
  2592  
  2593  	want := []string{"go", "go-github", "github"}
  2594  	if !cmp.Equal(got, want) {
  2595  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  2596  	}
  2597  
  2598  	const methodName = "ListAllTopics"
  2599  	testBadOptions(t, methodName, func() (err error) {
  2600  		_, _, err = client.Repositories.ListAllTopics(ctx, "\n", "\n")
  2601  		return err
  2602  	})
  2603  
  2604  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2605  		got, resp, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  2606  		if got != nil {
  2607  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2608  		}
  2609  		return resp, err
  2610  	})
  2611  }
  2612  
  2613  func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) {
  2614  	client, mux, _, teardown := setup()
  2615  	defer teardown()
  2616  
  2617  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2618  		testMethod(t, r, "GET")
  2619  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2620  		fmt.Fprint(w, `{"names":[]}`)
  2621  	})
  2622  
  2623  	ctx := context.Background()
  2624  	got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r")
  2625  	if err != nil {
  2626  		t.Fatalf("Repositories.ListAllTopics returned error: %v", err)
  2627  	}
  2628  
  2629  	want := []string{}
  2630  	if !cmp.Equal(got, want) {
  2631  		t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want)
  2632  	}
  2633  }
  2634  
  2635  func TestRepositoriesService_ReplaceAllTopics(t *testing.T) {
  2636  	client, mux, _, teardown := setup()
  2637  	defer teardown()
  2638  
  2639  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2640  		testMethod(t, r, "PUT")
  2641  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2642  		fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`)
  2643  	})
  2644  
  2645  	ctx := context.Background()
  2646  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  2647  	if err != nil {
  2648  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  2649  	}
  2650  
  2651  	want := []string{"go", "go-github", "github"}
  2652  	if !cmp.Equal(got, want) {
  2653  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  2654  	}
  2655  
  2656  	const methodName = "ReplaceAllTopics"
  2657  	testBadOptions(t, methodName, func() (err error) {
  2658  		_, _, err = client.Repositories.ReplaceAllTopics(ctx, "\n", "\n", []string{"\n", "\n", "\n"})
  2659  		return err
  2660  	})
  2661  
  2662  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2663  		got, resp, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"})
  2664  		if got != nil {
  2665  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2666  		}
  2667  		return resp, err
  2668  	})
  2669  }
  2670  
  2671  func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) {
  2672  	client, mux, _, teardown := setup()
  2673  	defer teardown()
  2674  
  2675  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2676  		testMethod(t, r, "PUT")
  2677  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2678  		testBody(t, r, `{"names":[]}`+"\n")
  2679  		fmt.Fprint(w, `{"names":[]}`)
  2680  	})
  2681  
  2682  	ctx := context.Background()
  2683  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", nil)
  2684  	if err != nil {
  2685  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  2686  	}
  2687  
  2688  	want := []string{}
  2689  	if !cmp.Equal(got, want) {
  2690  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  2691  	}
  2692  }
  2693  
  2694  func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) {
  2695  	client, mux, _, teardown := setup()
  2696  	defer teardown()
  2697  
  2698  	mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) {
  2699  		testMethod(t, r, "PUT")
  2700  		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
  2701  		testBody(t, r, `{"names":[]}`+"\n")
  2702  		fmt.Fprint(w, `{"names":[]}`)
  2703  	})
  2704  
  2705  	ctx := context.Background()
  2706  	got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{})
  2707  	if err != nil {
  2708  		t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err)
  2709  	}
  2710  
  2711  	want := []string{}
  2712  	if !cmp.Equal(got, want) {
  2713  		t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want)
  2714  	}
  2715  }
  2716  
  2717  func TestRepositoriesService_ListApps(t *testing.T) {
  2718  	client, mux, _, teardown := setup()
  2719  	defer teardown()
  2720  
  2721  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2722  		testMethod(t, r, "GET")
  2723  	})
  2724  
  2725  	ctx := context.Background()
  2726  	_, _, err := client.Repositories.ListApps(ctx, "o", "r", "b")
  2727  	if err != nil {
  2728  		t.Errorf("Repositories.ListApps returned error: %v", err)
  2729  	}
  2730  
  2731  	const methodName = "ListApps"
  2732  	testBadOptions(t, methodName, func() (err error) {
  2733  		_, _, err = client.Repositories.ListApps(ctx, "\n", "\n", "\n")
  2734  		return err
  2735  	})
  2736  
  2737  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2738  		got, resp, err := client.Repositories.ListApps(ctx, "o", "r", "b")
  2739  		if got != nil {
  2740  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2741  		}
  2742  		return resp, err
  2743  	})
  2744  }
  2745  
  2746  func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) {
  2747  	client, mux, _, teardown := setup()
  2748  	defer teardown()
  2749  
  2750  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2751  		testMethod(t, r, "PUT")
  2752  		fmt.Fprint(w, `[{
  2753  				"name": "octocat"
  2754  			}]`)
  2755  	})
  2756  	input := []string{"octocat"}
  2757  	ctx := context.Background()
  2758  	got, _, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", "b", input)
  2759  	if err != nil {
  2760  		t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err)
  2761  	}
  2762  	want := []*App{
  2763  		{Name: String("octocat")},
  2764  	}
  2765  	if !cmp.Equal(got, want) {
  2766  		t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want)
  2767  	}
  2768  
  2769  	const methodName = "ReplaceAppRestrictions"
  2770  	testBadOptions(t, methodName, func() (err error) {
  2771  		_, _, err = client.Repositories.ReplaceAppRestrictions(ctx, "\n", "\n", "\n", input)
  2772  		return err
  2773  	})
  2774  
  2775  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2776  		got, resp, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", "b", input)
  2777  		if got != nil {
  2778  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2779  		}
  2780  		return resp, err
  2781  	})
  2782  }
  2783  
  2784  func TestRepositoriesService_AddAppRestrictions(t *testing.T) {
  2785  	client, mux, _, teardown := setup()
  2786  	defer teardown()
  2787  
  2788  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2789  		testMethod(t, r, "POST")
  2790  		fmt.Fprint(w, `[{
  2791  				"name": "octocat"
  2792  			}]`)
  2793  	})
  2794  	input := []string{"octocat"}
  2795  	ctx := context.Background()
  2796  	got, _, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", "b", input)
  2797  	if err != nil {
  2798  		t.Errorf("Repositories.AddAppRestrictions returned error: %v", err)
  2799  	}
  2800  	want := []*App{
  2801  		{Name: String("octocat")},
  2802  	}
  2803  	if !cmp.Equal(got, want) {
  2804  		t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want)
  2805  	}
  2806  
  2807  	const methodName = "AddAppRestrictions"
  2808  	testBadOptions(t, methodName, func() (err error) {
  2809  		_, _, err = client.Repositories.AddAppRestrictions(ctx, "\n", "\n", "\n", input)
  2810  		return err
  2811  	})
  2812  
  2813  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2814  		got, resp, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", "b", input)
  2815  		if got != nil {
  2816  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2817  		}
  2818  		return resp, err
  2819  	})
  2820  }
  2821  
  2822  func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) {
  2823  	client, mux, _, teardown := setup()
  2824  	defer teardown()
  2825  
  2826  	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
  2827  		testMethod(t, r, "DELETE")
  2828  		fmt.Fprint(w, `[]`)
  2829  	})
  2830  	input := []string{"octocat"}
  2831  	ctx := context.Background()
  2832  	got, _, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", "b", input)
  2833  	if err != nil {
  2834  		t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err)
  2835  	}
  2836  	want := []*App{}
  2837  	if !cmp.Equal(got, want) {
  2838  		t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want)
  2839  	}
  2840  
  2841  	const methodName = "RemoveAppRestrictions"
  2842  	testBadOptions(t, methodName, func() (err error) {
  2843  		_, _, err = client.Repositories.RemoveAppRestrictions(ctx, "\n", "\n", "\n", input)
  2844  		return err
  2845  	})
  2846  
  2847  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2848  		got, resp, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", "b", input)
  2849  		if got != nil {
  2850  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2851  		}
  2852  		return resp, err
  2853  	})
  2854  }
  2855  
  2856  func TestRepositoriesService_Transfer(t *testing.T) {
  2857  	client, mux, _, teardown := setup()
  2858  	defer teardown()
  2859  
  2860  	input := TransferRequest{NewOwner: "a", TeamID: []int64{123}}
  2861  
  2862  	mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) {
  2863  		var v TransferRequest
  2864  		json.NewDecoder(r.Body).Decode(&v)
  2865  
  2866  		testMethod(t, r, "POST")
  2867  		if !cmp.Equal(v, input) {
  2868  			t.Errorf("Request body = %+v, want %+v", v, input)
  2869  		}
  2870  
  2871  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  2872  	})
  2873  
  2874  	ctx := context.Background()
  2875  	got, _, err := client.Repositories.Transfer(ctx, "o", "r", input)
  2876  	if err != nil {
  2877  		t.Errorf("Repositories.Transfer returned error: %v", err)
  2878  	}
  2879  
  2880  	want := &Repository{Owner: &User{Login: String("a")}}
  2881  	if !cmp.Equal(got, want) {
  2882  		t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want)
  2883  	}
  2884  
  2885  	const methodName = "Transfer"
  2886  	testBadOptions(t, methodName, func() (err error) {
  2887  		_, _, err = client.Repositories.Transfer(ctx, "\n", "\n", input)
  2888  		return err
  2889  	})
  2890  
  2891  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2892  		got, resp, err := client.Repositories.Transfer(ctx, "o", "r", input)
  2893  		if got != nil {
  2894  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2895  		}
  2896  		return resp, err
  2897  	})
  2898  }
  2899  
  2900  func TestRepositoriesService_Dispatch(t *testing.T) {
  2901  	client, mux, _, teardown := setup()
  2902  	defer teardown()
  2903  
  2904  	var input DispatchRequestOptions
  2905  
  2906  	mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) {
  2907  		var v DispatchRequestOptions
  2908  		json.NewDecoder(r.Body).Decode(&v)
  2909  
  2910  		testMethod(t, r, "POST")
  2911  		if !cmp.Equal(v, input) {
  2912  			t.Errorf("Request body = %+v, want %+v", v, input)
  2913  		}
  2914  
  2915  		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
  2916  	})
  2917  
  2918  	ctx := context.Background()
  2919  
  2920  	testCases := []interface{}{
  2921  		nil,
  2922  		struct {
  2923  			Foo string
  2924  		}{
  2925  			Foo: "test",
  2926  		},
  2927  		struct {
  2928  			Bar int
  2929  		}{
  2930  			Bar: 42,
  2931  		},
  2932  		struct {
  2933  			Foo string
  2934  			Bar int
  2935  			Baz bool
  2936  		}{
  2937  			Foo: "test",
  2938  			Bar: 42,
  2939  			Baz: false,
  2940  		},
  2941  	}
  2942  
  2943  	for _, tc := range testCases {
  2944  		if tc == nil {
  2945  			input = DispatchRequestOptions{EventType: "go"}
  2946  		} else {
  2947  			bytes, _ := json.Marshal(tc)
  2948  			payload := json.RawMessage(bytes)
  2949  			input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload}
  2950  		}
  2951  
  2952  		got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  2953  		if err != nil {
  2954  			t.Errorf("Repositories.Dispatch returned error: %v", err)
  2955  		}
  2956  
  2957  		want := &Repository{Owner: &User{Login: String("a")}}
  2958  		if !cmp.Equal(got, want) {
  2959  			t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want)
  2960  		}
  2961  	}
  2962  
  2963  	const methodName = "Dispatch"
  2964  	testBadOptions(t, methodName, func() (err error) {
  2965  		_, _, err = client.Repositories.Dispatch(ctx, "\n", "\n", input)
  2966  		return err
  2967  	})
  2968  
  2969  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2970  		got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input)
  2971  		if got != nil {
  2972  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
  2973  		}
  2974  		return resp, err
  2975  	})
  2976  }
  2977  
  2978  func TestAdvancedSecurity_Marshal(t *testing.T) {
  2979  	testJSONMarshal(t, &AdvancedSecurity{}, "{}")
  2980  
  2981  	u := &AdvancedSecurity{
  2982  		Status: String("status"),
  2983  	}
  2984  
  2985  	want := `{
  2986  		"status": "status"
  2987  	}`
  2988  
  2989  	testJSONMarshal(t, u, want)
  2990  }
  2991  
  2992  func TestAuthorizedActorsOnly_Marshal(t *testing.T) {
  2993  	testJSONMarshal(t, &AuthorizedActorsOnly{}, "{}")
  2994  
  2995  	u := &AuthorizedActorsOnly{
  2996  		From: Bool(true),
  2997  	}
  2998  
  2999  	want := `{
  3000  		"from" : true
  3001  	}`
  3002  
  3003  	testJSONMarshal(t, u, want)
  3004  }
  3005  
  3006  func TestDispatchRequestOptions_Marshal(t *testing.T) {
  3007  	testJSONMarshal(t, &DispatchRequestOptions{}, "{}")
  3008  
  3009  	cp := json.RawMessage(`{"testKey":"testValue"}`)
  3010  	u := &DispatchRequestOptions{
  3011  		EventType:     "test_event_type",
  3012  		ClientPayload: &cp,
  3013  	}
  3014  
  3015  	want := `{
  3016  		"event_type": "test_event_type",
  3017  		"client_payload": {
  3018  		  "testKey": "testValue"
  3019  		}
  3020  	  }`
  3021  
  3022  	testJSONMarshal(t, u, want)
  3023  }
  3024  
  3025  func TestTransferRequest_Marshal(t *testing.T) {
  3026  	testJSONMarshal(t, &TransferRequest{}, "{}")
  3027  
  3028  	u := &TransferRequest{
  3029  		NewOwner: "testOwner",
  3030  		TeamID:   []int64{1, 2},
  3031  	}
  3032  
  3033  	want := `{
  3034  		"new_owner": "testOwner",
  3035  		"team_ids": [1,2]
  3036  	}`
  3037  
  3038  	testJSONMarshal(t, u, want)
  3039  }
  3040  
  3041  func TestSignaturesProtectedBranch_Marshal(t *testing.T) {
  3042  	testJSONMarshal(t, &SignaturesProtectedBranch{}, "{}")
  3043  
  3044  	u := &SignaturesProtectedBranch{
  3045  		URL:     String("https://www.testURL.in"),
  3046  		Enabled: Bool(false),
  3047  	}
  3048  
  3049  	want := `{
  3050  		"url": "https://www.testURL.in",
  3051  		"enabled": false
  3052  	}`
  3053  
  3054  	testJSONMarshal(t, u, want)
  3055  
  3056  	u2 := &SignaturesProtectedBranch{
  3057  		URL:     String("testURL"),
  3058  		Enabled: Bool(true),
  3059  	}
  3060  
  3061  	want2 := `{
  3062  		"url": "testURL",
  3063  		"enabled": true
  3064  	}`
  3065  
  3066  	testJSONMarshal(t, u2, want2)
  3067  }
  3068  
  3069  func TestDismissalRestrictionsRequest_Marshal(t *testing.T) {
  3070  	testJSONMarshal(t, &DismissalRestrictionsRequest{}, "{}")
  3071  
  3072  	u := &DismissalRestrictionsRequest{
  3073  		Users: &[]string{"user1", "user2"},
  3074  		Teams: &[]string{"team1", "team2"},
  3075  		Apps:  &[]string{"app1", "app2"},
  3076  	}
  3077  
  3078  	want := `{
  3079  		"users": ["user1","user2"],
  3080  		"teams": ["team1","team2"],
  3081  		"apps": ["app1","app2"]
  3082  	}`
  3083  
  3084  	testJSONMarshal(t, u, want)
  3085  }
  3086  
  3087  func TestAdminEnforcement_Marshal(t *testing.T) {
  3088  	testJSONMarshal(t, &AdminEnforcement{}, "{}")
  3089  
  3090  	u := &AdminEnforcement{
  3091  		URL:     String("https://www.test-url.in"),
  3092  		Enabled: false,
  3093  	}
  3094  
  3095  	want := `{
  3096  		"url": "https://www.test-url.in",
  3097  		"enabled": false
  3098  	}`
  3099  
  3100  	testJSONMarshal(t, u, want)
  3101  }
  3102  
  3103  func TestPullRequestReviewsEnforcementUpdate_Marshal(t *testing.T) {
  3104  	testJSONMarshal(t, &PullRequestReviewsEnforcementUpdate{}, "{}")
  3105  
  3106  	u := &PullRequestReviewsEnforcementUpdate{
  3107  		BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{
  3108  			Users: []string{"user1", "user2"},
  3109  			Teams: []string{"team1", "team2"},
  3110  			Apps:  []string{"app1", "app2"},
  3111  		},
  3112  		DismissStaleReviews:          Bool(false),
  3113  		RequireCodeOwnerReviews:      Bool(true),
  3114  		RequiredApprovingReviewCount: 2,
  3115  	}
  3116  
  3117  	want := `{
  3118  		"bypass_pull_request_allowances": {
  3119  			"users": ["user1","user2"],
  3120  			"teams": ["team1","team2"],
  3121  			"apps": ["app1","app2"]
  3122  		},
  3123  		"dismiss_stale_reviews": false,
  3124  		"require_code_owner_reviews": true,
  3125  		"required_approving_review_count": 2
  3126  	}`
  3127  
  3128  	testJSONMarshal(t, u, want)
  3129  }
  3130  
  3131  func TestRequiredStatusCheck_Marshal(t *testing.T) {
  3132  	testJSONMarshal(t, &RequiredStatusCheck{}, "{}")
  3133  
  3134  	u := &RequiredStatusCheck{
  3135  		Context: "ctx",
  3136  		AppID:   Int64(1),
  3137  	}
  3138  
  3139  	want := `{
  3140  		"context": "ctx",
  3141  		"app_id": 1
  3142  	}`
  3143  
  3144  	testJSONMarshal(t, u, want)
  3145  }