348 lines
8.2 KiB
Go
348 lines
8.2 KiB
Go
package unit
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"wish-list-api/api/presenter"
|
|
"wish-list-api/pkg/auth"
|
|
"wish-list-api/pkg/entities"
|
|
"wish-list-api/pkg/user"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
)
|
|
|
|
var ErrUserNotFound = errors.New("user not found")
|
|
|
|
type MockUserRepository struct {
|
|
users map[string]*entities.User
|
|
email map[string]*entities.User
|
|
telegram map[int64]*entities.User
|
|
}
|
|
|
|
func NewMockUserRepository() user.Repository {
|
|
return &MockUserRepository{
|
|
users: make(map[string]*entities.User),
|
|
email: make(map[string]*entities.User),
|
|
telegram: make(map[int64]*entities.User),
|
|
}
|
|
}
|
|
|
|
func (r *MockUserRepository) CreateUser(user *entities.User) (*entities.User, error) {
|
|
if user.ID.IsZero() {
|
|
user.ID = primitive.NewObjectID()
|
|
}
|
|
user.CreatedAt = time.Now()
|
|
user.UpdatedAt = time.Now()
|
|
|
|
r.users[user.ID.Hex()] = user
|
|
r.email[user.Email] = user
|
|
if user.TelegramID != 0 {
|
|
r.telegram[user.TelegramID] = user
|
|
}
|
|
return user, nil
|
|
}
|
|
|
|
func (r *MockUserRepository) ReadUser(id string) (*entities.User, error) {
|
|
if user, ok := r.users[id]; ok {
|
|
return user, nil
|
|
}
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
func (r *MockUserRepository) ReadUserByEmail(email string) (*entities.User, error) {
|
|
if user, ok := r.email[email]; ok {
|
|
return user, nil
|
|
}
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
func (r *MockUserRepository) ReadAllUsers() (*[]presenter.User, error) {
|
|
var users []presenter.User
|
|
for _, u := range r.users {
|
|
users = append(users, presenter.User{
|
|
ID: u.ID,
|
|
Email: u.Email,
|
|
CreatedAt: u.CreatedAt,
|
|
UpdatedAt: u.UpdatedAt,
|
|
})
|
|
}
|
|
return &users, nil
|
|
}
|
|
|
|
func (r *MockUserRepository) UpdateUser(user *entities.User) (*entities.User, error) {
|
|
if _, ok := r.users[user.ID.Hex()]; !ok {
|
|
return nil, ErrUserNotFound
|
|
}
|
|
user.UpdatedAt = time.Now()
|
|
|
|
r.users[user.ID.Hex()] = user
|
|
|
|
for email, u := range r.email {
|
|
if u.ID == user.ID && email != user.Email {
|
|
delete(r.email, email)
|
|
break
|
|
}
|
|
}
|
|
r.email[user.Email] = user
|
|
|
|
if user.TelegramID != 0 {
|
|
r.telegram[user.TelegramID] = user
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (r *MockUserRepository) DeleteUser(id string) error {
|
|
user, ok := r.users[id]
|
|
if !ok {
|
|
return ErrUserNotFound
|
|
}
|
|
|
|
delete(r.users, id)
|
|
delete(r.email, user.Email)
|
|
if user.TelegramID != 0 {
|
|
delete(r.telegram, user.TelegramID)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *MockUserRepository) ReadUserByTelegramID(telegramID int64) (*entities.User, error) {
|
|
if user, ok := r.telegram[telegramID]; ok {
|
|
return user, nil
|
|
}
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
func (r *MockUserRepository) UpdateUserTelegramData(user *entities.User) (*entities.User, error) {
|
|
if _, ok := r.users[user.ID.Hex()]; !ok {
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
existingUser := r.users[user.ID.Hex()]
|
|
existingUser.TelegramID = user.TelegramID
|
|
existingUser.TelegramUsername = user.TelegramUsername
|
|
existingUser.FirstName = user.FirstName
|
|
existingUser.LastName = user.LastName
|
|
existingUser.PhotoURL = user.PhotoURL
|
|
existingUser.UpdatedAt = time.Now()
|
|
|
|
r.users[user.ID.Hex()] = existingUser
|
|
|
|
if user.TelegramID != 0 {
|
|
for tgID, u := range r.telegram {
|
|
if u.ID == user.ID && tgID != user.TelegramID {
|
|
delete(r.telegram, tgID)
|
|
break
|
|
}
|
|
}
|
|
r.telegram[user.TelegramID] = existingUser
|
|
}
|
|
|
|
return existingUser, nil
|
|
}
|
|
|
|
func TestRegister(t *testing.T) {
|
|
mockRepo := NewMockUserRepository()
|
|
mockUserService := user.NewService(mockRepo)
|
|
|
|
serviceConfig := auth.ServiceConfig{
|
|
UserService: mockUserService,
|
|
}
|
|
|
|
service := auth.NewService(serviceConfig)
|
|
|
|
t.Run("Register_Success", func(t *testing.T) {
|
|
userData := &entities.RegisterRequest{
|
|
Email: "test@example.com",
|
|
Password: "password123",
|
|
}
|
|
|
|
user, err := service.Register(userData)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, user)
|
|
assert.Equal(t, userData.Email, user.Email)
|
|
assert.NotEqual(t, userData.Password, user.Password)
|
|
})
|
|
|
|
t.Run("Register_DuplicateEmail", func(t *testing.T) {
|
|
userData := &entities.RegisterRequest{
|
|
Email: "test@example.com",
|
|
Password: "different_password",
|
|
}
|
|
|
|
user, err := service.Register(userData)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, user)
|
|
})
|
|
}
|
|
|
|
func TestLogin(t *testing.T) {
|
|
mockRepo := NewMockUserRepository()
|
|
mockUserService := user.NewService(mockRepo)
|
|
|
|
serviceConfig := auth.ServiceConfig{
|
|
UserService: mockUserService,
|
|
}
|
|
|
|
service := auth.NewService(serviceConfig)
|
|
|
|
registerData := &entities.RegisterRequest{
|
|
Email: "login_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
_, err := service.Register(registerData)
|
|
assert.NoError(t, err)
|
|
|
|
t.Run("Login_Success", func(t *testing.T) {
|
|
loginData := &entities.LoginRequest{
|
|
Email: "login_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
|
|
tokens, err := service.Login(loginData)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, tokens)
|
|
assert.NotEmpty(t, tokens.AccessToken)
|
|
assert.NotEmpty(t, tokens.RefreshToken)
|
|
})
|
|
|
|
t.Run("Login_InvalidEmail", func(t *testing.T) {
|
|
loginData := &entities.LoginRequest{
|
|
Email: "nonexistent@example.com",
|
|
Password: "password123",
|
|
}
|
|
|
|
tokens, err := service.Login(loginData)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, tokens)
|
|
})
|
|
|
|
t.Run("Login_InvalidPassword", func(t *testing.T) {
|
|
loginData := &entities.LoginRequest{
|
|
Email: "login_test@example.com",
|
|
Password: "wrong_password",
|
|
}
|
|
|
|
tokens, err := service.Login(loginData)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, tokens)
|
|
})
|
|
}
|
|
|
|
func TestRefreshToken(t *testing.T) {
|
|
mockRepo := NewMockUserRepository()
|
|
mockUserService := user.NewService(mockRepo)
|
|
|
|
serviceConfig := auth.ServiceConfig{
|
|
UserService: mockUserService,
|
|
}
|
|
|
|
service := auth.NewService(serviceConfig)
|
|
|
|
registerData := &entities.RegisterRequest{
|
|
Email: "refresh_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
_, err := service.Register(registerData)
|
|
assert.NoError(t, err)
|
|
|
|
loginData := &entities.LoginRequest{
|
|
Email: "refresh_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
tokens, err := service.Login(loginData)
|
|
assert.NoError(t, err)
|
|
|
|
t.Run("RefreshToken_Success", func(t *testing.T) {
|
|
newTokens, err := service.RefreshToken(tokens.RefreshToken)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, newTokens)
|
|
assert.NotEmpty(t, newTokens.AccessToken)
|
|
assert.NotEmpty(t, newTokens.RefreshToken)
|
|
})
|
|
|
|
t.Run("RefreshToken_Invalid", func(t *testing.T) {
|
|
newTokens, err := service.RefreshToken("invalid_refresh_token")
|
|
assert.Error(t, err)
|
|
assert.Nil(t, newTokens)
|
|
})
|
|
}
|
|
|
|
func TestValidateToken(t *testing.T) {
|
|
mockRepo := NewMockUserRepository()
|
|
mockUserService := user.NewService(mockRepo)
|
|
|
|
serviceConfig := auth.ServiceConfig{
|
|
UserService: mockUserService,
|
|
}
|
|
|
|
service := auth.NewService(serviceConfig)
|
|
|
|
registerData := &entities.RegisterRequest{
|
|
Email: "validate_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
_, err := service.Register(registerData)
|
|
assert.NoError(t, err)
|
|
|
|
loginData := &entities.LoginRequest{
|
|
Email: "validate_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
tokens, err := service.Login(loginData)
|
|
assert.NoError(t, err)
|
|
|
|
t.Run("ValidateToken_Success", func(t *testing.T) {
|
|
token, err := service.ValidateToken(tokens.AccessToken)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, token)
|
|
})
|
|
|
|
t.Run("ValidateToken_Invalid", func(t *testing.T) {
|
|
token, err := service.ValidateToken("invalid_token")
|
|
assert.Error(t, err)
|
|
assert.Nil(t, token)
|
|
})
|
|
}
|
|
|
|
func TestGetUserIDFromToken(t *testing.T) {
|
|
mockRepo := NewMockUserRepository()
|
|
mockUserService := user.NewService(mockRepo)
|
|
|
|
serviceConfig := auth.ServiceConfig{
|
|
UserService: mockUserService,
|
|
}
|
|
|
|
service := auth.NewService(serviceConfig)
|
|
|
|
registerData := &entities.RegisterRequest{
|
|
Email: "userid_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
user, err := service.Register(registerData)
|
|
assert.NoError(t, err)
|
|
|
|
loginData := &entities.LoginRequest{
|
|
Email: "userid_test@example.com",
|
|
Password: "password123",
|
|
}
|
|
tokens, err := service.Login(loginData)
|
|
assert.NoError(t, err)
|
|
|
|
t.Run("GetUserIDFromToken_Success", func(t *testing.T) {
|
|
userID, err := service.GetUserIDFromToken(tokens.AccessToken)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, user.ID.Hex(), userID)
|
|
})
|
|
|
|
t.Run("GetUserIDFromToken_Invalid", func(t *testing.T) {
|
|
userID, err := service.GetUserIDFromToken("invalid_token")
|
|
assert.Error(t, err)
|
|
assert.Empty(t, userID)
|
|
})
|
|
}
|