2015-02-17 13:19:56 +00:00
|
|
|
package tusd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
type concatPartialStore struct {
|
|
|
|
t *testing.T
|
|
|
|
zeroStore
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s concatPartialStore) NewUpload(info FileInfo) (string, error) {
|
|
|
|
if !info.IsPartial {
|
|
|
|
s.t.Error("expected upload to be partial")
|
|
|
|
}
|
|
|
|
|
|
|
|
if info.IsFinal {
|
|
|
|
s.t.Error("expected upload to not be final")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(info.PartialUploads) != 0 {
|
|
|
|
s.t.Error("expected no partial uploads")
|
|
|
|
}
|
|
|
|
|
|
|
|
return "foo", nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s concatPartialStore) GetInfo(id string) (FileInfo, error) {
|
|
|
|
return FileInfo{
|
|
|
|
IsPartial: true,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestConcatPartial(t *testing.T) {
|
|
|
|
handler, _ := NewHandler(Config{
|
|
|
|
MaxSize: 400,
|
|
|
|
BasePath: "files",
|
|
|
|
DataStore: concatPartialStore{
|
|
|
|
t: t,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2015-02-17 14:44:12 +00:00
|
|
|
(&httpTest{
|
|
|
|
Name: "Successful POST request",
|
|
|
|
Method: "POST",
|
|
|
|
ReqHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Tus-Resumable": "1.0.0",
|
|
|
|
"Upload-Length": "300",
|
|
|
|
"Upload-Concat": "partial",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
Code: http.StatusCreated,
|
|
|
|
}).Run(handler, t)
|
|
|
|
|
|
|
|
(&httpTest{
|
|
|
|
Name: "Successful HEAD request",
|
|
|
|
Method: "HEAD",
|
|
|
|
URL: "foo",
|
|
|
|
ReqHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Tus-Resumable": "1.0.0",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
Code: http.StatusNoContent,
|
|
|
|
ResHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Upload-Concat": "partial",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
}).Run(handler, t)
|
2015-02-17 13:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type concatFinalStore struct {
|
|
|
|
t *testing.T
|
|
|
|
zeroStore
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s concatFinalStore) NewUpload(info FileInfo) (string, error) {
|
|
|
|
if info.IsPartial {
|
|
|
|
s.t.Error("expected upload to not be partial")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !info.IsFinal {
|
|
|
|
s.t.Error("expected upload to be final")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(info.PartialUploads, []string{"a", "b"}) {
|
|
|
|
s.t.Error("unexpected partial uploads")
|
|
|
|
}
|
|
|
|
|
|
|
|
return "foo", nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s concatFinalStore) GetInfo(id string) (FileInfo, error) {
|
|
|
|
if id == "a" || id == "b" {
|
|
|
|
return FileInfo{
|
|
|
|
IsPartial: true,
|
|
|
|
Size: 5,
|
|
|
|
Offset: 5,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if id == "c" {
|
|
|
|
return FileInfo{
|
|
|
|
IsPartial: true,
|
|
|
|
Size: 5,
|
|
|
|
Offset: 3,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if id == "foo" {
|
|
|
|
return FileInfo{
|
|
|
|
IsFinal: true,
|
|
|
|
PartialUploads: []string{"a", "b"},
|
|
|
|
Size: 10,
|
|
|
|
Offset: 10,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return FileInfo{}, ErrNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s concatFinalStore) GetReader(id string) (io.Reader, error) {
|
|
|
|
if id == "a" {
|
|
|
|
return strings.NewReader("hello"), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if id == "b" {
|
|
|
|
return strings.NewReader("world"), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, ErrNotFound
|
|
|
|
}
|
|
|
|
|
2015-03-23 18:02:12 +00:00
|
|
|
func (s concatFinalStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) {
|
2015-02-17 13:19:56 +00:00
|
|
|
if id != "foo" {
|
|
|
|
s.t.Error("unexpected file id")
|
|
|
|
}
|
|
|
|
|
|
|
|
if offset != 0 {
|
|
|
|
s.t.Error("expected offset to be 0")
|
|
|
|
}
|
|
|
|
|
|
|
|
b, _ := ioutil.ReadAll(src)
|
|
|
|
if string(b) != "helloworld" {
|
|
|
|
s.t.Error("unexpected content")
|
|
|
|
}
|
|
|
|
|
2015-03-23 18:02:12 +00:00
|
|
|
return 10, nil
|
2015-02-17 13:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestConcatFinal(t *testing.T) {
|
|
|
|
handler, _ := NewHandler(Config{
|
|
|
|
MaxSize: 400,
|
|
|
|
BasePath: "files",
|
|
|
|
DataStore: concatFinalStore{
|
|
|
|
t: t,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2015-02-17 14:44:12 +00:00
|
|
|
(&httpTest{
|
|
|
|
Name: "Successful POST request",
|
|
|
|
Method: "POST",
|
|
|
|
ReqHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Tus-Resumable": "1.0.0",
|
|
|
|
"Upload-Concat": "final; http://tus.io/files/a /files/b/",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
Code: http.StatusCreated,
|
|
|
|
}).Run(handler, t)
|
|
|
|
|
|
|
|
(&httpTest{
|
|
|
|
Name: "Successful HEAD request",
|
|
|
|
Method: "HEAD",
|
|
|
|
URL: "foo",
|
|
|
|
ReqHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Tus-Resumable": "1.0.0",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
Code: http.StatusNoContent,
|
|
|
|
ResHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Upload-Concat": "final; http://tus.io/files/a http://tus.io/files/b",
|
|
|
|
"Upload-Length": "10",
|
2015-03-31 21:51:28 +00:00
|
|
|
"Upload-Offset": "10",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
}).Run(handler, t)
|
|
|
|
|
|
|
|
(&httpTest{
|
|
|
|
Name: "Concatenating non finished upload (id: c)",
|
|
|
|
Method: "POST",
|
|
|
|
ReqHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Tus-Resumable": "1.0.0",
|
|
|
|
"Upload-Concat": "final; http://tus.io/files/c",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
Code: http.StatusBadRequest,
|
|
|
|
}).Run(handler, t)
|
2015-02-17 13:19:56 +00:00
|
|
|
|
|
|
|
handler, _ = NewHandler(Config{
|
|
|
|
MaxSize: 9,
|
|
|
|
BasePath: "files",
|
|
|
|
DataStore: concatFinalStore{
|
|
|
|
t: t,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2015-02-17 14:44:12 +00:00
|
|
|
(&httpTest{
|
|
|
|
Name: "Exceeding MaxSize",
|
|
|
|
Method: "POST",
|
|
|
|
ReqHeader: map[string]string{
|
2015-03-23 17:15:05 +00:00
|
|
|
"Tus-Resumable": "1.0.0",
|
|
|
|
"Upload-Concat": "final; http://tus.io/files/a /files/b/",
|
2015-02-17 14:44:12 +00:00
|
|
|
},
|
|
|
|
Code: http.StatusRequestEntityTooLarge,
|
|
|
|
}).Run(handler, t)
|
2015-02-17 13:19:56 +00:00
|
|
|
}
|