mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
refactor(festa): extract festa logic into FestaService
The festa handler contained event lifecycle management (cleanup expired events, create new ones) and the repo enforced a business rule (skip zero-value soul submissions). Move these into a new FestaService to keep repos as pure data access and consolidate business logic.
This commit is contained in:
138
server/channelserver/svc_festa_test.go
Normal file
138
server/channelserver/svc_festa_test.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package channelserver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func newTestFestaService(mock *mockFestaRepo) *FestaService {
|
||||
logger, _ := zap.NewDevelopment()
|
||||
return NewFestaService(mock, logger)
|
||||
}
|
||||
|
||||
// --- EnsureActiveEvent tests ---
|
||||
|
||||
func TestFestaService_EnsureActiveEvent_StillActive(t *testing.T) {
|
||||
mock := &mockFestaRepo{}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
now := time.Unix(1000000, 0)
|
||||
start := uint32(now.Unix() - 100) // started 100s ago, well within lifespan
|
||||
|
||||
result, err := svc.EnsureActiveEvent(start, now, now.Add(24*time.Hour))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if result != start {
|
||||
t.Errorf("start = %d, want %d (unchanged)", result, start)
|
||||
}
|
||||
if mock.cleanupCalled {
|
||||
t.Error("CleanupAll should not be called when event is active")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFestaService_EnsureActiveEvent_Expired(t *testing.T) {
|
||||
mock := &mockFestaRepo{}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
now := time.Unix(10000000, 0)
|
||||
expiredStart := uint32(1) // long expired
|
||||
nextMidnight := now.Add(24 * time.Hour)
|
||||
|
||||
result, err := svc.EnsureActiveEvent(expiredStart, now, nextMidnight)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !mock.cleanupCalled {
|
||||
t.Error("CleanupAll should be called for expired event")
|
||||
}
|
||||
if result != uint32(nextMidnight.Unix()) {
|
||||
t.Errorf("start = %d, want %d (next midnight)", result, uint32(nextMidnight.Unix()))
|
||||
}
|
||||
if mock.insertedStart != uint32(nextMidnight.Unix()) {
|
||||
t.Errorf("insertedStart = %d, want %d", mock.insertedStart, uint32(nextMidnight.Unix()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFestaService_EnsureActiveEvent_NoEvent(t *testing.T) {
|
||||
mock := &mockFestaRepo{}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
now := time.Unix(1000000, 0)
|
||||
nextMidnight := now.Add(24 * time.Hour)
|
||||
|
||||
result, err := svc.EnsureActiveEvent(0, now, nextMidnight)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !mock.cleanupCalled {
|
||||
t.Error("CleanupAll should be called when no event exists")
|
||||
}
|
||||
if result != uint32(nextMidnight.Unix()) {
|
||||
t.Errorf("start = %d, want %d", result, uint32(nextMidnight.Unix()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFestaService_EnsureActiveEvent_CleanupError(t *testing.T) {
|
||||
mock := &mockFestaRepo{cleanupErr: errors.New("db error")}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
now := time.Unix(10000000, 0)
|
||||
_, err := svc.EnsureActiveEvent(0, now, now.Add(24*time.Hour))
|
||||
if err == nil {
|
||||
t.Fatal("expected error from cleanup failure")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFestaService_EnsureActiveEvent_InsertError(t *testing.T) {
|
||||
mock := &mockFestaRepo{insertErr: errors.New("db error")}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
now := time.Unix(10000000, 0)
|
||||
_, err := svc.EnsureActiveEvent(0, now, now.Add(24*time.Hour))
|
||||
if err == nil {
|
||||
t.Fatal("expected error from insert failure")
|
||||
}
|
||||
}
|
||||
|
||||
// --- SubmitSouls tests ---
|
||||
|
||||
func TestFestaService_SubmitSouls_FiltersZeros(t *testing.T) {
|
||||
mock := &mockFestaRepo{}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
err := svc.SubmitSouls(1, 10, []uint16{0, 5, 0, 3, 0})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
// Should call repo with the full slice (repo does batch insert)
|
||||
if mock.submittedSouls == nil {
|
||||
t.Fatal("SubmitSouls should be called on repo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFestaService_SubmitSouls_AllZeros(t *testing.T) {
|
||||
mock := &mockFestaRepo{}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
err := svc.SubmitSouls(1, 10, []uint16{0, 0, 0})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if mock.submittedSouls != nil {
|
||||
t.Error("SubmitSouls should not call repo when all zeros")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFestaService_SubmitSouls_RepoError(t *testing.T) {
|
||||
mock := &mockFestaRepo{submitErr: errors.New("db error")}
|
||||
svc := newTestFestaService(mock)
|
||||
|
||||
err := svc.SubmitSouls(1, 10, []uint16{5, 0, 3})
|
||||
if err == nil {
|
||||
t.Fatal("expected error from repo failure")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user