add lots more tests

This commit is contained in:
Will Norris 2014-12-04 17:30:01 -08:00
parent dd1df4631b
commit 76faab6363
3 changed files with 220 additions and 13 deletions

View file

@ -2,34 +2,45 @@ package imageproxy
import (
"bufio"
"bytes"
"errors"
"fmt"
"image"
"image/png"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
)
func TestAllowed(t *testing.T) {
p := &Proxy{
Whitelist: []string{"a.test", "*.b.test", "*c.test"},
}
whitelist := []string{"a.test", "*.b.test", "*c.test"}
tests := []struct {
url string
allowed bool
url string
whitelist []string
allowed bool
}{
{"http://a.test/image", true},
{"http://x.a.test/image", false},
{"http://foo/image", nil, true},
{"http://foo/image", []string{}, true},
{"http://b.test/image", true},
{"http://x.b.test/image", true},
{"http://x.y.b.test/image", true},
{"http://a.test/image", whitelist, true},
{"http://x.a.test/image", whitelist, false},
{"http://c.test/image", false},
{"http://xc.test/image", false},
{"/image", false},
{"http://b.test/image", whitelist, true},
{"http://x.b.test/image", whitelist, true},
{"http://x.y.b.test/image", whitelist, true},
{"http://c.test/image", whitelist, false},
{"http://xc.test/image", whitelist, false},
{"/image", whitelist, false},
}
for _, tt := range tests {
p := NewProxy(nil, nil)
p.Whitelist = tt.whitelist
u, err := url.Parse(tt.url)
if err != nil {
t.Errorf("error parsing url %q: %v", tt.url, err)
@ -112,3 +123,121 @@ func TestCheck304(t *testing.T) {
}
}
}
// testTransport is an http.RoundTripper that returns certained canned
// responses for particular requests.
type testTransport struct{}
func (t testTransport) RoundTrip(req *http.Request) (*http.Response, error) {
var raw string
switch req.URL.Path {
case "/ok":
raw = "HTTP/1.1 200 OK\n\n"
case "/error":
return nil, errors.New("http protocol error")
case "/nocontent":
raw = "HTTP/1.1 204 No Content\n\n"
case "/etag":
raw = "HTTP/1.1 200 OK\nEtag: \"tag\"\n\n"
case "/png":
m := image.NewNRGBA(image.Rect(0, 0, 1, 1))
img := new(bytes.Buffer)
png.Encode(img, m)
raw = fmt.Sprintf("HTTP/1.1 200 OK\nContent-Length: %d\n\n%v", len(img.Bytes()), img.Bytes())
default:
raw = "HTTP/1.1 404 Not Found\n\n"
}
buf := bufio.NewReader(bytes.NewBufferString(raw))
return http.ReadResponse(buf, req)
}
func TestProxy_ServeHTTP(t *testing.T) {
p := &Proxy{
Client: &http.Client{
Transport: testTransport{},
},
Whitelist: []string{"good.test"},
}
tests := []struct {
url string // request URL
code int // expected response status code
}{
{"/favicon.ico", http.StatusOK},
{"//foo", http.StatusBadRequest}, // invalid request URL
{"/http://bad.test/", http.StatusBadRequest}, // Disallowed host
{"/http://good.test/error", http.StatusInternalServerError}, // HTTP protocol error
{"/http://good.test/nocontent", http.StatusNoContent}, // non-OK response
{"/100/http://good.test/ok", http.StatusOK},
}
for _, tt := range tests {
req, _ := http.NewRequest("GET", "http://localhost"+tt.url, nil)
resp := httptest.NewRecorder()
p.ServeHTTP(resp, req)
if got, want := resp.Code, tt.code; got != want {
t.Errorf("ServeHTTP(%q) returned status %d, want %d", req, got, want)
}
}
}
// test that 304 Not Modified responses are returned properly.
func TestProxy_ServeHTTP_is304(t *testing.T) {
p := &Proxy{
Client: &http.Client{
Transport: testTransport{},
},
}
req, _ := http.NewRequest("GET", "http://localhost/http://good.test/etag", nil)
req.Header.Add("If-None-Match", `"tag"`)
resp := httptest.NewRecorder()
p.ServeHTTP(resp, req)
if got, want := resp.Code, http.StatusNotModified; got != want {
t.Errorf("ServeHTTP(%q) returned status %d, want %d", req, got, want)
}
if got, want := resp.Header().Get("Etag"), `"tag"`; got != want {
t.Errorf("ServeHTTP(%q) returned etag header %v, want %v", req, got, want)
}
}
func TestTransformingTransport(t *testing.T) {
client := new(http.Client)
tr := &TransformingTransport{testTransport{}, client}
client.Transport = tr
tests := []struct {
url string
code int
expectError bool
}{
{"http://good.test/png#1", http.StatusOK, false},
{"http://good.test/error#1", http.StatusInternalServerError, true},
// TODO: test more than just status code... verify that image
// is actually transformed and returned properly and that
// non-image responses are returned as-is
}
for _, tt := range tests {
req, _ := http.NewRequest("GET", tt.url, nil)
resp, err := tr.RoundTrip(req)
if err != nil {
if !tt.expectError {
t.Errorf("RoundTrip(%v) returned unexpected error: %v", tt.url, err)
}
continue
} else if tt.expectError {
t.Errorf("RoundTrip(%v) did not return expected error", tt.url)
}
if got, want := resp.StatusCode, tt.code; got != want {
t.Errorf("RoundTrip(%v) returned status code %d, want %d", got, want)
}
}
}