Skip to content

Commit a2d1b67

Browse files
authored
Add Download handler test for redirects and fix imports (#15)
1 parent d9258e6 commit a2d1b67

File tree

6 files changed

+138
-6
lines changed

6 files changed

+138
-6
lines changed

.github/workflows/go.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,8 @@ jobs:
2222
2323
- name: Build
2424
run: |
25-
go build ./...
25+
go build ./...
26+
27+
- name: Test
28+
run: |
29+
go test ./...

go.mod

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ go 1.20
44

55
require (
66
github.com/julienschmidt/httprouter v1.3.0
7-
github.com/suyashkumar/bin v1.3.1
87
golang.org/x/crypto v0.6.0
98
)
109

handlers/download.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"strings"
1818

1919
"github.com/julienschmidt/httprouter"
20-
"github.com/suyashkumar/bin/releases"
20+
"github.com/suyashkumar/getbin/releases"
2121
)
2222

2323
// OS is an enum representing an operating system variant

handlers/download_test.go

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package handlers
2+
3+
import (
4+
"errors"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
9+
"github.com/julienschmidt/httprouter"
10+
"github.com/suyashkumar/getbin/releases"
11+
)
12+
13+
var errStopRedirect = errors.New("an error to stop following redirects")
14+
var defaultGithubAPIResponse = []byte(`[{
15+
"assets": [
16+
{"browser_download_url": "http://localhost/some-file-darwin-x86.tar.gz", "content_type": "application/x-gzip"},
17+
{"browser_download_url": "http://localhost/some-file-windows-x86.tar.gz", "content_type": "application/x-gzip"},
18+
{"browser_download_url": "http://localhost/some-file-linux-x86.tar.gz", "content_type": "application/x-gzip"}
19+
]
20+
}]`)
21+
22+
func TestDownload_Redirect(t *testing.T) {
23+
cases := []struct {
24+
name string
25+
requestPath string
26+
userAgent string
27+
githubAPIResponse []byte
28+
wantRedirect string
29+
}{
30+
{
31+
name: "darwin option",
32+
requestPath: "/username/repo?os=darwin",
33+
githubAPIResponse: defaultGithubAPIResponse,
34+
wantRedirect: "http://localhost/some-file-darwin-x86.tar.gz",
35+
},
36+
{
37+
name: "darwin user-agent",
38+
requestPath: "/username/repo",
39+
userAgent: "darwin user agent",
40+
githubAPIResponse: defaultGithubAPIResponse,
41+
wantRedirect: "http://localhost/some-file-darwin-x86.tar.gz",
42+
},
43+
{
44+
name: "linux option",
45+
requestPath: "/username/repo?os=linux",
46+
githubAPIResponse: defaultGithubAPIResponse,
47+
wantRedirect: "http://localhost/some-file-linux-x86.tar.gz",
48+
},
49+
{
50+
name: "linux user-agent",
51+
requestPath: "/username/repo",
52+
userAgent: "linux user agent",
53+
githubAPIResponse: defaultGithubAPIResponse,
54+
wantRedirect: "http://localhost/some-file-linux-x86.tar.gz",
55+
},
56+
{
57+
name: "windows option",
58+
requestPath: "/username/repo?os=windows",
59+
githubAPIResponse: defaultGithubAPIResponse,
60+
wantRedirect: "http://localhost/some-file-windows-x86.tar.gz",
61+
},
62+
{
63+
name: "windows user-agent",
64+
requestPath: "/username/repo",
65+
userAgent: "windows user agent",
66+
githubAPIResponse: defaultGithubAPIResponse,
67+
wantRedirect: "http://localhost/some-file-windows-x86.tar.gz",
68+
},
69+
}
70+
71+
for _, tc := range cases {
72+
tc := tc
73+
t.Run(tc.name, func(t *testing.T) {
74+
wantRequestURL := "/repos/username/repo/releases"
75+
76+
// Setup fake GitHub server.
77+
githubServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
78+
if req.URL.String() != wantRequestURL {
79+
t.Errorf("unexpected request URL. got: %v, want: %v", req.URL.String(), wantRequestURL)
80+
w.WriteHeader(http.StatusBadRequest)
81+
return
82+
}
83+
w.Write(tc.githubAPIResponse)
84+
}))
85+
defer githubServer.Close()
86+
tempSetGithubAPIBase(t, githubServer.URL)
87+
88+
// Setup test getbin server to wrap the Download handler.
89+
router := httprouter.New()
90+
router.GET("/:username/:repo", Download)
91+
server := httptest.NewServer(router)
92+
defer server.Close()
93+
94+
// Make test request and client to getbin.
95+
req, err := http.NewRequest(http.MethodGet, server.URL+tc.requestPath, nil)
96+
if err != nil {
97+
t.Fatalf("unable to make GET request to getbin server: %v", err)
98+
}
99+
req.Header.Set("User-Agent", tc.userAgent)
100+
101+
cl := &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error {
102+
// Need to return an error to stop the client from auto
103+
// redirecting, since we want to inspect the redirect.
104+
return errStopRedirect
105+
}}
106+
107+
res, err := cl.Do(req)
108+
if !errors.Is(err, errStopRedirect) {
109+
t.Errorf("Unexpected error when making getbin request: %v", err)
110+
}
111+
112+
if res.StatusCode != http.StatusMovedPermanently {
113+
t.Errorf("unexpected StatusCode in response. got: %v, want: %v", res.StatusCode, http.StatusMovedPermanently)
114+
}
115+
if got := res.Header.Get("Location"); got != tc.wantRedirect {
116+
t.Errorf("unexpected redirect in response. got: %v, want: %v", got, tc.wantRedirect)
117+
}
118+
})
119+
}
120+
}
121+
122+
func tempSetGithubAPIBase(t *testing.T, newAPIBase string) {
123+
origVal := releases.GithubAPIBase
124+
releases.GithubAPIBase = newAPIBase
125+
t.Cleanup(func() {
126+
releases.GithubAPIBase = origVal
127+
})
128+
}

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"net/http"
77

88
"github.com/julienschmidt/httprouter"
9-
"github.com/suyashkumar/bin/handlers"
9+
"github.com/suyashkumar/getbin/handlers"
1010
"golang.org/x/crypto/acme/autocert"
1111
)
1212

releases/releases.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import (
77
"net/http"
88
)
99

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

1314
// Content type constants
1415
const (

0 commit comments

Comments
 (0)