package unit
import (
"errors"
"time"
"wish-list-api/pkg/auth"
"wish-list-api/pkg/entities"
"github.com/golang-jwt/jwt/v5"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// MockAuthService реализует интерфейс auth.Service
type MockAuthService struct {
users map[primitive.ObjectID]*entities.User
// Токен -> ID пользователя
tokens map[string]primitive.ObjectID
}
// NewMockAuthService создает новый mock сервис аутентификации
func NewMockAuthService() auth.Service {
return &MockAuthService{
users: make(map[primitive.ObjectID]*entities.User),
tokens: make(map[string]primitive.ObjectID),
}
}
// AddMockUser добавляет мок-пользователя в сервис
func (m *MockAuthService) AddMockUser(user *entities.User, token string) {
m.users[user.ID] = user
m.tokens[token] = user.ID
}
// Login реализация для теста
func (m *MockAuthService) Login(credentials *entities.LoginRequest) (*entities.TokenPair, error) {
for _, user := range m.users {
if user.Email == credentials.Email && m.ComparePasswords(user.Password, credentials.Password) {
token := "mock-token-for-" + user.ID.Hex()
m.tokens[token] = user.ID
return &entities.TokenPair{
AccessToken: token,
RefreshToken: "refresh-" + token,
}, nil
}
}
return nil, errors.New("invalid credentials")
}
// Register реализация для теста
func (m *MockAuthService) Register(userData *entities.RegisterRequest) (*entities.User, error) {
// Проверяем, что email не занят
for _, existingUser := range m.users {
if existingUser.Email == userData.Email {
return nil, errors.New("email already exists")
}
}
// Создаем нового пользователя
hashedPassword, _ := m.HashPassword(userData.Password)
user := &entities.User{
ID: primitive.NewObjectID(),
Email: userData.Email,
Password: hashedPassword,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
// Сохраняем пользователя
m.users[user.ID] = user
return user, nil
}
// RefreshToken реализация для теста
func (m *MockAuthService) RefreshToken(refreshToken string) (*entities.TokenPair, error) {
// Предполагаем, что refresh token имеет вид "refresh-<access-token>"
if len(refreshToken) < 8 {
return nil, errors.New("invalid refresh token")
}
accessToken := refreshToken[8:] // Получаем access token из refresh token
userID, ok := m.tokens[accessToken]
if !ok {
return nil, errors.New("invalid refresh token")
}
newToken := "mock-token-for-" + userID.Hex() + "-refreshed"
m.tokens[newToken] = userID
return &entities.TokenPair{
AccessToken: newToken,
RefreshToken: "refresh-" + newToken,
}, nil
}
// ValidateToken реализация для теста
func (m *MockAuthService) ValidateToken(tokenString string) (*jwt.Token, error) {
// Проверяем, имеет ли токен префикс "Bearer "
if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
tokenString = tokenString[7:]
}
userID, ok := m.tokens[tokenString]
if !ok {
return nil, errors.New("invalid token")
}
// Создаем mock JWT token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user_id": userID.Hex(),
"exp": time.Now().Add(time.Hour).Unix(),
})
return token, nil
}
// GetUserIDFromToken реализация для теста
func (m *MockAuthService) GetUserIDFromToken(tokenString string) (string, error) {
// Проверяем, имеет ли токен префикс "Bearer "
if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
tokenString = tokenString[7:]
}
userID, ok := m.tokens[tokenString]
if !ok {
return "", errors.New("invalid token")
}
return userID.Hex(), nil
}
// HashPassword реализация для теста
func (m *MockAuthService) HashPassword(password string) (string, error) {
// Просто возвращаем пароль с префиксом для имитации хеширования
return "hashed_" + password, nil
}
// ComparePasswords реализация для теста
func (m *MockAuthService) ComparePasswords(hashedPassword string, plainPassword string) bool {
// Проверяем, соответствует ли "хешированный" пароль нашей простой схеме
return hashedPassword == "hashed_"+plainPassword
}
package unit
import (
"errors"
"time"
"wish-list-api/api/presenter"
"wish-list-api/pkg/entities"
wishlist "wish-list-api/pkg/wish-list"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// MockWishListRepository реализует интерфейс Repository для тестирования
type MockWishListRepository struct {
wishLists map[string]*entities.WishList
wishListItems map[string]*entities.WishListItem
}
// NewMockWishListRepository создает новый экземпляр мок-репозитория
func NewMockWishListRepository() wishlist.Repository {
return &MockWishListRepository{
wishLists: make(map[string]*entities.WishList),
wishListItems: make(map[string]*entities.WishListItem),
}
}
// CreateWishList реализует создание списка желаний
func (r *MockWishListRepository) CreateWishList(wishList *entities.WishList) (*entities.WishList, error) {
if wishList.ID == "" {
wishList.ID = "mock-id-" + time.Now().String()
}
wishList.CreatedAt = time.Now()
wishList.UpdatedAt = time.Now()
r.wishLists[wishList.ID] = wishList
return wishList, nil
}
// ReadWishList реализует чтение списка желаний по ID
func (r *MockWishListRepository) ReadWishList(ID string) (*entities.WishList, error) {
if wishList, ok := r.wishLists[ID]; ok {
return wishList, nil
}
return nil, errors.New("wishlist not found")
}
// ReadAllWishLists реализует чтение всех списков желаний пользователя
func (r *MockWishListRepository) ReadAllWishLists(userID string) (*[]presenter.WishList, error) {
var result []presenter.WishList
for _, wl := range r.wishLists {
if wl.UserID == userID {
objID, _ := primitive.ObjectIDFromHex(wl.ID)
result = append(result, presenter.WishList{
ID: objID,
Title: wl.Title,
UserID: wl.UserID,
Description: wl.Description,
IsPublic: wl.IsPublic,
PhotoURL: wl.PhotoURL,
CreatedAt: wl.CreatedAt,
UpdatedAt: wl.UpdatedAt,
})
}
}
return &result, nil
}
// ReadPublicWishLists реализует чтение всех публичных списков желаний
func (r *MockWishListRepository) ReadPublicWishLists() (*[]presenter.WishList, error) {
var result []presenter.WishList
for _, wl := range r.wishLists {
if wl.IsPublic {
objID, _ := primitive.ObjectIDFromHex(wl.ID)
result = append(result, presenter.WishList{
ID: objID,
Title: wl.Title,
UserID: wl.UserID,
Description: wl.Description,
IsPublic: wl.IsPublic,
PhotoURL: wl.PhotoURL,
CreatedAt: wl.CreatedAt,
UpdatedAt: wl.UpdatedAt,
})
}
}
return &result, nil
}
// UpdateWishList реализует обновление списка желаний
func (r *MockWishListRepository) UpdateWishList(wishList *entities.WishList) (*entities.WishList, error) {
if _, ok := r.wishLists[wishList.ID]; !ok {
return nil, errors.New("wishlist not found")
}
wishList.UpdatedAt = time.Now()
r.wishLists[wishList.ID] = wishList
return wishList, nil
}
// DeleteWishList реализует удаление списка желаний
func (r *MockWishListRepository) DeleteWishList(ID string) error {
if _, ok := r.wishLists[ID]; !ok {
return errors.New("wishlist not found")
}
delete(r.wishLists, ID)
// Удаляем все элементы, связанные с этим списком
for id, item := range r.wishListItems {
if item.WishListID == ID {
delete(r.wishListItems, id)
}
}
return nil
}
// CreateWishListItem реализует создание элемента списка желаний
func (r *MockWishListRepository) CreateWishListItem(item *entities.WishListItem) (*entities.WishListItem, error) {
if _, ok := r.wishLists[item.WishListID]; !ok {
return nil, errors.New("wishlist not found")
}
if item.ID == "" {
item.ID = "mock-item-id-" + time.Now().String()
}
item.CreatedAt = time.Now()
item.UpdatedAt = time.Now()
r.wishListItems[item.ID] = item
return item, nil
}
// ReadWishListItem реализует чтение элемента списка желаний по ID
func (r *MockWishListRepository) ReadWishListItem(ID string) (*entities.WishListItem, error) {
if item, ok := r.wishListItems[ID]; ok {
return item, nil
}
return nil, errors.New("wishlist item not found")
}
// ReadAllWishListItems реализует чтение всех элементов списка желаний
func (r *MockWishListRepository) ReadAllWishListItems(wishListID string) (*[]presenter.WishListItem, error) {
if _, ok := r.wishLists[wishListID]; !ok {
return nil, errors.New("wishlist not found")
}
var result []presenter.WishListItem
for _, item := range r.wishListItems {
if item.WishListID == wishListID {
objID, _ := primitive.ObjectIDFromHex(item.ID)
result = append(result, presenter.WishListItem{
ID: objID,
Title: item.Title,
URL: item.URL,
Cost: item.Cost,
WishListID: item.WishListID,
Description: item.Description,
PhotoURL: item.PhotoURL,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
})
}
}
return &result, nil
}
// UpdateWishListItem реализует обновление элемента списка желаний
func (r *MockWishListRepository) UpdateWishListItem(item *entities.WishListItem) (*entities.WishListItem, error) {
if _, ok := r.wishListItems[item.ID]; !ok {
return nil, errors.New("wishlist item not found")
}
item.UpdatedAt = time.Now()
r.wishListItems[item.ID] = item
return item, nil
}
// DeleteWishListItem реализует удаление элемента списка желаний
func (r *MockWishListRepository) DeleteWishListItem(ID string) error {
if _, ok := r.wishListItems[ID]; !ok {
return errors.New("wishlist item not found")
}
delete(r.wishListItems, ID)
return nil
}