You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
2.3 KiB
Go

package httputil
// Tests for HTTP error mapping and response payloads.
import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/require"
errorspkg "knowfoolery/backend/shared/domain/errors"
)
// TestMapError verifies domain error codes map to HTTP status codes and response codes.
func TestMapError(t *testing.T) {
cases := []struct {
name string
err error
statusCode int
code string
}{
{"nil", nil, http.StatusInternalServerError, "INTERNAL"},
{"not_found", errorspkg.Wrap(errorspkg.CodeNotFound, "missing", nil), http.StatusNotFound, "NOT_FOUND"},
{"invalid", errorspkg.Wrap(errorspkg.CodeInvalidInput, "bad", nil), http.StatusBadRequest, "INVALID_INPUT"},
{"unauthorized", errorspkg.Wrap(errorspkg.CodeUnauthorized, "no", nil), http.StatusUnauthorized, "UNAUTHORIZED"},
{"forbidden", errorspkg.Wrap(errorspkg.CodeForbidden, "no", nil), http.StatusForbidden, "FORBIDDEN"},
{"conflict", errorspkg.Wrap(errorspkg.CodeConflict, "conflict", nil), http.StatusConflict, "CONFLICT"},
{"rate_limit", errorspkg.Wrap(errorspkg.CodeRateLimitExceeded, "slow", nil),
http.StatusTooManyRequests, "RATE_LIMIT_EXCEEDED"},
{"gone", errorspkg.Wrap(errorspkg.CodeSessionExpired, "gone", nil), http.StatusGone, "SESSION_EXPIRED"},
{"unprocessable", errorspkg.Wrap(errorspkg.CodeMaxAttemptsReached, "max", nil),
http.StatusUnprocessableEntity, "MAX_ATTEMPTS_REACHED"},
{"generic", errors.New("boom"), http.StatusInternalServerError, "INTERNAL"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
status, resp := MapError(tc.err)
require.Equal(t, tc.statusCode, status)
require.Equal(t, tc.code, resp.Code)
})
}
}
// TestSendError verifies SendError writes the correct status and payload.
func TestSendError(t *testing.T) {
app := fiber.New()
app.Get("/", func(c fiber.Ctx) error {
return SendError(c, errorspkg.ErrNotFound)
})
req := httptest.NewRequest(http.MethodGet, "/", nil)
resp, err := app.Test(req)
require.NoError(t, err)
defer resp.Body.Close()
require.Equal(t, http.StatusNotFound, resp.StatusCode)
var body ErrorResponse
require.NoError(t, json.NewDecoder(resp.Body).Decode(&body))
require.Equal(t, "NOT_FOUND", body.Code)
}