feat(http): add links to bucket service response structures
parent
5a35d04386
commit
d6098882f9
|
@ -4,11 +4,13 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/platform"
|
||||
kerrors "github.com/influxdata/platform/kit/errors"
|
||||
errors "github.com/influxdata/platform/kit/errors"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
|
@ -33,6 +35,40 @@ func NewBucketHandler() *BucketHandler {
|
|||
return h
|
||||
}
|
||||
|
||||
type bucketResponse struct {
|
||||
Links map[string]string `json:"links"`
|
||||
platform.Bucket
|
||||
}
|
||||
|
||||
func newBucketResponse(b *platform.Bucket) *bucketResponse {
|
||||
return &bucketResponse{
|
||||
Links: map[string]string{
|
||||
"self": fmt.Sprintf("/v1/buckets/%s", b.ID),
|
||||
"org": fmt.Sprintf("/v1/orgs/%s", b.OrganizationID),
|
||||
},
|
||||
Bucket: *b,
|
||||
}
|
||||
}
|
||||
|
||||
type bucketsResponse struct {
|
||||
Links map[string]string `json:"links"`
|
||||
Buckets []*bucketResponse `json:"buckets"`
|
||||
}
|
||||
|
||||
func newBucketsResponse(opts platform.FindOptions, f platform.BucketFilter, bs []*platform.Bucket) *bucketsResponse {
|
||||
rs := make([]*bucketResponse, 0, len(bs))
|
||||
for _, b := range bs {
|
||||
rs = append(rs, newBucketResponse(b))
|
||||
}
|
||||
return &bucketsResponse{
|
||||
// TODO(desa): update links to include paging and filter information
|
||||
Links: map[string]string{
|
||||
"self": "/v1/buckets",
|
||||
},
|
||||
Buckets: rs,
|
||||
}
|
||||
}
|
||||
|
||||
// handlePostBucket is the HTTP handler for the POST /v1/buckets route.
|
||||
func (h *BucketHandler) handlePostBucket(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
@ -48,7 +84,7 @@ func (h *BucketHandler) handlePostBucket(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
if err := encodeResponse(ctx, w, http.StatusCreated, req.Bucket); err != nil {
|
||||
if err := encodeResponse(ctx, w, http.StatusCreated, newBucketResponse(req.Bucket)); err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
@ -82,11 +118,15 @@ func (h *BucketHandler) handleGetBucket(w http.ResponseWriter, r *http.Request)
|
|||
|
||||
b, err := h.BucketService.FindBucketByID(ctx, req.BucketID)
|
||||
if err != nil {
|
||||
// TODO(desa): fix this when using real errors library
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
err = errors.New(err.Error(), errors.NotFound)
|
||||
}
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
if err := encodeResponse(ctx, w, http.StatusOK, b); err != nil {
|
||||
if err := encodeResponse(ctx, w, http.StatusOK, newBucketResponse(b)); err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
@ -100,7 +140,7 @@ func decodeGetBucketRequest(ctx context.Context, r *http.Request) (*getBucketReq
|
|||
params := httprouter.ParamsFromContext(ctx)
|
||||
id := params.ByName("id")
|
||||
if id == "" {
|
||||
return nil, kerrors.InvalidDataf("url missing id")
|
||||
return nil, errors.InvalidDataf("url missing id")
|
||||
}
|
||||
|
||||
var i platform.ID
|
||||
|
@ -125,11 +165,15 @@ func (h *BucketHandler) handleDeleteBucket(w http.ResponseWriter, r *http.Reques
|
|||
}
|
||||
|
||||
if err := h.BucketService.DeleteBucket(ctx, req.BucketID); err != nil {
|
||||
// TODO(desa): fix this when using real errors library
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
err = errors.New(err.Error(), errors.NotFound)
|
||||
}
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
type deleteBucketRequest struct {
|
||||
|
@ -140,7 +184,7 @@ func decodeDeleteBucketRequest(ctx context.Context, r *http.Request) (*deleteBuc
|
|||
params := httprouter.ParamsFromContext(ctx)
|
||||
id := params.ByName("id")
|
||||
if id == "" {
|
||||
return nil, kerrors.InvalidDataf("url missing id")
|
||||
return nil, errors.InvalidDataf("url missing id")
|
||||
}
|
||||
|
||||
var i platform.ID
|
||||
|
@ -164,13 +208,14 @@ func (h *BucketHandler) handleGetBuckets(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
bs, _, err := h.BucketService.FindBuckets(ctx, req.filter)
|
||||
opts := platform.FindOptions{}
|
||||
bs, _, err := h.BucketService.FindBuckets(ctx, req.filter, opts)
|
||||
if err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
if err := encodeResponse(ctx, w, http.StatusOK, bs); err != nil {
|
||||
if err := encodeResponse(ctx, w, http.StatusOK, newBucketsResponse(opts, req.filter, bs)); err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
@ -221,11 +266,15 @@ func (h *BucketHandler) handlePatchBucket(w http.ResponseWriter, r *http.Request
|
|||
|
||||
b, err := h.BucketService.UpdateBucket(ctx, req.BucketID, req.Update)
|
||||
if err != nil {
|
||||
// TODO(desa): fix this when using real errors library
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
err = errors.New(err.Error(), errors.NotFound)
|
||||
}
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
if err := encodeResponse(ctx, w, http.StatusOK, b); err != nil {
|
||||
if err := encodeResponse(ctx, w, http.StatusOK, newBucketResponse(b)); err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
@ -240,7 +289,7 @@ func decodePatchBucketRequest(ctx context.Context, r *http.Request) (*patchBucke
|
|||
params := httprouter.ParamsFromContext(ctx)
|
||||
id := params.ByName("id")
|
||||
if id == "" {
|
||||
return nil, kerrors.InvalidDataf("url missing id")
|
||||
return nil, errors.InvalidDataf("url missing id")
|
||||
}
|
||||
|
||||
var i platform.ID
|
||||
|
@ -362,13 +411,18 @@ func (s *BucketService) FindBuckets(ctx context.Context, filter platform.BucketF
|
|||
return nil, 0, err
|
||||
}
|
||||
|
||||
var bs []*platform.Bucket
|
||||
var bs bucketsResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&bs); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return bs, len(bs), nil
|
||||
buckets := make([]*platform.Bucket, 0, len(bs.Buckets))
|
||||
for _, b := range bs.Buckets {
|
||||
buckets = append(buckets, &b.Bucket)
|
||||
}
|
||||
|
||||
return buckets, len(buckets), nil
|
||||
}
|
||||
|
||||
// CreateBucket creates a new bucket and sets b.ID with the new identifier.
|
||||
|
|
|
@ -0,0 +1,586 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/platform"
|
||||
"github.com/influxdata/platform/mock"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func TestService_handleGetBuckets(t *testing.T) {
|
||||
type fields struct {
|
||||
BucketService platform.BucketService
|
||||
}
|
||||
type args struct {
|
||||
queryParams map[string][]string
|
||||
}
|
||||
type wants struct {
|
||||
statusCode int
|
||||
contentType string
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "get all buckets",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
FindBucketsFn: func(ctx context.Context, filter platform.BucketFilter, opts ...platform.FindOptions) ([]*platform.Bucket, int, error) {
|
||||
return []*platform.Bucket{
|
||||
{
|
||||
ID: platform.ID("0"),
|
||||
Name: "hello",
|
||||
OrganizationID: platform.ID("10"),
|
||||
},
|
||||
{
|
||||
ID: platform.ID("2"),
|
||||
Name: "example",
|
||||
OrganizationID: platform.ID("20"),
|
||||
},
|
||||
}, 2, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{},
|
||||
wants: wants{
|
||||
statusCode: http.StatusOK,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
body: `
|
||||
{
|
||||
"links": {
|
||||
"self": "/v1/buckets"
|
||||
},
|
||||
"buckets": [
|
||||
{
|
||||
"links": {
|
||||
"org": "/v1/orgs/3130",
|
||||
"self": "/v1/buckets/30"
|
||||
},
|
||||
"id": "30",
|
||||
"organizationID": "3130",
|
||||
"name": "hello",
|
||||
"retentionPeriod": 0
|
||||
},
|
||||
{
|
||||
"links": {
|
||||
"org": "/v1/orgs/3230",
|
||||
"self": "/v1/buckets/32"
|
||||
},
|
||||
"id": "32",
|
||||
"organizationID": "3230",
|
||||
"name": "example",
|
||||
"retentionPeriod": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get all buckets when there are none",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
FindBucketsFn: func(ctx context.Context, filter platform.BucketFilter, opts ...platform.FindOptions) ([]*platform.Bucket, int, error) {
|
||||
return []*platform.Bucket{}, 0, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{},
|
||||
wants: wants{
|
||||
statusCode: http.StatusOK,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
body: `
|
||||
{
|
||||
"links": {
|
||||
"self": "/v1/buckets"
|
||||
},
|
||||
"buckets": []
|
||||
}`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
h := NewBucketHandler()
|
||||
h.BucketService = tt.fields.BucketService
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", nil)
|
||||
|
||||
qp := r.URL.Query()
|
||||
for k, vs := range tt.args.queryParams {
|
||||
for _, v := range vs {
|
||||
qp.Add(k, v)
|
||||
}
|
||||
}
|
||||
r.URL.RawQuery = qp.Encode()
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.handleGetBuckets(w, r)
|
||||
|
||||
res := w.Result()
|
||||
content := res.Header.Get("Content-Type")
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
|
||||
if res.StatusCode != tt.wants.statusCode {
|
||||
t.Errorf("%q. handleGetBuckets() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
||||
}
|
||||
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
||||
t.Errorf("%q. handleGetBuckets() = %v, want %v", tt.name, content, tt.wants.contentType)
|
||||
}
|
||||
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
|
||||
t.Errorf("%q. handleGetBuckets() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_handleGetBucket(t *testing.T) {
|
||||
type fields struct {
|
||||
BucketService platform.BucketService
|
||||
}
|
||||
type args struct {
|
||||
id string
|
||||
}
|
||||
type wants struct {
|
||||
statusCode int
|
||||
contentType string
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "get a bucket by id",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
FindBucketByIDFn: func(ctx context.Context, id platform.ID) (*platform.Bucket, error) {
|
||||
if bytes.Equal(id, mustParseID("020f755c3c082000")) {
|
||||
return &platform.Bucket{
|
||||
ID: mustParseID("020f755c3c082000"),
|
||||
OrganizationID: mustParseID("020f755c3c082000"),
|
||||
Name: "hello",
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("not found")
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: "020f755c3c082000",
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: http.StatusOK,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
body: `
|
||||
{
|
||||
"links": {
|
||||
"org": "/v1/orgs/020f755c3c082000",
|
||||
"self": "/v1/buckets/020f755c3c082000"
|
||||
},
|
||||
"id": "020f755c3c082000",
|
||||
"organizationID": "020f755c3c082000",
|
||||
"name": "hello",
|
||||
"retentionPeriod": 0
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not found",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
FindBucketByIDFn: func(ctx context.Context, id platform.ID) (*platform.Bucket, error) {
|
||||
return nil, fmt.Errorf("bucket not found")
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: "020f755c3c082000",
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: http.StatusNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
h := NewBucketHandler()
|
||||
h.BucketService = tt.fields.BucketService
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", nil)
|
||||
|
||||
r = r.WithContext(context.WithValue(
|
||||
context.TODO(),
|
||||
httprouter.ParamsKey,
|
||||
httprouter.Params{
|
||||
{
|
||||
Key: "id",
|
||||
Value: tt.args.id,
|
||||
},
|
||||
}))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.handleGetBucket(w, r)
|
||||
|
||||
res := w.Result()
|
||||
content := res.Header.Get("Content-Type")
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
t.Logf(res.Header.Get("X-Influx-Error"))
|
||||
|
||||
if res.StatusCode != tt.wants.statusCode {
|
||||
t.Errorf("%q. handleGetBucket() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
||||
}
|
||||
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
||||
t.Errorf("%q. handleGetBucket() = %v, want %v", tt.name, content, tt.wants.contentType)
|
||||
}
|
||||
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
|
||||
t.Errorf("%q. handleGetBucket() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_handlePostBucket(t *testing.T) {
|
||||
type fields struct {
|
||||
BucketService platform.BucketService
|
||||
}
|
||||
type args struct {
|
||||
bucket *platform.Bucket
|
||||
}
|
||||
type wants struct {
|
||||
statusCode int
|
||||
contentType string
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "create a new bucket",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
CreateBucketFn: func(ctx context.Context, c *platform.Bucket) error {
|
||||
c.ID = mustParseID("020f755c3c082000")
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
bucket: &platform.Bucket{
|
||||
Name: "hello",
|
||||
OrganizationID: platform.ID("0"),
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: http.StatusCreated,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
body: `
|
||||
{
|
||||
"links": {
|
||||
"org": "/v1/orgs/30",
|
||||
"self": "/v1/buckets/020f755c3c082000"
|
||||
},
|
||||
"id": "020f755c3c082000",
|
||||
"organizationID": "30",
|
||||
"name": "hello",
|
||||
"retentionPeriod": 0
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
h := NewBucketHandler()
|
||||
h.BucketService = tt.fields.BucketService
|
||||
|
||||
b, err := json.Marshal(tt.args.bucket)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to unmarshal bucket: %v", err)
|
||||
}
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", bytes.NewReader(b))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.handlePostBucket(w, r)
|
||||
|
||||
res := w.Result()
|
||||
content := res.Header.Get("Content-Type")
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
|
||||
if res.StatusCode != tt.wants.statusCode {
|
||||
t.Errorf("%q. handlePostBucket() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
||||
}
|
||||
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
||||
t.Errorf("%q. handlePostBucket() = %v, want %v", tt.name, content, tt.wants.contentType)
|
||||
}
|
||||
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
|
||||
t.Errorf("%q. handlePostBucket() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_handleDeleteBucket(t *testing.T) {
|
||||
type fields struct {
|
||||
BucketService platform.BucketService
|
||||
}
|
||||
type args struct {
|
||||
id string
|
||||
}
|
||||
type wants struct {
|
||||
statusCode int
|
||||
contentType string
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "remove a bucket by id",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
DeleteBucketFn: func(ctx context.Context, id platform.ID) error {
|
||||
if bytes.Equal(id, mustParseID("020f755c3c082000")) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("wrong id")
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: "020f755c3c082000",
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: http.StatusNoContent,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bucket not found",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
DeleteBucketFn: func(ctx context.Context, id platform.ID) error {
|
||||
return fmt.Errorf("bucket not found")
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: "020f755c3c082000",
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: http.StatusNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
h := NewBucketHandler()
|
||||
h.BucketService = tt.fields.BucketService
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", nil)
|
||||
|
||||
r = r.WithContext(context.WithValue(
|
||||
context.TODO(),
|
||||
httprouter.ParamsKey,
|
||||
httprouter.Params{
|
||||
{
|
||||
Key: "id",
|
||||
Value: tt.args.id,
|
||||
},
|
||||
}))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.handleDeleteBucket(w, r)
|
||||
|
||||
res := w.Result()
|
||||
content := res.Header.Get("Content-Type")
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
|
||||
if res.StatusCode != tt.wants.statusCode {
|
||||
t.Errorf("%q. handleDeleteBucket() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
||||
}
|
||||
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
||||
t.Errorf("%q. handleDeleteBucket() = %v, want %v", tt.name, content, tt.wants.contentType)
|
||||
}
|
||||
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
|
||||
t.Errorf("%q. handleDeleteBucket() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_handlePatchBucket(t *testing.T) {
|
||||
type fields struct {
|
||||
BucketService platform.BucketService
|
||||
}
|
||||
type args struct {
|
||||
id string
|
||||
name string
|
||||
retention time.Duration
|
||||
}
|
||||
type wants struct {
|
||||
statusCode int
|
||||
contentType string
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "update a bucket name and retenion",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
UpdateBucketFn: func(ctx context.Context, id platform.ID, upd platform.BucketUpdate) (*platform.Bucket, error) {
|
||||
if bytes.Equal(id, mustParseID("020f755c3c082000")) {
|
||||
d := &platform.Bucket{
|
||||
ID: mustParseID("020f755c3c082000"),
|
||||
Name: "hello",
|
||||
OrganizationID: mustParseID("020f755c3c082000"),
|
||||
}
|
||||
|
||||
if upd.Name != nil {
|
||||
d.Name = *upd.Name
|
||||
}
|
||||
|
||||
if upd.RetentionPeriod != nil {
|
||||
d.RetentionPeriod = *upd.RetentionPeriod
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("not found")
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: "020f755c3c082000",
|
||||
name: "example",
|
||||
retention: 1234,
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: http.StatusOK,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
body: `
|
||||
{
|
||||
"links": {
|
||||
"org": "/v1/orgs/020f755c3c082000",
|
||||
"self": "/v1/buckets/020f755c3c082000"
|
||||
},
|
||||
"id": "020f755c3c082000",
|
||||
"organizationID": "020f755c3c082000",
|
||||
"name": "example",
|
||||
"retentionPeriod": 1234
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bucket not found",
|
||||
fields: fields{
|
||||
&mock.BucketService{
|
||||
UpdateBucketFn: func(ctx context.Context, id platform.ID, upd platform.BucketUpdate) (*platform.Bucket, error) {
|
||||
return nil, fmt.Errorf("not found")
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: "020f755c3c082000",
|
||||
name: "hello",
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: http.StatusNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
h := NewBucketHandler()
|
||||
h.BucketService = tt.fields.BucketService
|
||||
|
||||
upd := platform.BucketUpdate{}
|
||||
if tt.args.name != "" {
|
||||
upd.Name = &tt.args.name
|
||||
}
|
||||
if tt.args.retention != 0 {
|
||||
upd.RetentionPeriod = &tt.args.retention
|
||||
}
|
||||
|
||||
b, err := json.Marshal(upd)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to unmarshal bucket update: %v", err)
|
||||
}
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", bytes.NewReader(b))
|
||||
|
||||
r = r.WithContext(context.WithValue(
|
||||
context.TODO(),
|
||||
httprouter.ParamsKey,
|
||||
httprouter.Params{
|
||||
{
|
||||
Key: "id",
|
||||
Value: tt.args.id,
|
||||
},
|
||||
}))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.handlePatchBucket(w, r)
|
||||
|
||||
res := w.Result()
|
||||
content := res.Header.Get("Content-Type")
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
|
||||
if res.StatusCode != tt.wants.statusCode {
|
||||
t.Errorf("%q. handlePatchBucket() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
||||
}
|
||||
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
||||
t.Errorf("%q. handlePatchBucket() = %v, want %v", tt.name, content, tt.wants.contentType)
|
||||
}
|
||||
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
|
||||
t.Errorf("%q. handlePatchBucket() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -78,5 +78,5 @@ func (s *BucketService) UpdateBucket(ctx context.Context, id platform.ID, upd pl
|
|||
|
||||
// DeleteBucket removes a bucket by ID.
|
||||
func (s *BucketService) DeleteBucket(ctx context.Context, id platform.ID) error {
|
||||
return s.DeleteBucket(ctx, id)
|
||||
return s.DeleteBucketFn(ctx, id)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue