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

     1  // Copyright 2014 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  	"errors"
    11  	"fmt"
    12  	"io"
    13  	"net/http"
    14  	"net/url"
    15  	"testing"
    16  
    17  	"github.com/google/go-cmp/cmp"
    18  )
    19  
    20  func TestRepositoryContent_GetContent(t *testing.T) {
    21  	t.Parallel()
    22  	tests := []struct {
    23  		encoding, content *string // input encoding and content
    24  		want              string  // desired output
    25  		wantErr           bool    // whether an error is expected
    26  	}{
    27  		{
    28  			encoding: Ptr(""),
    29  			content:  Ptr("hello"),
    30  			want:     "hello",
    31  			wantErr:  false,
    32  		},
    33  		{
    34  			encoding: nil,
    35  			content:  Ptr("hello"),
    36  			want:     "hello",
    37  			wantErr:  false,
    38  		},
    39  		{
    40  			encoding: nil,
    41  			content:  nil,
    42  			want:     "",
    43  			wantErr:  false,
    44  		},
    45  		{
    46  			encoding: Ptr("base64"),
    47  			content:  Ptr("aGVsbG8="),
    48  			want:     "hello",
    49  			wantErr:  false,
    50  		},
    51  		{
    52  			encoding: Ptr("bad"),
    53  			content:  Ptr("aGVsbG8="),
    54  			want:     "",
    55  			wantErr:  true,
    56  		},
    57  		{
    58  			encoding: Ptr("none"),
    59  			content:  nil,
    60  			want:     "",
    61  			wantErr:  true,
    62  		},
    63  	}
    64  
    65  	for _, tt := range tests {
    66  		r := RepositoryContent{Encoding: tt.encoding, Content: tt.content}
    67  		got, err := r.GetContent()
    68  		if err != nil && !tt.wantErr {
    69  			t.Errorf("RepositoryContent(%s, %s) returned unexpected error: %v",
    70  				stringOrNil(tt.encoding), stringOrNil(tt.content), err)
    71  		}
    72  		if err == nil && tt.wantErr {
    73  			t.Errorf("RepositoryContent(%s, %s) did not return unexpected error",
    74  				stringOrNil(tt.encoding), stringOrNil(tt.content))
    75  		}
    76  		if want := tt.want; got != want {
    77  			t.Errorf("RepositoryContent.GetContent returned %+v, want %+v", got, want)
    78  		}
    79  	}
    80  }
    81  
    82  // stringOrNil converts a potentially null string pointer to string.
    83  // For non-nil input pointer, the returned string is enclosed in double-quotes.
    84  func stringOrNil(s *string) string {
    85  	if s == nil {
    86  		return "<nil>"
    87  	}
    88  	return fmt.Sprintf("%q", *s)
    89  }
    90  
    91  func TestRepositoriesService_GetReadme(t *testing.T) {
    92  	t.Parallel()
    93  	client, mux, _ := setup(t)
    94  
    95  	mux.HandleFunc("/repos/o/r/readme", func(w http.ResponseWriter, r *http.Request) {
    96  		testMethod(t, r, "GET")
    97  		fmt.Fprint(w, `{
    98  		  "type": "file",
    99  		  "encoding": "base64",
   100  		  "size": 5362,
   101  		  "name": "README.md",
   102  		  "path": "README.md"
   103  		}`)
   104  	})
   105  	ctx := context.Background()
   106  	readme, _, err := client.Repositories.GetReadme(ctx, "o", "r", &RepositoryContentGetOptions{})
   107  	if err != nil {
   108  		t.Errorf("Repositories.GetReadme returned error: %v", err)
   109  	}
   110  	want := &RepositoryContent{Type: Ptr("file"), Name: Ptr("README.md"), Size: Ptr(5362), Encoding: Ptr("base64"), Path: Ptr("README.md")}
   111  	if !cmp.Equal(readme, want) {
   112  		t.Errorf("Repositories.GetReadme returned %+v, want %+v", readme, want)
   113  	}
   114  
   115  	const methodName = "GetReadme"
   116  	testBadOptions(t, methodName, func() (err error) {
   117  		_, _, err = client.Repositories.GetReadme(ctx, "\n", "\n", &RepositoryContentGetOptions{})
   118  		return err
   119  	})
   120  
   121  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   122  		got, resp, err := client.Repositories.GetReadme(ctx, "o", "r", &RepositoryContentGetOptions{})
   123  		if got != nil {
   124  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   125  		}
   126  		return resp, err
   127  	})
   128  }
   129  
   130  func TestRepositoriesService_DownloadContents_SuccessForFile(t *testing.T) {
   131  	t.Parallel()
   132  	client, mux, serverURL := setup(t)
   133  
   134  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   135  		testMethod(t, r, "GET")
   136  		fmt.Fprint(w, `{
   137  		  "type": "file",
   138  		  "name": "f",
   139            "content": "foo",
   140  		  "download_url": "`+serverURL+baseURLPath+`/download/f"
   141  		}`)
   142  	})
   143  
   144  	ctx := context.Background()
   145  	r, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   146  	if err != nil {
   147  		t.Errorf("Repositories.DownloadContents returned error: %v", err)
   148  	}
   149  
   150  	if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
   151  		t.Errorf("Repositories.DownloadContents returned status code %v, want %v", got, want)
   152  	}
   153  
   154  	bytes, err := io.ReadAll(r)
   155  	if err != nil {
   156  		t.Errorf("Error reading response body: %v", err)
   157  	}
   158  	r.Close()
   159  
   160  	if got, want := string(bytes), "foo"; got != want {
   161  		t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want)
   162  	}
   163  
   164  	const methodName = "DownloadContents"
   165  	testBadOptions(t, methodName, func() (err error) {
   166  		_, _, err = client.Repositories.DownloadContents(ctx, "\n", "\n", "\n", nil)
   167  		return err
   168  	})
   169  
   170  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   171  		got, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   172  		if got != nil {
   173  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   174  		}
   175  		return resp, err
   176  	})
   177  }
   178  
   179  func TestRepositoriesService_DownloadContents_SuccessForDirectory(t *testing.T) {
   180  	t.Parallel()
   181  	client, mux, serverURL := setup(t)
   182  
   183  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   184  		testMethod(t, r, "GET")
   185  		fmt.Fprint(w, `{
   186  		  "type": "file",
   187  		  "name": "f"
   188  		}`)
   189  	})
   190  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   191  		testMethod(t, r, "GET")
   192  		fmt.Fprint(w, `[{
   193  		  "type": "file",
   194  		  "name": "f",
   195  		  "download_url": "`+serverURL+baseURLPath+`/download/f"
   196  		}]`)
   197  	})
   198  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   199  		testMethod(t, r, "GET")
   200  		fmt.Fprint(w, "foo")
   201  	})
   202  
   203  	ctx := context.Background()
   204  	r, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   205  	if err != nil {
   206  		t.Errorf("Repositories.DownloadContents returned error: %v", err)
   207  	}
   208  
   209  	if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
   210  		t.Errorf("Repositories.DownloadContents returned status code %v, want %v", got, want)
   211  	}
   212  
   213  	bytes, err := io.ReadAll(r)
   214  	if err != nil {
   215  		t.Errorf("Error reading response body: %v", err)
   216  	}
   217  	r.Close()
   218  
   219  	if got, want := string(bytes), "foo"; got != want {
   220  		t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want)
   221  	}
   222  
   223  	const methodName = "DownloadContents"
   224  	testBadOptions(t, methodName, func() (err error) {
   225  		_, _, err = client.Repositories.DownloadContents(ctx, "\n", "\n", "\n", nil)
   226  		return err
   227  	})
   228  
   229  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   230  		got, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   231  		if got != nil {
   232  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   233  		}
   234  		return resp, err
   235  	})
   236  }
   237  
   238  func TestRepositoriesService_DownloadContents_FailedResponse(t *testing.T) {
   239  	t.Parallel()
   240  	client, mux, serverURL := setup(t)
   241  
   242  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   243  		testMethod(t, r, "GET")
   244  		fmt.Fprint(w, `{
   245  			"type": "file",
   246  			"name": "f"
   247  		  }`)
   248  	})
   249  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   250  		testMethod(t, r, "GET")
   251  		fmt.Fprint(w, `[{
   252  			"type": "file",
   253  			"name": "f",
   254  			"download_url": "`+serverURL+baseURLPath+`/download/f"
   255  		  }]`)
   256  	})
   257  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   258  		testMethod(t, r, "GET")
   259  		w.WriteHeader(http.StatusInternalServerError)
   260  		fmt.Fprint(w, "foo error")
   261  	})
   262  
   263  	ctx := context.Background()
   264  	r, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   265  	if err != nil {
   266  		t.Errorf("Repositories.DownloadContents returned error: %v", err)
   267  	}
   268  
   269  	if got, want := resp.Response.StatusCode, http.StatusInternalServerError; got != want {
   270  		t.Errorf("Repositories.DownloadContents returned status code %v, want %v", got, want)
   271  	}
   272  
   273  	bytes, err := io.ReadAll(r)
   274  	if err != nil {
   275  		t.Errorf("Error reading response body: %v", err)
   276  	}
   277  	r.Close()
   278  
   279  	if got, want := string(bytes), "foo error"; got != want {
   280  		t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want)
   281  	}
   282  }
   283  
   284  func TestRepositoriesService_DownloadContents_NoDownloadURL(t *testing.T) {
   285  	t.Parallel()
   286  	client, mux, _ := setup(t)
   287  
   288  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   289  		testMethod(t, r, "GET")
   290  		fmt.Fprint(w, `{
   291  		  "type": "file",
   292  		  "name": "f",
   293  		  "content": ""
   294  		}`)
   295  	})
   296  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   297  		testMethod(t, r, "GET")
   298  		fmt.Fprint(w, `[{
   299  		  "type": "file",
   300  		  "name": "f",
   301  		  "content": ""
   302  		}]`)
   303  	})
   304  
   305  	ctx := context.Background()
   306  	reader, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   307  	if err == nil {
   308  		t.Error("Repositories.DownloadContents did not return expected error")
   309  	}
   310  
   311  	if resp == nil {
   312  		t.Error("Repositories.DownloadContents did not return expected response")
   313  	}
   314  
   315  	if reader != nil {
   316  		t.Error("Repositories.DownloadContents did not return expected reader")
   317  	}
   318  }
   319  
   320  func TestRepositoriesService_DownloadContents_NoFile(t *testing.T) {
   321  	t.Parallel()
   322  	client, mux, _ := setup(t)
   323  
   324  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   325  		testMethod(t, r, "GET")
   326  		fmt.Fprint(w, `{
   327  		  "type": "file",
   328  		  "name": "f",
   329  		  "content": ""
   330  		}`)
   331  	})
   332  
   333  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   334  		testMethod(t, r, "GET")
   335  		fmt.Fprint(w, `[]`)
   336  	})
   337  
   338  	ctx := context.Background()
   339  	reader, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   340  	if err == nil {
   341  		t.Error("Repositories.DownloadContents did not return expected error")
   342  	}
   343  
   344  	if resp == nil {
   345  		t.Error("Repositories.DownloadContents did not return expected response")
   346  	}
   347  
   348  	if reader != nil {
   349  		t.Error("Repositories.DownloadContents did not return expected reader")
   350  	}
   351  }
   352  
   353  func TestRepositoriesService_DownloadContentsWithMeta_SuccessForFile(t *testing.T) {
   354  	t.Parallel()
   355  	client, mux, serverURL := setup(t)
   356  
   357  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   358  		testMethod(t, r, "GET")
   359  		fmt.Fprint(w, `{
   360  		  "type": "file",
   361  		  "name": "f",
   362  		  "download_url": "`+serverURL+baseURLPath+`/download/f",
   363            "content": "foo"
   364  		}`)
   365  	})
   366  
   367  	ctx := context.Background()
   368  	r, c, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   369  	if err != nil {
   370  		t.Errorf("Repositories.DownloadContentsWithMeta returned error: %v", err)
   371  	}
   372  
   373  	if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
   374  		t.Errorf("Repositories.DownloadContentsWithMeta returned status code %v, want %v", got, want)
   375  	}
   376  
   377  	bytes, err := io.ReadAll(r)
   378  	if err != nil {
   379  		t.Errorf("Error reading response body: %v", err)
   380  	}
   381  	r.Close()
   382  
   383  	if got, want := string(bytes), "foo"; got != want {
   384  		t.Errorf("Repositories.DownloadContentsWithMeta returned %v, want %v", got, want)
   385  	}
   386  
   387  	if c != nil && c.Name != nil {
   388  		if got, want := *c.Name, "f"; got != want {
   389  			t.Errorf("Repositories.DownloadContentsWithMeta returned content name %v, want %v", got, want)
   390  		}
   391  	} else {
   392  		t.Error("Returned RepositoryContent is null")
   393  	}
   394  
   395  	const methodName = "DownloadContentsWithMeta"
   396  	testBadOptions(t, methodName, func() (err error) {
   397  		_, _, _, err = client.Repositories.DownloadContentsWithMeta(ctx, "\n", "\n", "\n", nil)
   398  		return err
   399  	})
   400  
   401  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   402  		got, cot, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   403  		if got != nil {
   404  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   405  		}
   406  		if cot != nil {
   407  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, cot)
   408  		}
   409  		return resp, err
   410  	})
   411  }
   412  
   413  func TestRepositoriesService_DownloadContentsWithMeta_SuccessForDirectory(t *testing.T) {
   414  	t.Parallel()
   415  	client, mux, serverURL := setup(t)
   416  
   417  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   418  		testMethod(t, r, "GET")
   419  		fmt.Fprint(w, `[{
   420  		  "type": "file",
   421  		  "name": "f",
   422  		  "download_url": "`+serverURL+baseURLPath+`/download/f"
   423  		}]`)
   424  	})
   425  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   426  		testMethod(t, r, "GET")
   427  		fmt.Fprint(w, "foo")
   428  	})
   429  
   430  	ctx := context.Background()
   431  	r, c, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   432  	if err != nil {
   433  		t.Errorf("Repositories.DownloadContentsWithMeta returned error: %v", err)
   434  	}
   435  
   436  	if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
   437  		t.Errorf("Repositories.DownloadContentsWithMeta returned status code %v, want %v", got, want)
   438  	}
   439  
   440  	bytes, err := io.ReadAll(r)
   441  	if err != nil {
   442  		t.Errorf("Error reading response body: %v", err)
   443  	}
   444  	r.Close()
   445  
   446  	if got, want := string(bytes), "foo"; got != want {
   447  		t.Errorf("Repositories.DownloadContentsWithMeta returned %v, want %v", got, want)
   448  	}
   449  
   450  	if c != nil && c.Name != nil {
   451  		if got, want := *c.Name, "f"; got != want {
   452  			t.Errorf("Repositories.DownloadContentsWithMeta returned content name %v, want %v", got, want)
   453  		}
   454  	} else {
   455  		t.Error("Returned RepositoryContent is null")
   456  	}
   457  }
   458  
   459  func TestRepositoriesService_DownloadContentsWithMeta_FailedResponse(t *testing.T) {
   460  	t.Parallel()
   461  	client, mux, serverURL := setup(t)
   462  
   463  	downloadURL := fmt.Sprintf("%s%s/download/f", serverURL, baseURLPath)
   464  
   465  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   466  		testMethod(t, r, "GET")
   467  		fmt.Fprint(w, `{
   468  			"type": "file",
   469  			"name": "f",
   470  			"download_url": "`+downloadURL+`"
   471  		  }`)
   472  	})
   473  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   474  		testMethod(t, r, "GET")
   475  		w.WriteHeader(http.StatusInternalServerError)
   476  		fmt.Fprint(w, "foo error")
   477  	})
   478  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   479  		testMethod(t, r, "GET")
   480  		fmt.Fprint(w, `[{
   481  			"type": "file",
   482  			"name": "f",
   483  			"download_url": "`+downloadURL+`"
   484  		  }]`)
   485  	})
   486  
   487  	ctx := context.Background()
   488  	r, c, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   489  	if err != nil {
   490  		t.Errorf("Repositories.DownloadContentsWithMeta returned error: %v", err)
   491  	}
   492  
   493  	if got, want := resp.Response.StatusCode, http.StatusInternalServerError; got != want {
   494  		t.Errorf("Repositories.DownloadContentsWithMeta returned status code %v, want %v", got, want)
   495  	}
   496  
   497  	bytes, err := io.ReadAll(r)
   498  	if err != nil {
   499  		t.Errorf("Error reading response body: %v", err)
   500  	}
   501  	r.Close()
   502  
   503  	if got, want := string(bytes), "foo error"; got != want {
   504  		t.Errorf("Repositories.DownloadContentsWithMeta returned %v, want %v", got, want)
   505  	}
   506  
   507  	if c != nil && c.Name != nil {
   508  		if got, want := *c.Name, "f"; got != want {
   509  			t.Errorf("Repositories.DownloadContentsWithMeta returned content name %v, want %v", got, want)
   510  		}
   511  	} else {
   512  		t.Error("Returned RepositoryContent is null")
   513  	}
   514  }
   515  
   516  func TestRepositoriesService_DownloadContentsWithMeta_NoDownloadURL(t *testing.T) {
   517  	t.Parallel()
   518  	client, mux, _ := setup(t)
   519  
   520  	mux.HandleFunc("/repos/o/r/contents/d/f", func(w http.ResponseWriter, r *http.Request) {
   521  		testMethod(t, r, "GET")
   522  		fmt.Fprint(w, `{
   523  		  "type": "file",
   524  		  "name": "f",
   525  		}`)
   526  	})
   527  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   528  		testMethod(t, r, "GET")
   529  		fmt.Fprint(w, `[{
   530  		  "type": "file",
   531  		  "name": "f",
   532  		  "content": ""
   533  		}]`)
   534  	})
   535  
   536  	ctx := context.Background()
   537  	reader, contents, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   538  	if err == nil {
   539  		t.Error("Repositories.DownloadContentsWithMeta did not return expected error")
   540  	}
   541  
   542  	if reader != nil {
   543  		t.Error("Repositories.DownloadContentsWithMeta did not return expected reader")
   544  	}
   545  
   546  	if resp == nil {
   547  		t.Error("Repositories.DownloadContentsWithMeta did not return expected response")
   548  	}
   549  
   550  	if contents == nil {
   551  		t.Error("Repositories.DownloadContentsWithMeta did not return expected content")
   552  	}
   553  }
   554  
   555  func TestRepositoriesService_DownloadContentsWithMeta_NoFile(t *testing.T) {
   556  	t.Parallel()
   557  	client, mux, _ := setup(t)
   558  
   559  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   560  		testMethod(t, r, "GET")
   561  		fmt.Fprint(w, `[]`)
   562  	})
   563  
   564  	ctx := context.Background()
   565  	_, _, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   566  	if err == nil {
   567  		t.Error("Repositories.DownloadContentsWithMeta did not return expected error")
   568  	}
   569  
   570  	if resp == nil {
   571  		t.Error("Repositories.DownloadContentsWithMeta did not return expected response")
   572  	}
   573  }
   574  
   575  func TestRepositoriesService_GetContents_File(t *testing.T) {
   576  	t.Parallel()
   577  	client, mux, _ := setup(t)
   578  
   579  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   580  		testMethod(t, r, "GET")
   581  		fmt.Fprint(w, `{
   582  		  "type": "file",
   583  		  "encoding": "base64",
   584  		  "size": 20678,
   585  		  "name": "LICENSE",
   586  		  "path": "LICENSE"
   587  		}`)
   588  	})
   589  	ctx := context.Background()
   590  	fileContents, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "p", &RepositoryContentGetOptions{})
   591  	if err != nil {
   592  		t.Errorf("Repositories.GetContents returned error: %v", err)
   593  	}
   594  	want := &RepositoryContent{Type: Ptr("file"), Name: Ptr("LICENSE"), Size: Ptr(20678), Encoding: Ptr("base64"), Path: Ptr("LICENSE")}
   595  	if !cmp.Equal(fileContents, want) {
   596  		t.Errorf("Repositories.GetContents returned %+v, want %+v", fileContents, want)
   597  	}
   598  
   599  	const methodName = "GetContents"
   600  	testBadOptions(t, methodName, func() (err error) {
   601  		_, _, _, err = client.Repositories.GetContents(ctx, "\n", "\n", "\n", &RepositoryContentGetOptions{})
   602  		return err
   603  	})
   604  
   605  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   606  		got, _, resp, err := client.Repositories.GetContents(ctx, "o", "r", "p", &RepositoryContentGetOptions{})
   607  		if got != nil {
   608  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   609  		}
   610  		return resp, err
   611  	})
   612  }
   613  
   614  func TestRepositoriesService_GetContents_FilenameNeedsEscape(t *testing.T) {
   615  	t.Parallel()
   616  	client, mux, _ := setup(t)
   617  
   618  	mux.HandleFunc("/repos/o/r/contents/p#?%/中.go", func(w http.ResponseWriter, r *http.Request) {
   619  		testMethod(t, r, "GET")
   620  		fmt.Fprint(w, `{}`)
   621  	})
   622  	ctx := context.Background()
   623  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "p#?%/中.go", &RepositoryContentGetOptions{})
   624  	if err != nil {
   625  		t.Fatalf("Repositories.GetContents returned error: %v", err)
   626  	}
   627  }
   628  
   629  func TestRepositoriesService_GetContents_DirectoryWithSpaces(t *testing.T) {
   630  	t.Parallel()
   631  	client, mux, _ := setup(t)
   632  
   633  	mux.HandleFunc("/repos/o/r/contents/some%20directory/file.go", func(w http.ResponseWriter, r *http.Request) {
   634  		testMethod(t, r, "GET")
   635  		fmt.Fprint(w, `{}`)
   636  	})
   637  	ctx := context.Background()
   638  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "some directory/file.go", &RepositoryContentGetOptions{})
   639  	if err != nil {
   640  		t.Fatalf("Repositories.GetContents returned error: %v", err)
   641  	}
   642  }
   643  
   644  func TestRepositoriesService_GetContents_PathWithParent(t *testing.T) {
   645  	t.Parallel()
   646  	client, mux, _ := setup(t)
   647  
   648  	mux.HandleFunc("/repos/o/r/contents/some/../directory/file.go", func(w http.ResponseWriter, r *http.Request) {
   649  		testMethod(t, r, "GET")
   650  		fmt.Fprint(w, `{}`)
   651  	})
   652  	ctx := context.Background()
   653  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "some/../directory/file.go", &RepositoryContentGetOptions{})
   654  	if err == nil {
   655  		t.Fatal("Repositories.GetContents expected error but got none")
   656  	}
   657  }
   658  
   659  func TestRepositoriesService_GetContents_DirectoryWithPlusChars(t *testing.T) {
   660  	t.Parallel()
   661  	client, mux, _ := setup(t)
   662  
   663  	mux.HandleFunc("/repos/o/r/contents/some%20directory%2Bname/file.go", func(w http.ResponseWriter, r *http.Request) {
   664  		testMethod(t, r, "GET")
   665  		fmt.Fprint(w, `{}`)
   666  	})
   667  	ctx := context.Background()
   668  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "some directory+name/file.go", &RepositoryContentGetOptions{})
   669  	if err != nil {
   670  		t.Fatalf("Repositories.GetContents returned error: %v", err)
   671  	}
   672  }
   673  
   674  func TestRepositoriesService_GetContents_Directory(t *testing.T) {
   675  	t.Parallel()
   676  	client, mux, _ := setup(t)
   677  
   678  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   679  		testMethod(t, r, "GET")
   680  		fmt.Fprint(w, `[{
   681  		  "type": "dir",
   682  		  "name": "lib",
   683  		  "path": "lib"
   684  		},
   685  		{
   686  		  "type": "file",
   687  		  "size": 20678,
   688  		  "name": "LICENSE",
   689  		  "path": "LICENSE"
   690  		}]`)
   691  	})
   692  	ctx := context.Background()
   693  	_, directoryContents, _, err := client.Repositories.GetContents(ctx, "o", "r", "p", &RepositoryContentGetOptions{})
   694  	if err != nil {
   695  		t.Errorf("Repositories.GetContents returned error: %v", err)
   696  	}
   697  	want := []*RepositoryContent{{Type: Ptr("dir"), Name: Ptr("lib"), Path: Ptr("lib")},
   698  		{Type: Ptr("file"), Name: Ptr("LICENSE"), Size: Ptr(20678), Path: Ptr("LICENSE")}}
   699  	if !cmp.Equal(directoryContents, want) {
   700  		t.Errorf("Repositories.GetContents_Directory returned %+v, want %+v", directoryContents, want)
   701  	}
   702  }
   703  
   704  func TestRepositoriesService_CreateFile(t *testing.T) {
   705  	t.Parallel()
   706  	client, mux, _ := setup(t)
   707  
   708  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   709  		testMethod(t, r, "PUT")
   710  		fmt.Fprint(w, `{
   711  			"content":{
   712  				"name":"p"
   713  			},
   714  			"commit":{
   715  				"message":"m",
   716  				"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
   717  			}
   718  		}`)
   719  	})
   720  	message := "m"
   721  	content := []byte("c")
   722  	repositoryContentsOptions := &RepositoryContentFileOptions{
   723  		Message:   &message,
   724  		Content:   content,
   725  		Committer: &CommitAuthor{Name: Ptr("n"), Email: Ptr("e")},
   726  	}
   727  	ctx := context.Background()
   728  	createResponse, _, err := client.Repositories.CreateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   729  	if err != nil {
   730  		t.Errorf("Repositories.CreateFile returned error: %v", err)
   731  	}
   732  	want := &RepositoryContentResponse{
   733  		Content: &RepositoryContent{Name: Ptr("p")},
   734  		Commit: Commit{
   735  			Message: Ptr("m"),
   736  			SHA:     Ptr("f5f369044773ff9c6383c087466d12adb6fa0828"),
   737  		},
   738  	}
   739  	if !cmp.Equal(createResponse, want) {
   740  		t.Errorf("Repositories.CreateFile returned %+v, want %+v", createResponse, want)
   741  	}
   742  
   743  	const methodName = "CreateFile"
   744  	testBadOptions(t, methodName, func() (err error) {
   745  		_, _, err = client.Repositories.CreateFile(ctx, "\n", "\n", "\n", repositoryContentsOptions)
   746  		return err
   747  	})
   748  
   749  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   750  		got, resp, err := client.Repositories.CreateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   751  		if got != nil {
   752  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   753  		}
   754  		return resp, err
   755  	})
   756  }
   757  
   758  func TestRepositoriesService_UpdateFile(t *testing.T) {
   759  	t.Parallel()
   760  	client, mux, _ := setup(t)
   761  
   762  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   763  		testMethod(t, r, "PUT")
   764  		fmt.Fprint(w, `{
   765  			"content":{
   766  				"name":"p"
   767  			},
   768  			"commit":{
   769  				"message":"m",
   770  				"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
   771  			}
   772  		}`)
   773  	})
   774  	message := "m"
   775  	content := []byte("c")
   776  	sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
   777  	repositoryContentsOptions := &RepositoryContentFileOptions{
   778  		Message:   &message,
   779  		Content:   content,
   780  		SHA:       &sha,
   781  		Committer: &CommitAuthor{Name: Ptr("n"), Email: Ptr("e")},
   782  	}
   783  	ctx := context.Background()
   784  	updateResponse, _, err := client.Repositories.UpdateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   785  	if err != nil {
   786  		t.Errorf("Repositories.UpdateFile returned error: %v", err)
   787  	}
   788  	want := &RepositoryContentResponse{
   789  		Content: &RepositoryContent{Name: Ptr("p")},
   790  		Commit: Commit{
   791  			Message: Ptr("m"),
   792  			SHA:     Ptr("f5f369044773ff9c6383c087466d12adb6fa0828"),
   793  		},
   794  	}
   795  	if !cmp.Equal(updateResponse, want) {
   796  		t.Errorf("Repositories.UpdateFile returned %+v, want %+v", updateResponse, want)
   797  	}
   798  
   799  	const methodName = "UpdateFile"
   800  	testBadOptions(t, methodName, func() (err error) {
   801  		_, _, err = client.Repositories.UpdateFile(ctx, "\n", "\n", "\n", repositoryContentsOptions)
   802  		return err
   803  	})
   804  
   805  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   806  		got, resp, err := client.Repositories.UpdateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   807  		if got != nil {
   808  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   809  		}
   810  		return resp, err
   811  	})
   812  }
   813  
   814  func TestRepositoriesService_DeleteFile(t *testing.T) {
   815  	t.Parallel()
   816  	client, mux, _ := setup(t)
   817  
   818  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   819  		testMethod(t, r, "DELETE")
   820  		fmt.Fprint(w, `{
   821  			"content": null,
   822  			"commit":{
   823  				"message":"m",
   824  				"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
   825  			}
   826  		}`)
   827  	})
   828  	message := "m"
   829  	sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
   830  	repositoryContentsOptions := &RepositoryContentFileOptions{
   831  		Message:   &message,
   832  		SHA:       &sha,
   833  		Committer: &CommitAuthor{Name: Ptr("n"), Email: Ptr("e")},
   834  	}
   835  	ctx := context.Background()
   836  	deleteResponse, _, err := client.Repositories.DeleteFile(ctx, "o", "r", "p", repositoryContentsOptions)
   837  	if err != nil {
   838  		t.Errorf("Repositories.DeleteFile returned error: %v", err)
   839  	}
   840  	want := &RepositoryContentResponse{
   841  		Content: nil,
   842  		Commit: Commit{
   843  			Message: Ptr("m"),
   844  			SHA:     Ptr("f5f369044773ff9c6383c087466d12adb6fa0828"),
   845  		},
   846  	}
   847  	if !cmp.Equal(deleteResponse, want) {
   848  		t.Errorf("Repositories.DeleteFile returned %+v, want %+v", deleteResponse, want)
   849  	}
   850  
   851  	const methodName = "DeleteFile"
   852  	testBadOptions(t, methodName, func() (err error) {
   853  		_, _, err = client.Repositories.DeleteFile(ctx, "\n", "\n", "\n", repositoryContentsOptions)
   854  		return err
   855  	})
   856  
   857  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   858  		got, resp, err := client.Repositories.DeleteFile(ctx, "o", "r", "p", repositoryContentsOptions)
   859  		if got != nil {
   860  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   861  		}
   862  		return resp, err
   863  	})
   864  }
   865  
   866  func TestRepositoriesService_GetArchiveLink(t *testing.T) {
   867  	t.Parallel()
   868  	tcs := []struct {
   869  		name              string
   870  		respectRateLimits bool
   871  	}{
   872  		{
   873  			name:              "withoutRateLimits",
   874  			respectRateLimits: false,
   875  		},
   876  		{
   877  			name:              "withRateLimits",
   878  			respectRateLimits: true,
   879  		},
   880  	}
   881  
   882  	for _, tc := range tcs {
   883  		t.Run(tc.name, func(t *testing.T) {
   884  			t.Parallel()
   885  			client, mux, _ := setup(t)
   886  			client.RateLimitRedirectionalEndpoints = tc.respectRateLimits
   887  
   888  			mux.HandleFunc("/repos/o/r/tarball/yo", func(w http.ResponseWriter, r *http.Request) {
   889  				testMethod(t, r, "GET")
   890  				http.Redirect(w, r, "http://github.com/a", http.StatusFound)
   891  			})
   892  			ctx := context.Background()
   893  			url, resp, err := client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{Ref: "yo"}, 1)
   894  			if err != nil {
   895  				t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
   896  			}
   897  			if resp.StatusCode != http.StatusFound {
   898  				t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound)
   899  			}
   900  			want := "http://github.com/a"
   901  			if url.String() != want {
   902  				t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want)
   903  			}
   904  
   905  			const methodName = "GetArchiveLink"
   906  			testBadOptions(t, methodName, func() (err error) {
   907  				_, _, err = client.Repositories.GetArchiveLink(ctx, "\n", "\n", Tarball, &RepositoryContentGetOptions{}, 1)
   908  				return err
   909  			})
   910  
   911  			// Add custom round tripper
   912  			client.client.Transport = roundTripperFunc(func(*http.Request) (*http.Response, error) {
   913  				return nil, errors.New("failed to get archive link")
   914  			})
   915  			testBadOptions(t, methodName, func() (err error) {
   916  				_, _, err = client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{}, 1)
   917  				return err
   918  			})
   919  		})
   920  	}
   921  }
   922  
   923  func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_dontFollowRedirects(t *testing.T) {
   924  	t.Parallel()
   925  	tcs := []struct {
   926  		name              string
   927  		respectRateLimits bool
   928  	}{
   929  		{
   930  			name:              "withoutRateLimits",
   931  			respectRateLimits: false,
   932  		},
   933  		{
   934  			name:              "withRateLimits",
   935  			respectRateLimits: true,
   936  		},
   937  	}
   938  
   939  	for _, tc := range tcs {
   940  		t.Run(tc.name, func(t *testing.T) {
   941  			t.Parallel()
   942  			client, mux, _ := setup(t)
   943  			client.RateLimitRedirectionalEndpoints = tc.respectRateLimits
   944  
   945  			mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
   946  				testMethod(t, r, "GET")
   947  				http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently)
   948  			})
   949  			ctx := context.Background()
   950  			_, resp, _ := client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{}, 0)
   951  			if resp.StatusCode != http.StatusMovedPermanently {
   952  				t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently)
   953  			}
   954  		})
   955  	}
   956  }
   957  
   958  func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_followRedirects(t *testing.T) {
   959  	t.Parallel()
   960  	tcs := []struct {
   961  		name              string
   962  		respectRateLimits bool
   963  	}{
   964  		{
   965  			name:              "withoutRateLimits",
   966  			respectRateLimits: false,
   967  		},
   968  		{
   969  			name:              "withRateLimits",
   970  			respectRateLimits: true,
   971  		},
   972  	}
   973  
   974  	for _, tc := range tcs {
   975  		t.Run(tc.name, func(t *testing.T) {
   976  			t.Parallel()
   977  			client, mux, serverURL := setup(t)
   978  			client.RateLimitRedirectionalEndpoints = tc.respectRateLimits
   979  
   980  			// Mock a redirect link, which leads to an archive link
   981  			mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
   982  				testMethod(t, r, "GET")
   983  				redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect")
   984  				http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
   985  			})
   986  			mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
   987  				testMethod(t, r, "GET")
   988  				http.Redirect(w, r, "http://github.com/a", http.StatusFound)
   989  			})
   990  			ctx := context.Background()
   991  			url, resp, err := client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{}, 1)
   992  			if err != nil {
   993  				t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
   994  			}
   995  			if resp.StatusCode != http.StatusFound {
   996  				t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound)
   997  			}
   998  			want := "http://github.com/a"
   999  			if url.String() != want {
  1000  				t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want)
  1001  			}
  1002  		})
  1003  	}
  1004  }
  1005  
  1006  func TestRepositoriesService_GetContents_NoTrailingSlashInDirectoryApiPath(t *testing.T) {
  1007  	t.Parallel()
  1008  	client, mux, _ := setup(t)
  1009  
  1010  	mux.HandleFunc("/repos/o/r/contents/.github", func(w http.ResponseWriter, r *http.Request) {
  1011  		testMethod(t, r, "GET")
  1012  		query := r.URL.Query()
  1013  		if query.Get("ref") != "mybranch" {
  1014  			t.Errorf("Repositories.GetContents returned %+v, want %+v", query.Get("ref"), "mybranch")
  1015  		}
  1016  		fmt.Fprint(w, `{}`)
  1017  	})
  1018  	ctx := context.Background()
  1019  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", ".github/", &RepositoryContentGetOptions{
  1020  		Ref: "mybranch",
  1021  	})
  1022  	if err != nil {
  1023  		t.Fatalf("Repositories.GetContents returned error: %v", err)
  1024  	}
  1025  }
  1026  
  1027  func TestRepositoryContent_Marshal(t *testing.T) {
  1028  	t.Parallel()
  1029  	testJSONMarshal(t, &RepositoryContent{}, "{}")
  1030  
  1031  	r := &RepositoryContent{
  1032  		Type:            Ptr("type"),
  1033  		Target:          Ptr("target"),
  1034  		Encoding:        Ptr("encoding"),
  1035  		Size:            Ptr(1),
  1036  		Name:            Ptr("name"),
  1037  		Path:            Ptr("path"),
  1038  		Content:         Ptr("content"),
  1039  		SHA:             Ptr("sha"),
  1040  		URL:             Ptr("url"),
  1041  		GitURL:          Ptr("gurl"),
  1042  		HTMLURL:         Ptr("hurl"),
  1043  		DownloadURL:     Ptr("durl"),
  1044  		SubmoduleGitURL: Ptr("smgurl"),
  1045  	}
  1046  
  1047  	want := `{
  1048  		"type": "type",
  1049  		"target": "target",
  1050  		"encoding": "encoding",
  1051  		"size": 1,
  1052  		"name": "name",
  1053  		"path": "path",
  1054  		"content": "content",
  1055  		"sha": "sha",
  1056  		"url": "url",
  1057  		"git_url": "gurl",
  1058  		"html_url": "hurl",
  1059  		"download_url": "durl",
  1060  		"submodule_git_url": "smgurl"
  1061  	}`
  1062  
  1063  	testJSONMarshal(t, r, want)
  1064  }
  1065  
  1066  func TestRepositoryContentResponse_Marshal(t *testing.T) {
  1067  	t.Parallel()
  1068  	testJSONMarshal(t, &RepositoryContentResponse{}, "{}")
  1069  
  1070  	r := &RepositoryContentResponse{
  1071  		Content: &RepositoryContent{
  1072  			Type:            Ptr("type"),
  1073  			Target:          Ptr("target"),
  1074  			Encoding:        Ptr("encoding"),
  1075  			Size:            Ptr(1),
  1076  			Name:            Ptr("name"),
  1077  			Path:            Ptr("path"),
  1078  			Content:         Ptr("content"),
  1079  			SHA:             Ptr("sha"),
  1080  			URL:             Ptr("url"),
  1081  			GitURL:          Ptr("gurl"),
  1082  			HTMLURL:         Ptr("hurl"),
  1083  			DownloadURL:     Ptr("durl"),
  1084  			SubmoduleGitURL: Ptr("smgurl"),
  1085  		},
  1086  		Commit: Commit{
  1087  			SHA: Ptr("s"),
  1088  			Author: &CommitAuthor{
  1089  				Date:  &Timestamp{referenceTime},
  1090  				Name:  Ptr("n"),
  1091  				Email: Ptr("e"),
  1092  				Login: Ptr("u"),
  1093  			},
  1094  			Committer: &CommitAuthor{
  1095  				Date:  &Timestamp{referenceTime},
  1096  				Name:  Ptr("n"),
  1097  				Email: Ptr("e"),
  1098  				Login: Ptr("u"),
  1099  			},
  1100  			Message: Ptr("m"),
  1101  			Tree: &Tree{
  1102  				SHA: Ptr("s"),
  1103  				Entries: []*TreeEntry{{
  1104  					SHA:     Ptr("s"),
  1105  					Path:    Ptr("p"),
  1106  					Mode:    Ptr("m"),
  1107  					Type:    Ptr("t"),
  1108  					Size:    Ptr(1),
  1109  					Content: Ptr("c"),
  1110  					URL:     Ptr("u"),
  1111  				}},
  1112  				Truncated: Ptr(false),
  1113  			},
  1114  			Parents: nil,
  1115  			HTMLURL: Ptr("h"),
  1116  			URL:     Ptr("u"),
  1117  			Verification: &SignatureVerification{
  1118  				Verified:  Ptr(false),
  1119  				Reason:    Ptr("r"),
  1120  				Signature: Ptr("s"),
  1121  				Payload:   Ptr("p"),
  1122  			},
  1123  			NodeID:       Ptr("n"),
  1124  			CommentCount: Ptr(1),
  1125  		},
  1126  	}
  1127  
  1128  	want := `{
  1129  		"content": {
  1130  			"type": "type",
  1131  			"target": "target",
  1132  			"encoding": "encoding",
  1133  			"size": 1,
  1134  			"name": "name",
  1135  			"path": "path",
  1136  			"content": "content",
  1137  			"sha": "sha",
  1138  			"url": "url",
  1139  			"git_url": "gurl",
  1140  			"html_url": "hurl",
  1141  			"download_url": "durl",
  1142  			"submodule_git_url": "smgurl"
  1143  		},
  1144  		"commit": {
  1145  			"sha": "s",
  1146  			"author": {
  1147  				"date": ` + referenceTimeStr + `,
  1148  				"name": "n",
  1149  				"email": "e",
  1150  				"username": "u"
  1151  			},
  1152  			"committer": {
  1153  				"date": ` + referenceTimeStr + `,
  1154  				"name": "n",
  1155  				"email": "e",
  1156  				"username": "u"
  1157  			},
  1158  			"message": "m",
  1159  			"tree": {
  1160  				"sha": "s",
  1161  				"tree": [
  1162  					{
  1163  						"sha": "s",
  1164  						"path": "p",
  1165  						"mode": "m",
  1166  						"type": "t",
  1167  						"size": 1,
  1168  						"content": "c",
  1169  						"url": "u"
  1170  					}
  1171  				],
  1172  				"truncated": false
  1173  			},
  1174  			"html_url": "h",
  1175  			"url": "u",
  1176  			"verification": {
  1177  				"verified": false,
  1178  				"reason": "r",
  1179  				"signature": "s",
  1180  				"payload": "p"
  1181  			},
  1182  			"node_id": "n",
  1183  			"comment_count": 1
  1184  		}
  1185  	}`
  1186  
  1187  	testJSONMarshal(t, r, want)
  1188  }
  1189  
  1190  func TestRepositoryContentFileOptions_Marshal(t *testing.T) {
  1191  	t.Parallel()
  1192  	testJSONMarshal(t, &RepositoryContentFileOptions{}, "{}")
  1193  
  1194  	r := &RepositoryContentFileOptions{
  1195  		Message: Ptr("type"),
  1196  		Content: []byte{1},
  1197  		SHA:     Ptr("type"),
  1198  		Branch:  Ptr("type"),
  1199  		Author: &CommitAuthor{
  1200  			Date:  &Timestamp{referenceTime},
  1201  			Name:  Ptr("name"),
  1202  			Email: Ptr("email"),
  1203  			Login: Ptr("login"),
  1204  		},
  1205  		Committer: &CommitAuthor{
  1206  			Date:  &Timestamp{referenceTime},
  1207  			Name:  Ptr("name"),
  1208  			Email: Ptr("email"),
  1209  			Login: Ptr("login"),
  1210  		},
  1211  	}
  1212  
  1213  	want := `{
  1214  		"message": "type",
  1215  		"content": "AQ==",
  1216  		"sha": "type",
  1217  		"branch": "type",
  1218  		"author": {
  1219  			"date": ` + referenceTimeStr + `,
  1220  			"name": "name",
  1221  			"email": "email",
  1222  			"username": "login"
  1223  		},
  1224  		"committer": {
  1225  			"date": ` + referenceTimeStr + `,
  1226  			"name": "name",
  1227  			"email": "email",
  1228  			"username": "login"
  1229  		}
  1230  	}`
  1231  
  1232  	testJSONMarshal(t, r, want)
  1233  }