github.com/minio/console@v1.4.1/api/errors_test.go (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package api
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/minio/console/models"
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  func TestError(t *testing.T) {
    29  	type args struct {
    30  		err []interface{}
    31  	}
    32  
    33  	type testError struct {
    34  		name string
    35  		args args
    36  		want *CodedAPIError
    37  	}
    38  
    39  	var tests []testError
    40  
    41  	type expectedError struct {
    42  		err  error
    43  		code int
    44  	}
    45  
    46  	appErrors := map[string]expectedError{
    47  		"ErrDefault": {code: 500, err: ErrDefault},
    48  
    49  		"ErrForbidden":                    {code: 403, err: ErrForbidden},
    50  		"ErrFileTooLarge":                 {code: 413, err: ErrFileTooLarge},
    51  		"ErrInvalidSession":               {code: 401, err: ErrInvalidSession},
    52  		"ErrNotFound":                     {code: 404, err: ErrNotFound},
    53  		"ErrGroupAlreadyExists":           {code: 400, err: ErrGroupAlreadyExists},
    54  		"ErrInvalidErasureCodingValue":    {code: 400, err: ErrInvalidErasureCodingValue},
    55  		"ErrBucketBodyNotInRequest":       {code: 400, err: ErrBucketBodyNotInRequest},
    56  		"ErrBucketNameNotInRequest":       {code: 400, err: ErrBucketNameNotInRequest},
    57  		"ErrGroupBodyNotInRequest":        {code: 400, err: ErrGroupBodyNotInRequest},
    58  		"ErrGroupNameNotInRequest":        {code: 400, err: ErrGroupNameNotInRequest},
    59  		"ErrPolicyNameNotInRequest":       {code: 400, err: ErrPolicyNameNotInRequest},
    60  		"ErrPolicyBodyNotInRequest":       {code: 400, err: ErrPolicyBodyNotInRequest},
    61  		"ErrInvalidEncryptionAlgorithm":   {code: 500, err: ErrInvalidEncryptionAlgorithm},
    62  		"ErrSSENotConfigured":             {code: 404, err: ErrSSENotConfigured},
    63  		"ErrBucketLifeCycleNotConfigured": {code: 404, err: ErrBucketLifeCycleNotConfigured},
    64  		"ErrChangePassword":               {code: 403, err: ErrChangePassword},
    65  		"ErrInvalidLicense":               {code: 404, err: ErrInvalidLicense},
    66  		"ErrLicenseNotFound":              {code: 404, err: ErrLicenseNotFound},
    67  		"ErrAvoidSelfAccountDelete":       {code: 403, err: ErrAvoidSelfAccountDelete},
    68  
    69  		"ErrNonUniqueAccessKey":               {code: 500, err: ErrNonUniqueAccessKey},
    70  		"ErrRemoteTierExists":                 {code: 400, err: ErrRemoteTierExists},
    71  		"ErrRemoteTierNotFound":               {code: 400, err: ErrRemoteTierNotFound},
    72  		"ErrRemoteTierUppercase":              {code: 400, err: ErrRemoteTierUppercase},
    73  		"ErrRemoteTierBucketNotFound":         {code: 400, err: ErrRemoteTierBucketNotFound},
    74  		"ErrRemoteInvalidCredentials":         {code: 403, err: ErrRemoteInvalidCredentials},
    75  		"ErrTooFewNodes":                      {code: 500, err: ErrTooFewNodes},
    76  		"ErrUnableToGetTenantUsage":           {code: 500, err: ErrUnableToGetTenantUsage},
    77  		"ErrTooManyNodes":                     {code: 500, err: ErrTooManyNodes},
    78  		"ErrAccessDenied":                     {code: 403, err: ErrAccessDenied},
    79  		"ErrTooFewAvailableNodes":             {code: 500, err: ErrTooFewAvailableNodes},
    80  		"ErrFewerThanFourNodes":               {code: 500, err: ErrFewerThanFourNodes},
    81  		"ErrUnableToGetTenantLogs":            {code: 500, err: ErrUnableToGetTenantLogs},
    82  		"ErrUnableToUpdateTenantCertificates": {code: 500, err: ErrUnableToUpdateTenantCertificates},
    83  		"ErrUpdatingEncryptionConfig":         {code: 500, err: ErrUpdatingEncryptionConfig},
    84  		"ErrDeletingEncryptionConfig":         {code: 500, err: ErrDeletingEncryptionConfig},
    85  		"ErrEncryptionConfigNotFound":         {code: 404, err: ErrEncryptionConfigNotFound},
    86  	}
    87  
    88  	for k, e := range appErrors {
    89  		tests = append(tests, testError{
    90  			name: fmt.Sprintf("%s error", k),
    91  			args: args{
    92  				err: []interface{}{e.err},
    93  			},
    94  			want: &CodedAPIError{
    95  				Code:     e.code,
    96  				APIError: &models.APIError{Message: e.err.Error(), DetailedMessage: e.err.Error()},
    97  			},
    98  		})
    99  	}
   100  
   101  	tests = append(tests,
   102  		testError{
   103  			name: "passing multiple errors but ErrInvalidLogin is last",
   104  			args: args{
   105  				err: []interface{}{ErrDefault, ErrInvalidLogin},
   106  			},
   107  			want: &CodedAPIError{
   108  				Code:     int(401),
   109  				APIError: &models.APIError{Message: ErrDefault.Error(), DetailedMessage: ""},
   110  			},
   111  		})
   112  	tests = append(tests,
   113  		testError{
   114  			name: "login error omits detailedMessage",
   115  			args: args{
   116  				err: []interface{}{ErrInvalidLogin},
   117  			},
   118  			want: &CodedAPIError{
   119  				Code:     int(401),
   120  				APIError: &models.APIError{Message: ErrInvalidLogin.Error(), DetailedMessage: ""},
   121  			},
   122  		})
   123  
   124  	for _, tt := range tests {
   125  		t.Run(tt.name, func(_ *testing.T) {
   126  			got := Error(tt.args.err...)
   127  			assert.Equalf(t, tt.want.Code, got.Code, "Error(%v) Got (%v)", tt.want.Code, got.Code)
   128  			assert.Equalf(t, tt.want.APIError.DetailedMessage, got.APIError.DetailedMessage, "Error(%s) Got (%s)", tt.want.APIError.DetailedMessage, got.APIError.DetailedMessage)
   129  		})
   130  	}
   131  }
   132  
   133  func TestErrorWithContext(t *testing.T) {
   134  	type args struct {
   135  		ctx context.Context
   136  		err []interface{}
   137  	}
   138  	tests := []struct {
   139  		name string
   140  		args args
   141  		want *CodedAPIError
   142  	}{
   143  		{
   144  			name: "default error",
   145  			args: args{
   146  				ctx: context.Background(),
   147  				err: []interface{}{ErrDefault},
   148  			},
   149  			want: &CodedAPIError{
   150  				Code: 500, APIError: &models.APIError{Message: ErrDefault.Error(), DetailedMessage: ErrDefault.Error()},
   151  			},
   152  		},
   153  	}
   154  	for _, tt := range tests {
   155  		t.Run(tt.name, func(_ *testing.T) {
   156  			assert.Equalf(t, tt.want, ErrorWithContext(tt.args.ctx, tt.args.err...), "ErrorWithContext(%v, %v)", tt.args.ctx, tt.args.err)
   157  		})
   158  	}
   159  }