234 lines
5.9 KiB
Go
234 lines
5.9 KiB
Go
package util_test
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"mime"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"allaboutapps.dev/aw/go-starter/internal/api"
|
|
"allaboutapps.dev/aw/go-starter/internal/api/httperrors"
|
|
"allaboutapps.dev/aw/go-starter/internal/test"
|
|
"allaboutapps.dev/aw/go-starter/internal/types"
|
|
"allaboutapps.dev/aw/go-starter/internal/types/auth"
|
|
"allaboutapps.dev/aw/go-starter/internal/util"
|
|
"github.com/gabriel-vasile/mimetype"
|
|
"github.com/go-openapi/strfmt"
|
|
"github.com/go-openapi/strfmt/conv"
|
|
"github.com/go-openapi/swag"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestBindAndValidateSuccess(t *testing.T) {
|
|
e := echo.New()
|
|
//nolint:gosec
|
|
testToken := "a546daf5-c845-46a7-8fa6-3d94ae7e1424"
|
|
testResponse := &types.PostLoginResponse{
|
|
AccessToken: conv.UUID4(strfmt.UUID4("afbcbc30-4794-48bd-93f1-08373a031fe3")),
|
|
RefreshToken: conv.UUID4(strfmt.UUID4("1dd1228c-fa9a-4755-b995-30e24dd6247d")),
|
|
ExpiresIn: swag.Int64(3600),
|
|
TokenType: swag.String("Bearer"),
|
|
}
|
|
|
|
e.POST("/", func(c echo.Context) error {
|
|
testParam1 := auth.NewGetUserInfoRouteParams()
|
|
testParam2 := auth.NewPostForgotPasswordRouteParams()
|
|
var body types.PostRefreshPayload
|
|
|
|
err := util.BindAndValidate(c, &body, &testParam1, &testParam2)
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, body)
|
|
assert.Equal(t, strfmt.UUID4(testToken), *body.RefreshToken)
|
|
|
|
return util.ValidateAndReturn(c, 200, testResponse)
|
|
})
|
|
testBody := test.GenericPayload{
|
|
"refresh_token": testToken,
|
|
}
|
|
|
|
s := &api.Server{
|
|
Echo: e,
|
|
}
|
|
|
|
res := test.PerformRequest(t, s, "POST", "/?test=true", testBody, nil)
|
|
|
|
require.Equal(t, http.StatusOK, res.Result().StatusCode)
|
|
|
|
var response types.PostLoginResponse
|
|
test.ParseResponseAndValidate(t, res, &response)
|
|
|
|
assert.Equal(t, *testResponse, response)
|
|
}
|
|
|
|
func TestBindAndValidateBadRequest(t *testing.T) {
|
|
e := echo.New()
|
|
testToken := "foo"
|
|
|
|
e.POST("/", func(c echo.Context) error {
|
|
var body types.PostRefreshPayload
|
|
|
|
err := util.BindAndValidateBody(c, &body)
|
|
require.Error(t, err)
|
|
|
|
return nil
|
|
})
|
|
testBody := test.GenericPayload{
|
|
"refresh_token": testToken,
|
|
}
|
|
|
|
s := &api.Server{
|
|
Echo: e,
|
|
}
|
|
|
|
_ = test.PerformRequest(t, s, "POST", "/?test=true", testBody, nil)
|
|
}
|
|
|
|
func TestParseFileUplaod(t *testing.T) {
|
|
originalDocumentPath := filepath.Join(util.GetProjectRootDir(), "test", "testdata", "example.jpg")
|
|
body, contentType := prepareFileUpload(t, originalDocumentPath)
|
|
|
|
e := echo.New()
|
|
e.POST("/", func(c echo.Context) error {
|
|
fh, file, mime, err := util.ParseFileUpload(c, "file", []string{"image/jpeg"})
|
|
require.NoError(t, err)
|
|
assert.True(t, mime.Is("image/jpeg"))
|
|
assert.NotEmpty(t, fh)
|
|
assert.NotEmpty(t, file)
|
|
|
|
return c.NoContent(204)
|
|
})
|
|
|
|
s := &api.Server{
|
|
Echo: e,
|
|
}
|
|
|
|
headers := http.Header{}
|
|
headers.Set(echo.HeaderContentType, contentType)
|
|
|
|
res := test.PerformRequestWithRawBody(t, s, "POST", "/", body, headers, nil)
|
|
|
|
require.Equal(t, http.StatusNoContent, res.Result().StatusCode)
|
|
}
|
|
|
|
func TestParseFileUplaodUnsupported(t *testing.T) {
|
|
originalDocumentPath := filepath.Join(util.GetProjectRootDir(), "test", "testdata", "example.jpg")
|
|
body, contentType := prepareFileUpload(t, originalDocumentPath)
|
|
|
|
e := echo.New()
|
|
e.POST("/", func(c echo.Context) error {
|
|
fh, file, mime, err := util.ParseFileUpload(c, "file", []string{"image/png"})
|
|
assert.Nil(t, fh)
|
|
assert.Nil(t, file)
|
|
assert.Nil(t, mime)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return c.NoContent(204)
|
|
})
|
|
|
|
s := &api.Server{
|
|
Echo: e,
|
|
}
|
|
|
|
headers := http.Header{}
|
|
headers.Set(echo.HeaderContentType, contentType)
|
|
|
|
res := test.PerformRequestWithRawBody(t, s, "POST", "/", body, headers, nil)
|
|
require.Equal(t, http.StatusUnsupportedMediaType, res.Result().StatusCode)
|
|
}
|
|
|
|
func TestParseFileUplaodEmpty(t *testing.T) {
|
|
var body bytes.Buffer
|
|
writer := multipart.NewWriter(&body)
|
|
|
|
_, err := writer.CreateFormFile("file", filepath.Base("example.txt"))
|
|
require.NoError(t, err)
|
|
|
|
err = writer.Close()
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
e.POST("/", func(c echo.Context) error {
|
|
fh, file, mime, err := util.ParseFileUpload(c, "file", []string{"text/plain"})
|
|
assert.Nil(t, fh)
|
|
assert.Nil(t, file)
|
|
assert.Nil(t, mime)
|
|
assert.Equal(t, httperrors.ErrBadRequestZeroFileSize, err)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse file upload: %w", err)
|
|
}
|
|
|
|
return c.NoContent(204)
|
|
})
|
|
|
|
s := &api.Server{
|
|
Echo: e,
|
|
}
|
|
|
|
headers := http.Header{}
|
|
headers.Set(echo.HeaderContentType, writer.FormDataContentType())
|
|
|
|
test.PerformRequestWithRawBody(t, s, "POST", "/", &body, headers, nil)
|
|
}
|
|
|
|
func prepareFileUpload(t *testing.T, filePath string) (*bytes.Buffer, string) {
|
|
t.Helper()
|
|
|
|
var body bytes.Buffer
|
|
writer := multipart.NewWriter(&body)
|
|
|
|
src, err := os.Open(filePath)
|
|
require.NoError(t, err)
|
|
defer src.Close()
|
|
|
|
dst, err := writer.CreateFormFile("file", filepath.Base(src.Name()))
|
|
require.NoError(t, err)
|
|
|
|
_, err = io.Copy(dst, src)
|
|
require.NoError(t, err)
|
|
|
|
err = writer.Close()
|
|
require.NoError(t, err)
|
|
|
|
return &body, writer.FormDataContentType()
|
|
}
|
|
|
|
func TestStreamFile(t *testing.T) {
|
|
filename := "file_with_special_characters_🎉_س_.vcf"
|
|
|
|
e := echo.New()
|
|
e.GET("/files", func(c echo.Context) error {
|
|
path := filepath.Join(util.GetProjectRootDir(), "test", "testdata", "example.jpg")
|
|
|
|
mediaType, err := mimetype.DetectFile(path)
|
|
require.NoError(t, err)
|
|
|
|
file, err := os.Open(path)
|
|
require.NoError(t, err)
|
|
|
|
return util.StreamFile(c, http.StatusOK, mediaType.String(), filename, file)
|
|
})
|
|
|
|
s := &api.Server{Echo: e}
|
|
|
|
res := test.PerformRequest(t, s, "GET", "/files", nil, nil)
|
|
require.Equal(t, http.StatusOK, res.Result().StatusCode)
|
|
|
|
mediaType, params, err := mime.ParseMediaType(res.Header().Get(echo.HeaderContentDisposition))
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "attachment", mediaType)
|
|
assert.Equal(t, filename, params["filename"])
|
|
|
|
contentType := res.Header().Get(echo.HeaderContentType)
|
|
assert.Equal(t, "image/jpeg", contentType)
|
|
}
|