refactor tests using httpTest

This commit is contained in:
Acconut 2015-02-17 15:44:12 +01:00
parent 93eb701e14
commit 2b66ccfd56
9 changed files with 270 additions and 256 deletions

View File

@ -4,7 +4,6 @@ import (
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"
@ -46,31 +45,29 @@ func TestConcatPartial(t *testing.T) {
},
})
// Test successful POST request
req, _ := http.NewRequest("POST", "", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Entity-Length", "300")
req.Header.Set("Concat", "partial")
req.Host = "tus.io"
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusCreated {
t.Errorf("Expected 201 Created (got %v)", w.Code)
}
(&httpTest{
Name: "Successful POST request",
Method: "POST",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Entity-Length": "300",
"Concat": "partial",
},
Code: http.StatusCreated,
}).Run(handler, t)
// Test successful HEAD request
req, _ = http.NewRequest("HEAD", "foo", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Host = "tus.io"
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("Expected 204 No Content (got %v)", w.Code)
}
if w.HeaderMap.Get("Concat") != "partial" {
t.Errorf("Expect Concat header to be set")
}
(&httpTest{
Name: "Successful HEAD request",
Method: "HEAD",
URL: "foo",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
},
Code: http.StatusNoContent,
ResHeader: map[string]string{
"Concat": "partial",
},
}).Run(handler, t)
}
type concatFinalStore struct {
@ -161,47 +158,40 @@ func TestConcatFinal(t *testing.T) {
},
})
// Test successful POST request
req, _ := http.NewRequest("POST", "", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Concat", "final; http://tus.io/files/a /files/b/")
req.Host = "tus.io"
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusCreated {
t.Errorf("Expected 201 Created (got %v)", w.Code)
}
(&httpTest{
Name: "Successful POST request",
Method: "POST",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Concat": "final; http://tus.io/files/a /files/b/",
},
Code: http.StatusCreated,
}).Run(handler, t)
// Test successful HEAD request
req, _ = http.NewRequest("HEAD", "foo", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Host = "tus.io"
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("Expected 204 No Content (got %v)", w.Code)
}
(&httpTest{
Name: "Successful HEAD request",
Method: "HEAD",
URL: "foo",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
},
Code: http.StatusNoContent,
ResHeader: map[string]string{
"Concat": "final; http://tus.io/files/a http://tus.io/files/b",
"Entity-Length": "10",
},
}).Run(handler, t)
if w.HeaderMap.Get("Concat") != "final; http://tus.io/files/a http://tus.io/files/b" {
t.Errorf("Expect Concat header to be set")
}
(&httpTest{
Name: "Concatenating non finished upload (id: c)",
Method: "POST",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Concat": "final; http://tus.io/files/c",
},
Code: http.StatusBadRequest,
}).Run(handler, t)
if w.HeaderMap.Get("Entity-Length") != "10" {
t.Errorf("Expect Entity-Length header to be 10")
}
// Test concatenating non finished upload (id: c)
req, _ = http.NewRequest("POST", "", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Concat", "final; http://tus.io/files/c")
req.Host = "tus.io"
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusBadRequest {
t.Errorf("Expected 201 Created (got %v)", w.Code)
}
// Test exceeding max. size
handler, _ = NewHandler(Config{
MaxSize: 9,
BasePath: "files",
@ -210,14 +200,13 @@ func TestConcatFinal(t *testing.T) {
},
})
req, _ = http.NewRequest("POST", "", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Concat", "final; http://tus.io/files/a /files/b/")
req.Host = "tus.io"
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusRequestEntityTooLarge {
t.Errorf("Expected 201 Created (got %v)", w.Code)
}
(&httpTest{
Name: "Exceeding MaxSize",
Method: "POST",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Concat": "final; http://tus.io/files/a /files/b/",
},
Code: http.StatusRequestEntityTooLarge,
}).Run(handler, t)
}

View File

@ -2,49 +2,37 @@ package tusd
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestCORS(t *testing.T) {
handler, _ := NewHandler(Config{})
// Test preflight request
req, _ := http.NewRequest("OPTIONS", "", nil)
req.Header.Set("Origin", "tus.io")
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("Expected 204 No Content for OPTIONS request (got %v)", w.Code)
}
(&httpTest{
Name: "Preflight request",
Method: "OPTIONS",
ReqHeader: map[string]string{
"Origin": "tus.io",
},
Code: http.StatusNoContent,
ResHeader: map[string]string{
"Access-Control-Allow-Headers": "",
"Access-Control-Allow-Methods": "",
"Access-Control-Max-Age": "",
"Access-Control-Allow-Origin": "tus.io",
},
}).Run(handler, t)
headers := []string{
"Access-Control-Allow-Headers",
"Access-Control-Allow-Methods",
"Access-Control-Max-Age",
}
for _, header := range headers {
if _, ok := w.HeaderMap[header]; !ok {
t.Errorf("Header '%s' not contained in response", header)
}
}
origin := w.HeaderMap.Get("Access-Control-Allow-Origin")
if origin != "tus.io" {
t.Errorf("Allowed origin not 'tus.io' but '%s'", origin)
}
// Test actual request
req, _ = http.NewRequest("GET", "", nil)
req.Header.Set("Origin", "tus.io")
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
origin = w.HeaderMap.Get("Access-Control-Allow-Origin")
if origin != "tus.io" {
t.Errorf("Allowed origin not 'tus.io' but '%s'", origin)
}
if _, ok := w.HeaderMap["Access-Control-Expose-Headers"]; !ok {
t.Error("Expose-Headers not contained in response")
}
(&httpTest{
Name: "Actual request",
Method: "GET",
ReqHeader: map[string]string{
"Origin": "tus.io",
},
Code: http.StatusMethodNotAllowed,
ResHeader: map[string]string{
"Access-Control-Expose-Headers": "",
"Access-Control-Allow-Origin": "tus.io",
},
}).Run(handler, t)
}

View File

@ -16,9 +16,9 @@ type FileInfo struct {
// Indicates that this is a partial upload which will later be used to form
// a final upload by concatenation. Partial uploads should not be processed
// when they are finished since they are only incomplete chunks of files.
IsPartial bool
IsPartial bool
// Indicates that this is a final upload
IsFinal bool
IsFinal bool
// If the upload is a final one (see IsFinal) this will be a non-empty
// ordered slice containing the ids of the uploads of which the final upload
// will consist after concatenation.

View File

@ -3,7 +3,6 @@ package tusd
import (
"io"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
@ -33,19 +32,14 @@ func TestGet(t *testing.T) {
DataStore: getStore{},
})
// Test successfull download
req, _ := http.NewRequest("GET", "yes", nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("Expected %v (got %v)", http.StatusOK, w.Code)
}
if string(w.Body.Bytes()) != "hello" {
t.Errorf("Expected response body to be 'hello'")
}
if w.HeaderMap.Get("Content-Length") != "5" {
t.Errorf("Expected Content-Length to be 5")
}
(&httpTest{
Name: "Successful download",
Method: "GET",
URL: "yes",
Code: http.StatusOK,
ResBody: "hello",
ResHeader: map[string]string{
"Content-Length": "5",
},
}).Run(handler, t)
}

View File

@ -2,6 +2,9 @@ package tusd
import (
"io"
"net/http"
"net/http/httptest"
"testing"
)
type zeroStore struct{}
@ -20,3 +23,52 @@ func (store zeroStore) GetInfo(id string) (FileInfo, error) {
func (store zeroStore) GetReader(id string) (io.Reader, error) {
return nil, ErrNotImplemented
}
type httpTest struct {
Name string
Method string
URL string
ReqBody io.Reader
ReqHeader map[string]string
Code int
ResBody string
ResHeader map[string]string
}
func (test *httpTest) Run(handler http.Handler, t *testing.T) {
t.Log(test.Name)
req, _ := http.NewRequest(test.Method, test.URL, test.ReqBody)
// Add headers
for key, value := range test.ReqHeader {
req.Header.Set(key, value)
}
req.Host = "tus.io"
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != test.Code {
t.Errorf("Expected %v as status code (got %v)", test.Code, w.Code)
}
for key, value := range test.ResHeader {
header := w.HeaderMap.Get(key)
if value == "" && header == "" {
t.Errorf("Expected '%s' in response", key)
}
if value != "" && value != header {
t.Errorf("Expected '%s' as '%s' (got '%s')", value, key, header)
}
}
if test.ResBody != "" && string(w.Body.Bytes()) != test.ResBody {
t.Errorf("Expected '%s' as body (got '%s'", test.ResBody, string(w.Body.Bytes()))
}
}

View File

@ -2,7 +2,6 @@ package tusd
import (
"net/http"
"net/http/httptest"
"os"
"testing"
)
@ -28,31 +27,27 @@ func TestHead(t *testing.T) {
DataStore: headStore{},
})
// Test successful request
req, _ := http.NewRequest("HEAD", "yes", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("Expected %v (got %v)", http.StatusNoContent, w.Code)
}
(&httpTest{
Name: "Successful request",
Method: "HEAD",
URL: "yes",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
},
Code: http.StatusNoContent,
ResHeader: map[string]string{
"Offset": "11",
"Entity-Length": "44",
},
}).Run(handler, t)
headers := map[string]string{
"Offset": "11",
"Entity-Length": "44",
}
for header, value := range headers {
if v := w.HeaderMap.Get(header); value != v {
t.Errorf("Unexpected header value '%s': %v", header, v)
}
}
// Test non-existing file
req, _ = http.NewRequest("HEAD", "no", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNotFound {
t.Errorf("Expected %v (got %v)", http.StatusNotFound, w.Code)
}
(&httpTest{
Name: "Non-existing file",
Method: "HEAD",
URL: "no",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
},
Code: http.StatusNotFound,
}).Run(handler, t)
}

View File

@ -2,7 +2,6 @@ package tusd
import (
"net/http"
"net/http/httptest"
"testing"
)
@ -11,32 +10,24 @@ func TestOptions(t *testing.T) {
MaxSize: 400,
})
// Test successful OPTIONS request
req, _ := http.NewRequest("OPTIONS", "", nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("Expected 204 No Content for OPTIONS request (got %v)", w.Code)
}
(&httpTest{
Name: "Successful request",
Method: "OPTIONS",
Code: http.StatusNoContent,
ResHeader: map[string]string{
"TUS-Extension": "file-creation,metadata,concatenation",
"TUS-Version": "1.0.0",
"TUS-Resumable": "1.0.0",
"TUS-Max-Size": "400",
},
}).Run(handler, t)
headers := map[string]string{
"TUS-Extension": "file-creation,metadata,concatenation",
"TUS-Version": "1.0.0",
"TUS-Resumable": "1.0.0",
"TUS-Max-Size": "400",
}
for header, value := range headers {
if v := w.HeaderMap.Get(header); value != v {
t.Errorf("Header '%s' not contained in response", header)
}
}
// Invalid or unsupported version
req, _ = http.NewRequest("POST", "", nil)
req.Header.Set("TUS-Resumable", "foo")
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusPreconditionFailed {
t.Errorf("Expected 412 Precondition Failed (got %v)", w.Code)
}
(&httpTest{
Name: "Invalid or unsupported version",
Method: "POST",
ReqHeader: map[string]string{
"TUS-Resumable": "foo",
},
Code: http.StatusPreconditionFailed,
}).Run(handler, t)
}

View File

@ -4,7 +4,6 @@ import (
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
@ -57,45 +56,51 @@ func TestPatch(t *testing.T) {
},
})
// Test successful request
req, _ := http.NewRequest("PATCH", "yes", strings.NewReader("hello"))
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Offset", "5")
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("Expected %v (got %v)", http.StatusNoContent, w.Code)
}
(&httpTest{
Name: "Successful request",
Method: "PATCH",
URL: "yes",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Offset": "5",
},
ReqBody: strings.NewReader("hello"),
Code: http.StatusNoContent,
}).Run(handler, t)
// Test non-existing file
req, _ = http.NewRequest("PATCH", "no", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Offset", "0")
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNotFound {
t.Errorf("Expected %v (got %v)", http.StatusNotFound, w.Code)
}
(&httpTest{
Name: "Non-existing file",
Method: "PATCH",
URL: "no",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Offset": "5",
},
Code: http.StatusNotFound,
}).Run(handler, t)
// Test wrong offset
req, _ = http.NewRequest("PATCH", "yes", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Offset", "4")
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusConflict {
t.Errorf("Expected %v (got %v)", http.StatusConflict, w.Code)
}
(&httpTest{
Name: "Wrong offset",
Method: "PATCH",
URL: "yes",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Offset": "4",
},
Code: http.StatusConflict,
}).Run(handler, t)
// Test exceeding file size
req, _ = http.NewRequest("PATCH", "yes", strings.NewReader("hellothisismorethan15bytes"))
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Offset", "5")
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusRequestEntityTooLarge {
t.Errorf("Expected %v (got %v)", http.StatusRequestEntityTooLarge, w.Code)
}
(&httpTest{
Name: "Exceeding file size",
Method: "PATCH",
URL: "yes",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Offset": "5",
},
ReqBody: strings.NewReader("hellothisismorethan15bytes"),
Code: http.StatusRequestEntityTooLarge,
}).Run(handler, t)
}
type overflowPatchStore struct {
@ -180,14 +185,16 @@ func TestPatchOverflow(t *testing.T) {
body.Close()
}()
// Test too big body exceeding file size
req, _ := http.NewRequest("PATCH", "yes", body)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Offset", "5")
req.Header.Set("Content-Length", "3")
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("Expected %v (got %v)", http.StatusNoContent, w.Code)
}
(&httpTest{
Name: "Too big body exceeding file size",
Method: "PATCH",
URL: "yes",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Offset": "5",
"Content-Length": "3",
},
ReqBody: body,
Code: http.StatusNoContent,
}).Run(handler, t)
}

View File

@ -2,7 +2,6 @@ package tusd
import (
"net/http"
"net/http/httptest"
"testing"
)
@ -41,29 +40,28 @@ func TestPost(t *testing.T) {
},
})
// Test successful request
req, _ := http.NewRequest("POST", "", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Entity-Length", "300")
req.Header.Set("Metadata", "foo aGVsbG8=, bar d29ybGQ=")
req.Host = "tus.io"
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusCreated {
t.Errorf("Expected 201 Created for OPTIONS request (got %v)", w.Code)
}
(&httpTest{
Name: "Successful request",
Method: "POST",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Entity-Length": "300",
"Metadata": "foo aGVsbG8=, bar d29ybGQ=",
},
Code: http.StatusCreated,
ResHeader: map[string]string{
"Location": "http://tus.io/files/foo",
},
}).Run(handler, t)
if location := w.HeaderMap.Get("Location"); location != "http://tus.io/files/foo" {
t.Errorf("Unexpected location header (got '%v')", location)
}
// Test exceeding MaxSize
req, _ = http.NewRequest("POST", "", nil)
req.Header.Set("TUS-Resumable", "1.0.0")
req.Header.Set("Entity-Length", "500")
w = httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusRequestEntityTooLarge {
t.Errorf("Expected %v for OPTIONS request (got %v)", http.StatusRequestEntityTooLarge, w.Code)
}
(&httpTest{
Name: "Exceeding MaxSize",
Method: "POST",
ReqHeader: map[string]string{
"TUS-Resumable": "1.0.0",
"Entity-Length": "500",
"Metadata": "foo aGVsbG8=, bar d29ybGQ=",
},
Code: http.StatusRequestEntityTooLarge,
}).Run(handler, t)
}