The oapi-codegen update to v2.5.0 changed the Details field of the main Error type to be an empty interface. This requires updates to the error handling tests to accommodate the new structure.
204 lines
6.8 KiB
Go
204 lines
6.8 KiB
Go
package v2
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestHTTPErrorReturnsEchoHTTPError(t *testing.T) {
|
|
for _, se := range getServiceErrors() {
|
|
err := HTTPError(se.code)
|
|
echoError, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
require.Equal(t, se.httpStatus, echoError.Code)
|
|
detailsError, ok := echoError.Message.(detailsError)
|
|
require.True(t, ok)
|
|
require.Equal(t, se.code, detailsError.errorCode)
|
|
}
|
|
}
|
|
|
|
func TestAPIError(t *testing.T) {
|
|
e := echo.New()
|
|
for _, svcErr := range getServiceErrors() {
|
|
ctx := e.NewContext(nil, nil)
|
|
ctx.Set("operationID", "test-operation-id")
|
|
se := svcErr // avoid G601
|
|
apiError := APIError(&se, ctx, nil)
|
|
require.Equal(t, fmt.Sprintf("/api/image-builder-composer/v2/errors/%d", se.code), apiError.Href)
|
|
require.Equal(t, fmt.Sprintf("%d", se.code), apiError.Id)
|
|
require.Equal(t, "Error", apiError.Kind)
|
|
require.Equal(t, fmt.Sprintf("IMAGE-BUILDER-COMPOSER-%d", se.code), apiError.Code)
|
|
require.Equal(t, "test-operation-id", apiError.OperationId)
|
|
require.Equal(t, se.reason, apiError.Reason)
|
|
}
|
|
}
|
|
|
|
func TestAPIErrorOperationID(t *testing.T) {
|
|
ctx := echo.New().NewContext(nil, nil)
|
|
|
|
apiError := APIError(find(ErrorUnauthenticated), ctx, nil)
|
|
require.Equal(t, "IMAGE-BUILDER-COMPOSER-10003", apiError.Code)
|
|
|
|
ctx.Set("operationID", 5)
|
|
apiError = APIError(find(ErrorUnauthenticated), ctx, nil)
|
|
require.Equal(t, "IMAGE-BUILDER-COMPOSER-10003", apiError.Code)
|
|
|
|
ctx.Set("operationID", "test-operation-id")
|
|
apiError = APIError(find(ErrorUnauthenticated), ctx, nil)
|
|
require.Equal(t, "IMAGE-BUILDER-COMPOSER-401", apiError.Code)
|
|
}
|
|
|
|
func TestAPIErrorList(t *testing.T) {
|
|
ctx := echo.New().NewContext(nil, nil)
|
|
ctx.Set("operationID", "test-operation-id")
|
|
|
|
// negative values return empty list
|
|
errs := APIErrorList(-10, -30, ctx)
|
|
require.Equal(t, 0, errs.Size)
|
|
require.Equal(t, 0, len(errs.Items))
|
|
errs = APIErrorList(0, -30, ctx)
|
|
require.Equal(t, 0, errs.Size)
|
|
require.Equal(t, 0, len(errs.Items))
|
|
errs = APIErrorList(-10, 0, ctx)
|
|
require.Equal(t, 0, errs.Size)
|
|
require.Equal(t, 0, len(errs.Items))
|
|
|
|
// all of them
|
|
errs = APIErrorList(0, 1000, ctx)
|
|
require.Equal(t, len(getServiceErrors()), errs.Size)
|
|
|
|
// some of them
|
|
errs = APIErrorList(0, 10, ctx)
|
|
require.Equal(t, 10, errs.Size)
|
|
require.Equal(t, len(getServiceErrors()), errs.Total)
|
|
require.Equal(t, 0, errs.Page)
|
|
require.Equal(t, "IMAGE-BUILDER-COMPOSER-401", errs.Items[0].Code)
|
|
errs = APIErrorList(1, 10, ctx)
|
|
require.Equal(t, 10, errs.Size)
|
|
require.Equal(t, len(getServiceErrors()), errs.Total)
|
|
require.Equal(t, 1, errs.Page)
|
|
require.Equal(t, "IMAGE-BUILDER-COMPOSER-11", errs.Items[0].Code)
|
|
|
|
// high page
|
|
errs = APIErrorList(1000, 1, ctx)
|
|
require.Equal(t, 0, errs.Size)
|
|
require.Equal(t, len(getServiceErrors()), errs.Total)
|
|
require.Equal(t, 1000, errs.Page)
|
|
|
|
// zero pagesize
|
|
errs = APIErrorList(1000, 0, ctx)
|
|
require.Equal(t, 0, errs.Size)
|
|
require.Equal(t, len(getServiceErrors()), errs.Total)
|
|
require.Equal(t, 1000, errs.Page)
|
|
}
|
|
|
|
func TestHTTPErrorHandler(t *testing.T) {
|
|
e := echo.New()
|
|
|
|
// HTTPError
|
|
{
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.Set("operationID", "opid")
|
|
HTTPErrorHandler(HTTPError(ErrorEnqueueingJob), c)
|
|
require.Equal(t, find(ErrorEnqueueingJob).httpStatus, rec.Code)
|
|
var apiErr Error
|
|
require.NoError(t, json.NewDecoder(rec.Body).Decode(&apiErr))
|
|
require.NotNil(t, apiErr)
|
|
require.Equal(t, "opid", apiErr.OperationId)
|
|
require.Equal(t, find(ErrorEnqueueingJob).reason, apiErr.Reason)
|
|
require.Empty(t, apiErr.Details)
|
|
}
|
|
|
|
// HTTPErrorWithInternal
|
|
{
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.Set("operationID", "opid")
|
|
err := fmt.Errorf("some more details")
|
|
HTTPErrorHandler(HTTPErrorWithInternal(ErrorEnqueueingJob, err), c)
|
|
require.Equal(t, find(ErrorEnqueueingJob).httpStatus, rec.Code)
|
|
var apiErr Error
|
|
require.NoError(t, json.NewDecoder(rec.Body).Decode(&apiErr))
|
|
require.NotNil(t, apiErr)
|
|
require.Equal(t, "opid", apiErr.OperationId)
|
|
require.Equal(t, find(ErrorEnqueueingJob).reason, apiErr.Reason)
|
|
require.Equal(t, err.Error(), apiErr.Details)
|
|
}
|
|
|
|
// HTTPErrorWithDetails
|
|
// internalErr gets ignored for explicit details
|
|
{
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.Set("operationID", "opid")
|
|
err := fmt.Errorf("some more details")
|
|
HTTPErrorHandler(HTTPErrorWithDetails(ErrorEnqueueingJob, err, "even more extra details"), c)
|
|
require.Equal(t, find(ErrorEnqueueingJob).httpStatus, rec.Code)
|
|
var apiErr Error
|
|
require.NoError(t, json.NewDecoder(rec.Body).Decode(&apiErr))
|
|
require.NotNil(t, apiErr)
|
|
require.Equal(t, "opid", apiErr.OperationId)
|
|
require.Equal(t, find(ErrorEnqueueingJob).reason, apiErr.Reason)
|
|
require.Equal(t, "even more extra details", apiErr.Details)
|
|
}
|
|
|
|
// echo.HTTPError
|
|
{
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.Set("operationID", "opid")
|
|
err := fmt.Errorf("some unexpected internal http error")
|
|
HTTPErrorHandler(echo.NewHTTPError(http.StatusInternalServerError, err), c)
|
|
require.Equal(t, find(ErrorUnspecified).httpStatus, rec.Code)
|
|
var apiErr Error
|
|
require.NoError(t, json.NewDecoder(rec.Body).Decode(&apiErr))
|
|
require.NotNil(t, apiErr)
|
|
require.Equal(t, "opid", apiErr.OperationId)
|
|
require.Equal(t, find(ErrorUnspecified).reason, apiErr.Reason)
|
|
require.Equal(t, "code=500, message=some unexpected internal http error", apiErr.Details)
|
|
}
|
|
|
|
// echo.HTTPError and internalErr is nil
|
|
{
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.Set("operationID", "opid")
|
|
HTTPErrorHandler(echo.NewHTTPError(http.StatusInternalServerError, nil), c)
|
|
require.Equal(t, find(ErrorUnspecified).httpStatus, rec.Code)
|
|
var apiErr Error
|
|
require.NoError(t, json.NewDecoder(rec.Body).Decode(&apiErr))
|
|
require.NotNil(t, apiErr)
|
|
require.Equal(t, "opid", apiErr.OperationId)
|
|
require.Equal(t, find(ErrorUnspecified).reason, apiErr.Reason)
|
|
require.Equal(t, "code=500, message=<nil>", apiErr.Details)
|
|
}
|
|
|
|
// plain error
|
|
{
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.Set("operationID", "opid")
|
|
err := fmt.Errorf("some unexpected internal error")
|
|
HTTPErrorHandler(err, c)
|
|
require.Equal(t, find(ErrorNotHTTPError).httpStatus, rec.Code)
|
|
var apiErr Error
|
|
require.NoError(t, json.NewDecoder(rec.Body).Decode(&apiErr))
|
|
require.NotNil(t, apiErr)
|
|
require.Equal(t, "opid", apiErr.OperationId)
|
|
require.Equal(t, find(ErrorNotHTTPError).reason, apiErr.Reason)
|
|
require.Equal(t, "some unexpected internal error", apiErr.Details)
|
|
}
|
|
}
|