Files

67 lines
2.0 KiB
Go

package middleware
import (
"bytes"
"encoding/json"
"mime/multipart"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/pocket-id/pocket-id/backend/internal/apperror"
"github.com/stretchr/testify/require"
)
func TestFileSizeLimitMiddlewareClassifiesMultipartErrors(t *testing.T) {
gin.SetMode(gin.TestMode)
t.Run("oversized body", func(t *testing.T) {
var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, err := writer.CreateFormFile("file", "large.png")
require.NoError(t, err)
_, err = part.Write(bytes.Repeat([]byte("x"), 128))
require.NoError(t, err)
require.NoError(t, writer.Close())
recorder := serveMultipartRequest(t, body.Bytes(), writer.FormDataContentType(), 64)
require.Equal(t, http.StatusRequestEntityTooLarge, recorder.Code)
require.Equal(t, apperror.CodeFileTooLarge, responseCode(t, recorder))
})
t.Run("malformed body", func(t *testing.T) {
recorder := serveMultipartRequest(t, []byte("not multipart"), "multipart/form-data; boundary=missing", 1024)
require.Equal(t, http.StatusBadRequest, recorder.Code)
require.Equal(t, apperror.CodeInvalidRequestBody, responseCode(t, recorder))
})
}
func serveMultipartRequest(t *testing.T, body []byte, contentType string, maxSize int64) *httptest.ResponseRecorder {
t.Helper()
router := gin.New()
router.Use(NewErrorHandlerMiddleware().Add())
router.POST("/", NewFileSizeLimitMiddleware().Add(maxSize), func(c *gin.Context) {
c.Status(http.StatusNoContent)
})
recorder := httptest.NewRecorder()
request := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/", bytes.NewReader(body))
request.Header.Set("Content-Type", contentType)
router.ServeHTTP(recorder, request)
return recorder
}
func responseCode(t *testing.T, recorder *httptest.ResponseRecorder) apperror.Code {
t.Helper()
var body struct {
Code apperror.Code `json:"code"`
}
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &body))
return body.Code
}