mirror of
https://github.com/willnorris/imageproxy.git
synced 2024-12-30 22:34:18 -05:00
add lots more tests
This commit is contained in:
parent
dd1df4631b
commit
76faab6363
3 changed files with 220 additions and 13 deletions
27
cache_test.go
Normal file
27
cache_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2014 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package imageproxy
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNopCache(t *testing.T) {
|
||||
data, ok := NopCache.Get("foo")
|
||||
if data != nil {
|
||||
t.Errorf("NopCache.Get returned non-nil data")
|
||||
}
|
||||
if ok != false {
|
||||
t.Errorf("NopCache.Get returned ok = true, should always be false.")
|
||||
}
|
||||
}
|
|
@ -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
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package imageproxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"image/gif"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
|
@ -32,6 +37,52 @@ func newImage(w, h int, pixels ...color.NRGBA) image.Image {
|
|||
return m
|
||||
}
|
||||
|
||||
func TestTransform(t *testing.T) {
|
||||
src := newImage(2, 2, red, green, blue, yellow)
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
png.Encode(buf, src)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
encode func(io.Writer, image.Image)
|
||||
exactOutput bool // whether input and output should match exactly
|
||||
}{
|
||||
{"gif", func(w io.Writer, m image.Image) { gif.Encode(w, m, nil) }, true},
|
||||
{"jpeg", func(w io.Writer, m image.Image) { jpeg.Encode(w, m, nil) }, false},
|
||||
{"png", func(w io.Writer, m image.Image) { png.Encode(w, m) }, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
buf := new(bytes.Buffer)
|
||||
tt.encode(buf, src)
|
||||
in := buf.Bytes()
|
||||
|
||||
out, err := Transform(in, emptyOptions)
|
||||
if err != nil {
|
||||
t.Errorf("Transform with encoder %s returned unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(in, out) {
|
||||
t.Errorf("Transform with with encoder %s with empty options returned modified result")
|
||||
}
|
||||
|
||||
out, err = Transform(in, Options{Width: -1, Height: -1})
|
||||
if err != nil {
|
||||
t.Errorf("Transform with encoder %s returned unexpected error: %v", tt.name, err)
|
||||
}
|
||||
if len(out) == 0 {
|
||||
t.Errorf("Transform with encoder %s returned empty bytes", tt.name)
|
||||
}
|
||||
if tt.exactOutput && !reflect.DeepEqual(in, out) {
|
||||
t.Errorf("Transform with encoder %s with noop Options returned modified result", tt.name)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := Transform([]byte{}, Options{Width: 1}); err == nil {
|
||||
t.Errorf("Transform with invalid image input did not return expected err")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransformImage(t *testing.T) {
|
||||
// ref is a 2x2 reference image containing four colors
|
||||
ref := newImage(2, 2, red, green, blue, yellow)
|
||||
|
|
Loading…
Reference in a new issue