refactor: introduce clock to make tests reproducible
This commit is contained in:
@@ -5,12 +5,16 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/wotra/wotra/internal/clock"
|
||||
"github.com/wotra/wotra/internal/domain"
|
||||
"github.com/wotra/wotra/internal/service"
|
||||
"github.com/wotra/wotra/internal/store"
|
||||
)
|
||||
|
||||
func newTestDayServices(t *testing.T) (*service.EntryService, *service.DayService, *service.SettingsService) {
|
||||
// dayTestAnchor is a fixed Tuesday used as "now" across day service tests.
|
||||
var dayTestAnchor = time.Date(2026, 5, 13, 10, 0, 0, 0, time.UTC)
|
||||
|
||||
func newTestDayServices(t *testing.T) (*service.EntryService, *service.DayService, *service.SettingsService, *clock.FixedClock) {
|
||||
t.Helper()
|
||||
db, err := store.Open(":memory:")
|
||||
if err != nil {
|
||||
@@ -24,18 +28,18 @@ func newTestDayServices(t *testing.T) (*service.EntryService, *service.DayServic
|
||||
settingsStore := store.NewSettingsStore(db)
|
||||
syncStore := store.NewSyncStore(db)
|
||||
tz, _ := time.LoadLocation("UTC")
|
||||
clk := clock.Fixed(dayTestAnchor)
|
||||
|
||||
entrySvc := service.NewEntryService(entryStore, closedDayStore, settingsStore, syncStore, tz)
|
||||
daySvc := service.NewDayService(entryStore, closedDayStore, closedWeekStore, settingsStore, syncStore, tz)
|
||||
settingsSvc := service.NewSettingsService(settingsStore, syncStore)
|
||||
return entrySvc, daySvc, settingsSvc
|
||||
entrySvc := service.NewEntryService(entryStore, closedDayStore, settingsStore, syncStore, tz, clk)
|
||||
daySvc := service.NewDayService(entryStore, closedDayStore, closedWeekStore, settingsStore, syncStore, tz, clk)
|
||||
settingsSvc := service.NewSettingsService(settingsStore, syncStore, clk)
|
||||
return entrySvc, daySvc, settingsSvc, clk
|
||||
}
|
||||
|
||||
func TestCloseDayBasic(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
entrySvc, daySvc, _ := newTestDayServices(t)
|
||||
entrySvc, daySvc, _, clk := newTestDayServices(t)
|
||||
|
||||
// Start and stop an entry
|
||||
_, err := entrySvc.Start(ctx, "work")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -45,7 +49,7 @@ func TestCloseDayBasic(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
today := time.Now().UTC().Format("2006-01-02")
|
||||
today := clk.Now().UTC().Format("2006-01-02")
|
||||
cd, err := daySvc.CloseDay(ctx, today)
|
||||
if err != nil {
|
||||
t.Fatalf("CloseDay: %v", err)
|
||||
@@ -60,14 +64,14 @@ func TestCloseDayBasic(t *testing.T) {
|
||||
|
||||
func TestCloseDayWithRunningEntryFails(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
entrySvc, daySvc, _ := newTestDayServices(t)
|
||||
entrySvc, daySvc, _, clk := newTestDayServices(t)
|
||||
|
||||
_, err := entrySvc.Start(ctx, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
today := time.Now().UTC().Format("2006-01-02")
|
||||
today := clk.Now().UTC().Format("2006-01-02")
|
||||
_, err = daySvc.CloseDay(ctx, today)
|
||||
if err == nil {
|
||||
t.Fatal("expected error closing day with running entry")
|
||||
@@ -79,11 +83,11 @@ func TestCloseDayWithRunningEntryFails(t *testing.T) {
|
||||
|
||||
func TestCloseDayTwiceFails(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
entrySvc, daySvc, _ := newTestDayServices(t)
|
||||
entrySvc, daySvc, _, clk := newTestDayServices(t)
|
||||
|
||||
entrySvc.Start(ctx, "")
|
||||
entrySvc.Stop(ctx)
|
||||
today := time.Now().UTC().Format("2006-01-02")
|
||||
today := clk.Now().UTC().Format("2006-01-02")
|
||||
daySvc.CloseDay(ctx, today)
|
||||
|
||||
_, err := daySvc.CloseDay(ctx, today)
|
||||
@@ -94,9 +98,9 @@ func TestCloseDayTwiceFails(t *testing.T) {
|
||||
|
||||
func TestMarkDayHoliday(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, daySvc, _ := newTestDayServices(t)
|
||||
_, daySvc, _, clk := newTestDayServices(t)
|
||||
|
||||
today := time.Now().UTC().Format("2006-01-02")
|
||||
today := clk.Now().UTC().Format("2006-01-02")
|
||||
cd, err := daySvc.MarkDay(ctx, today, domain.DayKindHoliday)
|
||||
if err != nil {
|
||||
t.Fatalf("MarkDay: %v", err)
|
||||
@@ -104,32 +108,28 @@ func TestMarkDayHoliday(t *testing.T) {
|
||||
if cd.Kind != domain.DayKindHoliday {
|
||||
t.Errorf("expected kind=holiday, got %s", cd.Kind)
|
||||
}
|
||||
// Monday-Friday = 40h/5 = 8h = 28800000ms expected
|
||||
if today == time.Now().UTC().Format("2006-01-02") {
|
||||
wd := int(time.Now().UTC().Weekday())
|
||||
// workdays Mon-Fri (mask=31): weekdays 1-5
|
||||
if wd >= 1 && wd <= 5 {
|
||||
if cd.WorkedMs != 8*3600*1000 {
|
||||
t.Errorf("expected 8h worked_ms for holiday on workday, got %d", cd.WorkedMs)
|
||||
}
|
||||
// dayTestAnchor is a Tuesday (weekday 2): Mon-Fri workdays → 40h/5 = 8h = 28800000ms
|
||||
wd := int(clk.Now().UTC().Weekday())
|
||||
if wd >= 1 && wd <= 5 {
|
||||
if cd.WorkedMs != 8*3600*1000 {
|
||||
t.Errorf("expected 8h worked_ms for holiday on workday, got %d", cd.WorkedMs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReopenDay(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
entrySvc, daySvc, _ := newTestDayServices(t)
|
||||
entrySvc, daySvc, _, clk := newTestDayServices(t)
|
||||
|
||||
entrySvc.Start(ctx, "")
|
||||
entrySvc.Stop(ctx)
|
||||
today := time.Now().UTC().Format("2006-01-02")
|
||||
today := clk.Now().UTC().Format("2006-01-02")
|
||||
daySvc.CloseDay(ctx, today)
|
||||
|
||||
if err := daySvc.ReopenDay(ctx, today); err != nil {
|
||||
t.Fatalf("ReopenDay: %v", err)
|
||||
}
|
||||
|
||||
// Should be closeable again
|
||||
_, err := daySvc.CloseDay(ctx, today)
|
||||
if err != nil {
|
||||
t.Fatalf("CloseDay after reopen: %v", err)
|
||||
@@ -138,7 +138,7 @@ func TestReopenDay(t *testing.T) {
|
||||
|
||||
func TestSettingsUpsertAndHistory(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, _, settingsSvc := newTestDayServices(t)
|
||||
_, _, settingsSvc, _ := newTestDayServices(t)
|
||||
|
||||
set, err := settingsSvc.Upsert(ctx, service.UpsertSettingsInput{
|
||||
EffectiveFrom: "2024-01-01",
|
||||
|
||||
Reference in New Issue
Block a user