Files
api_tmpl/internal/handlers/http/middleware_test.go
T
2026-01-08 01:15:07 +00:00

115 lines
3.5 KiB
Go

package api
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/FernandoJVideira/simple_bank/internal/auth"
"github.com/FernandoJVideira/simple_bank/internal/domain/role"
mocksvc "github.com/FernandoJVideira/simple_bank/internal/service/mock"
"github.com/FernandoJVideira/simple_bank/pkg/testutil"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
)
func addAuth(t *testing.T, request *http.Request, tokenMaker auth.Maker, authType string, username string, role string, duration time.Duration) {
token, payload, err := tokenMaker.CreateToken(username, role, duration)
require.NoError(t, err)
require.NotEmpty(t, payload)
authorizationHeader := fmt.Sprintf("%s %s", authType, token)
request.Header.Set(authHeaderKey, authorizationHeader)
}
func TestAuthMiddleware(t *testing.T) {
username := testutil.RandomOwner()
testRole := role.MemberRole
testCases := []struct {
name string
setupAuth func(t *testing.T, request *http.Request, tokenMaker auth.Maker)
checkResponse func(t *testing.T, recorder *httptest.ResponseRecorder)
}{
{
name: "OK",
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
addAuth(t, request, tokenMaker, authTypeBearer, username, testRole, time.Minute)
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusOK, recorder.Code)
},
},
{
name: "NoAuthorization",
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
// Do not add any authorization header
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusUnauthorized, recorder.Code)
},
},
{
name: "UnsupportedAuthType",
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
addAuth(t, request, tokenMaker, "UnsupportedAuthType", username, testRole, time.Minute)
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusUnauthorized, recorder.Code)
},
},
{
name: "InvalidAuthFormat",
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
addAuth(t, request, tokenMaker, "", username, testRole, time.Minute)
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusUnauthorized, recorder.Code)
},
},
{
name: "ExpiredAtToken",
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
addAuth(t, request, tokenMaker, authTypeBearer, username, testRole, -time.Minute)
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusUnauthorized, recorder.Code)
},
},
}
for i := range testCases {
tc := testCases[i]
t.Run(tc.name, func(t *testing.T) {
authCtrl := gomock.NewController(t)
defer authCtrl.Finish()
authService := mocksvc.NewMockAuthService(authCtrl)
s := newTestServer(t, nil, nil, nil, authService)
authPath := "/auth"
s.router.GET(
authPath,
authMiddleware(s.tokenMaker, []string{role.AdminRole, role.MemberRole}),
func(ctx *gin.Context) {
ctx.JSON(200, gin.H{})
},
)
recorder := httptest.NewRecorder()
request, err := http.NewRequest(http.MethodGet, authPath, nil)
require.NoError(t, err)
tc.setupAuth(t, request, s.tokenMaker)
s.router.ServeHTTP(recorder, request)
tc.checkResponse(t, recorder)
})
}
}