Write some functional handler tests

Also found / fixes a few issues thanks to this!
This commit is contained in:
Felix Geisendörfer 2013-05-07 10:52:03 +02:00
parent d490f50d45
commit 6adf639d37
2 changed files with 127 additions and 4 deletions

View File

@ -93,14 +93,17 @@ func (h *Handler) createFile(w http.ResponseWriter, r *http.Request) {
finalLength, err := strconv.ParseInt(r.Header.Get("Final-Length"), 10, 64) finalLength, err := strconv.ParseInt(r.Header.Get("Final-Length"), 10, 64)
if err != nil { if err != nil {
err = errors.New("invalid Final-Length header: "+err.Error()) err = errors.New("invalid Final-Length header: " + err.Error())
h.err(err, w, http.StatusBadRequest) h.err(err, w, http.StatusBadRequest)
return return
} }
// @TODO: What happens if Final-Length is <= 0 if finalLength < 0 {
h.err(errors.New("negative Final-Length values not supported"), w, http.StatusBadRequest)
return
}
// @TODO: Provide meta data // @TODO: Define meta data extension and implement it here
// @TODO: Make max finalLength configurable, reply with error if exceeded. // @TODO: Make max finalLength configurable, reply with error if exceeded.
// This should go into the protocol as well. // This should go into the protocol as well.
if err := h.store.CreateFile(id, finalLength, nil); err != nil { if err := h.store.CreateFile(id, finalLength, nil); err != nil {
@ -108,8 +111,8 @@ func (h *Handler) createFile(w http.ResponseWriter, r *http.Request) {
return return
} }
w.WriteHeader(http.StatusCreated)
w.Header().Set("Location", h.absUrl(r, "/"+id)) w.Header().Set("Location", h.absUrl(r, "/"+id))
w.WriteHeader(http.StatusCreated)
} }
// absUrl turn a relPath (e.g. "/foo") into an absolute url (e.g. // absUrl turn a relPath (e.g. "/foo") into an absolute url (e.g.

120
src/http/handler_test.go Normal file
View File

@ -0,0 +1,120 @@
package http
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"regexp"
"testing"
)
const basePath = "/files/"
var Protocol_FileCreation_Tests = []struct {
Description string
Method string
Headers map[string]string
ExpectStatusCode int
ExpectHeaders map[string]string
MatchLocation *regexp.Regexp
}{
{
Description: "Bad method",
Method: "PUT",
ExpectStatusCode: http.StatusMethodNotAllowed,
ExpectHeaders: map[string]string{"Allow": "POST"},
},
{
Description: "Missing Final-Length header",
ExpectStatusCode: http.StatusBadRequest,
},
{
Description: "Invalid Final-Length header",
Headers: map[string]string{"Final-Length": "fuck"},
ExpectStatusCode: http.StatusBadRequest,
},
{
Description: "Negative Final-Length header",
Headers: map[string]string{"Final-Length": "-10"},
ExpectStatusCode: http.StatusBadRequest,
},
{
Description: "Valid Request",
Headers: map[string]string{"Final-Length": "1024"},
ExpectStatusCode: http.StatusCreated,
MatchLocation: regexp.MustCompile("^http://.+" + regexp.QuoteMeta(basePath) + "[a-z0-9]{32}$"),
},
}
func TestProtocol_FileCreation(t *testing.T) {
dir, err := ioutil.TempDir("", "tus_handler_test")
if err != nil {
t.Fatal(err)
}
defer os.Remove(dir)
config := HandlerConfig{
Dir: dir,
MaxSize: 1024 * 1024,
BasePath: basePath,
}
handler, err := NewHandler(config)
if err != nil {
t.Fatal(err)
}
server := httptest.NewServer(handler)
defer server.Close()
Tests:
for _, test := range Protocol_FileCreation_Tests {
t.Logf("test: %s", test.Description)
method := test.Method
if method == "" {
method = "POST"
}
req, err := http.NewRequest(method, server.URL+config.BasePath, nil)
if err != nil {
t.Fatal(err)
}
for key, val := range test.Headers {
req.Header.Set(key, val)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
if test.ExpectStatusCode != 0 && test.ExpectStatusCode != res.StatusCode {
t.Errorf("bad status: %d, expected: %d - %s", res.StatusCode, test.ExpectStatusCode, body)
continue Tests
}
for key, val := range test.ExpectHeaders {
if got := res.Header.Get(key); got != val {
t.Errorf("expected \"%s: %s\" header, but got: \"%s: %s\"", key, val, key, got)
continue Tests
}
}
if test.MatchLocation != nil {
location := res.Header.Get("Location")
if !test.MatchLocation.MatchString(location) {
t.Errorf("location \"%s\" did not match: \"%s\"", location, test.MatchLocation.String())
continue Tests
}
}
}
}