chat_back_go/internal/service/auth_test.go

226 lines
6.4 KiB
Go

package service
import (
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"net/http"
"testing"
"git.urec56.ru/urec/chat_back_go/config"
"git.urec56.ru/urec/chat_back_go/internal/domain"
"git.urec56.ru/urec/chat_back_go/internal/logger"
mock_service "git.urec56.ru/urec/chat_back_go/internal/service/mocks"
)
func Test_newAuthService(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
cfg := config.JWT{}
log := logger.NewLogger(config.Config{Mode: "TEST"})
serv := newAuthService(cfg, log)
assert.Equal(t, &authService{cfg: cfg, parser: jwt.NewParser(), l: log}, serv)
}
func TestAuthService_keyFunc(t *testing.T) {
testTable := []struct {
name string
token *jwt.Token
cfgSecretKey []byte
expectedKey any
expectedErr error
}{
{
name: "ok_1",
cfgSecretKey: []byte("secretKey"),
expectedKey: []byte("secretKey"),
},
{
name: "ok_2",
cfgSecretKey: []byte("another_secretKey"),
expectedKey: []byte("another_secretKey"),
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
serv := &authService{cfg: config.JWT{SecretKey: tc.cfgSecretKey}}
key, err := serv.keyFunc(tc.token)
assert.Equal(t, tc.expectedKey, key)
assert.Equal(t, tc.expectedErr, err)
})
}
}
func TestAuthService_ExtractAuthToken(t *testing.T) {
testTable := []struct {
name string
req *http.Request
reqHeader string
reqToken string
isError bool
expectedToken string
}{
{
name: "ok_1",
req: &http.Request{Header: http.Header{}},
reqHeader: "Authorization",
reqToken: "Bearer 123",
expectedToken: "123",
},
{
name: "ok_2",
req: &http.Request{Header: http.Header{}},
reqHeader: "authorization",
reqToken: "bearer 123",
expectedToken: "123",
},
{
name: "incorrect_header",
req: &http.Request{Header: http.Header{}},
reqToken: "Bearer 123",
isError: true,
},
{
name: "incorrect_token_prefix",
req: &http.Request{Header: http.Header{}},
reqHeader: "authorization",
reqToken: "Beaer 123",
isError: true,
},
{
name: "incorrect_token",
req: &http.Request{Header: http.Header{}},
reqHeader: "authorization",
reqToken: "Bearer",
isError: true,
},
{
name: "incorrect_token_length",
req: &http.Request{Header: http.Header{}},
reqHeader: "authorization",
reqToken: "123",
isError: true,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
tc.req.Header.Set(tc.reqHeader, tc.reqToken)
auth := newAuthService(config.JWT{}, &logger.Logger{})
token, err := auth.ExtractAuthToken(tc.req)
assert.Equal(t, tc.expectedToken, token)
assert.Equal(t, tc.isError, err != nil)
})
}
}
func TestAuthService_DecodeAuthToken(t *testing.T) {
type parserBehavior func(p *mock_service.MockParser, token string, keyFunc jwt.Keyfunc, jwtToken *jwt.Token, err error)
type jwtTokenConstructor func(claims Claims) *jwt.Token
type claimsBehavior func(c *mock_service.MockClaims, subject string, err error)
testTable := []struct {
name string
parserBehavior parserBehavior
claimsBehavior claimsBehavior
jwtTokenConstructor jwtTokenConstructor
parserToken string
parserErr error
claimsUserID string
claimsErr error
secretKey []byte
keyFuncErr error
expectedUserID int
expectedErr error
}{
{
name: "ok",
parserBehavior: func(p *mock_service.MockParser, token string, keyFunc jwt.Keyfunc, jwtToken *jwt.Token, err error) {
p.EXPECT().Parse(token, gomock.Any()).Return(jwtToken, err)
},
claimsBehavior: func(c *mock_service.MockClaims, subject string, err error) {
c.EXPECT().GetSubject().Return(subject, err)
},
jwtTokenConstructor: func(claims Claims) *jwt.Token {
return &jwt.Token{Claims: claims}
},
parserToken: "token",
claimsUserID: "1",
secretKey: []byte("secret_key"),
expectedUserID: 1,
},
{
name: "parser_error",
parserBehavior: func(p *mock_service.MockParser, token string, keyFunc jwt.Keyfunc, jwtToken *jwt.Token, err error) {
p.EXPECT().Parse(token, gomock.Any()).Return(jwtToken, err)
},
claimsBehavior: func(c *mock_service.MockClaims, subject string, err error) {},
jwtTokenConstructor: func(claims Claims) *jwt.Token { return &jwt.Token{} },
parserToken: "token",
parserErr: domain.AnyError,
expectedErr: domain.TokenError,
},
{
name: "claims_error",
parserBehavior: func(p *mock_service.MockParser, token string, keyFunc jwt.Keyfunc, jwtToken *jwt.Token, err error) {
p.EXPECT().Parse(token, gomock.Any()).Return(jwtToken, err)
},
claimsBehavior: func(c *mock_service.MockClaims, subject string, err error) {
c.EXPECT().GetSubject().Return(subject, err)
},
jwtTokenConstructor: func(claims Claims) *jwt.Token {
return &jwt.Token{Claims: claims}
},
parserToken: "token",
secretKey: []byte("secret_key"),
claimsErr: domain.AnyError,
expectedErr: domain.TokenError,
},
{
name: "incorrect_id",
parserBehavior: func(p *mock_service.MockParser, token string, keyFunc jwt.Keyfunc, jwtToken *jwt.Token, err error) {
p.EXPECT().Parse(token, gomock.Any()).Return(jwtToken, err)
},
claimsBehavior: func(c *mock_service.MockClaims, subject string, err error) {
c.EXPECT().GetSubject().Return(subject, err)
},
jwtTokenConstructor: func(claims Claims) *jwt.Token {
return &jwt.Token{Claims: claims}
},
parserToken: "token",
claimsUserID: "not_number",
secretKey: []byte("secret_key"),
expectedErr: domain.TokenError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
parser := mock_service.NewMockParser(c)
claims := mock_service.NewMockClaims(c)
jwtToken := tc.jwtTokenConstructor(claims)
tc.claimsBehavior(claims, tc.claimsUserID, tc.claimsErr)
serv := &authService{cfg: config.JWT{SecretKey: tc.secretKey}, parser: parser}
tc.parserBehavior(parser, tc.parserToken, serv.keyFunc, jwtToken, tc.parserErr)
userID, err := serv.DecodeAuthToken(tc.parserToken)
assert.Equal(t, tc.expectedUserID, userID)
assert.Equal(t, tc.expectedErr, err)
})
}
}