Skip to content

Commit

Permalink
Add Download handler test for redirects and fix imports (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
suyashkumar authored Feb 19, 2023
1 parent d9258e6 commit a2d1b67
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 6 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ jobs:
- name: Build
run: |
go build ./...
go build ./...
- name: Test
run: |
go test ./...
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.20

require (
github.com/julienschmidt/httprouter v1.3.0
github.com/suyashkumar/bin v1.3.1
golang.org/x/crypto v0.6.0
)

Expand Down
2 changes: 1 addition & 1 deletion handlers/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"strings"

"github.com/julienschmidt/httprouter"
"github.com/suyashkumar/bin/releases"
"github.com/suyashkumar/getbin/releases"
)

// OS is an enum representing an operating system variant
Expand Down
128 changes: 128 additions & 0 deletions handlers/download_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package handlers

import (
"errors"
"net/http"
"net/http/httptest"
"testing"

"github.com/julienschmidt/httprouter"
"github.com/suyashkumar/getbin/releases"
)

var errStopRedirect = errors.New("an error to stop following redirects")
var defaultGithubAPIResponse = []byte(`[{
"assets": [
{"browser_download_url": "http://localhost/some-file-darwin-x86.tar.gz", "content_type": "application/x-gzip"},
{"browser_download_url": "http://localhost/some-file-windows-x86.tar.gz", "content_type": "application/x-gzip"},
{"browser_download_url": "http://localhost/some-file-linux-x86.tar.gz", "content_type": "application/x-gzip"}
]
}]`)

func TestDownload_Redirect(t *testing.T) {
cases := []struct {
name string
requestPath string
userAgent string
githubAPIResponse []byte
wantRedirect string
}{
{
name: "darwin option",
requestPath: "/username/repo?os=darwin",
githubAPIResponse: defaultGithubAPIResponse,
wantRedirect: "http://localhost/some-file-darwin-x86.tar.gz",
},
{
name: "darwin user-agent",
requestPath: "/username/repo",
userAgent: "darwin user agent",
githubAPIResponse: defaultGithubAPIResponse,
wantRedirect: "http://localhost/some-file-darwin-x86.tar.gz",
},
{
name: "linux option",
requestPath: "/username/repo?os=linux",
githubAPIResponse: defaultGithubAPIResponse,
wantRedirect: "http://localhost/some-file-linux-x86.tar.gz",
},
{
name: "linux user-agent",
requestPath: "/username/repo",
userAgent: "linux user agent",
githubAPIResponse: defaultGithubAPIResponse,
wantRedirect: "http://localhost/some-file-linux-x86.tar.gz",
},
{
name: "windows option",
requestPath: "/username/repo?os=windows",
githubAPIResponse: defaultGithubAPIResponse,
wantRedirect: "http://localhost/some-file-windows-x86.tar.gz",
},
{
name: "windows user-agent",
requestPath: "/username/repo",
userAgent: "windows user agent",
githubAPIResponse: defaultGithubAPIResponse,
wantRedirect: "http://localhost/some-file-windows-x86.tar.gz",
},
}

for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
wantRequestURL := "/repos/username/repo/releases"

// Setup fake GitHub server.
githubServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if req.URL.String() != wantRequestURL {
t.Errorf("unexpected request URL. got: %v, want: %v", req.URL.String(), wantRequestURL)
w.WriteHeader(http.StatusBadRequest)
return
}
w.Write(tc.githubAPIResponse)
}))
defer githubServer.Close()
tempSetGithubAPIBase(t, githubServer.URL)

// Setup test getbin server to wrap the Download handler.
router := httprouter.New()
router.GET("/:username/:repo", Download)
server := httptest.NewServer(router)
defer server.Close()

// Make test request and client to getbin.
req, err := http.NewRequest(http.MethodGet, server.URL+tc.requestPath, nil)
if err != nil {
t.Fatalf("unable to make GET request to getbin server: %v", err)
}
req.Header.Set("User-Agent", tc.userAgent)

cl := &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error {
// Need to return an error to stop the client from auto
// redirecting, since we want to inspect the redirect.
return errStopRedirect
}}

res, err := cl.Do(req)
if !errors.Is(err, errStopRedirect) {
t.Errorf("Unexpected error when making getbin request: %v", err)
}

if res.StatusCode != http.StatusMovedPermanently {
t.Errorf("unexpected StatusCode in response. got: %v, want: %v", res.StatusCode, http.StatusMovedPermanently)
}
if got := res.Header.Get("Location"); got != tc.wantRedirect {
t.Errorf("unexpected redirect in response. got: %v, want: %v", got, tc.wantRedirect)
}
})
}
}

func tempSetGithubAPIBase(t *testing.T, newAPIBase string) {
origVal := releases.GithubAPIBase
releases.GithubAPIBase = newAPIBase
t.Cleanup(func() {
releases.GithubAPIBase = origVal
})
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net/http"

"github.com/julienschmidt/httprouter"
"github.com/suyashkumar/bin/handlers"
"github.com/suyashkumar/getbin/handlers"
"golang.org/x/crypto/acme/autocert"
)

Expand Down
5 changes: 3 additions & 2 deletions releases/releases.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import (
"net/http"
)

// GithubAPIBase represents the base url for the GitHub API
const GithubAPIBase = "https://api.github.com"
// GithubAPIBase represents the base url for the GitHub API. This can be
// changed, primarily for test purposes.
var GithubAPIBase = "https://api.github.com"

// Content type constants
const (
Expand Down

0 comments on commit a2d1b67

Please sign in to comment.