...

Source file src/github.com/google/go-github/v45/github/repos_contents_test.go

Documentation: github.com/google/go-github/v45/github

     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/ioutil"
    13  	"net/http"
    14  	"net/url"
    15  	"testing"
    16  
    17  	"github.com/google/go-cmp/cmp"
    18  	"golang.org/x/crypto/openpgp"
    19  )
    20  
    21  func TestRepositoryContent_GetContent(t *testing.T) {
    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: String(""),
    29  			content:  String("hello"),
    30  			want:     "hello",
    31  			wantErr:  false,
    32  		},
    33  		{
    34  			encoding: nil,
    35  			content:  String("hello"),
    36  			want:     "hello",
    37  			wantErr:  false,
    38  		},
    39  		{
    40  			encoding: nil,
    41  			content:  nil,
    42  			want:     "",
    43  			wantErr:  false,
    44  		},
    45  		{
    46  			encoding: String("base64"),
    47  			content:  String("aGVsbG8="),
    48  			want:     "hello",
    49  			wantErr:  false,
    50  		},
    51  		{
    52  			encoding: String("bad"),
    53  			content:  String("aGVsbG8="),
    54  			want:     "",
    55  			wantErr:  true,
    56  		},
    57  	}
    58  
    59  	for _, tt := range tests {
    60  		r := RepositoryContent{Encoding: tt.encoding, Content: tt.content}
    61  		got, err := r.GetContent()
    62  		if err != nil && !tt.wantErr {
    63  			t.Errorf("RepositoryContent(%s, %s) returned unexpected error: %v",
    64  				stringOrNil(tt.encoding), stringOrNil(tt.content), err)
    65  		}
    66  		if err == nil && tt.wantErr {
    67  			t.Errorf("RepositoryContent(%s, %s) did not return unexpected error",
    68  				stringOrNil(tt.encoding), stringOrNil(tt.content))
    69  		}
    70  		if want := tt.want; got != want {
    71  			t.Errorf("RepositoryContent.GetContent returned %+v, want %+v", got, want)
    72  		}
    73  	}
    74  }
    75  
    76  // stringOrNil converts a potentially null string pointer to string.
    77  // For non-nil input pointer, the returned string is enclosed in double-quotes.
    78  func stringOrNil(s *string) string {
    79  	if s == nil {
    80  		return "<nil>"
    81  	}
    82  	return fmt.Sprintf("%q", *s)
    83  }
    84  
    85  func TestRepositoriesService_GetReadme(t *testing.T) {
    86  	client, mux, _, teardown := setup()
    87  	defer teardown()
    88  	mux.HandleFunc("/repos/o/r/readme", func(w http.ResponseWriter, r *http.Request) {
    89  		testMethod(t, r, "GET")
    90  		fmt.Fprint(w, `{
    91  		  "type": "file",
    92  		  "encoding": "base64",
    93  		  "size": 5362,
    94  		  "name": "README.md",
    95  		  "path": "README.md"
    96  		}`)
    97  	})
    98  	ctx := context.Background()
    99  	readme, _, err := client.Repositories.GetReadme(ctx, "o", "r", &RepositoryContentGetOptions{})
   100  	if err != nil {
   101  		t.Errorf("Repositories.GetReadme returned error: %v", err)
   102  	}
   103  	want := &RepositoryContent{Type: String("file"), Name: String("README.md"), Size: Int(5362), Encoding: String("base64"), Path: String("README.md")}
   104  	if !cmp.Equal(readme, want) {
   105  		t.Errorf("Repositories.GetReadme returned %+v, want %+v", readme, want)
   106  	}
   107  
   108  	const methodName = "GetReadme"
   109  	testBadOptions(t, methodName, func() (err error) {
   110  		_, _, err = client.Repositories.GetReadme(ctx, "\n", "\n", &RepositoryContentGetOptions{})
   111  		return err
   112  	})
   113  
   114  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   115  		got, resp, err := client.Repositories.GetReadme(ctx, "o", "r", &RepositoryContentGetOptions{})
   116  		if got != nil {
   117  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   118  		}
   119  		return resp, err
   120  	})
   121  }
   122  
   123  func TestRepositoriesService_DownloadContents_Success(t *testing.T) {
   124  	client, mux, serverURL, teardown := setup()
   125  	defer teardown()
   126  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   127  		testMethod(t, r, "GET")
   128  		fmt.Fprint(w, `[{
   129  		  "type": "file",
   130  		  "name": "f",
   131  		  "download_url": "`+serverURL+baseURLPath+`/download/f"
   132  		}]`)
   133  	})
   134  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   135  		testMethod(t, r, "GET")
   136  		fmt.Fprint(w, "foo")
   137  	})
   138  
   139  	ctx := context.Background()
   140  	r, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   141  	if err != nil {
   142  		t.Errorf("Repositories.DownloadContents returned error: %v", err)
   143  	}
   144  
   145  	if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
   146  		t.Errorf("Repositories.DownloadContents returned status code %v, want %v", got, want)
   147  	}
   148  
   149  	bytes, err := ioutil.ReadAll(r)
   150  	if err != nil {
   151  		t.Errorf("Error reading response body: %v", err)
   152  	}
   153  	r.Close()
   154  
   155  	if got, want := string(bytes), "foo"; got != want {
   156  		t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want)
   157  	}
   158  
   159  	const methodName = "DownloadContents"
   160  	testBadOptions(t, methodName, func() (err error) {
   161  		_, _, err = client.Repositories.DownloadContents(ctx, "\n", "\n", "\n", nil)
   162  		return err
   163  	})
   164  
   165  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   166  		got, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   167  		if got != nil {
   168  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   169  		}
   170  		return resp, err
   171  	})
   172  }
   173  
   174  func TestRepositoriesService_DownloadContents_FailedResponse(t *testing.T) {
   175  	client, mux, serverURL, teardown := setup()
   176  	defer teardown()
   177  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   178  		testMethod(t, r, "GET")
   179  		fmt.Fprint(w, `[{
   180  			"type": "file",
   181  			"name": "f",
   182  			"download_url": "`+serverURL+baseURLPath+`/download/f"
   183  		  }]`)
   184  	})
   185  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   186  		testMethod(t, r, "GET")
   187  		w.WriteHeader(http.StatusInternalServerError)
   188  		fmt.Fprint(w, "foo error")
   189  	})
   190  
   191  	ctx := context.Background()
   192  	r, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   193  	if err != nil {
   194  		t.Errorf("Repositories.DownloadContents returned error: %v", err)
   195  	}
   196  
   197  	if got, want := resp.Response.StatusCode, http.StatusInternalServerError; got != want {
   198  		t.Errorf("Repositories.DownloadContents returned status code %v, want %v", got, want)
   199  	}
   200  
   201  	bytes, err := ioutil.ReadAll(r)
   202  	if err != nil {
   203  		t.Errorf("Error reading response body: %v", err)
   204  	}
   205  	r.Close()
   206  
   207  	if got, want := string(bytes), "foo error"; got != want {
   208  		t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want)
   209  	}
   210  }
   211  
   212  func TestRepositoriesService_DownloadContents_NoDownloadURL(t *testing.T) {
   213  	client, mux, _, teardown := setup()
   214  	defer teardown()
   215  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   216  		testMethod(t, r, "GET")
   217  		fmt.Fprint(w, `[{
   218  		  "type": "file",
   219  		  "name": "f",
   220  		}]`)
   221  	})
   222  
   223  	ctx := context.Background()
   224  	_, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   225  	if err == nil {
   226  		t.Errorf("Repositories.DownloadContents did not return expected error")
   227  	}
   228  
   229  	if resp == nil {
   230  		t.Errorf("Repositories.DownloadContents did not return expected response")
   231  	}
   232  }
   233  
   234  func TestRepositoriesService_DownloadContents_NoFile(t *testing.T) {
   235  	client, mux, _, teardown := setup()
   236  	defer teardown()
   237  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   238  		testMethod(t, r, "GET")
   239  		fmt.Fprint(w, `[]`)
   240  	})
   241  
   242  	ctx := context.Background()
   243  	_, resp, err := client.Repositories.DownloadContents(ctx, "o", "r", "d/f", nil)
   244  	if err == nil {
   245  		t.Errorf("Repositories.DownloadContents did not return expected error")
   246  	}
   247  
   248  	if resp == nil {
   249  		t.Errorf("Repositories.DownloadContents did not return expected response")
   250  	}
   251  }
   252  
   253  func TestRepositoriesService_DownloadContentsWithMeta_Success(t *testing.T) {
   254  	client, mux, serverURL, teardown := setup()
   255  	defer teardown()
   256  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   257  		testMethod(t, r, "GET")
   258  		fmt.Fprint(w, `[{
   259  		  "type": "file",
   260  		  "name": "f",
   261  		  "download_url": "`+serverURL+baseURLPath+`/download/f"
   262  		}]`)
   263  	})
   264  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   265  		testMethod(t, r, "GET")
   266  		fmt.Fprint(w, "foo")
   267  	})
   268  
   269  	ctx := context.Background()
   270  	r, c, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   271  	if err != nil {
   272  		t.Errorf("Repositories.DownloadContentsWithMeta returned error: %v", err)
   273  	}
   274  
   275  	if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
   276  		t.Errorf("Repositories.DownloadContentsWithMeta returned status code %v, want %v", got, want)
   277  	}
   278  
   279  	bytes, err := ioutil.ReadAll(r)
   280  	if err != nil {
   281  		t.Errorf("Error reading response body: %v", err)
   282  	}
   283  	r.Close()
   284  
   285  	if got, want := string(bytes), "foo"; got != want {
   286  		t.Errorf("Repositories.DownloadContentsWithMeta returned %v, want %v", got, want)
   287  	}
   288  
   289  	if c != nil && c.Name != nil {
   290  		if got, want := *c.Name, "f"; got != want {
   291  			t.Errorf("Repositories.DownloadContentsWithMeta returned content name %v, want %v", got, want)
   292  		}
   293  	} else {
   294  		t.Errorf("Returned RepositoryContent is null")
   295  	}
   296  
   297  	const methodName = "DownloadContentsWithMeta"
   298  	testBadOptions(t, methodName, func() (err error) {
   299  		_, _, _, err = client.Repositories.DownloadContentsWithMeta(ctx, "\n", "\n", "\n", nil)
   300  		return err
   301  	})
   302  
   303  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   304  		got, cot, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   305  		if got != nil {
   306  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   307  		}
   308  		if cot != nil {
   309  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, cot)
   310  		}
   311  		return resp, err
   312  	})
   313  }
   314  
   315  func TestRepositoriesService_DownloadContentsWithMeta_FailedResponse(t *testing.T) {
   316  	client, mux, serverURL, teardown := setup()
   317  	defer teardown()
   318  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   319  		testMethod(t, r, "GET")
   320  		fmt.Fprint(w, `[{
   321  			"type": "file",
   322  			"name": "f",
   323  			"download_url": "`+serverURL+baseURLPath+`/download/f"
   324  		  }]`)
   325  	})
   326  	mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
   327  		testMethod(t, r, "GET")
   328  		w.WriteHeader(http.StatusInternalServerError)
   329  		fmt.Fprint(w, "foo error")
   330  	})
   331  
   332  	ctx := context.Background()
   333  	r, c, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   334  	if err != nil {
   335  		t.Errorf("Repositories.DownloadContentsWithMeta returned error: %v", err)
   336  	}
   337  
   338  	if got, want := resp.Response.StatusCode, http.StatusInternalServerError; got != want {
   339  		t.Errorf("Repositories.DownloadContentsWithMeta returned status code %v, want %v", got, want)
   340  	}
   341  
   342  	bytes, err := ioutil.ReadAll(r)
   343  	if err != nil {
   344  		t.Errorf("Error reading response body: %v", err)
   345  	}
   346  	r.Close()
   347  
   348  	if got, want := string(bytes), "foo error"; got != want {
   349  		t.Errorf("Repositories.DownloadContentsWithMeta returned %v, want %v", got, want)
   350  	}
   351  
   352  	if c != nil && c.Name != nil {
   353  		if got, want := *c.Name, "f"; got != want {
   354  			t.Errorf("Repositories.DownloadContentsWithMeta returned content name %v, want %v", got, want)
   355  		}
   356  	} else {
   357  		t.Errorf("Returned RepositoryContent is null")
   358  	}
   359  }
   360  
   361  func TestRepositoriesService_DownloadContentsWithMeta_NoDownloadURL(t *testing.T) {
   362  	client, mux, _, teardown := setup()
   363  	defer teardown()
   364  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   365  		testMethod(t, r, "GET")
   366  		fmt.Fprint(w, `[{
   367  		  "type": "file",
   368  		  "name": "f",
   369  		}]`)
   370  	})
   371  
   372  	ctx := context.Background()
   373  	_, _, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   374  	if err == nil {
   375  		t.Errorf("Repositories.DownloadContentsWithMeta did not return expected error")
   376  	}
   377  
   378  	if resp == nil {
   379  		t.Errorf("Repositories.DownloadContentsWithMeta did not return expected response")
   380  	}
   381  }
   382  
   383  func TestRepositoriesService_DownloadContentsWithMeta_NoFile(t *testing.T) {
   384  	client, mux, _, teardown := setup()
   385  	defer teardown()
   386  	mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
   387  		testMethod(t, r, "GET")
   388  		fmt.Fprint(w, `[]`)
   389  	})
   390  
   391  	ctx := context.Background()
   392  	_, _, resp, err := client.Repositories.DownloadContentsWithMeta(ctx, "o", "r", "d/f", nil)
   393  	if err == nil {
   394  		t.Errorf("Repositories.DownloadContentsWithMeta did not return expected error")
   395  	}
   396  
   397  	if resp == nil {
   398  		t.Errorf("Repositories.DownloadContentsWithMeta did not return expected response")
   399  	}
   400  }
   401  
   402  func TestRepositoriesService_GetContents_File(t *testing.T) {
   403  	client, mux, _, teardown := setup()
   404  	defer teardown()
   405  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   406  		testMethod(t, r, "GET")
   407  		fmt.Fprint(w, `{
   408  		  "type": "file",
   409  		  "encoding": "base64",
   410  		  "size": 20678,
   411  		  "name": "LICENSE",
   412  		  "path": "LICENSE"
   413  		}`)
   414  	})
   415  	ctx := context.Background()
   416  	fileContents, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "p", &RepositoryContentGetOptions{})
   417  	if err != nil {
   418  		t.Errorf("Repositories.GetContents returned error: %v", err)
   419  	}
   420  	want := &RepositoryContent{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Encoding: String("base64"), Path: String("LICENSE")}
   421  	if !cmp.Equal(fileContents, want) {
   422  		t.Errorf("Repositories.GetContents returned %+v, want %+v", fileContents, want)
   423  	}
   424  
   425  	const methodName = "GetContents"
   426  	testBadOptions(t, methodName, func() (err error) {
   427  		_, _, _, err = client.Repositories.GetContents(ctx, "\n", "\n", "\n", &RepositoryContentGetOptions{})
   428  		return err
   429  	})
   430  
   431  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   432  		got, _, resp, err := client.Repositories.GetContents(ctx, "o", "r", "p", &RepositoryContentGetOptions{})
   433  		if got != nil {
   434  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   435  		}
   436  		return resp, err
   437  	})
   438  }
   439  
   440  func TestRepositoriesService_GetContents_FilenameNeedsEscape(t *testing.T) {
   441  	client, mux, _, teardown := setup()
   442  	defer teardown()
   443  	mux.HandleFunc("/repos/o/r/contents/p#?%/中.go", func(w http.ResponseWriter, r *http.Request) {
   444  		testMethod(t, r, "GET")
   445  		fmt.Fprint(w, `{}`)
   446  	})
   447  	ctx := context.Background()
   448  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "p#?%/中.go", &RepositoryContentGetOptions{})
   449  	if err != nil {
   450  		t.Fatalf("Repositories.GetContents returned error: %v", err)
   451  	}
   452  }
   453  
   454  func TestRepositoriesService_GetContents_DirectoryWithSpaces(t *testing.T) {
   455  	client, mux, _, teardown := setup()
   456  	defer teardown()
   457  	mux.HandleFunc("/repos/o/r/contents/some directory/file.go", func(w http.ResponseWriter, r *http.Request) {
   458  		testMethod(t, r, "GET")
   459  		fmt.Fprint(w, `{}`)
   460  	})
   461  	ctx := context.Background()
   462  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "some directory/file.go", &RepositoryContentGetOptions{})
   463  	if err != nil {
   464  		t.Fatalf("Repositories.GetContents returned error: %v", err)
   465  	}
   466  }
   467  
   468  func TestRepositoriesService_GetContents_DirectoryWithPlusChars(t *testing.T) {
   469  	client, mux, _, teardown := setup()
   470  	defer teardown()
   471  	mux.HandleFunc("/repos/o/r/contents/some directory+name/file.go", func(w http.ResponseWriter, r *http.Request) {
   472  		testMethod(t, r, "GET")
   473  		fmt.Fprint(w, `{}`)
   474  	})
   475  	ctx := context.Background()
   476  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "some directory+name/file.go", &RepositoryContentGetOptions{})
   477  	if err != nil {
   478  		t.Fatalf("Repositories.GetContents returned error: %v", err)
   479  	}
   480  }
   481  
   482  func TestRepositoriesService_GetContents_Directory(t *testing.T) {
   483  	client, mux, _, teardown := setup()
   484  	defer teardown()
   485  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   486  		testMethod(t, r, "GET")
   487  		fmt.Fprint(w, `[{
   488  		  "type": "dir",
   489  		  "name": "lib",
   490  		  "path": "lib"
   491  		},
   492  		{
   493  		  "type": "file",
   494  		  "size": 20678,
   495  		  "name": "LICENSE",
   496  		  "path": "LICENSE"
   497  		}]`)
   498  	})
   499  	ctx := context.Background()
   500  	_, directoryContents, _, err := client.Repositories.GetContents(ctx, "o", "r", "p", &RepositoryContentGetOptions{})
   501  	if err != nil {
   502  		t.Errorf("Repositories.GetContents returned error: %v", err)
   503  	}
   504  	want := []*RepositoryContent{{Type: String("dir"), Name: String("lib"), Path: String("lib")},
   505  		{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Path: String("LICENSE")}}
   506  	if !cmp.Equal(directoryContents, want) {
   507  		t.Errorf("Repositories.GetContents_Directory returned %+v, want %+v", directoryContents, want)
   508  	}
   509  }
   510  
   511  func TestRepositoriesService_CreateFile(t *testing.T) {
   512  	client, mux, _, teardown := setup()
   513  	defer teardown()
   514  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   515  		testMethod(t, r, "PUT")
   516  		fmt.Fprint(w, `{
   517  			"content":{
   518  				"name":"p"
   519  			},
   520  			"commit":{
   521  				"message":"m",
   522  				"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
   523  			}
   524  		}`)
   525  	})
   526  	message := "m"
   527  	content := []byte("c")
   528  	repositoryContentsOptions := &RepositoryContentFileOptions{
   529  		Message:   &message,
   530  		Content:   content,
   531  		Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
   532  	}
   533  	ctx := context.Background()
   534  	createResponse, _, err := client.Repositories.CreateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   535  	if err != nil {
   536  		t.Errorf("Repositories.CreateFile returned error: %v", err)
   537  	}
   538  	want := &RepositoryContentResponse{
   539  		Content: &RepositoryContent{Name: String("p")},
   540  		Commit: Commit{
   541  			Message: String("m"),
   542  			SHA:     String("f5f369044773ff9c6383c087466d12adb6fa0828"),
   543  		},
   544  	}
   545  	if !cmp.Equal(createResponse, want) {
   546  		t.Errorf("Repositories.CreateFile returned %+v, want %+v", createResponse, want)
   547  	}
   548  
   549  	const methodName = "CreateFile"
   550  	testBadOptions(t, methodName, func() (err error) {
   551  		_, _, err = client.Repositories.CreateFile(ctx, "\n", "\n", "\n", repositoryContentsOptions)
   552  		return err
   553  	})
   554  
   555  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   556  		got, resp, err := client.Repositories.CreateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   557  		if got != nil {
   558  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   559  		}
   560  		return resp, err
   561  	})
   562  }
   563  
   564  func TestRepositoriesService_UpdateFile(t *testing.T) {
   565  	client, mux, _, teardown := setup()
   566  	defer teardown()
   567  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   568  		testMethod(t, r, "PUT")
   569  		fmt.Fprint(w, `{
   570  			"content":{
   571  				"name":"p"
   572  			},
   573  			"commit":{
   574  				"message":"m",
   575  				"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
   576  			}
   577  		}`)
   578  	})
   579  	message := "m"
   580  	content := []byte("c")
   581  	sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
   582  	repositoryContentsOptions := &RepositoryContentFileOptions{
   583  		Message:   &message,
   584  		Content:   content,
   585  		SHA:       &sha,
   586  		Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
   587  	}
   588  	ctx := context.Background()
   589  	updateResponse, _, err := client.Repositories.UpdateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   590  	if err != nil {
   591  		t.Errorf("Repositories.UpdateFile returned error: %v", err)
   592  	}
   593  	want := &RepositoryContentResponse{
   594  		Content: &RepositoryContent{Name: String("p")},
   595  		Commit: Commit{
   596  			Message: String("m"),
   597  			SHA:     String("f5f369044773ff9c6383c087466d12adb6fa0828"),
   598  		},
   599  	}
   600  	if !cmp.Equal(updateResponse, want) {
   601  		t.Errorf("Repositories.UpdateFile returned %+v, want %+v", updateResponse, want)
   602  	}
   603  
   604  	const methodName = "UpdateFile"
   605  	testBadOptions(t, methodName, func() (err error) {
   606  		_, _, err = client.Repositories.UpdateFile(ctx, "\n", "\n", "\n", repositoryContentsOptions)
   607  		return err
   608  	})
   609  
   610  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   611  		got, resp, err := client.Repositories.UpdateFile(ctx, "o", "r", "p", repositoryContentsOptions)
   612  		if got != nil {
   613  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   614  		}
   615  		return resp, err
   616  	})
   617  }
   618  
   619  func TestRepositoriesService_DeleteFile(t *testing.T) {
   620  	client, mux, _, teardown := setup()
   621  	defer teardown()
   622  	mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
   623  		testMethod(t, r, "DELETE")
   624  		fmt.Fprint(w, `{
   625  			"content": null,
   626  			"commit":{
   627  				"message":"m",
   628  				"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
   629  			}
   630  		}`)
   631  	})
   632  	message := "m"
   633  	sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
   634  	repositoryContentsOptions := &RepositoryContentFileOptions{
   635  		Message:   &message,
   636  		SHA:       &sha,
   637  		Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
   638  	}
   639  	ctx := context.Background()
   640  	deleteResponse, _, err := client.Repositories.DeleteFile(ctx, "o", "r", "p", repositoryContentsOptions)
   641  	if err != nil {
   642  		t.Errorf("Repositories.DeleteFile returned error: %v", err)
   643  	}
   644  	want := &RepositoryContentResponse{
   645  		Content: nil,
   646  		Commit: Commit{
   647  			Message: String("m"),
   648  			SHA:     String("f5f369044773ff9c6383c087466d12adb6fa0828"),
   649  		},
   650  	}
   651  	if !cmp.Equal(deleteResponse, want) {
   652  		t.Errorf("Repositories.DeleteFile returned %+v, want %+v", deleteResponse, want)
   653  	}
   654  
   655  	const methodName = "DeleteFile"
   656  	testBadOptions(t, methodName, func() (err error) {
   657  		_, _, err = client.Repositories.DeleteFile(ctx, "\n", "\n", "\n", repositoryContentsOptions)
   658  		return err
   659  	})
   660  
   661  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   662  		got, resp, err := client.Repositories.DeleteFile(ctx, "o", "r", "p", repositoryContentsOptions)
   663  		if got != nil {
   664  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   665  		}
   666  		return resp, err
   667  	})
   668  }
   669  
   670  func TestRepositoriesService_GetArchiveLink(t *testing.T) {
   671  	client, mux, _, teardown := setup()
   672  	defer teardown()
   673  	mux.HandleFunc("/repos/o/r/tarball/yo", func(w http.ResponseWriter, r *http.Request) {
   674  		testMethod(t, r, "GET")
   675  		http.Redirect(w, r, "http://github.com/a", http.StatusFound)
   676  	})
   677  	ctx := context.Background()
   678  	url, resp, err := client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{Ref: "yo"}, true)
   679  	if err != nil {
   680  		t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
   681  	}
   682  	if resp.StatusCode != http.StatusFound {
   683  		t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound)
   684  	}
   685  	want := "http://github.com/a"
   686  	if url.String() != want {
   687  		t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want)
   688  	}
   689  
   690  	const methodName = "GetArchiveLink"
   691  	testBadOptions(t, methodName, func() (err error) {
   692  		_, _, err = client.Repositories.GetArchiveLink(ctx, "\n", "\n", Tarball, &RepositoryContentGetOptions{}, true)
   693  		return err
   694  	})
   695  
   696  	// Add custom round tripper
   697  	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
   698  		return nil, errors.New("failed to get archive link")
   699  	})
   700  	testBadOptions(t, methodName, func() (err error) {
   701  		_, _, err = client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{}, true)
   702  		return err
   703  	})
   704  }
   705  
   706  func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_dontFollowRedirects(t *testing.T) {
   707  	client, mux, _, teardown := setup()
   708  	defer teardown()
   709  	mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
   710  		testMethod(t, r, "GET")
   711  		http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently)
   712  	})
   713  	ctx := context.Background()
   714  	_, resp, _ := client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{}, false)
   715  	if resp.StatusCode != http.StatusMovedPermanently {
   716  		t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently)
   717  	}
   718  }
   719  
   720  func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_followRedirects(t *testing.T) {
   721  	client, mux, serverURL, teardown := setup()
   722  	defer teardown()
   723  	// Mock a redirect link, which leads to an archive link
   724  	mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
   725  		testMethod(t, r, "GET")
   726  		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect")
   727  		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
   728  	})
   729  	mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
   730  		testMethod(t, r, "GET")
   731  		http.Redirect(w, r, "http://github.com/a", http.StatusFound)
   732  	})
   733  	ctx := context.Background()
   734  	url, resp, err := client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{}, true)
   735  	if err != nil {
   736  		t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
   737  	}
   738  	if resp.StatusCode != http.StatusFound {
   739  		t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound)
   740  	}
   741  	want := "http://github.com/a"
   742  	if url.String() != want {
   743  		t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want)
   744  	}
   745  }
   746  
   747  func TestRepositoriesService_GetContents_NoTrailingSlashInDirectoryApiPath(t *testing.T) {
   748  	client, mux, _, teardown := setup()
   749  	defer teardown()
   750  	mux.HandleFunc("/repos/o/r/contents/.github", func(w http.ResponseWriter, r *http.Request) {
   751  		testMethod(t, r, "GET")
   752  		query := r.URL.Query()
   753  		if query.Get("ref") != "mybranch" {
   754  			t.Errorf("Repositories.GetContents returned %+v, want %+v", query.Get("ref"), "mybranch")
   755  		}
   756  		fmt.Fprint(w, `{}`)
   757  	})
   758  	ctx := context.Background()
   759  	_, _, _, err := client.Repositories.GetContents(ctx, "o", "r", ".github/", &RepositoryContentGetOptions{
   760  		Ref: "mybranch",
   761  	})
   762  	if err != nil {
   763  		t.Fatalf("Repositories.GetContents returned error: %v", err)
   764  	}
   765  }
   766  
   767  func TestRepositoryContent_Marshal(t *testing.T) {
   768  	testJSONMarshal(t, &RepositoryContent{}, "{}")
   769  
   770  	r := &RepositoryContent{
   771  		Type:        String("type"),
   772  		Target:      String("target"),
   773  		Encoding:    String("encoding"),
   774  		Size:        Int(1),
   775  		Name:        String("name"),
   776  		Path:        String("path"),
   777  		Content:     String("content"),
   778  		SHA:         String("sha"),
   779  		URL:         String("url"),
   780  		GitURL:      String("gurl"),
   781  		HTMLURL:     String("hurl"),
   782  		DownloadURL: String("durl"),
   783  	}
   784  
   785  	want := `{
   786  		"type": "type",
   787  		"target": "target",
   788  		"encoding": "encoding",
   789  		"size": 1,
   790  		"name": "name",
   791  		"path": "path",
   792  		"content": "content",
   793  		"sha": "sha",
   794  		"url": "url",
   795  		"git_url": "gurl",
   796  		"html_url": "hurl",
   797  		"download_url": "durl"
   798  	}`
   799  
   800  	testJSONMarshal(t, r, want)
   801  }
   802  
   803  func TestRepositoryContentResponse_Marshal(t *testing.T) {
   804  	testJSONMarshal(t, &RepositoryContentResponse{}, "{}")
   805  
   806  	r := &RepositoryContentResponse{
   807  		Content: &RepositoryContent{
   808  			Type:        String("type"),
   809  			Target:      String("target"),
   810  			Encoding:    String("encoding"),
   811  			Size:        Int(1),
   812  			Name:        String("name"),
   813  			Path:        String("path"),
   814  			Content:     String("content"),
   815  			SHA:         String("sha"),
   816  			URL:         String("url"),
   817  			GitURL:      String("gurl"),
   818  			HTMLURL:     String("hurl"),
   819  			DownloadURL: String("durl"),
   820  		},
   821  		Commit: Commit{
   822  			SHA: String("s"),
   823  			Author: &CommitAuthor{
   824  				Date:  &referenceTime,
   825  				Name:  String("n"),
   826  				Email: String("e"),
   827  				Login: String("u"),
   828  			},
   829  			Committer: &CommitAuthor{
   830  				Date:  &referenceTime,
   831  				Name:  String("n"),
   832  				Email: String("e"),
   833  				Login: String("u"),
   834  			},
   835  			Message: String("m"),
   836  			Tree: &Tree{
   837  				SHA: String("s"),
   838  				Entries: []*TreeEntry{{
   839  					SHA:     String("s"),
   840  					Path:    String("p"),
   841  					Mode:    String("m"),
   842  					Type:    String("t"),
   843  					Size:    Int(1),
   844  					Content: String("c"),
   845  					URL:     String("u"),
   846  				}},
   847  				Truncated: Bool(false),
   848  			},
   849  			Parents: nil,
   850  			Stats: &CommitStats{
   851  				Additions: Int(1),
   852  				Deletions: Int(1),
   853  				Total:     Int(1),
   854  			},
   855  			HTMLURL: String("h"),
   856  			URL:     String("u"),
   857  			Verification: &SignatureVerification{
   858  				Verified:  Bool(false),
   859  				Reason:    String("r"),
   860  				Signature: String("s"),
   861  				Payload:   String("p"),
   862  			},
   863  			NodeID:       String("n"),
   864  			CommentCount: Int(1),
   865  			SigningKey:   &openpgp.Entity{},
   866  		},
   867  	}
   868  
   869  	want := `{
   870  		"content": {
   871  			"type": "type",
   872  			"target": "target",
   873  			"encoding": "encoding",
   874  			"size": 1,
   875  			"name": "name",
   876  			"path": "path",
   877  			"content": "content",
   878  			"sha": "sha",
   879  			"url": "url",
   880  			"git_url": "gurl",
   881  			"html_url": "hurl",
   882  			"download_url": "durl"
   883  		},
   884  		"commit": {
   885  			"sha": "s",
   886  			"author": {
   887  				"date": ` + referenceTimeStr + `,
   888  				"name": "n",
   889  				"email": "e",
   890  				"username": "u"
   891  			},
   892  			"committer": {
   893  				"date": ` + referenceTimeStr + `,
   894  				"name": "n",
   895  				"email": "e",
   896  				"username": "u"
   897  			},
   898  			"message": "m",
   899  			"tree": {
   900  				"sha": "s",
   901  				"tree": [
   902  					{
   903  						"sha": "s",
   904  						"path": "p",
   905  						"mode": "m",
   906  						"type": "t",
   907  						"size": 1,
   908  						"content": "c",
   909  						"url": "u"
   910  					}
   911  				],
   912  				"truncated": false
   913  			},
   914  			"stats": {
   915  				"additions": 1,
   916  				"deletions": 1,
   917  				"total": 1
   918  			},
   919  			"html_url": "h",
   920  			"url": "u",
   921  			"verification": {
   922  				"verified": false,
   923  				"reason": "r",
   924  				"signature": "s",
   925  				"payload": "p"
   926  			},
   927  			"node_id": "n",
   928  			"comment_count": 1
   929  		}
   930  	}`
   931  
   932  	testJSONMarshal(t, r, want)
   933  }
   934  
   935  func TestRepositoryContentFileOptions_Marshal(t *testing.T) {
   936  	testJSONMarshal(t, &RepositoryContentFileOptions{}, "{}")
   937  
   938  	r := &RepositoryContentFileOptions{
   939  		Message: String("type"),
   940  		Content: []byte{1},
   941  		SHA:     String("type"),
   942  		Branch:  String("type"),
   943  		Author: &CommitAuthor{
   944  			Date:  &referenceTime,
   945  			Name:  String("name"),
   946  			Email: String("email"),
   947  			Login: String("login"),
   948  		},
   949  		Committer: &CommitAuthor{
   950  			Date:  &referenceTime,
   951  			Name:  String("name"),
   952  			Email: String("email"),
   953  			Login: String("login"),
   954  		},
   955  	}
   956  
   957  	want := `{
   958  		"message": "type",
   959  		"content": "AQ==",
   960  		"sha": "type",
   961  		"branch": "type",
   962  		"author": {
   963  			"date": ` + referenceTimeStr + `,
   964  			"name": "name",
   965  			"email": "email",
   966  			"username": "login"
   967  		},
   968  		"committer": {
   969  			"date": ` + referenceTimeStr + `,
   970  			"name": "name",
   971  			"email": "email",
   972  			"username": "login"
   973  		}
   974  	}`
   975  
   976  	testJSONMarshal(t, r, want)
   977  }
   978  

View as plain text