chat_back_go/internal/service/users_test.go

357 lines
11 KiB
Go

package service
import (
"errors"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"testing"
"time"
"git.urec56.ru/urec/chat_back_go/internal/domain"
mock_logger "git.urec56.ru/urec/chat_back_go/internal/logger/mocks"
mock_repository "git.urec56.ru/urec/chat_back_go/internal/repository/mocks"
mock_service "git.urec56.ru/urec/chat_back_go/internal/service/mocks"
)
func Test_newUserService(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockUser(c)
auth := mock_service.NewMockAuth(c)
log := mock_logger.NewMockLog(c)
serv := newUserService(repo, auth, log)
assert.Equal(t, &userService{ur: repo, auth: auth, l: log}, serv)
}
func TestUserService_Get(t *testing.T) {
type mockBehavior func(r *mock_repository.MockUser, userID int, user domain.User, err error)
testTable := []struct {
name string
mockBehavior mockBehavior
userID int
expectedUser domain.User
repoErr error
expectedErr error
}{
{
name: "ok",
mockBehavior: func(r *mock_repository.MockUser, userID int, user domain.User, err error) {
r.EXPECT().GetByID(userID).Return(user, err)
},
userID: 1,
expectedUser: domain.User{
ID: 1,
},
},
{
name: "user_not_found",
mockBehavior: func(r *mock_repository.MockUser, userID int, user domain.User, err error) {
r.EXPECT().GetByID(userID).Return(user, err)
},
repoErr: domain.UserNotFoundError,
expectedErr: domain.UserNotFoundError,
},
{
name: "internal_error",
mockBehavior: func(r *mock_repository.MockUser, userID int, user domain.User, err error) {
r.EXPECT().GetByID(userID).Return(user, err)
},
repoErr: domain.InternalServerError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockUser(c)
serv := userService{ur: repo}
tc.mockBehavior(repo, tc.userID, tc.expectedUser, tc.repoErr)
u, err := serv.Get(tc.userID)
assert.Equal(t, tc.expectedUser, u)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestUserService_GetVerificated(t *testing.T) {
type mockBehavior func(r *mock_repository.MockUser, userID int, user domain.User, err error)
testTable := []struct {
name string
mockBehavior mockBehavior
userID int
expectedUser domain.User
repoErr error
expectedErr error
}{
{
name: "ok",
mockBehavior: func(r *mock_repository.MockUser, userID int, user domain.User, err error) {
r.EXPECT().GetByID(userID).Return(user, err)
},
userID: 1,
expectedUser: domain.User{
ID: 1,
Role: domain.VerificatedUser,
},
},
{
name: "user_not_found",
mockBehavior: func(r *mock_repository.MockUser, userID int, user domain.User, err error) {
r.EXPECT().GetByID(userID).Return(user, err)
},
userID: 1,
repoErr: domain.UserNotFoundError,
expectedErr: domain.UserNotFoundError,
},
{
name: "user_unverified",
mockBehavior: func(r *mock_repository.MockUser, userID int, user domain.User, err error) {
r.EXPECT().GetByID(userID).Return(user, err)
},
userID: 1,
expectedUser: domain.User{
ID: 1,
Role: domain.UnverifiedUser,
},
expectedErr: domain.UnverifiedUserError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockUser(c)
serv := userService{ur: repo}
tc.mockBehavior(repo, tc.userID, tc.expectedUser, tc.repoErr)
u, err := serv.GetVerificated(tc.userID)
assert.Equal(t, tc.expectedUser, u)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestUserService_GetAll(t *testing.T) {
type mockBehavior func(r *mock_repository.MockUser, username string, users []domain.User, err error)
testTable := []struct {
name string
mockBehavior mockBehavior
username string
expectedUsers []domain.User
repoErr error
expectedErr error
}{
{
name: "ok",
mockBehavior: func(r *mock_repository.MockUser, username string, users []domain.User, err error) {
r.EXPECT().GetAll(username).Return(users, err)
},
expectedUsers: []domain.User{
{ID: 1},
},
},
{
name: "internal_error",
mockBehavior: func(r *mock_repository.MockUser, username string, users []domain.User, err error) {
r.EXPECT().GetAll(username).Return(users, err)
},
repoErr: domain.InternalServerError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockUser(c)
serv := userService{ur: repo}
tc.mockBehavior(repo, tc.username, tc.expectedUsers, tc.repoErr)
u, err := serv.GetAll(tc.username)
assert.Equal(t, tc.expectedUsers, u)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestUserService_FindOne(t *testing.T) {
type mockBehavior func(r *mock_repository.MockUser, username, email string, user domain.User, err error)
testTable := []struct {
name string
mockBehavior mockBehavior
username string
email string
expectedUser domain.User
repoErr error
expectedErr error
}{
{
name: "ok",
mockBehavior: func(r *mock_repository.MockUser, username, email string, user domain.User, err error) {
r.EXPECT().FindOne(username, email).Return(user, err)
},
expectedUser: domain.User{
ID: 1,
Role: domain.UnverifiedUser,
},
},
{
name: "any_error",
mockBehavior: func(r *mock_repository.MockUser, username, email string, user domain.User, err error) {
r.EXPECT().FindOne(username, email).Return(user, err)
},
repoErr: errors.New("some error"),
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockUser(c)
serv := userService{ur: repo}
tc.mockBehavior(repo, tc.username, tc.email, tc.expectedUser, tc.repoErr)
u, err := serv.FindOne(tc.username, tc.email)
assert.Equal(t, tc.expectedUser, u)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestUserService_Register(t *testing.T) {
type hashMockBehavior func(s *mock_service.MockAuth, p, hp string, err error)
type repoMockBehavior func(r *mock_repository.MockUser, email, hp, username string, dateOfBirth time.Time, user domain.User, err error)
type encodeMockBehavior func(s *mock_service.MockAuth, userID int, token string, err error)
testTable := []struct {
name string
hashMockBehavior hashMockBehavior
repoMockBehavior repoMockBehavior
encodeMockBehavior encodeMockBehavior
ud domain.UserRegister
hp string
repoUser domain.User
hashErr error
repoErr error
encodeErr error
expectedToken string
expectedErr error
}{
{
name: "ok",
hashMockBehavior: func(s *mock_service.MockAuth, p, hp string, err error) {
s.EXPECT().HashPassword(p).Return(hp, err)
},
repoMockBehavior: func(r *mock_repository.MockUser, email, hp, username string, dateOfBirth time.Time, user domain.User, err error) {
r.EXPECT().Register(email, hp, username, dateOfBirth).Return(user, err)
},
encodeMockBehavior: func(s *mock_service.MockAuth, userID int, token string, err error) {
s.EXPECT().EncodeAuthToken(userID).Return(token, err)
},
ud: domain.UserRegister{
Email: "mail@mail.ru",
Username: "username",
Password: "pass",
},
hp: "hp",
repoUser: domain.User{ID: 1},
expectedToken: "token",
},
{
name: "user_already_exists",
hashMockBehavior: func(s *mock_service.MockAuth, p, hp string, err error) {
s.EXPECT().HashPassword(p).Return(hp, err)
},
repoMockBehavior: func(r *mock_repository.MockUser, email, hp, username string, dateOfBirth time.Time, user domain.User, err error) {
r.EXPECT().Register(email, hp, username, dateOfBirth).Return(user, err)
},
encodeMockBehavior: func(s *mock_service.MockAuth, userID int, token string, err error) {},
repoErr: domain.UserAlreadyExistsError,
expectedErr: domain.UserAlreadyExistsError,
},
{
name: "hash_failed",
hashMockBehavior: func(s *mock_service.MockAuth, p, hp string, err error) {
s.EXPECT().HashPassword(p).Return(hp, err)
},
repoMockBehavior: func(r *mock_repository.MockUser, email, hp, username string, dateOfBirth time.Time, user domain.User, err error) {
},
encodeMockBehavior: func(s *mock_service.MockAuth, userID int, token string, err error) {},
hashErr: errors.New("some error"),
expectedErr: domain.InternalServerError,
},
{
name: "db_error",
hashMockBehavior: func(s *mock_service.MockAuth, p, hp string, err error) {
s.EXPECT().HashPassword(p).Return(hp, err)
},
repoMockBehavior: func(r *mock_repository.MockUser, email, hp, username string, dateOfBirth time.Time, user domain.User, err error) {
r.EXPECT().Register(email, hp, username, dateOfBirth).Return(user, err)
},
encodeMockBehavior: func(s *mock_service.MockAuth, userID int, token string, err error) {},
repoErr: errors.New("some error"),
expectedErr: domain.InternalServerError,
},
{
name: "token_encoding_error",
hashMockBehavior: func(s *mock_service.MockAuth, p, hp string, err error) {
s.EXPECT().HashPassword(p).Return(hp, err)
},
repoMockBehavior: func(r *mock_repository.MockUser, email, hp, username string, dateOfBirth time.Time, user domain.User, err error) {
r.EXPECT().Register(email, hp, username, dateOfBirth).Return(user, err)
},
encodeMockBehavior: func(s *mock_service.MockAuth, userID int, token string, err error) {
s.EXPECT().EncodeAuthToken(userID).Return(token, err)
},
encodeErr: errors.New("some error"),
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockUser(c)
auth := mock_service.NewMockAuth(c)
log := mock_logger.NewMockLog(c)
serv := userService{ur: repo, auth: auth, l: log}
tc.hashMockBehavior(auth, tc.ud.Password, tc.hp, tc.hashErr)
tc.repoMockBehavior(repo, tc.ud.Email, tc.hp, tc.ud.Username, tc.ud.DateOfBirth.Time, tc.repoUser, tc.repoErr)
tc.encodeMockBehavior(auth, tc.repoUser.ID, tc.expectedToken, tc.encodeErr)
token, err := serv.Register(tc.ud)
assert.Equal(t, tc.expectedToken, token)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}