From 2fde7f1ff76a018f884741d6f6aeaaf9d5c4524b Mon Sep 17 00:00:00 2001 From: oabrivard Date: Fri, 13 Feb 2026 10:44:41 +0100 Subject: [PATCH] Improved code comments --- .../internal/application/admin/service.go | 1 + .../infra/persistence/postgres/audit_repo.go | 1 + .../internal/interfaces/http/handler.go | 1 + .../tests/integration_http_test.go | 13 +++++++ .../application/session/service_test.go | 31 ++++++++++++++++ .../interfaces/http/handler_unit_test.go | 5 +++ .../tests/integration_http_test.go | 35 +++++++++++++++++++ .../http/middleware/middleware_test.go | 12 +++++++ .../tests/integration_http_test.go | 9 +++++ .../application/leaderboard/service_test.go | 24 +++++++++++++ .../interfaces/http/handler_unit_test.go | 5 +++ .../tests/integration_http_test.go | 26 ++++++++++++++ .../application/question/service_test.go | 5 +++ .../tests/integration_http_test.go | 19 ++++++++++ .../internal/application/user/service_test.go | 7 ++++ .../tests/integration_http_test.go | 2 ++ backend/shared/domain/events/event_test.go | 2 ++ .../shared/infra/auth/zitadel/client_test.go | 4 +++ .../infra/auth/zitadel/middleware_test.go | 1 + .../infra/database/redis/client_test.go | 1 + .../infra/observability/metrics/http_test.go | 2 ++ .../shared/infra/utils/envutil/env_test.go | 8 +++++ .../infra/utils/serviceboot/fiber_test.go | 6 ++++ 23 files changed, 220 insertions(+) diff --git a/backend/services/admin-service/internal/application/admin/service.go b/backend/services/admin-service/internal/application/admin/service.go index 54b7830..d962bf1 100644 --- a/backend/services/admin-service/internal/application/admin/service.go +++ b/backend/services/admin-service/internal/application/admin/service.go @@ -15,6 +15,7 @@ type Service struct { retention time.Duration } +// NewService builds an admin service with a retention period in days. func NewService(auditRepo audit.Repository, retentionDays int) *Service { if retentionDays <= 0 { retentionDays = 90 diff --git a/backend/services/admin-service/internal/infra/persistence/postgres/audit_repo.go b/backend/services/admin-service/internal/infra/persistence/postgres/audit_repo.go index 473f12b..76c4f87 100644 --- a/backend/services/admin-service/internal/infra/persistence/postgres/audit_repo.go +++ b/backend/services/admin-service/internal/infra/persistence/postgres/audit_repo.go @@ -17,6 +17,7 @@ type AuditRepository struct { db *sharedpostgres.Client } +// NewAuditRepository creates a PostgreSQL-backed audit repository. func NewAuditRepository(db *sharedpostgres.Client) *AuditRepository { return &AuditRepository{db: db} } diff --git a/backend/services/admin-service/internal/interfaces/http/handler.go b/backend/services/admin-service/internal/interfaces/http/handler.go index 7c6b16b..20f7d25 100644 --- a/backend/services/admin-service/internal/interfaces/http/handler.go +++ b/backend/services/admin-service/internal/interfaces/http/handler.go @@ -20,6 +20,7 @@ type Handler struct { metrics *metrics.Metrics } +// NewHandler creates HTTP handlers for admin endpoints. func NewHandler(svc *appadmin.Service, logger *logging.Logger, metrics *metrics.Metrics) *Handler { return &Handler{svc: svc, logger: logger, metrics: metrics} } diff --git a/backend/services/admin-service/tests/integration_http_test.go b/backend/services/admin-service/tests/integration_http_test.go index f249ca4..4606cf3 100644 --- a/backend/services/admin-service/tests/integration_http_test.go +++ b/backend/services/admin-service/tests/integration_http_test.go @@ -1,5 +1,7 @@ package tests +// integration_http_test.go contains tests for backend behavior. + import ( "context" "encoding/json" @@ -28,12 +30,15 @@ type inMemoryAuditRepo struct { appendErr error } +// newInMemoryAuditRepo is a test helper. func newInMemoryAuditRepo() *inMemoryAuditRepo { return &inMemoryAuditRepo{entries: make([]audit.Entry, 0)} } +// EnsureSchema is a test helper. func (r *inMemoryAuditRepo) EnsureSchema(ctx context.Context) error { return nil } +// Append is a test helper. func (r *inMemoryAuditRepo) Append(ctx context.Context, e audit.Entry) error { if r.appendErr != nil { return r.appendErr @@ -42,6 +47,7 @@ func (r *inMemoryAuditRepo) Append(ctx context.Context, e audit.Entry) error { return nil } +// List is a test helper. func (r *inMemoryAuditRepo) List(ctx context.Context, limit, offset int) ([]audit.Entry, error) { if r.listErr != nil { return nil, r.listErr @@ -58,6 +64,7 @@ func (r *inMemoryAuditRepo) List(ctx context.Context, limit, offset int) ([]audi return out, nil } +// Count is a test helper. func (r *inMemoryAuditRepo) Count(ctx context.Context) (int64, error) { if r.countErr != nil { return 0, r.countErr @@ -65,10 +72,12 @@ func (r *inMemoryAuditRepo) Count(ctx context.Context) (int64, error) { return int64(len(r.entries)), nil } +// PruneBefore is a test helper. func (r *inMemoryAuditRepo) PruneBefore(ctx context.Context, before time.Time) (int64, error) { return 0, nil } +// setupApp is a test helper. func setupApp(t *testing.T, repo *inMemoryAuditRepo) *fiber.App { t.Helper() @@ -105,6 +114,7 @@ func setupApp(t *testing.T, repo *inMemoryAuditRepo) *fiber.App { return app } +// TestAdminAuthRoute verifies expected behavior. func TestAdminAuthRoute(t *testing.T) { repo := newInMemoryAuditRepo() app := setupApp(t, repo) @@ -123,6 +133,7 @@ func TestAdminAuthRoute(t *testing.T) { } } +// TestDashboardRouteSuccessAndErrors verifies expected behavior. func TestDashboardRouteSuccessAndErrors(t *testing.T) { t.Run("forbidden for non-admin", func(t *testing.T) { repo := newInMemoryAuditRepo() @@ -170,6 +181,7 @@ func TestDashboardRouteSuccessAndErrors(t *testing.T) { }) } +// TestAuditRouteSuccessAndErrors verifies expected behavior. func TestAuditRouteSuccessAndErrors(t *testing.T) { t.Run("forbidden for non-admin", func(t *testing.T) { repo := newInMemoryAuditRepo() @@ -221,6 +233,7 @@ func TestAuditRouteSuccessAndErrors(t *testing.T) { }) } +// TestRegisterRoutesDoesNotPanic verifies expected behavior. func TestRegisterRoutesDoesNotPanic(t *testing.T) { app := fiber.New() repo := newInMemoryAuditRepo() diff --git a/backend/services/game-session-service/internal/application/session/service_test.go b/backend/services/game-session-service/internal/application/session/service_test.go index 17e8abe..d023a9d 100644 --- a/backend/services/game-session-service/internal/application/session/service_test.go +++ b/backend/services/game-session-service/internal/application/session/service_test.go @@ -1,5 +1,7 @@ package session +// service_test.go contains tests for backend behavior. + import ( "context" "errors" @@ -17,6 +19,7 @@ type fakeRepo struct { events []*domain.SessionEvent } +// newFakeRepo is a test helper. func newFakeRepo() *fakeRepo { return &fakeRepo{ sessions: map[string]*domain.GameSession{}, @@ -25,8 +28,10 @@ func newFakeRepo() *fakeRepo { } } +// EnsureSchema is a test helper. func (r *fakeRepo) EnsureSchema(ctx context.Context) error { return nil } +// CreateSession is a test helper. func (r *fakeRepo) CreateSession(ctx context.Context, session *domain.GameSession) (*domain.GameSession, error) { session.ID = "sess-1" now := time.Now().UTC() @@ -37,6 +42,7 @@ func (r *fakeRepo) CreateSession(ctx context.Context, session *domain.GameSessio return &cp, nil } +// GetSessionByID is a test helper. func (r *fakeRepo) GetSessionByID(ctx context.Context, id string) (*domain.GameSession, error) { s, ok := r.sessions[id] if !ok { @@ -46,6 +52,7 @@ func (r *fakeRepo) GetSessionByID(ctx context.Context, id string) (*domain.GameS return &cp, nil } +// GetActiveSessionByPlayerID is a test helper. func (r *fakeRepo) GetActiveSessionByPlayerID(ctx context.Context, playerID string) (*domain.GameSession, error) { for _, s := range r.sessions { if s.PlayerID == playerID && s.Status == domain.StatusActive { @@ -56,6 +63,7 @@ func (r *fakeRepo) GetActiveSessionByPlayerID(ctx context.Context, playerID stri return nil, domain.ErrSessionNotFound } +// UpdateSession is a test helper. func (r *fakeRepo) UpdateSession(ctx context.Context, session *domain.GameSession) (*domain.GameSession, error) { if _, ok := r.sessions[session.ID]; !ok { return nil, domain.ErrSessionNotFound @@ -66,18 +74,21 @@ func (r *fakeRepo) UpdateSession(ctx context.Context, session *domain.GameSessio return &cp, nil } +// CreateAttempt is a test helper. func (r *fakeRepo) CreateAttempt(ctx context.Context, attempt *domain.SessionAttempt) error { cp := *attempt r.attempts = append(r.attempts, &cp) return nil } +// CreateEvent is a test helper. func (r *fakeRepo) CreateEvent(ctx context.Context, event *domain.SessionEvent) error { cp := *event r.events = append(r.events, &cp) return nil } +// ListQuestionIDsForSession is a test helper. func (r *fakeRepo) ListQuestionIDsForSession(ctx context.Context, sessionID string) ([]string, error) { seen := map[string]bool{} ids := make([]string, 0) @@ -100,6 +111,7 @@ type fakeQuestionBank struct { answerOK bool } +// GetRandomQuestion is a test helper. func (f *fakeQuestionBank) GetRandomQuestion( ctx context.Context, exclusions []string, @@ -119,6 +131,7 @@ func (f *fakeQuestionBank) GetRandomQuestion( return nil, sharederrors.New(sharederrors.CodeNoQuestionsAvailable, "no questions available") } +// GetQuestionByID is a test helper. func (f *fakeQuestionBank) GetQuestionByID(ctx context.Context, id string) (*SessionQuestion, error) { for _, q := range f.questions { if q.ID == id { @@ -129,6 +142,7 @@ func (f *fakeQuestionBank) GetQuestionByID(ctx context.Context, id string) (*Ses return nil, sharederrors.New(sharederrors.CodeQuestionNotFound, "question not found") } +// ValidateAnswer is a test helper. func (f *fakeQuestionBank) ValidateAnswer( ctx context.Context, questionID, answer string, @@ -141,6 +155,7 @@ type fakeUserClient struct { profile UserProfile } +// GetUserProfile is a test helper. func (f *fakeUserClient) GetUserProfile(ctx context.Context, userID, bearerToken string) (*UserProfile, error) { p := f.profile if p.ID == "" { @@ -156,6 +171,7 @@ type fakeStateStore struct { locks map[string]bool } +// newFakeStateStore is a test helper. func newFakeStateStore() *fakeStateStore { return &fakeStateStore{ active: map[string]string{}, @@ -164,30 +180,43 @@ func newFakeStateStore() *fakeStateStore { } } +// GetActiveSession is a test helper. func (s *fakeStateStore) GetActiveSession(ctx context.Context, playerID string) (string, bool) { id, ok := s.active[playerID] return id, ok } + +// SetActiveSession is a test helper. func (s *fakeStateStore) SetActiveSession(ctx context.Context, playerID, sessionID string, ttl time.Duration) error { s.active[playerID] = sessionID return nil } + +// ClearActiveSession is a test helper. func (s *fakeStateStore) ClearActiveSession(ctx context.Context, playerID string) error { delete(s.active, playerID) return nil } + +// SetTimer is a test helper. func (s *fakeStateStore) SetTimer(ctx context.Context, sessionID string, expiresAt time.Time, ttl time.Duration) error { s.timers[sessionID] = expiresAt return nil } + +// GetTimer is a test helper. func (s *fakeStateStore) GetTimer(ctx context.Context, sessionID string) (time.Time, bool) { t, ok := s.timers[sessionID] return t, ok } + +// ClearTimer is a test helper. func (s *fakeStateStore) ClearTimer(ctx context.Context, sessionID string) error { delete(s.timers, sessionID) return nil } + +// AcquireLock is a test helper. func (s *fakeStateStore) AcquireLock(ctx context.Context, sessionID string, ttl time.Duration) bool { if s.locks[sessionID] { return false @@ -195,6 +224,8 @@ func (s *fakeStateStore) AcquireLock(ctx context.Context, sessionID string, ttl s.locks[sessionID] = true return true } + +// ReleaseLock is a test helper. func (s *fakeStateStore) ReleaseLock(ctx context.Context, sessionID string) { delete(s.locks, sessionID) } diff --git a/backend/services/game-session-service/internal/interfaces/http/handler_unit_test.go b/backend/services/game-session-service/internal/interfaces/http/handler_unit_test.go index 791e47c..f70446f 100644 --- a/backend/services/game-session-service/internal/interfaces/http/handler_unit_test.go +++ b/backend/services/game-session-service/internal/interfaces/http/handler_unit_test.go @@ -1,5 +1,7 @@ package http +// handler_unit_test.go contains tests for backend behavior. + import ( "bytes" "net/http" @@ -11,6 +13,7 @@ import ( "knowfoolery/backend/shared/infra/utils/validation" ) +// TestUnauthorizedBranches verifies expected behavior. func TestUnauthorizedBranches(t *testing.T) { h := NewHandler(nil, validation.NewValidator(), nil, nil) app := fiber.New() @@ -45,6 +48,7 @@ func TestUnauthorizedBranches(t *testing.T) { } } +// TestStartAndEndValidationBranches verifies expected behavior. func TestStartAndEndValidationBranches(t *testing.T) { h := NewHandler(nil, validation.NewValidator(), nil, nil) app := fiber.New() @@ -103,6 +107,7 @@ func TestStartAndEndValidationBranches(t *testing.T) { } +// TestBearerTokenAndClaimsHelpers verifies expected behavior. func TestBearerTokenAndClaimsHelpers(t *testing.T) { app := fiber.New() app.Use(func(c fiber.Ctx) error { diff --git a/backend/services/game-session-service/tests/integration_http_test.go b/backend/services/game-session-service/tests/integration_http_test.go index 3de5f39..634175b 100644 --- a/backend/services/game-session-service/tests/integration_http_test.go +++ b/backend/services/game-session-service/tests/integration_http_test.go @@ -29,6 +29,7 @@ type inMemoryRepo struct { attempts []*domain.SessionAttempt } +// newInMemoryRepo is a test helper. func newInMemoryRepo() *inMemoryRepo { return &inMemoryRepo{ sessions: map[string]*domain.GameSession{}, @@ -36,8 +37,10 @@ func newInMemoryRepo() *inMemoryRepo { } } +// EnsureSchema is a test helper. func (r *inMemoryRepo) EnsureSchema(ctx context.Context) error { return nil } +// CreateSession is a test helper. func (r *inMemoryRepo) CreateSession(ctx context.Context, session *domain.GameSession) (*domain.GameSession, error) { session.ID = "sess-1" now := time.Now().UTC() @@ -48,6 +51,7 @@ func (r *inMemoryRepo) CreateSession(ctx context.Context, session *domain.GameSe return &cp, nil } +// GetSessionByID is a test helper. func (r *inMemoryRepo) GetSessionByID(ctx context.Context, id string) (*domain.GameSession, error) { s, ok := r.sessions[id] if !ok { @@ -57,6 +61,7 @@ func (r *inMemoryRepo) GetSessionByID(ctx context.Context, id string) (*domain.G return &cp, nil } +// GetActiveSessionByPlayerID is a test helper. func (r *inMemoryRepo) GetActiveSessionByPlayerID(ctx context.Context, playerID string) (*domain.GameSession, error) { for _, s := range r.sessions { if s.PlayerID == playerID && s.Status == domain.StatusActive { @@ -67,6 +72,7 @@ func (r *inMemoryRepo) GetActiveSessionByPlayerID(ctx context.Context, playerID return nil, domain.ErrSessionNotFound } +// UpdateSession is a test helper. func (r *inMemoryRepo) UpdateSession(ctx context.Context, session *domain.GameSession) (*domain.GameSession, error) { cp := *session cp.UpdatedAt = time.Now().UTC() @@ -74,14 +80,17 @@ func (r *inMemoryRepo) UpdateSession(ctx context.Context, session *domain.GameSe return &cp, nil } +// CreateAttempt is a test helper. func (r *inMemoryRepo) CreateAttempt(ctx context.Context, attempt *domain.SessionAttempt) error { cp := *attempt r.attempts = append(r.attempts, &cp) return nil } +// CreateEvent is a test helper. func (r *inMemoryRepo) CreateEvent(ctx context.Context, event *domain.SessionEvent) error { return nil } +// ListQuestionIDsForSession is a test helper. func (r *inMemoryRepo) ListQuestionIDsForSession(ctx context.Context, sessionID string) ([]string, error) { seen := map[string]bool{} ids := make([]string, 0) @@ -103,6 +112,7 @@ type fakeQuestionBank struct { questions []appsession.SessionQuestion } +// GetRandomQuestion is a test helper. func (f *fakeQuestionBank) GetRandomQuestion( ctx context.Context, exclusions []string, @@ -122,6 +132,7 @@ func (f *fakeQuestionBank) GetRandomQuestion( return nil, domain.ErrSessionNotFound } +// GetQuestionByID is a test helper. func (f *fakeQuestionBank) GetQuestionByID(ctx context.Context, id string) (*appsession.SessionQuestion, error) { for _, q := range f.questions { if q.ID == id { @@ -132,6 +143,7 @@ func (f *fakeQuestionBank) GetQuestionByID(ctx context.Context, id string) (*app return nil, domain.ErrSessionNotFound } +// ValidateAnswer is a test helper. func (f *fakeQuestionBank) ValidateAnswer( ctx context.Context, questionID, answer string, @@ -145,6 +157,7 @@ func (f *fakeQuestionBank) ValidateAnswer( // fakeUserClient returns a verified user profile for tests. type fakeUserClient struct{} +// GetUserProfile is a test helper. func (f *fakeUserClient) GetUserProfile( ctx context.Context, userID, bearerToken string, @@ -162,6 +175,7 @@ type fakeStateStore struct { locks map[string]bool } +// newFakeStateStore is a test helper. func newFakeStateStore() *fakeStateStore { return &fakeStateStore{ active: map[string]string{}, @@ -169,25 +183,38 @@ func newFakeStateStore() *fakeStateStore { } } +// GetActiveSession is a test helper. func (s *fakeStateStore) GetActiveSession(ctx context.Context, playerID string) (string, bool) { id, ok := s.active[playerID] return id, ok } + +// SetActiveSession is a test helper. func (s *fakeStateStore) SetActiveSession(ctx context.Context, playerID, sessionID string, ttl time.Duration) error { s.active[playerID] = sessionID return nil } + +// ClearActiveSession is a test helper. func (s *fakeStateStore) ClearActiveSession(ctx context.Context, playerID string) error { delete(s.active, playerID) return nil } + +// SetTimer is a test helper. func (s *fakeStateStore) SetTimer(ctx context.Context, sessionID string, expiresAt time.Time, ttl time.Duration) error { return nil } + +// GetTimer is a test helper. func (s *fakeStateStore) GetTimer(ctx context.Context, sessionID string) (time.Time, bool) { return time.Time{}, false } + +// ClearTimer is a test helper. func (s *fakeStateStore) ClearTimer(ctx context.Context, sessionID string) error { return nil } + +// AcquireLock is a test helper. func (s *fakeStateStore) AcquireLock(ctx context.Context, sessionID string, ttl time.Duration) bool { if s.locks[sessionID] { return false @@ -195,6 +222,8 @@ func (s *fakeStateStore) AcquireLock(ctx context.Context, sessionID string, ttl s.locks[sessionID] = true return true } + +// ReleaseLock is a test helper. func (s *fakeStateStore) ReleaseLock(ctx context.Context, sessionID string) { delete(s.locks, sessionID) } @@ -343,6 +372,7 @@ func TestMetricsEndpoint(t *testing.T) { assertStatus(t, resp, http.StatusOK, "metrics failed") } +// mustJSONRequest is a test helper. func mustJSONRequest( t *testing.T, app *fiber.App, @@ -369,6 +399,7 @@ func mustJSONRequest( return sharedhttpx.MustTest(t, app, req) } +// assertStatus is a test helper. func assertStatus(t *testing.T, resp *http.Response, want int, msg string) { t.Helper() if resp.StatusCode != want { @@ -376,6 +407,7 @@ func assertStatus(t *testing.T, resp *http.Response, want int, msg string) { } } +// decodeDataMap is a test helper. func decodeDataMap(t *testing.T, resp *http.Response) map[string]any { t.Helper() @@ -389,6 +421,7 @@ func decodeDataMap(t *testing.T, resp *http.Response) map[string]any { return payload.Data } +// asMap is a test helper. func asMap(t *testing.T, v any) map[string]any { t.Helper() m, ok := v.(map[string]any) @@ -398,6 +431,7 @@ func asMap(t *testing.T, v any) map[string]any { return m } +// asString is a test helper. func asString(t *testing.T, v any) string { t.Helper() s, ok := v.(string) @@ -407,6 +441,7 @@ func asString(t *testing.T, v any) string { return s } +// decodeAny is a test helper. func decodeAny(t *testing.T, resp *http.Response) map[string]any { t.Helper() diff --git a/backend/services/gateway-service/internal/interfaces/http/middleware/middleware_test.go b/backend/services/gateway-service/internal/interfaces/http/middleware/middleware_test.go index 7101810..814d4c4 100644 --- a/backend/services/gateway-service/internal/interfaces/http/middleware/middleware_test.go +++ b/backend/services/gateway-service/internal/interfaces/http/middleware/middleware_test.go @@ -1,5 +1,7 @@ package middleware +// middleware_test.go contains tests for backend behavior. + import ( "net/http" "net/http/httptest" @@ -16,6 +18,7 @@ import ( "knowfoolery/backend/shared/infra/observability/logging" ) +// TestCORSMiddleware verifies expected behavior. func TestCORSMiddleware(t *testing.T) { app := fiber.New() app.Use(CORS(gconfig.CORSConfig{ @@ -66,6 +69,7 @@ func TestCORSMiddleware(t *testing.T) { } } +// TestCORSAllowAll verifies expected behavior. func TestCORSAllowAll(t *testing.T) { app := fiber.New() app.Use(CORS(gconfig.CORSConfig{AllowedOrigins: []string{"*"}})) @@ -83,6 +87,7 @@ func TestCORSAllowAll(t *testing.T) { } } +// TestSecurityHeadersMiddleware verifies expected behavior. func TestSecurityHeadersMiddleware(t *testing.T) { app := fiber.New() app.Use(SecurityHeaders(gconfig.SecurityHeadersConfig{ @@ -118,6 +123,7 @@ func TestSecurityHeadersMiddleware(t *testing.T) { } } +// TestSecurityHeadersNoHSTSOnHTTP verifies expected behavior. func TestSecurityHeadersNoHSTSOnHTTP(t *testing.T) { app := fiber.New() app.Use(SecurityHeaders(gconfig.SecurityHeadersConfig{ @@ -137,6 +143,7 @@ func TestSecurityHeadersNoHSTSOnHTTP(t *testing.T) { } } +// TestRequestContextMiddlewareAndRequestID verifies expected behavior. func TestRequestContextMiddlewareAndRequestID(t *testing.T) { app := fiber.New() app.Use(RequestContext(nil)) @@ -172,6 +179,7 @@ func TestRequestContextMiddlewareAndRequestID(t *testing.T) { } } +// TestRequestContextWithLoggerAndInvalidRequestIDLocal verifies expected behavior. func TestRequestContextWithLoggerAndInvalidRequestIDLocal(t *testing.T) { logger := logging.NewLogger(logging.DefaultConfig()) app := fiber.New() @@ -195,6 +203,7 @@ func TestRequestContextWithLoggerAndInvalidRequestIDLocal(t *testing.T) { } } +// TestRateLimitMiddlewareDegradedModeAndHelpers verifies expected behavior. func TestRateLimitMiddlewareDegradedModeAndHelpers(t *testing.T) { app := fiber.New() mw := RateLimitMiddleware(nil, gconfig.RateLimitConfig{ @@ -296,6 +305,7 @@ func TestRateLimitMiddlewareDegradedModeAndHelpers(t *testing.T) { } } +// TestRateLimitMiddlewareRedisAllowedAndBlocked verifies expected behavior. func TestRateLimitMiddlewareRedisAllowedAndBlocked(t *testing.T) { mr, err := miniredis.Run() if err != nil { @@ -348,6 +358,7 @@ func TestRateLimitMiddlewareRedisAllowedAndBlocked(t *testing.T) { } } +// TestRateLimitMiddlewareRedisErrorDegrades verifies expected behavior. func TestRateLimitMiddlewareRedisErrorDegrades(t *testing.T) { // Use a client pointing to an unreachable endpoint to force script.Run error. client := redisv9.NewClient(&redisv9.Options{Addr: "127.0.0.1:1"}) @@ -379,6 +390,7 @@ func TestRateLimitMiddlewareRedisErrorDegrades(t *testing.T) { } } +// TestIdentifyRequester verifies expected behavior. func TestIdentifyRequester(t *testing.T) { app := fiber.New() app.Get("/id", func(c fiber.Ctx) error { diff --git a/backend/services/gateway-service/tests/integration_http_test.go b/backend/services/gateway-service/tests/integration_http_test.go index 935ce93..7dc643a 100644 --- a/backend/services/gateway-service/tests/integration_http_test.go +++ b/backend/services/gateway-service/tests/integration_http_test.go @@ -1,5 +1,7 @@ package tests +// integration_http_test.go contains tests for backend behavior. + import ( "io" "net/http" @@ -19,6 +21,7 @@ import ( "knowfoolery/backend/shared/infra/auth/zitadel" ) +// TestGateway_PublicRoute_ProxiesAndRewritesPath verifies expected behavior. func TestGateway_PublicRoute_ProxiesAndRewritesPath(t *testing.T) { t.Parallel() @@ -46,6 +49,7 @@ func TestGateway_PublicRoute_ProxiesAndRewritesPath(t *testing.T) { require.Equal(t, "degraded", res.Header.Get("X-RateLimit-Policy")) } +// TestGateway_ProtectedRoute_RequiresAuth verifies expected behavior. func TestGateway_ProtectedRoute_RequiresAuth(t *testing.T) { t.Parallel() @@ -63,6 +67,7 @@ func TestGateway_ProtectedRoute_RequiresAuth(t *testing.T) { require.Equal(t, http.StatusUnauthorized, res.StatusCode) } +// TestGateway_ProtectedRoute_ForwardsUserHeaders verifies expected behavior. func TestGateway_ProtectedRoute_ForwardsUserHeaders(t *testing.T) { t.Parallel() @@ -90,6 +95,7 @@ func TestGateway_ProtectedRoute_ForwardsUserHeaders(t *testing.T) { require.Equal(t, "true", received["x-user-mfa"]) } +// TestGateway_PreflightCors verifies expected behavior. func TestGateway_PreflightCors(t *testing.T) { t.Parallel() @@ -110,6 +116,7 @@ func TestGateway_PreflightCors(t *testing.T) { require.Equal(t, "http://localhost:5173", res.Header.Get("Access-Control-Allow-Origin")) } +// buildTestApp is a test helper. func buildTestApp(t *testing.T, upstreamURL string, client *http.Client) *fiber.App { t.Helper() @@ -179,10 +186,12 @@ func buildTestApp(t *testing.T, upstreamURL string, client *http.Client) *fiber. type roundTripperFunc func(*http.Request) (*http.Response, error) +// RoundTrip is a test helper. func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) { return fn(req) } +// jsonResponse is a test helper. func jsonResponse(status int, body string) *http.Response { return &http.Response{ StatusCode: status, diff --git a/backend/services/leaderboard-service/internal/application/leaderboard/service_test.go b/backend/services/leaderboard-service/internal/application/leaderboard/service_test.go index 183899d..4d2a473 100644 --- a/backend/services/leaderboard-service/internal/application/leaderboard/service_test.go +++ b/backend/services/leaderboard-service/internal/application/leaderboard/service_test.go @@ -1,5 +1,7 @@ package leaderboard +// service_test.go contains tests for backend behavior. + import ( "context" "encoding/json" @@ -23,6 +25,7 @@ type fakeRepo struct { globalErr error } +// newFakeRepo is a test helper. func newFakeRepo() *fakeRepo { return &fakeRepo{ entries: make([]*domain.LeaderboardEntry, 0), @@ -30,8 +33,10 @@ func newFakeRepo() *fakeRepo { } } +// EnsureSchema is a test helper. func (r *fakeRepo) EnsureSchema(ctx context.Context) error { return nil } +// IngestEntry is a test helper. func (r *fakeRepo) IngestEntry( ctx context.Context, entry *domain.LeaderboardEntry, @@ -88,6 +93,7 @@ func (r *fakeRepo) IngestEntry( return &cp, false, nil } +// ListTop is a test helper. func (r *fakeRepo) ListTop( ctx context.Context, filter domain.TopFilter, @@ -106,6 +112,7 @@ func (r *fakeRepo) ListTop( return out, nil } +// GetPlayerStats is a test helper. func (r *fakeRepo) GetPlayerStats(ctx context.Context, playerID string) (*domain.PlayerStats, error) { if r.statsErr != nil { return nil, r.statsErr @@ -118,6 +125,7 @@ func (r *fakeRepo) GetPlayerStats(ctx context.Context, playerID string) (*domain return &cp, nil } +// GetPlayerRank is a test helper. func (r *fakeRepo) GetPlayerRank(ctx context.Context, playerID string) (int64, error) { if r.rankErr != nil { return 0, r.rankErr @@ -128,6 +136,7 @@ func (r *fakeRepo) GetPlayerRank(ctx context.Context, playerID string) (int64, e return 1, nil } +// ListPlayerHistory is a test helper. func (r *fakeRepo) ListPlayerHistory( ctx context.Context, playerID string, @@ -145,6 +154,7 @@ func (r *fakeRepo) ListPlayerHistory( return out, int64(len(out)), nil } +// GetGlobalStats is a test helper. func (r *fakeRepo) GetGlobalStats(ctx context.Context, filter domain.TopFilter) (*domain.GlobalStats, error) { if r.globalErr != nil { return nil, r.globalErr @@ -158,13 +168,18 @@ type fakeState struct { deleteErr error } +// newFakeState is a test helper. func newFakeState() *fakeState { return &fakeState{data: map[string]string{}} } + +// Get is a test helper. func (s *fakeState) Get(ctx context.Context, key string) (string, bool) { v, ok := s.data[key] return v, ok } + +// Set is a test helper. func (s *fakeState) Set(ctx context.Context, key, value string, ttl time.Duration) error { if s.setErr != nil { return s.setErr @@ -172,6 +187,8 @@ func (s *fakeState) Set(ctx context.Context, key, value string, ttl time.Duratio s.data[key] = value return nil } + +// Delete is a test helper. func (s *fakeState) Delete(ctx context.Context, keys ...string) error { if s.deleteErr != nil { return s.deleteErr @@ -182,6 +199,7 @@ func (s *fakeState) Delete(ctx context.Context, keys ...string) error { return nil } +// TestUpdateScoreIdempotent verifies expected behavior. func TestUpdateScoreIdempotent(t *testing.T) { repo := newFakeRepo() state := newFakeState() @@ -212,6 +230,7 @@ func TestUpdateScoreIdempotent(t *testing.T) { } } +// TestUpdateScoreValidatesInput verifies expected behavior. func TestUpdateScoreValidatesInput(t *testing.T) { svc := NewService(newFakeRepo(), newFakeState(), Config{}) _, err := svc.UpdateScore(context.Background(), UpdateScoreInput{ @@ -230,6 +249,7 @@ func TestUpdateScoreValidatesInput(t *testing.T) { } } +// TestGetPlayerRanking verifies expected behavior. func TestGetPlayerRanking(t *testing.T) { repo := newFakeRepo() state := newFakeState() @@ -264,6 +284,7 @@ func TestGetPlayerRanking(t *testing.T) { } } +// TestUpdateScoreValidationAndErrorPaths verifies expected behavior. func TestUpdateScoreValidationAndErrorPaths(t *testing.T) { svc := NewService(newFakeRepo(), newFakeState(), Config{}) cases := []UpdateScoreInput{ @@ -291,6 +312,7 @@ func TestUpdateScoreValidationAndErrorPaths(t *testing.T) { } } +// TestTopAndStatsCachePaths verifies expected behavior. func TestTopAndStatsCachePaths(t *testing.T) { repo := newFakeRepo() state := newFakeState() @@ -346,6 +368,7 @@ func TestTopAndStatsCachePaths(t *testing.T) { } } +// TestRankingValidationAndErrorPaths verifies expected behavior. func TestRankingValidationAndErrorPaths(t *testing.T) { repo := newFakeRepo() state := newFakeState() @@ -400,6 +423,7 @@ func TestRankingValidationAndErrorPaths(t *testing.T) { } } +// TestGlobalStatsAndTopErrors verifies expected behavior. func TestGlobalStatsAndTopErrors(t *testing.T) { repo := newFakeRepo() repo.topErr = errors.New("top boom") diff --git a/backend/services/leaderboard-service/internal/interfaces/http/handler_unit_test.go b/backend/services/leaderboard-service/internal/interfaces/http/handler_unit_test.go index ed181fb..a27a0a1 100644 --- a/backend/services/leaderboard-service/internal/interfaces/http/handler_unit_test.go +++ b/backend/services/leaderboard-service/internal/interfaces/http/handler_unit_test.go @@ -1,5 +1,7 @@ package http +// handler_unit_test.go contains tests for backend behavior. + import ( "bytes" "net/http" @@ -11,6 +13,7 @@ import ( "knowfoolery/backend/shared/infra/utils/validation" ) +// TestUpdateAuthAndValidationBranches verifies expected behavior. func TestUpdateAuthAndValidationBranches(t *testing.T) { h := NewHandler(nil, validation.NewValidator(), nil, nil, true, 20, 100) app := fiber.New() @@ -86,6 +89,7 @@ func TestUpdateAuthAndValidationBranches(t *testing.T) { } } +// TestGetPlayerRankingForbiddenBranch verifies expected behavior. func TestGetPlayerRankingForbiddenBranch(t *testing.T) { h := NewHandler(nil, validation.NewValidator(), nil, nil, false, 20, 100) app := fiber.New() @@ -107,6 +111,7 @@ func TestGetPlayerRankingForbiddenBranch(t *testing.T) { } } +// TestHelperFunctions verifies expected behavior. func TestHelperFunctions(t *testing.T) { if got := atoiWithDefault("", 3); got != 3 { t.Fatalf("expected default for empty input") diff --git a/backend/services/leaderboard-service/tests/integration_http_test.go b/backend/services/leaderboard-service/tests/integration_http_test.go index 2bfe02d..113837b 100644 --- a/backend/services/leaderboard-service/tests/integration_http_test.go +++ b/backend/services/leaderboard-service/tests/integration_http_test.go @@ -1,5 +1,7 @@ package tests +// integration_http_test.go contains tests for backend behavior. + import ( "bytes" "context" @@ -27,6 +29,7 @@ type inMemoryRepo struct { stats map[string]*domain.PlayerStats } +// newInMemoryRepo is a test helper. func newInMemoryRepo() *inMemoryRepo { return &inMemoryRepo{ entries: make([]*domain.LeaderboardEntry, 0), @@ -34,7 +37,10 @@ func newInMemoryRepo() *inMemoryRepo { } } +// EnsureSchema is a test helper. func (r *inMemoryRepo) EnsureSchema(ctx context.Context) error { return nil } + +// IngestEntry is a test helper. func (r *inMemoryRepo) IngestEntry( ctx context.Context, entry *domain.LeaderboardEntry, @@ -68,6 +74,8 @@ func (r *inMemoryRepo) IngestEntry( } return &cp, false, nil } + +// ListTop is a test helper. func (r *inMemoryRepo) ListTop( ctx context.Context, filter domain.TopFilter, @@ -82,6 +90,8 @@ func (r *inMemoryRepo) ListTop( } return out, nil } + +// GetPlayerStats is a test helper. func (r *inMemoryRepo) GetPlayerStats(ctx context.Context, playerID string) (*domain.PlayerStats, error) { stats := r.stats[playerID] if stats == nil { @@ -90,12 +100,16 @@ func (r *inMemoryRepo) GetPlayerStats(ctx context.Context, playerID string) (*do cp := *stats return &cp, nil } + +// GetPlayerRank is a test helper. func (r *inMemoryRepo) GetPlayerRank(ctx context.Context, playerID string) (int64, error) { if _, ok := r.stats[playerID]; !ok { return 0, domain.ErrPlayerNotFound } return 1, nil } + +// ListPlayerHistory is a test helper. func (r *inMemoryRepo) ListPlayerHistory( ctx context.Context, playerID string, @@ -109,6 +123,8 @@ func (r *inMemoryRepo) ListPlayerHistory( } return out, int64(len(out)), nil } + +// GetGlobalStats is a test helper. func (r *inMemoryRepo) GetGlobalStats(ctx context.Context, filter domain.TopFilter) (*domain.GlobalStats, error) { return &domain.GlobalStats{ TotalGames: int64(len(r.entries)), @@ -119,12 +135,18 @@ func (r *inMemoryRepo) GetGlobalStats(ctx context.Context, filter domain.TopFilt type fakeState struct{} +// Get is a test helper. func (s *fakeState) Get(ctx context.Context, key string) (string, bool) { return "", false } + +// Set is a test helper. func (s *fakeState) Set(ctx context.Context, key, value string, ttl time.Duration) error { return nil } + +// Delete is a test helper. func (s *fakeState) Delete(ctx context.Context, keys ...string) error { return nil } +// setupApp is a test helper. func setupApp(t *testing.T) *fiber.App { t.Helper() repo := newInMemoryRepo() @@ -156,6 +178,7 @@ func setupApp(t *testing.T) *fiber.App { return app } +// TestUpdateAndTop10 verifies expected behavior. func TestUpdateAndTop10(t *testing.T) { app := setupApp(t) @@ -188,6 +211,7 @@ func TestUpdateAndTop10(t *testing.T) { } } +// TestPlayerAuthAndStats verifies expected behavior. func TestPlayerAuthAndStats(t *testing.T) { app := setupApp(t) @@ -215,6 +239,7 @@ func TestPlayerAuthAndStats(t *testing.T) { } } +// TestMetricsEndpoint verifies expected behavior. func TestMetricsEndpoint(t *testing.T) { app := setupApp(t) req := httptest.NewRequest(http.MethodGet, "/metrics", nil) @@ -225,6 +250,7 @@ func TestMetricsEndpoint(t *testing.T) { } } +// assertStatus is a test helper. func assertStatus(t *testing.T, resp *http.Response, want int, msg string) { t.Helper() if resp.StatusCode != want { diff --git a/backend/services/question-bank-service/internal/application/question/service_test.go b/backend/services/question-bank-service/internal/application/question/service_test.go index c6e5f8c..00ed36f 100644 --- a/backend/services/question-bank-service/internal/application/question/service_test.go +++ b/backend/services/question-bank-service/internal/application/question/service_test.go @@ -219,6 +219,7 @@ func TestValidateAnswerByQuestionID_ValidationError(t *testing.T) { } } +// TestGetRandomQuestion_InvalidDifficulty verifies expected behavior. func TestGetRandomQuestion_InvalidDifficulty(t *testing.T) { svc := NewService(&fakeRepo{}, &fakeCache{}, time.Minute, 200) _, err := svc.GetRandomQuestion(context.Background(), RandomQuestionRequest{ @@ -229,6 +230,7 @@ func TestGetRandomQuestion_InvalidDifficulty(t *testing.T) { } } +// TestGetRandomQuestion_RepoErrors verifies expected behavior. func TestGetRandomQuestion_RepoErrors(t *testing.T) { repo := &fakeRepo{countErr: errors.New("count boom")} svc := NewService(repo, &fakeCache{}, time.Minute, 200) @@ -249,6 +251,7 @@ func TestGetRandomQuestion_RepoErrors(t *testing.T) { } } +// TestQuestionCRUDAndThemes verifies expected behavior. func TestQuestionCRUDAndThemes(t *testing.T) { repo := &fakeRepo{} cache := &fakeCache{} @@ -304,6 +307,7 @@ func TestQuestionCRUDAndThemes(t *testing.T) { } } +// TestQuestionCRUDValidationAndErrors verifies expected behavior. func TestQuestionCRUDValidationAndErrors(t *testing.T) { repo := &fakeRepo{createErr: errors.New("create boom")} svc := NewService(repo, &fakeCache{}, time.Minute, 200) @@ -353,6 +357,7 @@ func TestQuestionCRUDValidationAndErrors(t *testing.T) { } } +// TestBulkImportScenarios verifies expected behavior. func TestBulkImportScenarios(t *testing.T) { cache := &fakeCache{} repo := &fakeRepo{bulkCount: 1, bulkErrors: []domain.BulkError{{Index: 0, Reason: "row"}}} diff --git a/backend/services/question-bank-service/tests/integration_http_test.go b/backend/services/question-bank-service/tests/integration_http_test.go index 7ee98c1..882b800 100644 --- a/backend/services/question-bank-service/tests/integration_http_test.go +++ b/backend/services/question-bank-service/tests/integration_http_test.go @@ -29,22 +29,28 @@ type inMemoryRepo struct { items map[string]*domain.Question } +// newInMemoryRepo is a test helper. func newInMemoryRepo() *inMemoryRepo { return &inMemoryRepo{items: map[string]*domain.Question{}} } +// GetByID is a test helper. func (r *inMemoryRepo) GetByID(ctx context.Context, id string) (*domain.Question, error) { if q, ok := r.items[id]; ok { return q, nil } return nil, domain.ErrQuestionNotFound } + +// Create is a test helper. func (r *inMemoryRepo) Create(ctx context.Context, q *domain.Question) (*domain.Question, error) { q.ID = "q-created" q.IsActive = true r.items[q.ID] = q return q, nil } + +// Update is a test helper. func (r *inMemoryRepo) Update(ctx context.Context, id string, q *domain.Question) (*domain.Question, error) { if _, ok := r.items[id]; !ok { return nil, domain.ErrQuestionNotFound @@ -53,6 +59,8 @@ func (r *inMemoryRepo) Update(ctx context.Context, id string, q *domain.Question r.items[id] = q return q, nil } + +// SoftDelete is a test helper. func (r *inMemoryRepo) SoftDelete(ctx context.Context, id string) error { if q, ok := r.items[id]; ok { q.IsActive = false @@ -60,9 +68,13 @@ func (r *inMemoryRepo) SoftDelete(ctx context.Context, id string) error { } return domain.ErrQuestionNotFound } + +// ListThemes is a test helper. func (r *inMemoryRepo) ListThemes(ctx context.Context) ([]string, error) { return []string{"Science"}, nil } + +// CountRandomCandidates is a test helper. func (r *inMemoryRepo) CountRandomCandidates(ctx context.Context, filter domain.RandomFilter) (int, error) { count := 0 for _, q := range r.items { @@ -73,6 +85,8 @@ func (r *inMemoryRepo) CountRandomCandidates(ctx context.Context, filter domain. } return count, nil } + +// RandomByOffset is a test helper. func (r *inMemoryRepo) RandomByOffset(ctx context.Context, filter domain.RandomFilter, offset int) (*domain.Question, error) { for _, q := range r.items { @@ -82,6 +96,8 @@ func (r *inMemoryRepo) RandomByOffset(ctx context.Context, } return nil, domain.ErrNoQuestionsAvailable } + +// BulkCreate is a test helper. func (r *inMemoryRepo) BulkCreate(ctx context.Context, questions []*domain.Question) (int, []domain.BulkError, error) { for i, q := range questions { id := "bulk-" + strconv.Itoa(i) @@ -95,12 +111,15 @@ func (r *inMemoryRepo) BulkCreate(ctx context.Context, questions []*domain.Quest // noOpCache disables caching behavior in HTTP integration tests. type noOpCache struct{} +// Get is a test helper. func (c *noOpCache) Get(ctx context.Context, key string) (*domain.Question, bool) { return nil, false } +// Set is a test helper. func (c *noOpCache) Set(ctx context.Context, key string, q *domain.Question, ttl time.Duration) {} +// Invalidate is a test helper. func (c *noOpCache) Invalidate(ctx context.Context) {} // setupApp wires a test Fiber app with in-memory dependencies and admin middleware. diff --git a/backend/services/user-service/internal/application/user/service_test.go b/backend/services/user-service/internal/application/user/service_test.go index 5fba8fd..32dd2e6 100644 --- a/backend/services/user-service/internal/application/user/service_test.go +++ b/backend/services/user-service/internal/application/user/service_test.go @@ -1,5 +1,7 @@ package user +// service_test.go contains tests for backend behavior. + import ( "context" "errors" @@ -247,6 +249,7 @@ func TestDeleteAndExport(t *testing.T) { } } +// TestRegisterValidationAndRepoErrors verifies expected behavior. func TestRegisterValidationAndRepoErrors(t *testing.T) { svc := NewService(newFakeRepo()) _, err := svc.Register(context.Background(), RegisterInput{}) @@ -305,6 +308,7 @@ func TestRegisterValidationAndRepoErrors(t *testing.T) { } } +// TestProfileAndEmailFlows verifies expected behavior. func TestProfileAndEmailFlows(t *testing.T) { repo := newFakeRepo() svc := NewService(repo) @@ -345,6 +349,7 @@ func TestProfileAndEmailFlows(t *testing.T) { } } +// TestProfileValidationAndRepoErrors verifies expected behavior. func TestProfileValidationAndRepoErrors(t *testing.T) { repo := newFakeRepo() svc := NewService(repo) @@ -395,6 +400,7 @@ func TestProfileValidationAndRepoErrors(t *testing.T) { } } +// TestAdminListAndExport verifies expected behavior. func TestAdminListAndExport(t *testing.T) { repo := newFakeRepo() svc := NewService(repo) @@ -432,6 +438,7 @@ func TestAdminListAndExport(t *testing.T) { } } +// TestDeleteListExportErrors verifies expected behavior. func TestDeleteListExportErrors(t *testing.T) { repo := newFakeRepo() svc := NewService(repo) diff --git a/backend/services/user-service/tests/integration_http_test.go b/backend/services/user-service/tests/integration_http_test.go index df8fd7a..80d410b 100644 --- a/backend/services/user-service/tests/integration_http_test.go +++ b/backend/services/user-service/tests/integration_http_test.go @@ -1,5 +1,7 @@ package tests +// integration_http_test.go contains tests for backend behavior. + import ( "bytes" "context" diff --git a/backend/shared/domain/events/event_test.go b/backend/shared/domain/events/event_test.go index 0d3ffc4..1b455c7 100644 --- a/backend/shared/domain/events/event_test.go +++ b/backend/shared/domain/events/event_test.go @@ -54,10 +54,12 @@ func TestEventType_NonEmpty(t *testing.T) { type dummyEventBus struct{} +// Publish is a test helper. func (d *dummyEventBus) Publish(_ context.Context, _ Event) error { return nil } +// Subscribe is a test helper. func (d *dummyEventBus) Subscribe(_ EventHandler) error { return nil } diff --git a/backend/shared/infra/auth/zitadel/client_test.go b/backend/shared/infra/auth/zitadel/client_test.go index e4fffca..f0c7b60 100644 --- a/backend/shared/infra/auth/zitadel/client_test.go +++ b/backend/shared/infra/auth/zitadel/client_test.go @@ -33,6 +33,7 @@ type jwks struct { Keys []jwksKey `json:"keys"` } +// generateJWKS is a test helper. func generateJWKS(t *testing.T) (*rsa.PrivateKey, jwks, string) { t.Helper() key, err := rsa.GenerateKey(rand.Reader, 2048) @@ -56,6 +57,7 @@ func generateJWKS(t *testing.T) (*rsa.PrivateKey, jwks, string) { }, kid } +// signToken is a test helper. func signToken(t *testing.T, key *rsa.PrivateKey, kid string, claims jwt.MapClaims) string { t.Helper() token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) @@ -65,6 +67,7 @@ func signToken(t *testing.T, key *rsa.PrivateKey, kid string, claims jwt.MapClai return signed } +// newOIDCServer is a test helper. func newOIDCServer(t *testing.T, jwksDoc jwks) *httptest.Server { t.Helper() var baseURL string @@ -295,6 +298,7 @@ func TestRefreshToken_UsesForm(t *testing.T) { require.Contains(t, captured, "client_id=client") } +// serverURL is a test helper. func serverURL(r *http.Request) string { return "http://" + r.Host } diff --git a/backend/shared/infra/auth/zitadel/middleware_test.go b/backend/shared/infra/auth/zitadel/middleware_test.go index cb519fe..02c32e2 100644 --- a/backend/shared/infra/auth/zitadel/middleware_test.go +++ b/backend/shared/infra/auth/zitadel/middleware_test.go @@ -19,6 +19,7 @@ type fakeValidator struct { called int } +// ValidateToken is a test helper. func (f *fakeValidator) ValidateToken(ctx context.Context, token string, _ ValidationOptions) (*AuthClaims, error) { f.called++ return f.claims, f.err diff --git a/backend/shared/infra/database/redis/client_test.go b/backend/shared/infra/database/redis/client_test.go index 97fff9a..01d8795 100644 --- a/backend/shared/infra/database/redis/client_test.go +++ b/backend/shared/infra/database/redis/client_test.go @@ -28,6 +28,7 @@ func TestAddr(t *testing.T) { require.Equal(t, "localhost:6379", cfg.Addr()) } +// newClientForMiniRedis is a test helper. func newClientForMiniRedis(t *testing.T) (*Client, *miniredis.Miniredis) { t.Helper() diff --git a/backend/shared/infra/observability/metrics/http_test.go b/backend/shared/infra/observability/metrics/http_test.go index 9f27fc1..75fd573 100644 --- a/backend/shared/infra/observability/metrics/http_test.go +++ b/backend/shared/infra/observability/metrics/http_test.go @@ -1,5 +1,7 @@ package metrics +// http_test.go contains tests for backend behavior. + import ( "net/http" "net/http/httptest" diff --git a/backend/shared/infra/utils/envutil/env_test.go b/backend/shared/infra/utils/envutil/env_test.go index 741fbae..90af497 100644 --- a/backend/shared/infra/utils/envutil/env_test.go +++ b/backend/shared/infra/utils/envutil/env_test.go @@ -1,5 +1,7 @@ package envutil +// env_test.go contains tests for backend behavior. + import ( "testing" "time" @@ -7,31 +9,37 @@ import ( "github.com/stretchr/testify/require" ) +// TestString verifies expected behavior. func TestString(t *testing.T) { t.Setenv("APP_VALUE", "configured") require.Equal(t, "configured", String("APP_VALUE", "fallback")) } +// TestStringFallback verifies expected behavior. func TestStringFallback(t *testing.T) { t.Setenv("APP_VALUE", "") require.Equal(t, "fallback", String("APP_VALUE", "fallback")) } +// TestInt verifies expected behavior. func TestInt(t *testing.T) { t.Setenv("APP_PORT", "8080") require.Equal(t, 8080, Int("APP_PORT", 3000)) } +// TestIntFallbackInvalid verifies expected behavior. func TestIntFallbackInvalid(t *testing.T) { t.Setenv("APP_PORT", "oops") require.Equal(t, 3000, Int("APP_PORT", 3000)) } +// TestDuration verifies expected behavior. func TestDuration(t *testing.T) { t.Setenv("APP_TIMEOUT", "7s") require.Equal(t, 7*time.Second, Duration("APP_TIMEOUT", time.Second)) } +// TestDurationFallbackInvalid verifies expected behavior. func TestDurationFallbackInvalid(t *testing.T) { t.Setenv("APP_TIMEOUT", "oops") require.Equal(t, 2*time.Second, Duration("APP_TIMEOUT", 2*time.Second)) diff --git a/backend/shared/infra/utils/serviceboot/fiber_test.go b/backend/shared/infra/utils/serviceboot/fiber_test.go index c32de88..529a454 100644 --- a/backend/shared/infra/utils/serviceboot/fiber_test.go +++ b/backend/shared/infra/utils/serviceboot/fiber_test.go @@ -1,5 +1,7 @@ package serviceboot +// fiber_test.go contains tests for backend behavior. + import ( "encoding/json" "net/http" @@ -9,6 +11,7 @@ import ( "github.com/stretchr/testify/require" ) +// TestRegisterHealth verifies expected behavior. func TestRegisterHealth(t *testing.T) { app := NewFiberApp(Config{AppName: "test-service"}) RegisterHealth(app, "svc") @@ -24,16 +27,19 @@ func TestRegisterHealth(t *testing.T) { require.Equal(t, "svc", body["service"]) } +// TestListenAddressFromEnv verifies expected behavior. func TestListenAddressFromEnv(t *testing.T) { t.Setenv("SERVICE_PORT", "9090") require.Equal(t, ":9090", ListenAddress("SERVICE_PORT", 8080)) } +// TestListenAddressFallback verifies expected behavior. func TestListenAddressFallback(t *testing.T) { t.Setenv("SERVICE_PORT", "bad") require.Equal(t, ":8080", ListenAddress("SERVICE_PORT", 8080)) } +// TestListenAddressOutOfRangeFallback verifies expected behavior. func TestListenAddressOutOfRangeFallback(t *testing.T) { t.Setenv("SERVICE_PORT", "70000") require.Equal(t, ":8080", ListenAddress("SERVICE_PORT", 8080))