Add unit tests for bucket handlers
This commit is contained in:
parent
74fc4819fd
commit
6273ee201c
12 changed files with 235 additions and 32 deletions
|
@ -4,26 +4,27 @@ import (
|
|||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/mastertinner/s3-manager/web"
|
||||
"github.com/mastertinner/s3-manager/datasources"
|
||||
"github.com/mastertinner/s3-manager/utils"
|
||||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
// CreateHandler creates a new bucket
|
||||
func CreateHandler(s3 *minio.Client) http.Handler {
|
||||
func CreateHandler(s3 datasources.S3Client) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var bucket minio.BucketInfo
|
||||
|
||||
err := json.NewDecoder(r.Body).Decode(&bucket)
|
||||
if err != nil {
|
||||
msg := "error decoding json"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
err = s3.MakeBucket(bucket.Name, "")
|
||||
if err != nil {
|
||||
msg := "error making bucket"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -33,7 +34,7 @@ func CreateHandler(s3 *minio.Client) http.Handler {
|
|||
err = json.NewEncoder(w).Encode(bucket)
|
||||
if err != nil {
|
||||
msg := "error encoding json"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
69
buckets/create-handler_test.go
Normal file
69
buckets/create-handler_test.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package buckets_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/mastertinner/s3-manager/buckets"
|
||||
"github.com/mastertinner/s3-manager/mock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreateHandler(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
s3Client *mock.S3Client
|
||||
body string
|
||||
expectedStatusCode int
|
||||
expectedBody string
|
||||
}{
|
||||
{
|
||||
description: "success",
|
||||
s3Client: &mock.S3Client{},
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
expectedStatusCode: http.StatusCreated,
|
||||
expectedBody: "{\"name\":\"myBucket\",\"creationDate\":\"0001-01-01T00:00:00Z\"}\n",
|
||||
},
|
||||
{
|
||||
description: "empty request",
|
||||
s3Client: &mock.S3Client{},
|
||||
body: "",
|
||||
expectedStatusCode: http.StatusUnprocessableEntity,
|
||||
expectedBody: "error decoding json\n",
|
||||
},
|
||||
{
|
||||
description: "malformed request",
|
||||
s3Client: &mock.S3Client{},
|
||||
body: "}",
|
||||
expectedStatusCode: http.StatusUnprocessableEntity,
|
||||
expectedBody: "error decoding json\n",
|
||||
},
|
||||
{
|
||||
description: "s3 error",
|
||||
s3Client: &mock.S3Client{
|
||||
Err: errors.New("internal S3 error"),
|
||||
},
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBody: "error making bucket\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
req, err := http.NewRequest("POST", "/api/buckets", bytes.NewBufferString(tc.body))
|
||||
assert.NoError(err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := buckets.CreateHandler(tc.s3Client)
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, rr.Code, tc.description)
|
||||
assert.Equal(tc.expectedBody, rr.Body.String(), tc.description)
|
||||
}
|
||||
}
|
|
@ -4,19 +4,19 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mastertinner/s3-manager/web"
|
||||
minio "github.com/minio/minio-go"
|
||||
"github.com/mastertinner/s3-manager/datasources"
|
||||
"github.com/mastertinner/s3-manager/utils"
|
||||
)
|
||||
|
||||
// DeleteHandler deletes a bucket
|
||||
func DeleteHandler(s3 *minio.Client) http.Handler {
|
||||
func DeleteHandler(s3 datasources.S3Client) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
err := s3.RemoveBucket(vars["bucketName"])
|
||||
if err != nil {
|
||||
msg := "error removing bucket"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
51
buckets/delete-handler_test.go
Normal file
51
buckets/delete-handler_test.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package buckets_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/mastertinner/s3-manager/buckets"
|
||||
"github.com/mastertinner/s3-manager/mock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDeleteHandler(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
s3Client *mock.S3Client
|
||||
expectedStatusCode int
|
||||
expectedBody string
|
||||
}{
|
||||
{
|
||||
description: "success",
|
||||
s3Client: &mock.S3Client{},
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
expectedBody: "",
|
||||
},
|
||||
{
|
||||
description: "s3 error",
|
||||
s3Client: &mock.S3Client{
|
||||
Err: errors.New("internal S3 error"),
|
||||
},
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBody: "error removing bucket\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
req, err := http.NewRequest("DELETE", "/api/buckets/bucketName", nil)
|
||||
assert.NoError(err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := buckets.DeleteHandler(tc.s3Client)
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, rr.Code, tc.description)
|
||||
assert.Equal(tc.expectedBody, rr.Body.String(), tc.description)
|
||||
}
|
||||
}
|
19
datasources/s3-client.go
Normal file
19
datasources/s3-client.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package datasources
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
// S3Client is a client to interact with S3 storage
|
||||
type S3Client interface {
|
||||
CopyObject(string, string, string, minio.CopyConditions) error
|
||||
GetObject(string, string) (*minio.Object, error)
|
||||
ListBuckets() ([]minio.BucketInfo, error)
|
||||
ListObjectsV2(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo
|
||||
MakeBucket(string, string) error
|
||||
PutObject(string, string, io.Reader, string) (int64, error)
|
||||
RemoveBucket(string) error
|
||||
RemoveObject(string, string) error
|
||||
}
|
20
glide.lock
generated
20
glide.lock
generated
|
@ -1,8 +1,8 @@
|
|||
hash: 7dca8ea81fe671d950fb6be894196f33ffd39619039913b4fe573cd6c6f8d720
|
||||
updated: 2017-03-30T15:17:43.230828675+02:00
|
||||
hash: 5af937afdf2e2b202f0394765f6fa07af14098dd77047df4705611751b70fc16
|
||||
updated: 2017-04-02T17:09:45.925326395+02:00
|
||||
imports:
|
||||
- name: github.com/gorilla/context
|
||||
version: 1ea25387ff6f684839d82767c1733ff4d4d15d0a
|
||||
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
|
||||
- name: github.com/gorilla/mux
|
||||
version: 392c28fe23e1c45ddba891b0320b3b5df220beea
|
||||
- name: github.com/minio/minio-go
|
||||
|
@ -12,4 +12,16 @@ imports:
|
|||
- pkg/s3signer
|
||||
- pkg/s3utils
|
||||
- pkg/set
|
||||
testImports: []
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
subpackages:
|
||||
- assert
|
||||
testImports:
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
|
|
|
@ -4,3 +4,7 @@ import:
|
|||
version: ^2.0.2
|
||||
- package: github.com/gorilla/mux
|
||||
version: ^1.1.0
|
||||
- package: github.com/stretchr/testify
|
||||
version: ^1.1.4
|
||||
subpackages:
|
||||
- assert
|
||||
|
|
46
mock/s3-client.go
Normal file
46
mock/s3-client.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
type S3Client struct {
|
||||
Buckets []minio.BucketInfo
|
||||
ObjectInfos []minio.ObjectInfo
|
||||
Objects []minio.Object
|
||||
Err error
|
||||
}
|
||||
|
||||
func (s S3Client) CopyObject(string, string, string, minio.CopyConditions) error {
|
||||
return s.Err
|
||||
}
|
||||
|
||||
func (s S3Client) GetObject(string, string) (*minio.Object, error) {
|
||||
return &s.Objects[0], s.Err
|
||||
}
|
||||
|
||||
func (s S3Client) ListBuckets() ([]minio.BucketInfo, error) {
|
||||
return s.Buckets, s.Err
|
||||
}
|
||||
|
||||
func (s S3Client) ListObjectsV2(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
return make(<-chan minio.ObjectInfo)
|
||||
}
|
||||
|
||||
func (s S3Client) MakeBucket(string, string) error {
|
||||
return s.Err
|
||||
}
|
||||
|
||||
func (s S3Client) PutObject(string, string, io.Reader, string) (int64, error) {
|
||||
return 0, s.Err
|
||||
}
|
||||
|
||||
func (s S3Client) RemoveBucket(string) error {
|
||||
return s.Err
|
||||
}
|
||||
|
||||
func (s S3Client) RemoveObject(string, string) error {
|
||||
return s.Err
|
||||
}
|
|
@ -6,7 +6,8 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mastertinner/s3-manager/web"
|
||||
"github.com/mastertinner/s3-manager/datasources"
|
||||
"github.com/mastertinner/s3-manager/utils"
|
||||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
|
@ -19,7 +20,7 @@ type CopyObjectInfo struct {
|
|||
}
|
||||
|
||||
// CreateHandler allows to upload a new object
|
||||
func CreateHandler(s3 *minio.Client) http.Handler {
|
||||
func CreateHandler(s3 datasources.S3Client) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
|
@ -29,16 +30,16 @@ func CreateHandler(s3 *minio.Client) http.Handler {
|
|||
err := json.NewDecoder(r.Body).Decode(©)
|
||||
if err != nil {
|
||||
msg := "error decoding json"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
var copyConds = minio.NewCopyConditions()
|
||||
copyConds := minio.NewCopyConditions()
|
||||
objectSource := fmt.Sprintf("/%s/%s", copy.SourceBucketName, copy.SourceObjectName)
|
||||
err = s3.CopyObject(copy.BucketName, copy.ObjectName, objectSource, copyConds)
|
||||
if err != nil {
|
||||
msg := "error copying object"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -48,21 +49,21 @@ func CreateHandler(s3 *minio.Client) http.Handler {
|
|||
err = json.NewEncoder(w).Encode(copy)
|
||||
if err != nil {
|
||||
msg := "error encoding json"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err := r.ParseMultipartForm(32 << 20)
|
||||
if err != nil {
|
||||
msg := "error parsing form"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
file, handler, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
msg := "error getting form file"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
@ -70,7 +71,7 @@ func CreateHandler(s3 *minio.Client) http.Handler {
|
|||
_, err = s3.PutObject(vars["bucketName"], handler.Filename, file, "application/octet-stream")
|
||||
if err != nil {
|
||||
msg := "error putting object"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -4,19 +4,19 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mastertinner/s3-manager/web"
|
||||
minio "github.com/minio/minio-go"
|
||||
"github.com/mastertinner/s3-manager/datasources"
|
||||
"github.com/mastertinner/s3-manager/utils"
|
||||
)
|
||||
|
||||
// DeleteHandler deletes an object
|
||||
func DeleteHandler(s3 *minio.Client) http.Handler {
|
||||
func DeleteHandler(s3 datasources.S3Client) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
err := s3.RemoveObject(vars["bucketName"], vars["objectName"])
|
||||
if err != nil {
|
||||
msg := "error removing object"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mastertinner/s3-manager/web"
|
||||
minio "github.com/minio/minio-go"
|
||||
"github.com/mastertinner/s3-manager/datasources"
|
||||
"github.com/mastertinner/s3-manager/utils"
|
||||
)
|
||||
|
||||
// GetHandler downloads an object to the client
|
||||
func GetHandler(s3 *minio.Client) http.Handler {
|
||||
func GetHandler(s3 datasources.S3Client) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
objectName := vars["objectName"]
|
||||
|
@ -19,7 +19,7 @@ func GetHandler(s3 *minio.Client) http.Handler {
|
|||
object, err := s3.GetObject(vars["bucketName"], objectName)
|
||||
if err != nil {
|
||||
msg := "error getting object"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ func GetHandler(s3 *minio.Client) http.Handler {
|
|||
_, err = io.Copy(w, object)
|
||||
if err != nil {
|
||||
msg := "error copying object"
|
||||
web.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
utils.HandleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package web
|
||||
package utils
|
||||
|
||||
import (
|
||||
"log"
|
Loading…
Reference in a new issue