package testutil import ( "context" "gorm.io/gorm" "tercul/internal/domain" ) // UnifiedMockWorkRepository is a shared mock for WorkRepository tests // Implements all required methods and uses an in-memory slice type UnifiedMockWorkRepository struct { Works []*domain.Work } func NewUnifiedMockWorkRepository() *UnifiedMockWorkRepository { return &UnifiedMockWorkRepository{Works: []*domain.Work{}} } func (m *UnifiedMockWorkRepository) AddWork(work *domain.Work) { work.ID = uint(len(m.Works) + 1) if work.Language == "" { work.Language = "en" // default for tests, can be set by caller } m.Works = append(m.Works, work) } // BaseRepository methods with context support func (m *UnifiedMockWorkRepository) Create(ctx context.Context, entity *domain.Work) error { m.AddWork(entity) return nil } func (m *UnifiedMockWorkRepository) GetByID(ctx context.Context, id uint) (*domain.Work, error) { for _, w := range m.Works { if w.ID == id { return w, nil } } return nil, domain.ErrEntityNotFound } func (m *UnifiedMockWorkRepository) Update(ctx context.Context, entity *domain.Work) error { for i, w := range m.Works { if w.ID == entity.ID { m.Works[i] = entity return nil } } return domain.ErrEntityNotFound } func (m *UnifiedMockWorkRepository) Delete(ctx context.Context, id uint) error { for i, w := range m.Works { if w.ID == id { m.Works = append(m.Works[:i], m.Works[i+1:]...) return nil } } return domain.ErrEntityNotFound } func (m *UnifiedMockWorkRepository) List(ctx context.Context, page, pageSize int) (*domain.PaginatedResult[domain.Work], error) { var all []domain.Work for _, w := range m.Works { if w != nil { all = append(all, *w) } } total := int64(len(all)) start := (page - 1) * pageSize end := start + pageSize if start > len(all) { return &domain.PaginatedResult[domain.Work]{Items: []domain.Work{}, TotalCount: total}, nil } if end > len(all) { end = len(all) } return &domain.PaginatedResult[domain.Work]{Items: all[start:end], TotalCount: total}, nil } func (m *UnifiedMockWorkRepository) ListAll(ctx context.Context) ([]domain.Work, error) { var all []domain.Work for _, w := range m.Works { if w != nil { all = append(all, *w) } } return all, nil } func (m *UnifiedMockWorkRepository) Count(ctx context.Context) (int64, error) { return int64(len(m.Works)), nil } func (m *UnifiedMockWorkRepository) FindWithPreload(ctx context.Context, preloads []string, id uint) (*domain.Work, error) { for _, w := range m.Works { if w.ID == id { return w, nil } } return nil, domain.ErrEntityNotFound } func (m *UnifiedMockWorkRepository) GetAllForSync(ctx context.Context, batchSize, offset int) ([]domain.Work, error) { var result []domain.Work end := offset + batchSize if end > len(m.Works) { end = len(m.Works) } for i := offset; i < end; i++ { if m.Works[i] != nil { result = append(result, *m.Works[i]) } } return result, nil } // New BaseRepository methods func (m *UnifiedMockWorkRepository) CreateInTx(ctx context.Context, tx *gorm.DB, entity *domain.Work) error { return m.Create(ctx, entity) } func (m *UnifiedMockWorkRepository) GetByIDWithOptions(ctx context.Context, id uint, options *domain.QueryOptions) (*domain.Work, error) { return m.GetByID(ctx, id) } func (m *UnifiedMockWorkRepository) UpdateInTx(ctx context.Context, tx *gorm.DB, entity *domain.Work) error { return m.Update(ctx, entity) } func (m *UnifiedMockWorkRepository) DeleteInTx(ctx context.Context, tx *gorm.DB, id uint) error { return m.Delete(ctx, id) } func (m *UnifiedMockWorkRepository) ListWithOptions(ctx context.Context, options *domain.QueryOptions) ([]domain.Work, error) { result, err := m.List(ctx, 1, 1000) if err != nil { return nil, err } return result.Items, nil } func (m *UnifiedMockWorkRepository) CountWithOptions(ctx context.Context, options *domain.QueryOptions) (int64, error) { return m.Count(ctx) } func (m *UnifiedMockWorkRepository) Exists(ctx context.Context, id uint) (bool, error) { _, err := m.GetByID(ctx, id) return err == nil, nil } func (m *UnifiedMockWorkRepository) BeginTx(ctx context.Context) (*gorm.DB, error) { return nil, nil } func (m *UnifiedMockWorkRepository) WithTx(ctx context.Context, fn func(tx *gorm.DB) error) error { return fn(nil) } // WorkRepository specific methods func (m *UnifiedMockWorkRepository) FindByTitle(ctx context.Context, title string) ([]domain.Work, error) { var result []domain.Work for _, w := range m.Works { if len(title) == 0 || (len(w.Title) >= len(title) && w.Title[:len(title)] == title) { result = append(result, *w) } } return result, nil } func (m *UnifiedMockWorkRepository) FindByLanguage(ctx context.Context, language string, page, pageSize int) (*domain.PaginatedResult[domain.Work], error) { var filtered []domain.Work for _, w := range m.Works { if w.Language == language { filtered = append(filtered, *w) } } total := int64(len(filtered)) start := (page - 1) * pageSize end := start + pageSize if start > len(filtered) { return &domain.PaginatedResult[domain.Work]{Items: []domain.Work{}, TotalCount: total}, nil } if end > len(filtered) { end = len(filtered) } return &domain.PaginatedResult[domain.Work]{Items: filtered[start:end], TotalCount: total}, nil } func (m *UnifiedMockWorkRepository) FindByAuthor(ctx context.Context, authorID uint) ([]domain.Work, error) { result := make([]domain.Work, len(m.Works)) for i, w := range m.Works { if w != nil { result[i] = *w } } return result, nil } func (m *UnifiedMockWorkRepository) FindByCategory(ctx context.Context, categoryID uint) ([]domain.Work, error) { result := make([]domain.Work, len(m.Works)) for i, w := range m.Works { if w != nil { result[i] = *w } } return result, nil } func (m *UnifiedMockWorkRepository) GetWithTranslations(ctx context.Context, id uint) (*domain.Work, error) { for _, w := range m.Works { if w.ID == id { return w, nil } } return nil, domain.ErrEntityNotFound } func (m *UnifiedMockWorkRepository) ListWithTranslations(ctx context.Context, page, pageSize int) (*domain.PaginatedResult[domain.Work], error) { var all []domain.Work for _, w := range m.Works { if w != nil { all = append(all, *w) } } total := int64(len(all)) start := (page - 1) * pageSize end := start + pageSize if start > len(all) { return &domain.PaginatedResult[domain.Work]{Items: []domain.Work{}, TotalCount: total}, nil } if end > len(all) { end = len(all) } return &domain.PaginatedResult[domain.Work]{Items: all[start:end], TotalCount: total}, nil } func (m *UnifiedMockWorkRepository) Reset() { m.Works = []*domain.Work{} } // Add helper to get GraphQL-style Work with Name mapped from Title func (m *UnifiedMockWorkRepository) GetGraphQLWorkByID(id uint) map[string]interface{} { for _, w := range m.Works { if w.ID == id { return map[string]interface{}{ "id": w.ID, "name": w.Title, "language": w.Language, "content": "", } } } return nil } // Add other interface methods as needed for your tests