internal/handler/mocks_test.go
Rama main · réplica de lectura del repositorio original.
package handler
import (
"errors"
"fmt"
"time"
"github.com/johnzastrow/actalog/internal/domain"
"github.com/johnzastrow/actalog/internal/service"
)
// Common errors for mocks
var (
ErrMockNotFound = errors.New("not found")
ErrMockUnauthorized = errors.New("unauthorized")
ErrMockInternalError = errors.New("internal error")
)
// Helper function to create test AuditLogService
func createTestAuditLogService() *service.AuditLogService {
mockAuditLogRepo := NewMockAuditLogRepository()
return service.NewAuditLogService(mockAuditLogRepo)
}
// MockMovementRepository is a mock implementation of MovementRepository
type MockMovementRepository struct {
movements []*domain.Movement
shouldError bool
errorToReturn error
searchResults []*domain.Movement
}
func NewMockMovementRepository() *MockMovementRepository {
userID := int64(1)
return &MockMovementRepository{
movements: []*domain.Movement{
{ID: 1, Name: "Back Squat", Type: "weightlifting", IsStandard: true},
{ID: 2, Name: "Deadlift", Type: "weightlifting", IsStandard: true},
{ID: 3, Name: "Bench Press", Type: "weightlifting", IsStandard: true},
{ID: 4, Name: "My Custom Movement", Type: "bodyweight", IsStandard: false, CreatedBy: &userID},
},
}
}
func (m *MockMovementRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockMovementRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockMovementRepository) Create(movement *domain.Movement) error {
if m.shouldError {
return m.errorToReturn
}
movement.ID = int64(len(m.movements) + 1)
m.movements = append(m.movements, movement)
return nil
}
func (m *MockMovementRepository) GetByID(id int64) (*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, mov := range m.movements {
if mov.ID == id {
return mov, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockMovementRepository) GetByName(name string) (*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, mov := range m.movements {
if mov.Name == name {
return mov, nil
}
}
// Return nil, nil when not found (no duplicate) - consistent with real repo behavior
return nil, nil
}
func (m *MockMovementRepository) ListAll() ([]*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.movements, nil
}
func (m *MockMovementRepository) ListStandard() ([]*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Movement
for _, mov := range m.movements {
if mov.IsStandard {
result = append(result, mov)
}
}
return result, nil
}
func (m *MockMovementRepository) ListByUser(userID int64) ([]*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Movement
for _, mov := range m.movements {
if mov.CreatedBy != nil && *mov.CreatedBy == userID {
result = append(result, mov)
}
}
return result, nil
}
func (m *MockMovementRepository) ListAllUserCreated() ([]*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Movement
for _, mov := range m.movements {
if !mov.IsStandard {
result = append(result, mov)
}
}
return result, nil
}
func (m *MockMovementRepository) ListAllUserCreatedWithUserInfo() ([]*domain.MovementWithCreator, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []*domain.MovementWithCreator{}, nil
}
func (m *MockMovementRepository) ListAllUserCreatedWithUserInfoFiltered(limit, offset int, search, movementType, creator string) ([]*domain.MovementWithCreator, int64, error) {
if m.shouldError {
return nil, 0, m.errorToReturn
}
return []*domain.MovementWithCreator{}, 0, nil
}
func (m *MockMovementRepository) CountAllUserCreated() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
count := int64(0)
for _, mov := range m.movements {
if !mov.IsStandard {
count++
}
}
return count, nil
}
func (m *MockMovementRepository) Update(movement *domain.Movement) error {
if m.shouldError {
return m.errorToReturn
}
for i, mov := range m.movements {
if mov.ID == movement.ID {
m.movements[i] = movement
return nil
}
}
return ErrMockNotFound
}
func (m *MockMovementRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for i, mov := range m.movements {
if mov.ID == id {
m.movements = append(m.movements[:i], m.movements[i+1:]...)
return nil
}
}
return ErrMockNotFound
}
func (m *MockMovementRepository) Search(query string, limit int) ([]*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
if m.searchResults != nil {
return m.searchResults, nil
}
// Simple search implementation
var result []*domain.Movement
for _, mov := range m.movements {
if len(result) >= limit {
break
}
result = append(result, mov)
}
return result, nil
}
func (m *MockMovementRepository) CopyToStandard(id int64, newName string) (*domain.Movement, error) {
if m.shouldError {
return nil, m.errorToReturn
}
mov, err := m.GetByID(id)
if err != nil {
return nil, err
}
newMov := &domain.Movement{
ID: int64(len(m.movements) + 1),
Name: newName,
Type: mov.Type,
IsStandard: true,
}
m.movements = append(m.movements, newMov)
return newMov, nil
}
// MockNotificationRepository is a mock implementation of NotificationRepository
type MockNotificationRepository struct {
notifications []*domain.Notification
shouldError bool
errorToReturn error
unreadCount int64
}
func NewMockNotificationRepository() *MockNotificationRepository {
now := time.Now()
readAt := now.Add(-time.Hour) // 1 hour ago for read notifications
return &MockNotificationRepository{
notifications: []*domain.Notification{
{ID: 1, UserID: 1, Type: "pr", Title: "New PR!", Message: "You set a new PR", ReadAt: nil, CreatedAt: now},
{ID: 2, UserID: 1, Type: "info", Title: "Welcome", Message: "Welcome to ActaLog", ReadAt: &readAt, CreatedAt: now},
},
unreadCount: 1,
}
}
func (m *MockNotificationRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockNotificationRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockNotificationRepository) Create(notification *domain.Notification) error {
if m.shouldError {
return m.errorToReturn
}
notification.ID = int64(len(m.notifications) + 1)
m.notifications = append(m.notifications, notification)
return nil
}
func (m *MockNotificationRepository) GetByID(id int64) (*domain.Notification, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, n := range m.notifications {
if n.ID == id {
return n, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockNotificationRepository) GetByUserID(userID int64, limit, offset int) ([]*domain.Notification, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Notification
for _, n := range m.notifications {
if n.UserID == userID {
result = append(result, n)
}
}
// Apply offset and limit
if offset >= len(result) {
return []*domain.Notification{}, nil
}
result = result[offset:]
if limit > 0 && len(result) > limit {
result = result[:limit]
}
return result, nil
}
func (m *MockNotificationRepository) GetUnreadByUserID(userID int64, limit, offset int) ([]*domain.Notification, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Notification
for _, n := range m.notifications {
if n.UserID == userID && n.ReadAt == nil {
result = append(result, n)
}
}
if offset >= len(result) {
return []*domain.Notification{}, nil
}
result = result[offset:]
if limit > 0 && len(result) > limit {
result = result[:limit]
}
return result, nil
}
func (m *MockNotificationRepository) CountUnreadByUserID(userID int64) (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
count := int64(0)
for _, n := range m.notifications {
if n.UserID == userID && n.ReadAt == nil {
count++
}
}
return count, nil
}
func (m *MockNotificationRepository) MarkAsRead(id int64) error {
if m.shouldError {
return m.errorToReturn
}
now := time.Now()
for _, n := range m.notifications {
if n.ID == id {
n.ReadAt = &now
return nil
}
}
return ErrMockNotFound
}
func (m *MockNotificationRepository) MarkAsUnread(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for _, n := range m.notifications {
if n.ID == id {
n.ReadAt = nil
return nil
}
}
return ErrMockNotFound
}
func (m *MockNotificationRepository) MarkAllAsReadForUser(userID int64) error {
if m.shouldError {
return m.errorToReturn
}
now := time.Now()
for _, n := range m.notifications {
if n.UserID == userID {
n.ReadAt = &now
}
}
return nil
}
func (m *MockNotificationRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for i, n := range m.notifications {
if n.ID == id {
m.notifications = append(m.notifications[:i], m.notifications[i+1:]...)
return nil
}
}
return ErrMockNotFound
}
func (m *MockNotificationRepository) DeleteOlderThan(cutoff time.Time) (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
count := int64(0)
var remaining []*domain.Notification
for _, n := range m.notifications {
if n.CreatedAt.Before(cutoff) {
count++
} else {
remaining = append(remaining, n)
}
}
m.notifications = remaining
return count, nil
}
// MockWODRepository is a mock implementation of WODRepository
type MockWODRepository struct {
wods []*domain.WOD
shouldError bool
errorToReturn error
}
func NewMockWODRepository() *MockWODRepository {
userID := int64(1)
return &MockWODRepository{
wods: []*domain.WOD{
{ID: 1, Name: "Fran", ScoreType: "Time", IsStandard: true, Source: "CrossFit", Type: "Girl"},
{ID: 2, Name: "Cindy", ScoreType: "Rounds+Reps", IsStandard: true, Source: "CrossFit", Type: "Girl"},
{ID: 3, Name: "Murph", ScoreType: "Time", IsStandard: true, Source: "CrossFit", Type: "Hero"},
{ID: 4, Name: "My Custom WOD", ScoreType: "Time", IsStandard: false, CreatedBy: &userID, Source: "Self-recorded", Type: "Self-created"},
},
}
}
func (m *MockWODRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockWODRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockWODRepository) Create(wod *domain.WOD) error {
if m.shouldError {
return m.errorToReturn
}
wod.ID = int64(len(m.wods) + 1)
m.wods = append(m.wods, wod)
return nil
}
func (m *MockWODRepository) GetByID(id int64) (*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, wod := range m.wods {
if wod.ID == id {
return wod, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockWODRepository) GetByName(name string) (*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, wod := range m.wods {
if wod.Name == name {
return wod, nil
}
}
// Return nil, nil when not found (no duplicate)
return nil, nil
}
func (m *MockWODRepository) List(filters map[string]interface{}, limit, offset int) ([]*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
if offset >= len(m.wods) {
return []*domain.WOD{}, nil
}
result := m.wods[offset:]
if limit > 0 && len(result) > limit {
result = result[:limit]
}
return result, nil
}
func (m *MockWODRepository) ListStandard(limit, offset int) ([]*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.WOD
for _, wod := range m.wods {
if wod.IsStandard {
result = append(result, wod)
}
}
if offset >= len(result) {
return []*domain.WOD{}, nil
}
result = result[offset:]
if limit > 0 && len(result) > limit {
result = result[:limit]
}
return result, nil
}
func (m *MockWODRepository) ListByUser(userID int64, limit, offset int) ([]*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.WOD
for _, wod := range m.wods {
if wod.CreatedBy != nil && *wod.CreatedBy == userID {
result = append(result, wod)
}
}
if offset >= len(result) {
return []*domain.WOD{}, nil
}
result = result[offset:]
if limit > 0 && len(result) > limit {
result = result[:limit]
}
return result, nil
}
func (m *MockWODRepository) ListAllUserCreated(limit, offset int) ([]*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.WOD
for _, wod := range m.wods {
if !wod.IsStandard {
result = append(result, wod)
}
}
return result, nil
}
func (m *MockWODRepository) ListAllUserCreatedWithUserInfo(limit, offset int) ([]*domain.WODWithCreator, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []*domain.WODWithCreator{}, nil
}
func (m *MockWODRepository) ListAllUserCreatedWithUserInfoFiltered(limit, offset int, search, scoreType, creator string) ([]*domain.WODWithCreator, int64, error) {
if m.shouldError {
return nil, 0, m.errorToReturn
}
return []*domain.WODWithCreator{}, 0, nil
}
func (m *MockWODRepository) CountAllUserCreated() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
count := int64(0)
for _, wod := range m.wods {
if !wod.IsStandard {
count++
}
}
return count, nil
}
func (m *MockWODRepository) Update(wod *domain.WOD) error {
if m.shouldError {
return m.errorToReturn
}
for i, w := range m.wods {
if w.ID == wod.ID {
m.wods[i] = wod
return nil
}
}
return ErrMockNotFound
}
func (m *MockWODRepository) UpdateStandard(wod *domain.WOD) error {
return m.Update(wod)
}
func (m *MockWODRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for i, wod := range m.wods {
if wod.ID == id {
m.wods = append(m.wods[:i], m.wods[i+1:]...)
return nil
}
}
return ErrMockNotFound
}
func (m *MockWODRepository) Search(query string, limit int) ([]*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.WOD
for _, wod := range m.wods {
if len(result) >= limit {
break
}
result = append(result, wod)
}
return result, nil
}
func (m *MockWODRepository) CopyToStandard(id int64, newName string) (*domain.WOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
wod, err := m.GetByID(id)
if err != nil {
return nil, err
}
newWOD := &domain.WOD{
ID: int64(len(m.wods) + 1),
Name: newName,
ScoreType: wod.ScoreType,
IsStandard: true,
}
m.wods = append(m.wods, newWOD)
return newWOD, nil
}
// MockUserRepository is a mock implementation of UserRepository
type MockUserRepository struct {
users []*domain.User
shouldError bool
errorToReturn error
}
func NewMockUserRepository() *MockUserRepository {
return &MockUserRepository{
users: []*domain.User{
{ID: 1, Email: "admin@example.com", Name: "Admin User", Role: "admin"},
{ID: 2, Email: "test@example.com", Name: "Test User", Role: "athlete"},
},
}
}
func (m *MockUserRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockUserRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockUserRepository) Create(user *domain.User) error {
if m.shouldError {
return m.errorToReturn
}
user.ID = int64(len(m.users) + 1)
m.users = append(m.users, user)
return nil
}
func (m *MockUserRepository) GetByID(id int64) (*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, u := range m.users {
if u.ID == id {
return u, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockUserRepository) GetByEmail(email string) (*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, u := range m.users {
if u.Email == email {
return u, nil
}
}
// Return nil, nil when not found (no user exists with this email)
return nil, nil
}
func (m *MockUserRepository) GetByResetToken(token string) (*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return nil, ErrMockNotFound
}
func (m *MockUserRepository) GetByVerificationToken(token string) (*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return nil, ErrMockNotFound
}
func (m *MockUserRepository) Update(user *domain.User) error {
if m.shouldError {
return m.errorToReturn
}
for i, u := range m.users {
if u.ID == user.ID {
m.users[i] = user
return nil
}
}
return ErrMockNotFound
}
func (m *MockUserRepository) UpdatePassword(userID int64, hashedPassword string) error {
if m.shouldError {
return m.errorToReturn
}
for _, u := range m.users {
if u.ID == userID {
u.PasswordHash = hashedPassword
return nil
}
}
return ErrMockNotFound
}
func (m *MockUserRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for i, u := range m.users {
if u.ID == id {
m.users = append(m.users[:i], m.users[i+1:]...)
return nil
}
}
return ErrMockNotFound
}
func (m *MockUserRepository) List(limit, offset int) ([]*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
if offset >= len(m.users) {
return []*domain.User{}, nil
}
result := m.users[offset:]
if limit > 0 && len(result) > limit {
result = result[:limit]
}
return result, nil
}
func (m *MockUserRepository) Count() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return int64(len(m.users)), nil
}
func (m *MockUserRepository) IncrementFailedAttempts(userID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserRepository) ResetFailedAttempts(userID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserRepository) LockAccount(userID int64, lockDuration time.Duration) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserRepository) UnlockAccount(userID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserRepository) IsAccountLocked(userID int64) (bool, *time.Time, error) {
if m.shouldError {
return false, nil, m.errorToReturn
}
return false, nil, nil
}
func (m *MockUserRepository) DisableAccount(userID int64, disabledBy int64, reason string) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserRepository) EnableAccount(userID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserRepository) ListAdmins() ([]*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var admins []*domain.User
for _, u := range m.users {
if u.Role == "admin" {
admins = append(admins, u)
}
}
return admins, nil
}
func (m *MockUserRepository) CountNewThisMonth() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return 0, nil
}
func (m *MockUserRepository) CountDisabled() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
var count int64
for _, u := range m.users {
if u.AccountDisabled {
count++
}
}
return count, nil
}
func (m *MockUserRepository) ListWithFilter(filter domain.UserListFilter, limit, offset int) ([]*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
// Simple implementation - just return all users
return m.users, nil
}
func (m *MockUserRepository) CountWithFilter(filter domain.UserListFilter) (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return int64(len(m.users)), nil
}
// MockOrganizationRepository is a mock implementation of OrganizationRepository
type MockOrganizationRepository struct {
organizations []*domain.Organization
shouldError bool
errorToReturn error
}
func NewMockOrganizationRepository() *MockOrganizationRepository {
return &MockOrganizationRepository{
organizations: []*domain.Organization{
{ID: 1, Name: "Test Org"},
},
}
}
func (m *MockOrganizationRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockOrganizationRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockOrganizationRepository) Create(org *domain.Organization) error {
if m.shouldError {
return m.errorToReturn
}
org.ID = int64(len(m.organizations) + 1)
m.organizations = append(m.organizations, org)
return nil
}
func (m *MockOrganizationRepository) GetByID(id int64) (*domain.Organization, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, org := range m.organizations {
if org.ID == id {
return org, nil
}
}
return nil, nil // Not found returns nil, nil per repository pattern
}
func (m *MockOrganizationRepository) GetByOwner(ownerID int64) (*domain.Organization, error) {
if m.shouldError {
return nil, m.errorToReturn
}
// Return first organization for simplicity in tests
if len(m.organizations) > 0 {
return m.organizations[0], nil
}
return nil, ErrMockNotFound
}
func (m *MockOrganizationRepository) Update(org *domain.Organization) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockOrganizationRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockOrganizationRepository) List(limit, offset int) ([]*domain.Organization, int64, error) {
if m.shouldError {
return nil, 0, m.errorToReturn
}
return m.organizations, int64(len(m.organizations)), nil
}
func (m *MockOrganizationRepository) GetMemberIDs(orgID int64) ([]int64, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []int64{1, 2}, nil
}
func (m *MockOrganizationRepository) GetByName(name string) (*domain.Organization, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, org := range m.organizations {
if org.Name == name {
return org, nil
}
}
return nil, nil // Not found returns nil, nil per repository pattern
}
func (m *MockOrganizationRepository) Count() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return int64(len(m.organizations)), nil
}
func (m *MockOrganizationRepository) AddUserToOrganization(userID, orgID int64, role string) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockOrganizationRepository) RemoveUserFromOrganization(userID, orgID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockOrganizationRepository) GetUserOrganizations(userID int64) ([]*domain.Organization, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.organizations, nil
}
func (m *MockOrganizationRepository) GetOrganizationUsers(orgID int64) ([]*domain.User, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []*domain.User{{ID: 1, Email: "test@example.com"}}, nil
}
func (m *MockOrganizationRepository) IsUserInOrganization(userID, orgID int64) (bool, error) {
if m.shouldError {
return false, m.errorToReturn
}
return true, nil
}
func (m *MockOrganizationRepository) GetUserOrganizationIDs(userID int64) ([]int64, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []int64{1}, nil
}
// MockUserSettingsRepository is a mock implementation of UserSettingsRepository
type MockUserSettingsRepository struct {
settings map[int64]*domain.UserSettings
shouldError bool
errorToReturn error
}
func NewMockUserSettingsRepository() *MockUserSettingsRepository {
return &MockUserSettingsRepository{
settings: make(map[int64]*domain.UserSettings),
}
}
func (m *MockUserSettingsRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockUserSettingsRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockUserSettingsRepository) Create(settings *domain.UserSettings) error {
if m.shouldError {
return m.errorToReturn
}
m.settings[settings.UserID] = settings
return nil
}
func (m *MockUserSettingsRepository) GetByUserID(userID int64) (*domain.UserSettings, error) {
if m.shouldError {
return nil, m.errorToReturn
}
if s, ok := m.settings[userID]; ok {
return s, nil
}
// Return default settings
return &domain.UserSettings{
UserID: userID,
NotificationPreferences: `{"email_on_pr":true,"email_on_announcement":true}`,
DataExportFormat: "JSON",
Theme: "light",
WeightUnit: "lbs",
DistanceUnit: "miles",
}, nil
}
func (m *MockUserSettingsRepository) Update(settings *domain.UserSettings) error {
if m.shouldError {
return m.errorToReturn
}
m.settings[settings.UserID] = settings
return nil
}
func (m *MockUserSettingsRepository) Delete(userID int64) error {
if m.shouldError {
return m.errorToReturn
}
delete(m.settings, userID)
return nil
}
// MockEmailService is a mock implementation of email.EmailService
type MockEmailService struct {
shouldError bool
errorToReturn error
sentEmails []string
}
func NewMockEmailService() *MockEmailService {
return &MockEmailService{
sentEmails: []string{},
}
}
func (m *MockEmailService) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockEmailService) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockEmailService) SendPasswordResetEmail(to, resetURL string) error {
if m.shouldError {
return m.errorToReturn
}
m.sentEmails = append(m.sentEmails, to)
return nil
}
func (m *MockEmailService) SendVerificationEmail(to, verifyURL string) error {
if m.shouldError {
return m.errorToReturn
}
m.sentEmails = append(m.sentEmails, to)
return nil
}
func (m *MockEmailService) SendHTMLEmail(to, subject, htmlBody string) error {
if m.shouldError {
return m.errorToReturn
}
m.sentEmails = append(m.sentEmails, to)
return nil
}
func (m *MockEmailService) SendWelcomeEmail(to, userName, appURL string) error {
if m.shouldError {
return m.errorToReturn
}
m.sentEmails = append(m.sentEmails, to)
return nil
}
// MockAuditLogRepository is a mock implementation of AuditLogRepository
type MockAuditLogRepository struct {
logs []*domain.AuditLog
shouldError bool
errorToReturn error
}
func NewMockAuditLogRepository() *MockAuditLogRepository {
return &MockAuditLogRepository{
logs: []*domain.AuditLog{},
}
}
func (m *MockAuditLogRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockAuditLogRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockAuditLogRepository) Create(log *domain.AuditLog) error {
if m.shouldError {
return m.errorToReturn
}
log.ID = int64(len(m.logs) + 1)
m.logs = append(m.logs, log)
return nil
}
func (m *MockAuditLogRepository) GetByID(id int64) (*domain.AuditLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, log := range m.logs {
if log.ID == id {
return log, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockAuditLogRepository) List(filters domain.AuditLogFilters, limit, offset int) ([]*domain.AuditLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.logs, nil
}
func (m *MockAuditLogRepository) Count(filters domain.AuditLogFilters) (int, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return len(m.logs), nil
}
func (m *MockAuditLogRepository) GetByUserID(userID int64, limit, offset int) ([]*domain.AuditLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.logs, nil
}
func (m *MockAuditLogRepository) GetByTargetUserID(targetUserID int64, limit, offset int) ([]*domain.AuditLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.logs, nil
}
func (m *MockAuditLogRepository) DeleteOlderThan(cutoff time.Time) (int, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return 0, nil
}
// MockDataChangeLogRepository is a mock implementation of DataChangeLogRepository
type MockDataChangeLogRepository struct {
logs []*domain.DataChangeLog
shouldError bool
errorToReturn error
}
func NewMockDataChangeLogRepository() *MockDataChangeLogRepository {
return &MockDataChangeLogRepository{
logs: []*domain.DataChangeLog{},
}
}
func (m *MockDataChangeLogRepository) AddLog(log *domain.DataChangeLog) {
m.logs = append(m.logs, log)
}
func (m *MockDataChangeLogRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockDataChangeLogRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockDataChangeLogRepository) Create(log *domain.DataChangeLog) error {
if m.shouldError {
return m.errorToReturn
}
log.ID = int64(len(m.logs) + 1)
m.logs = append(m.logs, log)
return nil
}
func (m *MockDataChangeLogRepository) GetByID(id int64) (*domain.DataChangeLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, log := range m.logs {
if log.ID == id {
return log, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockDataChangeLogRepository) List(filters domain.DataChangeLogFilters, limit, offset int) ([]*domain.DataChangeLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.logs, nil
}
func (m *MockDataChangeLogRepository) Count(filters domain.DataChangeLogFilters) (int, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return len(m.logs), nil
}
func (m *MockDataChangeLogRepository) GetByEntityID(entityType string, entityID int64, limit, offset int) ([]*domain.DataChangeLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.logs, nil
}
func (m *MockDataChangeLogRepository) GetByUserID(userID int64, limit, offset int) ([]*domain.DataChangeLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.logs, nil
}
func (m *MockDataChangeLogRepository) DeleteOlderThan(cutoff time.Time) (int, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return 0, nil
}
// MockRefreshTokenRepository is a mock implementation of RefreshTokenRepository
type MockRefreshTokenRepository struct {
tokens []*domain.RefreshToken
shouldError bool
errorToReturn error
}
func NewMockRefreshTokenRepository() *MockRefreshTokenRepository {
return &MockRefreshTokenRepository{
tokens: []*domain.RefreshToken{},
}
}
func (m *MockRefreshTokenRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockRefreshTokenRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockRefreshTokenRepository) Create(token *domain.RefreshToken) error {
if m.shouldError {
return m.errorToReturn
}
token.ID = int64(len(m.tokens) + 1)
m.tokens = append(m.tokens, token)
return nil
}
func (m *MockRefreshTokenRepository) GetByToken(token string) (*domain.RefreshToken, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, t := range m.tokens {
if t.Token == token {
return t, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockRefreshTokenRepository) GetByUserID(userID int64) ([]*domain.RefreshToken, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.RefreshToken
for _, t := range m.tokens {
if t.UserID == userID {
result = append(result, t)
}
}
return result, nil
}
func (m *MockRefreshTokenRepository) Revoke(tokenID int64) error {
if m.shouldError {
return m.errorToReturn
}
for _, t := range m.tokens {
if t.ID == tokenID {
now := time.Now()
t.RevokedAt = &now
return nil
}
}
return ErrMockNotFound
}
func (m *MockRefreshTokenRepository) RevokeAllForUser(userID int64) error {
if m.shouldError {
return m.errorToReturn
}
now := time.Now()
for _, t := range m.tokens {
if t.UserID == userID {
t.RevokedAt = &now
}
}
return nil
}
func (m *MockRefreshTokenRepository) DeleteExpired() error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockRefreshTokenRepository) Delete(tokenID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
// MockUserSubscriptionRepository is a mock implementation of UserSubscriptionRepository
type MockUserSubscriptionRepository struct {
subscriptions []*domain.UserSubscription
shouldError bool
errorToReturn error
}
func NewMockUserSubscriptionRepository() *MockUserSubscriptionRepository {
return &MockUserSubscriptionRepository{
subscriptions: []*domain.UserSubscription{},
}
}
func (m *MockUserSubscriptionRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockUserSubscriptionRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockUserSubscriptionRepository) Create(sub *domain.UserSubscription) error {
if m.shouldError {
return m.errorToReturn
}
sub.ID = int64(len(m.subscriptions) + 1)
m.subscriptions = append(m.subscriptions, sub)
return nil
}
func (m *MockUserSubscriptionRepository) GetByID(id int64) (*domain.UserSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, sub := range m.subscriptions {
if sub.ID == id {
return sub, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockUserSubscriptionRepository) GetActiveByUserID(userID int64) (*domain.UserSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, sub := range m.subscriptions {
if sub.UserID == userID && sub.Status == "active" {
return sub, nil
}
}
return nil, nil
}
func (m *MockUserSubscriptionRepository) GetByUserID(userID int64) ([]*domain.UserSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.UserSubscription
for _, sub := range m.subscriptions {
if sub.UserID == userID {
result = append(result, sub)
}
}
return result, nil
}
func (m *MockUserSubscriptionRepository) Update(sub *domain.UserSubscription) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserSubscriptionRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserSubscriptionRepository) ListAll() ([]*domain.UserSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.subscriptions, nil
}
func (m *MockUserSubscriptionRepository) MarkAsPaid(id int64, paymentDate time.Time, adminUserID int64, durationDays *int) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserSubscriptionRepository) MarkAsExpired(id int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserSubscriptionRepository) Cancel(id int64, reason string, adminUserID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserSubscriptionRepository) ListExpiring(days int) ([]*domain.UserSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
now := time.Now()
futureDate := now.AddDate(0, 0, days)
var result []*domain.UserSubscription
for _, sub := range m.subscriptions {
if sub.Status == domain.SubscriptionStatusActive &&
!sub.IsPermanentFree &&
sub.EndDate != nil &&
sub.EndDate.After(now) &&
sub.EndDate.Before(futureDate) {
result = append(result, sub)
}
}
return result, nil
}
func (m *MockUserSubscriptionRepository) ListExpired() ([]*domain.UserSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
now := time.Now()
var result []*domain.UserSubscription
for _, sub := range m.subscriptions {
if sub.Status == domain.SubscriptionStatusExpired ||
(sub.Status == domain.SubscriptionStatusActive &&
!sub.IsPermanentFree &&
sub.EndDate != nil &&
sub.EndDate.Before(now)) {
result = append(result, sub)
}
}
return result, nil
}
func (m *MockUserSubscriptionRepository) CountActive() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
var count int64
for _, sub := range m.subscriptions {
if sub.Status == domain.SubscriptionStatusActive {
count++
}
}
return count, nil
}
func (m *MockUserSubscriptionRepository) CountExpired() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
var count int64
now := time.Now()
for _, sub := range m.subscriptions {
if sub.Status == domain.SubscriptionStatusExpired ||
(sub.Status == domain.SubscriptionStatusActive &&
!sub.IsPermanentFree &&
sub.EndDate != nil &&
sub.EndDate.Before(now)) {
count++
}
}
return count, nil
}
func (m *MockUserSubscriptionRepository) CountExpiringSoon(days int) (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
now := time.Now()
futureDate := now.AddDate(0, 0, days)
var count int64
for _, sub := range m.subscriptions {
if sub.Status == domain.SubscriptionStatusActive &&
!sub.IsPermanentFree &&
sub.EndDate != nil &&
sub.EndDate.After(now) &&
sub.EndDate.Before(futureDate) {
count++
}
}
return count, nil
}
// MockUserWorkoutWODRepository is a mock implementation of UserWorkoutWODRepository
type MockUserWorkoutWODRepository struct {
wods []*domain.UserWorkoutWOD
shouldError bool
errorToReturn error
}
func NewMockUserWorkoutWODRepository() *MockUserWorkoutWODRepository {
return &MockUserWorkoutWODRepository{
wods: []*domain.UserWorkoutWOD{},
}
}
func (m *MockUserWorkoutWODRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockUserWorkoutWODRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockUserWorkoutWODRepository) Create(uww *domain.UserWorkoutWOD) error {
if m.shouldError {
return m.errorToReturn
}
uww.ID = int64(len(m.wods) + 1)
m.wods = append(m.wods, uww)
return nil
}
func (m *MockUserWorkoutWODRepository) CreateBatch(wods []*domain.UserWorkoutWOD) error {
if m.shouldError {
return m.errorToReturn
}
for _, wod := range wods {
wod.ID = int64(len(m.wods) + 1)
m.wods = append(m.wods, wod)
}
return nil
}
func (m *MockUserWorkoutWODRepository) GetByID(id int64) (*domain.UserWorkoutWOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, wod := range m.wods {
if wod.ID == id {
return wod, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockUserWorkoutWODRepository) GetByUserWorkoutID(userWorkoutID int64) ([]*domain.UserWorkoutWOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.UserWorkoutWOD
for _, wod := range m.wods {
if wod.UserWorkoutID == userWorkoutID {
result = append(result, wod)
}
}
return result, nil
}
func (m *MockUserWorkoutWODRepository) Update(uww *domain.UserWorkoutWOD) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserWorkoutWODRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserWorkoutWODRepository) DeleteByUserWorkoutID(userWorkoutID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockUserWorkoutWODRepository) GetBestTimeForWOD(userID, wodID int64) (*int, error) {
if m.shouldError {
return nil, m.errorToReturn
}
bestTime := 300 // 5 minutes in seconds
return &bestTime, nil
}
func (m *MockUserWorkoutWODRepository) GetBestRoundsRepsForWOD(userID, wodID int64) (rounds *int, reps *int, err error) {
if m.shouldError {
return nil, nil, m.errorToReturn
}
r, p := 10, 5
return &r, &p, nil
}
func (m *MockUserWorkoutWODRepository) GetPRWODs(userID int64, limit int) ([]*domain.UserWorkoutWOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []*domain.UserWorkoutWOD{}, nil
}
func (m *MockUserWorkoutWODRepository) UpdatePRFlag(id int64, isPR bool) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
// MockWorkoutRepository is a mock implementation of WorkoutRepository
type MockWorkoutRepository struct {
workouts []*domain.Workout
shouldError bool
errorToReturn error
}
func NewMockWorkoutRepository() *MockWorkoutRepository {
userID := int64(1)
return &MockWorkoutRepository{
workouts: []*domain.Workout{
{ID: 1, Name: "Push Day"},
{ID: 2, Name: "Pull Day"},
{ID: 3, Name: "My Custom Workout", CreatedBy: &userID},
},
}
}
func (m *MockWorkoutRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockWorkoutRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockWorkoutRepository) Create(workout *domain.Workout) error {
if m.shouldError {
return m.errorToReturn
}
workout.ID = int64(len(m.workouts) + 1)
m.workouts = append(m.workouts, workout)
return nil
}
func (m *MockWorkoutRepository) GetByID(id int64) (*domain.Workout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, w := range m.workouts {
if w.ID == id {
return w, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockWorkoutRepository) GetByIDWithDetails(id int64) (*domain.Workout, error) {
return m.GetByID(id)
}
func (m *MockWorkoutRepository) List(filters map[string]interface{}, limit, offset int) ([]*domain.Workout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.workouts, nil
}
func (m *MockWorkoutRepository) ListByUser(userID int64, limit, offset int) ([]*domain.Workout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Workout
for _, w := range m.workouts {
if w.CreatedBy != nil && *w.CreatedBy == userID {
result = append(result, w)
}
}
return result, nil
}
func (m *MockWorkoutRepository) ListStandard(limit, offset int) ([]*domain.Workout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Workout
for _, w := range m.workouts {
if w.CreatedBy == nil { // Standard workouts have no creator
result = append(result, w)
}
}
return result, nil
}
func (m *MockWorkoutRepository) ListAllUserCreated(limit, offset int) ([]*domain.Workout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.Workout
for _, w := range m.workouts {
if w.CreatedBy != nil { // User-created workouts have a creator
result = append(result, w)
}
}
return result, nil
}
func (m *MockWorkoutRepository) ListAllUserCreatedWithUserInfo(limit, offset int) ([]*domain.WorkoutWithCreator, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []*domain.WorkoutWithCreator{}, nil
}
func (m *MockWorkoutRepository) CountAllUserCreated() (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
count := int64(0)
for _, w := range m.workouts {
if w.CreatedBy != nil { // User-created workouts have a creator
count++
}
}
return count, nil
}
func (m *MockWorkoutRepository) Count(userID *int64) (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return int64(len(m.workouts)), nil
}
func (m *MockWorkoutRepository) GetUsageStats(workoutID int64) (*domain.WorkoutWithUsageStats, error) {
if m.shouldError {
return nil, m.errorToReturn
}
w, err := m.GetByID(workoutID)
if err != nil {
return nil, err
}
return &domain.WorkoutWithUsageStats{Workout: *w, TimesUsed: 5}, nil
}
func (m *MockWorkoutRepository) ListAllUserCreatedWithUserInfoFiltered(limit, offset int, search, creator string) ([]*domain.WorkoutWithCreator, int64, error) {
if m.shouldError {
return nil, 0, m.errorToReturn
}
return []*domain.WorkoutWithCreator{}, 0, nil
}
func (m *MockWorkoutRepository) Update(workout *domain.Workout) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockWorkoutRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockWorkoutRepository) Search(query string, limit int) ([]*domain.Workout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.workouts, nil
}
func (m *MockWorkoutRepository) CopyToStandard(id int64, newName string) (*domain.Workout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
newWorkout := &domain.Workout{
ID: int64(len(m.workouts) + 1),
Name: newName,
CreatedBy: nil, // nil CreatedBy indicates standard workout
}
m.workouts = append(m.workouts, newWorkout)
return newWorkout, nil
}
// MockBackupService is a mock implementation of BackupService
type MockBackupService struct {
backups []domain.BackupMetadata
shouldError bool
errorToReturn error
}
func NewMockBackupService() *MockBackupService {
return &MockBackupService{
backups: []domain.BackupMetadata{
{
Filename: "backup_2024-01-15.json",
FileSize: 1024,
CreatedAt: time.Now(),
CreatedByEmail: "admin@example.com",
Version: "0.17.0",
DatabaseDriver: "sqlite3",
DatabaseName: "test.db",
TotalUsers: 5,
TotalWorkouts: 100,
TotalMovements: 50,
TotalWODs: 20,
},
},
}
}
func (m *MockBackupService) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockBackupService) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockBackupService) CreateBackup(createdByUserID int64) (string, error) {
if m.shouldError {
return "", m.errorToReturn
}
filename := "backup_test.json"
backup := domain.BackupMetadata{
Filename: filename,
FileSize: 2048,
CreatedAt: time.Now(),
CreatedByEmail: "admin@example.com",
Version: "0.17.0",
DatabaseDriver: "sqlite3",
DatabaseName: "test.db",
}
m.backups = append(m.backups, backup)
return filename, nil
}
func (m *MockBackupService) ListBackups() ([]domain.BackupMetadata, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.backups, nil
}
func (m *MockBackupService) GetBackupMetadata(filename string) (*domain.BackupMetadata, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, b := range m.backups {
if b.Filename == filename {
return &b, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockBackupService) DownloadBackup(filename string) (string, error) {
if m.shouldError {
return "", m.errorToReturn
}
return "/tmp/backups/" + filename, nil
}
func (m *MockBackupService) UploadBackup(file interface{}, filename string, uploadedByUserID int64) (string, error) {
if m.shouldError {
return "", m.errorToReturn
}
// Add the uploaded backup to the list so GetBackupMetadata will find it
backup := domain.BackupMetadata{
Filename: filename,
FileSize: 1024,
CreatedAt: time.Now(),
CreatedByEmail: "admin@example.com",
Version: "0.17.0",
DatabaseDriver: "sqlite3",
DatabaseName: "test.db",
}
m.backups = append(m.backups, backup)
return filename, nil
}
func (m *MockBackupService) DeleteBackup(filename string, deletedByUserID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockBackupService) RestoreBackup(filename string, restoredByUserID int64, mode domain.RestoreMode) (*domain.RestoreResult, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return &domain.RestoreResult{
Mode: mode,
TablesRestored: 10,
RecordsCreated: 500,
RecordsUpdated: 0,
RecordsSkipped: 0,
}, nil
}
// createTestUserSettingsService creates a UserSettingsService with mock repositories
func createTestUserSettingsService() *service.UserSettingsService {
settingsRepo := NewMockUserSettingsRepository()
auditLogRepo := NewMockAuditLogRepository()
return service.NewUserSettingsService(settingsRepo, auditLogRepo)
}
// MockNotificationLikeRepository is a mock implementation of NotificationLikeRepository
type MockNotificationLikeRepository struct {
likes map[int64][]*domain.NotificationLike
userLikes map[string]bool // key: "notifID-userID"
shouldError bool
errorToReturn error
}
func NewMockNotificationLikeRepository() *MockNotificationLikeRepository {
return &MockNotificationLikeRepository{
likes: make(map[int64][]*domain.NotificationLike),
userLikes: make(map[string]bool),
}
}
func (m *MockNotificationLikeRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockNotificationLikeRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockNotificationLikeRepository) Create(like *domain.NotificationLike) error {
if m.shouldError {
return m.errorToReturn
}
key := fmt.Sprintf("%d-%d", like.NotificationID, like.UserID)
m.userLikes[key] = true
m.likes[like.NotificationID] = append(m.likes[like.NotificationID], like)
return nil
}
func (m *MockNotificationLikeRepository) Delete(notificationID, userID int64) error {
if m.shouldError {
return m.errorToReturn
}
key := fmt.Sprintf("%d-%d", notificationID, userID)
delete(m.userLikes, key)
return nil
}
func (m *MockNotificationLikeRepository) GetByNotificationID(notificationID int64) ([]*domain.NotificationLike, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.likes[notificationID], nil
}
func (m *MockNotificationLikeRepository) GetLikeCount(notificationID int64) (int, error) {
if m.shouldError {
return 0, m.errorToReturn
}
return len(m.likes[notificationID]), nil
}
func (m *MockNotificationLikeRepository) HasUserLiked(notificationID, userID int64) (bool, error) {
if m.shouldError {
return false, m.errorToReturn
}
key := fmt.Sprintf("%d-%d", notificationID, userID)
return m.userLikes[key], nil
}
// createTestNotificationLikeService creates a NotificationLikeService with mock repositories
func createTestNotificationLikeService() *service.NotificationLikeService {
likeRepo := NewMockNotificationLikeRepository()
notificationRepo := NewMockNotificationRepository()
return service.NewNotificationLikeService(likeRepo, notificationRepo)
}
// MockEmailLogRepository is a mock implementation of EmailLogRepository
type MockEmailLogRepository struct {
logs []*domain.EmailLog
shouldError bool
errorToReturn error
}
func NewMockEmailLogRepository() *MockEmailLogRepository {
now := time.Now()
userID := int64(1)
userEmail := "admin@example.com"
errMsg := "SMTP connection failed"
return &MockEmailLogRepository{
logs: []*domain.EmailLog{
{
ID: 1,
RecipientEmail: "test@example.com",
EmailType: domain.EmailTypeTest,
Subject: "ActaLog Test Email",
Success: true,
SentByUserID: &userID,
CreatedAt: now,
SentByUserEmail: &userEmail,
},
{
ID: 2,
RecipientEmail: "user@example.com",
EmailType: domain.EmailTypePasswordReset,
Subject: "Password Reset Request",
Success: true,
CreatedAt: now.Add(-time.Hour),
SentByUserEmail: nil,
},
{
ID: 3,
RecipientEmail: "failed@example.com",
EmailType: domain.EmailTypeTest,
Subject: "ActaLog Test Email",
Success: false,
ErrorMessage: &errMsg,
SentByUserID: &userID,
CreatedAt: now.Add(-2 * time.Hour),
SentByUserEmail: &userEmail,
},
},
}
}
func (m *MockEmailLogRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockEmailLogRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockEmailLogRepository) Create(log *domain.EmailLog) error {
if m.shouldError {
return m.errorToReturn
}
log.ID = int64(len(m.logs) + 1)
m.logs = append(m.logs, log)
return nil
}
func (m *MockEmailLogRepository) GetByID(id int64) (*domain.EmailLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, log := range m.logs {
if log.ID == id {
return log, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockEmailLogRepository) List(filters domain.EmailLogFilters, limit, offset int) ([]*domain.EmailLog, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.EmailLog
for _, log := range m.logs {
// Apply filters
if filters.EmailType != nil && log.EmailType != *filters.EmailType {
continue
}
if filters.Success != nil && log.Success != *filters.Success {
continue
}
if filters.RecipientEmail != nil && log.RecipientEmail != *filters.RecipientEmail {
continue
}
result = append(result, log)
}
// Apply pagination
if offset >= len(result) {
return []*domain.EmailLog{}, nil
}
result = result[offset:]
if limit > 0 && len(result) > limit {
result = result[:limit]
}
return result, nil
}
func (m *MockEmailLogRepository) Count(filters domain.EmailLogFilters) (int, error) {
if m.shouldError {
return 0, m.errorToReturn
}
count := 0
for _, log := range m.logs {
// Apply filters
if filters.EmailType != nil && log.EmailType != *filters.EmailType {
continue
}
if filters.Success != nil && log.Success != *filters.Success {
continue
}
if filters.RecipientEmail != nil && log.RecipientEmail != *filters.RecipientEmail {
continue
}
count++
}
return count, nil
}
func (m *MockEmailLogRepository) DeleteOlderThan(before time.Time) (int64, error) {
if m.shouldError {
return 0, m.errorToReturn
}
deleted := int64(0)
var remaining []*domain.EmailLog
for _, log := range m.logs {
if log.CreatedAt.Before(before) {
deleted++
} else {
remaining = append(remaining, log)
}
}
m.logs = remaining
return deleted, nil
}
// createTestEmailLogService creates an EmailLogService with mock repository
func createTestEmailLogService() *service.EmailLogService {
emailLogRepo := NewMockEmailLogRepository()
return service.NewEmailLogService(emailLogRepo)
}
// MockOrganizationSubscriptionRepository is a mock implementation of OrganizationSubscriptionRepository
type MockOrganizationSubscriptionRepository struct {
subscriptions []*domain.OrganizationSubscription
shouldError bool
errorToReturn error
}
func NewMockOrganizationSubscriptionRepository() *MockOrganizationSubscriptionRepository {
return &MockOrganizationSubscriptionRepository{
subscriptions: []*domain.OrganizationSubscription{},
}
}
func (m *MockOrganizationSubscriptionRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockOrganizationSubscriptionRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockOrganizationSubscriptionRepository) Create(sub *domain.OrganizationSubscription) error {
if m.shouldError {
return m.errorToReturn
}
sub.ID = int64(len(m.subscriptions) + 1)
m.subscriptions = append(m.subscriptions, sub)
return nil
}
func (m *MockOrganizationSubscriptionRepository) GetByID(id int64) (*domain.OrganizationSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, sub := range m.subscriptions {
if sub.ID == id {
return sub, nil
}
}
return nil, nil
}
func (m *MockOrganizationSubscriptionRepository) GetActiveByOrganizationID(orgID int64) (*domain.OrganizationSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, sub := range m.subscriptions {
if sub.OrganizationID == orgID && sub.Status == "active" {
return sub, nil
}
}
return nil, nil
}
func (m *MockOrganizationSubscriptionRepository) GetByOrganizationID(orgID int64) ([]*domain.OrganizationSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.OrganizationSubscription
for _, sub := range m.subscriptions {
if sub.OrganizationID == orgID {
result = append(result, sub)
}
}
return result, nil
}
func (m *MockOrganizationSubscriptionRepository) Update(sub *domain.OrganizationSubscription) error {
if m.shouldError {
return m.errorToReturn
}
for i, s := range m.subscriptions {
if s.ID == sub.ID {
m.subscriptions[i] = sub
return nil
}
}
return nil
}
func (m *MockOrganizationSubscriptionRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for i, sub := range m.subscriptions {
if sub.ID == id {
m.subscriptions = append(m.subscriptions[:i], m.subscriptions[i+1:]...)
return nil
}
}
return nil
}
func (m *MockOrganizationSubscriptionRepository) ListAll() ([]*domain.OrganizationSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return m.subscriptions, nil
}
func (m *MockOrganizationSubscriptionRepository) ListExpiring(days int) ([]*domain.OrganizationSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.OrganizationSubscription
deadline := time.Now().AddDate(0, 0, days)
for _, sub := range m.subscriptions {
if sub.Status == "active" && sub.EndDate != nil && sub.EndDate.Before(deadline) {
result = append(result, sub)
}
}
return result, nil
}
func (m *MockOrganizationSubscriptionRepository) ListExpired() ([]*domain.OrganizationSubscription, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.OrganizationSubscription
now := time.Now()
for _, sub := range m.subscriptions {
if sub.Status == "expired" || (sub.EndDate != nil && sub.EndDate.Before(now)) {
result = append(result, sub)
}
}
return result, nil
}
func (m *MockOrganizationSubscriptionRepository) MarkAsPaid(id int64, paymentDate time.Time, adminUserID int64, durationDays *int) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockOrganizationSubscriptionRepository) MarkAsExpired(id int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
func (m *MockOrganizationSubscriptionRepository) Cancel(id int64, reason string, adminUserID int64) error {
if m.shouldError {
return m.errorToReturn
}
return nil
}
// MockSubscriptionAccessRepository is a mock implementation of SubscriptionAccessRepository
type MockSubscriptionAccessRepository struct {
hasAccess bool
shouldError bool
errorToReturn error
}
func NewMockSubscriptionAccessRepository() *MockSubscriptionAccessRepository {
return &MockSubscriptionAccessRepository{
hasAccess: true,
}
}
func (m *MockSubscriptionAccessRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockSubscriptionAccessRepository) ClearError() {
m.shouldError = false
m.errorToReturn = nil
}
func (m *MockSubscriptionAccessRepository) CheckUserAccess(userID int64) (*domain.SubscriptionAccessResult, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return &domain.SubscriptionAccessResult{
HasAccess: m.hasAccess,
Source: "user",
UserSubscription: nil,
OrgSubscriptions: nil,
ExpiresAt: nil,
}, nil
}
// createTestSubscriptionService creates a SubscriptionService with mock repositories
func createTestSubscriptionService() *service.SubscriptionService {
userSubRepo := NewMockUserSubscriptionRepository()
orgSubRepo := NewMockOrganizationSubscriptionRepository()
accessRepo := NewMockSubscriptionAccessRepository()
auditLogRepo := NewMockAuditLogRepository()
userRepo := NewMockUserRepository()
orgRepo := NewMockOrganizationRepository()
return service.NewSubscriptionService(
userSubRepo,
orgSubRepo,
accessRepo,
auditLogRepo,
userRepo,
orgRepo,
)
}
// subscriptionMocks holds references to all mocks for a SubscriptionService
type subscriptionMocks struct {
userSubRepo *MockUserSubscriptionRepository
orgSubRepo *MockOrganizationSubscriptionRepository
accessRepo *MockSubscriptionAccessRepository
auditLogRepo *MockAuditLogRepository
userRepo *MockUserRepository
orgRepo *MockOrganizationRepository
}
// createTestSubscriptionServiceWithMocks creates a SubscriptionService with mock repositories
// and returns both the service and the mocks for testing error paths
func createTestSubscriptionServiceWithMocks() (*service.SubscriptionService, *subscriptionMocks) {
mocks := &subscriptionMocks{
userSubRepo: NewMockUserSubscriptionRepository(),
orgSubRepo: NewMockOrganizationSubscriptionRepository(),
accessRepo: NewMockSubscriptionAccessRepository(),
auditLogRepo: NewMockAuditLogRepository(),
userRepo: NewMockUserRepository(),
orgRepo: NewMockOrganizationRepository(),
}
svc := service.NewSubscriptionService(
mocks.userSubRepo,
mocks.orgSubRepo,
mocks.accessRepo,
mocks.auditLogRepo,
mocks.userRepo,
mocks.orgRepo,
)
return svc, mocks
}
// ===== MockUserWorkoutRepository =====
type MockUserWorkoutRepository struct {
userWorkouts []*domain.UserWorkout
shouldError bool
errorToReturn error
}
func NewMockUserWorkoutRepository() *MockUserWorkoutRepository {
return &MockUserWorkoutRepository{
userWorkouts: []*domain.UserWorkout{},
}
}
func (m *MockUserWorkoutRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockUserWorkoutRepository) Create(userWorkout *domain.UserWorkout) error {
if m.shouldError {
return m.errorToReturn
}
userWorkout.ID = int64(len(m.userWorkouts) + 1)
m.userWorkouts = append(m.userWorkouts, userWorkout)
return nil
}
func (m *MockUserWorkoutRepository) GetByID(id int64) (*domain.UserWorkout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, uw := range m.userWorkouts {
if uw.ID == id {
return uw, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockUserWorkoutRepository) GetByIDWithDetails(id int64, userID int64) (*domain.UserWorkoutWithDetails, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, uw := range m.userWorkouts {
if uw.ID == id && uw.UserID == userID {
return &domain.UserWorkoutWithDetails{
UserWorkout: *uw,
Movements: []*domain.WorkoutMovement{},
WODs: []*domain.WorkoutWODWithDetails{},
}, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockUserWorkoutRepository) ListByUser(userID int64, limit, offset int) ([]*domain.UserWorkout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.UserWorkout
for _, uw := range m.userWorkouts {
if uw.UserID == userID {
result = append(result, uw)
}
}
return result, nil
}
func (m *MockUserWorkoutRepository) ListByUserWithDetails(userID int64, limit, offset int) ([]*domain.UserWorkoutWithDetails, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.UserWorkoutWithDetails
for _, uw := range m.userWorkouts {
if uw.UserID == userID {
result = append(result, &domain.UserWorkoutWithDetails{
UserWorkout: *uw,
Movements: []*domain.WorkoutMovement{},
WODs: []*domain.WorkoutWODWithDetails{},
})
}
}
return result, nil
}
func (m *MockUserWorkoutRepository) ListByUserAndDateRange(userID int64, startDate, endDate time.Time) ([]*domain.UserWorkout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.UserWorkout
for _, uw := range m.userWorkouts {
if uw.UserID == userID {
result = append(result, uw)
}
}
return result, nil
}
func (m *MockUserWorkoutRepository) Update(userWorkout *domain.UserWorkout) error {
if m.shouldError {
return m.errorToReturn
}
for i, uw := range m.userWorkouts {
if uw.ID == userWorkout.ID {
m.userWorkouts[i] = userWorkout
return nil
}
}
return ErrMockNotFound
}
func (m *MockUserWorkoutRepository) Delete(id int64, userID int64) error {
if m.shouldError {
return m.errorToReturn
}
for i, uw := range m.userWorkouts {
if uw.ID == id && uw.UserID == userID {
m.userWorkouts = append(m.userWorkouts[:i], m.userWorkouts[i+1:]...)
return nil
}
}
return ErrMockNotFound
}
func (m *MockUserWorkoutRepository) GetByUserWorkoutDate(userID, workoutID int64, date time.Time) (*domain.UserWorkout, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, uw := range m.userWorkouts {
if uw.UserID == userID && uw.WorkoutID != nil && *uw.WorkoutID == workoutID {
return uw, nil
}
}
return nil, ErrMockNotFound
}
func (m *MockUserWorkoutRepository) GetActiveUsersThisMonth(userID int64) ([]map[string]interface{}, error) {
if m.shouldError {
return nil, m.errorToReturn
}
return []map[string]interface{}{}, nil
}
// ===== MockWorkoutWODRepository =====
type MockWorkoutWODRepository struct {
workoutWODs []*domain.WorkoutWOD
shouldError bool
errorToReturn error
}
func NewMockWorkoutWODRepository() *MockWorkoutWODRepository {
return &MockWorkoutWODRepository{
workoutWODs: []*domain.WorkoutWOD{},
}
}
func (m *MockWorkoutWODRepository) SetError(err error) {
m.shouldError = true
m.errorToReturn = err
}
func (m *MockWorkoutWODRepository) Create(workoutWOD *domain.WorkoutWOD) error {
if m.shouldError {
return m.errorToReturn
}
workoutWOD.ID = int64(len(m.workoutWODs) + 1)
m.workoutWODs = append(m.workoutWODs, workoutWOD)
return nil
}
func (m *MockWorkoutWODRepository) GetByID(id int64) (*domain.WorkoutWOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
for _, ww := range m.workoutWODs {
if ww.ID == id {
return ww, nil
}
}
return nil, nil
}
func (m *MockWorkoutWODRepository) ListByWorkout(workoutID int64) ([]*domain.WorkoutWOD, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.WorkoutWOD
for _, ww := range m.workoutWODs {
if ww.WorkoutID == workoutID {
result = append(result, ww)
}
}
return result, nil
}
func (m *MockWorkoutWODRepository) ListByWorkoutWithDetails(workoutID int64) ([]*domain.WorkoutWODWithDetails, error) {
if m.shouldError {
return nil, m.errorToReturn
}
var result []*domain.WorkoutWODWithDetails
for _, ww := range m.workoutWODs {
if ww.WorkoutID == workoutID {
result = append(result, &domain.WorkoutWODWithDetails{
WorkoutWOD: *ww,
WODName: "Test WOD",
})
}
}
return result, nil
}
func (m *MockWorkoutWODRepository) Update(workoutWOD *domain.WorkoutWOD) error {
if m.shouldError {
return m.errorToReturn
}
for i, ww := range m.workoutWODs {
if ww.ID == workoutWOD.ID {
m.workoutWODs[i] = workoutWOD
return nil
}
}
return ErrMockNotFound
}
func (m *MockWorkoutWODRepository) Delete(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for i, ww := range m.workoutWODs {
if ww.ID == id {
m.workoutWODs = append(m.workoutWODs[:i], m.workoutWODs[i+1:]...)
return nil
}
}
return nil
}
func (m *MockWorkoutWODRepository) DeleteByWorkout(workoutID int64) error {
if m.shouldError {
return m.errorToReturn
}
var remaining []*domain.WorkoutWOD
for _, ww := range m.workoutWODs {
if ww.WorkoutID != workoutID {
remaining = append(remaining, ww)
}
}
m.workoutWODs = remaining
return nil
}
func (m *MockWorkoutWODRepository) TogglePR(id int64) error {
if m.shouldError {
return m.errorToReturn
}
for _, ww := range m.workoutWODs {
if ww.ID == id {
ww.IsPR = !ww.IsPR
return nil
}
}
return ErrMockNotFound
}
// createTestWorkoutWODService creates a WorkoutWODService with mock repositories for testing
func createTestWorkoutWODService() *service.WorkoutWODService {
mockWorkoutWODRepo := NewMockWorkoutWODRepository()
mockWorkoutRepo := NewMockWorkoutRepository()
mockWODRepo := NewMockWODRepository()
// Add a test workout template with a known creator
userID := int64(1)
mockWorkoutRepo.workouts = append(mockWorkoutRepo.workouts, &domain.Workout{
ID: 1,
Name: "Test Workout",
CreatedBy: &userID,
})
// Add a test WOD
mockWODRepo.wods = append(mockWODRepo.wods, &domain.WOD{
ID: 1,
Name: "Test WOD",
ScoreType: "Time (HH:MM:SS)",
})
return service.NewWorkoutWODService(mockWorkoutWODRepo, mockWorkoutRepo, mockWODRepo)
}