359 lines
13 KiB
Go
359 lines
13 KiB
Go
package middleware
|
|
|
|
import (
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/mock/gomock"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.urec56.ru/urec/chat_back_go/internal/domain"
|
|
mock_logger "git.urec56.ru/urec/chat_back_go/internal/logger/mocks"
|
|
mock_service "git.urec56.ru/urec/chat_back_go/internal/service/mocks"
|
|
)
|
|
|
|
func TestMiddleware_Auth(t *testing.T) {
|
|
type extractBehavior func(s *mock_service.MockServ, r *http.Request, token string, err error)
|
|
type decodeBehavior func(s *mock_service.MockServ, token string, userID int, err error)
|
|
type getBehavior func(s *mock_service.MockServ, userID int, user domain.User, err error)
|
|
type logBehavior func(l *mock_logger.MockLog, path string, err error)
|
|
|
|
testTable := []struct {
|
|
name string
|
|
extractBehavior extractBehavior
|
|
decodeBehavior decodeBehavior
|
|
getBehavior getBehavior
|
|
logBehavior logBehavior
|
|
reqToken string
|
|
extractToken string
|
|
extractErr error
|
|
decodeUserID int
|
|
decodeErr error
|
|
getUser domain.User
|
|
getErr error
|
|
logErr error
|
|
expectedUser domain.User
|
|
expectedStatusCode int
|
|
}{
|
|
{
|
|
name: "ok",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {
|
|
s.EXPECT().Get(userID).Return(user, err)
|
|
},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {},
|
|
reqToken: "Bearer token",
|
|
extractToken: "token",
|
|
decodeUserID: 1,
|
|
getUser: domain.User{
|
|
ID: 1,
|
|
Role: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
HashedPassword: "hp",
|
|
AvatarImage: "image",
|
|
BlackPhoenix: true,
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
expectedUser: domain.User{
|
|
ID: 1,
|
|
Role: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
HashedPassword: "hp",
|
|
AvatarImage: "image",
|
|
BlackPhoenix: true,
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
expectedStatusCode: http.StatusOK,
|
|
},
|
|
{
|
|
name: "user_not_found",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {
|
|
s.EXPECT().Get(userID).Return(user, err)
|
|
},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {},
|
|
reqToken: "Bearer token",
|
|
extractToken: "token",
|
|
getErr: domain.UserNotFoundError,
|
|
expectedStatusCode: http.StatusNotFound,
|
|
},
|
|
{
|
|
name: "extract_error",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {
|
|
l.EXPECT().Infof("[%s] error extracting token: %s", path, err.Error())
|
|
},
|
|
extractErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusUnauthorized,
|
|
},
|
|
{
|
|
name: "decode_error",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {
|
|
l.EXPECT().Infof("[%s] error decoding token: %s", path, err.Error())
|
|
},
|
|
decodeErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusUnauthorized,
|
|
},
|
|
{
|
|
name: "get_error",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {
|
|
s.EXPECT().Get(userID).Return(user, err)
|
|
},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {
|
|
l.EXPECT().Infof("[%s] error resolving user: %s", path, err.Error())
|
|
},
|
|
getErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testTable {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := mock_logger.NewMockLog(c)
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
reqPath := "/"
|
|
req := httptest.NewRequest(http.MethodGet, reqPath, nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
req.Header.Set("Authorization", tc.reqToken)
|
|
|
|
tc.extractBehavior(serv, req, tc.extractToken, tc.extractErr)
|
|
tc.decodeBehavior(serv, tc.extractToken, tc.decodeUserID, tc.decodeErr)
|
|
tc.getBehavior(serv, tc.decodeUserID, tc.getUser, tc.getErr)
|
|
tc.logBehavior(log, reqPath, tc.logErr)
|
|
|
|
m := &Middleware{serv: serv, l: log}
|
|
|
|
server := m.Auth(func(w http.ResponseWriter, r *http.Request) {
|
|
u := r.Context().Value("user")
|
|
|
|
assert.Equal(t, tc.expectedUser, u)
|
|
})
|
|
server.ServeHTTP(w, req)
|
|
|
|
resp := w.Result()
|
|
|
|
assert.Equal(t, tc.expectedStatusCode, resp.StatusCode)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMiddleware_VerificatedAuth(t *testing.T) {
|
|
type extractBehavior func(s *mock_service.MockServ, r *http.Request, token string, err error)
|
|
type decodeBehavior func(s *mock_service.MockServ, token string, userID int, err error)
|
|
type getBehavior func(s *mock_service.MockServ, userID int, user domain.User, err error)
|
|
type logBehavior func(l *mock_logger.MockLog, path string, err error)
|
|
|
|
testTable := []struct {
|
|
name string
|
|
extractBehavior extractBehavior
|
|
decodeBehavior decodeBehavior
|
|
getBehavior getBehavior
|
|
logBehavior logBehavior
|
|
reqToken string
|
|
extractToken string
|
|
extractErr error
|
|
decodeUserID int
|
|
decodeErr error
|
|
getUser domain.User
|
|
getErr error
|
|
logErr error
|
|
expectedUser domain.User
|
|
expectedStatusCode int
|
|
}{
|
|
{
|
|
name: "ok",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {
|
|
s.EXPECT().GetVerificated(userID).Return(user, err)
|
|
},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {},
|
|
reqToken: "Bearer token",
|
|
extractToken: "token",
|
|
decodeUserID: 1,
|
|
getUser: domain.User{
|
|
ID: 1,
|
|
Role: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
HashedPassword: "hp",
|
|
AvatarImage: "image",
|
|
BlackPhoenix: true,
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
expectedUser: domain.User{
|
|
ID: 1,
|
|
Role: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
HashedPassword: "hp",
|
|
AvatarImage: "image",
|
|
BlackPhoenix: true,
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
expectedStatusCode: http.StatusOK,
|
|
},
|
|
{
|
|
name: "unverified_user",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {
|
|
s.EXPECT().GetVerificated(userID).Return(user, err)
|
|
},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {},
|
|
reqToken: "Bearer token",
|
|
extractToken: "token",
|
|
getErr: domain.UnverifiedUserError,
|
|
expectedStatusCode: http.StatusConflict,
|
|
},
|
|
{
|
|
name: "user_not_found",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {
|
|
s.EXPECT().GetVerificated(userID).Return(user, err)
|
|
},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {},
|
|
reqToken: "Bearer token",
|
|
extractToken: "token",
|
|
getErr: domain.UserNotFoundError,
|
|
expectedStatusCode: http.StatusNotFound,
|
|
},
|
|
{
|
|
name: "extract_error",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {
|
|
l.EXPECT().Infof("[%s] error extracting token: %s", path, err.Error())
|
|
},
|
|
extractErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusUnauthorized,
|
|
},
|
|
{
|
|
name: "decode_error",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {
|
|
l.EXPECT().Infof("[%s] error decoding token: %s", path, err.Error())
|
|
},
|
|
decodeErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusUnauthorized,
|
|
},
|
|
{
|
|
name: "get_error",
|
|
extractBehavior: func(s *mock_service.MockServ, r *http.Request, token string, err error) {
|
|
s.EXPECT().ExtractAuthToken(r).Return(token, err)
|
|
},
|
|
decodeBehavior: func(s *mock_service.MockServ, token string, userID int, err error) {
|
|
s.EXPECT().DecodeAuthToken(token).Return(userID, err)
|
|
},
|
|
getBehavior: func(s *mock_service.MockServ, userID int, user domain.User, err error) {
|
|
s.EXPECT().GetVerificated(userID).Return(user, err)
|
|
},
|
|
logBehavior: func(l *mock_logger.MockLog, path string, err error) {
|
|
l.EXPECT().Infof("[%s] error resolving user: %s", path, err.Error())
|
|
},
|
|
getErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testTable {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := mock_logger.NewMockLog(c)
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
reqPath := "/"
|
|
req := httptest.NewRequest(http.MethodGet, reqPath, nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
req.Header.Set("Authorization", tc.reqToken)
|
|
|
|
tc.extractBehavior(serv, req, tc.extractToken, tc.extractErr)
|
|
tc.decodeBehavior(serv, tc.extractToken, tc.decodeUserID, tc.decodeErr)
|
|
tc.getBehavior(serv, tc.decodeUserID, tc.getUser, tc.getErr)
|
|
tc.logBehavior(log, reqPath, tc.logErr)
|
|
|
|
m := &Middleware{serv: serv, l: log}
|
|
|
|
server := m.VerificatedAuth(func(w http.ResponseWriter, r *http.Request) {
|
|
u := r.Context().Value("user")
|
|
|
|
assert.Equal(t, tc.expectedUser, u)
|
|
})
|
|
server.ServeHTTP(w, req)
|
|
|
|
resp := w.Result()
|
|
|
|
assert.Equal(t, tc.expectedStatusCode, resp.StatusCode)
|
|
})
|
|
}
|
|
}
|