// Copyright 2023 Versity Software // This file is licensed under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package controllers import ( "context" "net/http" "testing" "github.com/versity/versitygw/s3err" ) func TestS3ApiController_DeleteBucketTagging(t *testing.T) { tests := []struct { name string input testInput output testOutput }{ { name: "verify access fails", input: testInput{ locals: accessDeniedLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", }, }, err: s3err.GetAPIError(s3err.ErrAccessDenied), }, }, { name: "backend returns error", input: testInput{ locals: defaultLocals, beErr: s3err.GetAPIError(s3err.ErrAclNotSupported), }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, err: s3err.GetAPIError(s3err.ErrAclNotSupported), }, }, { name: "successful response", input: testInput{ locals: defaultLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { be := &BackendMock{ DeleteBucketTaggingFunc: func(_ context.Context, _ string) error { return tt.input.beErr }, GetBucketPolicyFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) { return nil, s3err.GetAPIError(s3err.ErrAccessDenied) }, } ctrl := S3ApiController{ be: be, } testController( t, ctrl.DeleteBucketTagging, tt.output.response, tt.output.err, ctxInputs{ locals: tt.input.locals, }) }) } } func TestS3ApiController_DeleteBucketOwnershipControls(t *testing.T) { tests := []struct { name string input testInput output testOutput }{ { name: "verify access fails", input: testInput{ locals: accessDeniedLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", }, }, err: s3err.GetAPIError(s3err.ErrAccessDenied), }, }, { name: "backend returns error", input: testInput{ locals: defaultLocals, beErr: s3err.GetAPIError(s3err.ErrInvalidAccessKeyID), }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, err: s3err.GetAPIError(s3err.ErrInvalidAccessKeyID), }, }, { name: "successful response", input: testInput{ locals: defaultLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { be := &BackendMock{ DeleteBucketOwnershipControlsFunc: func(contextMoqParam context.Context, bucket string) error { return tt.input.beErr }, GetBucketPolicyFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) { return nil, s3err.GetAPIError(s3err.ErrAccessDenied) }, } ctrl := S3ApiController{ be: be, } testController( t, ctrl.DeleteBucketOwnershipControls, tt.output.response, tt.output.err, ctxInputs{ locals: tt.input.locals, }) }) } } func TestS3ApiController_DeleteBucketPolicy(t *testing.T) { tests := []struct { name string input testInput output testOutput }{ { name: "verify access fails", input: testInput{ locals: accessDeniedLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", }, }, err: s3err.GetAPIError(s3err.ErrAccessDenied), }, }, { name: "backend returns error", input: testInput{ locals: defaultLocals, beErr: s3err.GetAPIError(s3err.ErrInvalidDigest), }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, err: s3err.GetAPIError(s3err.ErrInvalidDigest), }, }, { name: "successful response", input: testInput{ locals: defaultLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { be := &BackendMock{ DeleteBucketPolicyFunc: func(contextMoqParam context.Context, bucket string) error { return tt.input.beErr }, GetBucketPolicyFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) { return nil, s3err.GetAPIError(s3err.ErrAccessDenied) }, } ctrl := S3ApiController{ be: be, } testController( t, ctrl.DeleteBucketPolicy, tt.output.response, tt.output.err, ctxInputs{ locals: tt.input.locals, }) }) } } func TestS3ApiController_DeleteBucketCors(t *testing.T) { tests := []struct { name string input testInput output testOutput }{ { name: "verify access fails", input: testInput{ locals: accessDeniedLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", }, }, err: s3err.GetAPIError(s3err.ErrAccessDenied), }, }, { name: "backend returns error", input: testInput{ locals: defaultLocals, beErr: s3err.GetAPIError(s3err.ErrAdminMethodNotSupported), }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, err: s3err.GetAPIError(s3err.ErrAdminMethodNotSupported), }, }, { name: "successful response", input: testInput{ locals: defaultLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { be := &BackendMock{ DeleteBucketCorsFunc: func(contextMoqParam context.Context, bucket string) error { return tt.input.beErr }, GetBucketPolicyFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) { return nil, s3err.GetAPIError(s3err.ErrAccessDenied) }, } ctrl := S3ApiController{ be: be, } testController( t, ctrl.DeleteBucketCors, tt.output.response, tt.output.err, ctxInputs{ locals: tt.input.locals, }) }) } } func TestS3ApiController_DeleteBucket(t *testing.T) { tests := []struct { name string input testInput output testOutput }{ { name: "verify access fails", input: testInput{ locals: accessDeniedLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", }, }, err: s3err.GetAPIError(s3err.ErrAccessDenied), }, }, { name: "backend returns error", input: testInput{ locals: defaultLocals, beErr: s3err.GetAPIError(s3err.ErrInvalidDigest), }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, err: s3err.GetAPIError(s3err.ErrInvalidDigest), }, }, { name: "successful response", input: testInput{ locals: defaultLocals, }, output: testOutput{ response: &Response{ MetaOpts: &MetaOptions{ BucketOwner: "root", Status: http.StatusNoContent, }, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { be := &BackendMock{ DeleteBucketFunc: func(contextMoqParam context.Context, bucket string) error { return tt.input.beErr }, GetBucketPolicyFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) { return nil, s3err.GetAPIError(s3err.ErrAccessDenied) }, } ctrl := S3ApiController{ be: be, } testController( t, ctrl.DeleteBucket, tt.output.response, tt.output.err, ctxInputs{ locals: tt.input.locals, }) }) } }