2015-12-25 21:33:27 +00:00
|
|
|
package tusd_test
|
2015-02-01 13:57:57 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
2015-02-17 14:44:12 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2015-10-06 16:27:40 +00:00
|
|
|
"os"
|
|
|
|
"strings"
|
2015-02-17 14:44:12 +00:00
|
|
|
"testing"
|
2015-12-25 21:33:27 +00:00
|
|
|
|
2016-01-20 15:40:13 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
2015-12-25 21:33:27 +00:00
|
|
|
. "github.com/tus/tusd"
|
2015-02-01 13:57:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type zeroStore struct{}
|
|
|
|
|
2015-02-16 16:53:50 +00:00
|
|
|
func (store zeroStore) NewUpload(info FileInfo) (string, error) {
|
2015-02-01 13:57:57 +00:00
|
|
|
return "", nil
|
|
|
|
}
|
2015-03-23 18:02:12 +00:00
|
|
|
func (store zeroStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) {
|
|
|
|
return 0, nil
|
2015-02-01 13:57:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (store zeroStore) GetInfo(id string) (FileInfo, error) {
|
|
|
|
return FileInfo{}, nil
|
|
|
|
}
|
|
|
|
|
2015-02-06 21:05:33 +00:00
|
|
|
func (store zeroStore) GetReader(id string) (io.Reader, error) {
|
|
|
|
return nil, ErrNotImplemented
|
|
|
|
}
|
2015-02-17 14:44:12 +00:00
|
|
|
|
|
|
|
type httpTest struct {
|
|
|
|
Name string
|
|
|
|
|
|
|
|
Method string
|
|
|
|
URL string
|
|
|
|
|
|
|
|
ReqBody io.Reader
|
|
|
|
ReqHeader map[string]string
|
|
|
|
|
|
|
|
Code int
|
|
|
|
ResBody string
|
|
|
|
ResHeader map[string]string
|
|
|
|
}
|
|
|
|
|
2015-11-26 15:25:34 +00:00
|
|
|
func (test *httpTest) Run(handler http.Handler, t *testing.T) *httptest.ResponseRecorder {
|
2016-01-20 15:40:13 +00:00
|
|
|
t.Logf("'%s' in %s", test.Name, assert.CallerInfo()[1])
|
2015-02-17 14:44:12 +00:00
|
|
|
|
|
|
|
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 {
|
2015-03-23 17:17:21 +00:00
|
|
|
t.Errorf("Expected %v %s as status code (got %v %s)", test.Code, http.StatusText(test.Code), w.Code, http.StatusText(w.Code))
|
2015-02-17 14:44:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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()))
|
|
|
|
}
|
2015-11-26 15:25:34 +00:00
|
|
|
|
|
|
|
return w
|
2015-02-17 14:44:12 +00:00
|
|
|
}
|
2015-10-06 16:27:40 +00:00
|
|
|
|
|
|
|
type methodOverrideStore struct {
|
|
|
|
zeroStore
|
|
|
|
t *testing.T
|
|
|
|
called bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s methodOverrideStore) GetInfo(id string) (FileInfo, error) {
|
|
|
|
if id != "yes" {
|
|
|
|
return FileInfo{}, os.ErrNotExist
|
|
|
|
}
|
|
|
|
|
|
|
|
return FileInfo{
|
|
|
|
Offset: 5,
|
|
|
|
Size: 20,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *methodOverrideStore) WriteChunk(id string, offset int64, src io.Reader) (int64, error) {
|
|
|
|
s.called = true
|
|
|
|
|
|
|
|
return 5, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMethodOverride(t *testing.T) {
|
|
|
|
store := &methodOverrideStore{
|
|
|
|
t: t,
|
|
|
|
}
|
|
|
|
handler, _ := NewHandler(Config{
|
|
|
|
DataStore: store,
|
|
|
|
})
|
|
|
|
|
|
|
|
(&httpTest{
|
|
|
|
Name: "Successful request",
|
|
|
|
Method: "POST",
|
|
|
|
URL: "yes",
|
|
|
|
ReqHeader: map[string]string{
|
|
|
|
"Tus-Resumable": "1.0.0",
|
|
|
|
"Upload-Offset": "5",
|
2015-11-04 09:56:32 +00:00
|
|
|
"Content-Type": "application/offset+octet-stream",
|
2015-10-06 16:27:40 +00:00
|
|
|
"X-HTTP-Method-Override": "PATCH",
|
|
|
|
},
|
|
|
|
ReqBody: strings.NewReader("hello"),
|
|
|
|
Code: http.StatusNoContent,
|
|
|
|
ResHeader: map[string]string{
|
|
|
|
"Upload-Offset": "10",
|
|
|
|
},
|
|
|
|
}).Run(handler, t)
|
|
|
|
|
|
|
|
if !store.called {
|
|
|
|
t.Fatal("WriteChunk implementation not called")
|
|
|
|
}
|
|
|
|
}
|