rdev/internal/handlers/mock_operation_test.go
jordan 62460bf098 feat: complete template upgrade - chassis framework, UI library, auth, app-nextjs, OpenAPI, and cookbook
Weeks 1-7 of the template upgrade plan:
- pkg/api: typed HTTPError with sentinels, Wrap/WrapMiddleware, Bind, health probes, OpenAPI schema/param builders
- skeleton/packages: ui (design tokens, components), layout (DashboardShell), auth (AuthProvider, ProtectedRoute), api-client
- skeleton/pkg: httperror, app/handler, app/bind, app/health, auth (JWT/API key middleware)
- components/app-nextjs: Next.js 14 App Router template with dashboard, server actions, auth
- cookbooks/feature-development.md with test and validation scripts
- Handler tests for components, project management, and woodpecker webhook
- 3 rounds of code review fixes applied

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:46:51 -07:00

147 lines
3.4 KiB
Go

package handlers
import (
"context"
"sync"
"time"
"github.com/orchard9/rdev/internal/domain"
)
// mockOperationRepo is a mock implementation of port.OperationRepository for testing.
type mockOperationRepo struct {
mu sync.Mutex
operations map[string]*domain.Operation
}
func newMockOperationRepo() *mockOperationRepo {
return &mockOperationRepo{
operations: make(map[string]*domain.Operation),
}
}
func (m *mockOperationRepo) Create(_ context.Context, op *domain.Operation) error {
m.mu.Lock()
defer m.mu.Unlock()
m.operations[op.ID] = op
return nil
}
func (m *mockOperationRepo) Update(_ context.Context, op *domain.Operation) error {
m.mu.Lock()
defer m.mu.Unlock()
m.operations[op.ID] = op
return nil
}
func (m *mockOperationRepo) Get(_ context.Context, id string) (*domain.Operation, error) {
m.mu.Lock()
defer m.mu.Unlock()
op, ok := m.operations[id]
if !ok {
return nil, domain.ErrOperationNotFound
}
return op, nil
}
func (m *mockOperationRepo) GetByCommitSHA(_ context.Context, projectID, sha string) (*domain.Operation, error) {
m.mu.Lock()
defer m.mu.Unlock()
for _, op := range m.operations {
if op.ProjectID == projectID && op.CommitSHA == sha {
return op, nil
}
}
return nil, domain.ErrOperationNotFound
}
func (m *mockOperationRepo) List(_ context.Context, filter domain.OperationFilters) ([]*domain.Operation, error) {
m.mu.Lock()
defer m.mu.Unlock()
var result []*domain.Operation
for _, op := range m.operations {
if filter.ProjectID != "" && op.ProjectID != filter.ProjectID {
continue
}
result = append(result, op)
}
return result, nil
}
func (m *mockOperationRepo) AddStep(_ context.Context, operationID string, step domain.OperationStep) error {
m.mu.Lock()
defer m.mu.Unlock()
op, ok := m.operations[operationID]
if !ok {
return domain.ErrOperationNotFound
}
op.Steps = append(op.Steps, step)
return nil
}
func (m *mockOperationRepo) UpdateStep(_ context.Context, operationID string, step domain.OperationStep) error {
m.mu.Lock()
defer m.mu.Unlock()
op, ok := m.operations[operationID]
if !ok {
return domain.ErrOperationNotFound
}
for i, s := range op.Steps {
if s.Name == step.Name {
op.Steps[i] = step
return nil
}
}
return nil
}
func (m *mockOperationRepo) Complete(_ context.Context, operationID string, status domain.OperationStatus, output map[string]any, errMsg, errDetail string) error {
m.mu.Lock()
defer m.mu.Unlock()
op, ok := m.operations[operationID]
if !ok {
return domain.ErrOperationNotFound
}
op.Status = status
now := time.Now()
op.CompletedAt = &now
op.DurationMs = now.Sub(op.StartedAt).Milliseconds()
op.Output = output
op.Error = errMsg
op.ErrorDetail = errDetail
return nil
}
func (m *mockOperationRepo) SetCommitSHA(_ context.Context, operationID, sha string) error {
m.mu.Lock()
defer m.mu.Unlock()
op, ok := m.operations[operationID]
if !ok {
return domain.ErrOperationNotFound
}
op.CommitSHA = sha
return nil
}
func (m *mockOperationRepo) SetTriggeredBy(_ context.Context, operationID, parentID string) error {
m.mu.Lock()
defer m.mu.Unlock()
op, ok := m.operations[operationID]
if !ok {
return domain.ErrOperationNotFound
}
op.TriggeredBy = parentID
return nil
}
func (m *mockOperationRepo) DeleteOlderThan(_ context.Context, _ time.Time) (int64, error) {
return 0, nil
}
// count returns the number of operations stored.
func (m *mockOperationRepo) count() int {
m.mu.Lock()
defer m.mu.Unlock()
return len(m.operations)
}