package repository import ( "testing" "time" "github.com/daniil/homelab-api/internal/model" ) func TestHabitFreezeRepository_CountFrozenDaysLogic(t *testing.T) { // Test the overlap calculation logic that CountFrozenDaysInRange uses tests := []struct { name string freezeStart, freezeEnd time.Time queryStart, queryEnd time.Time wantDays int }{ { name: "full overlap", freezeStart: time.Date(2025, 1, 5, 0, 0, 0, 0, time.UTC), freezeEnd: time.Date(2025, 1, 10, 0, 0, 0, 0, time.UTC), queryStart: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC), queryEnd: time.Date(2025, 1, 31, 0, 0, 0, 0, time.UTC), wantDays: 6, }, { name: "partial overlap start", freezeStart: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC), freezeEnd: time.Date(2025, 1, 10, 0, 0, 0, 0, time.UTC), queryStart: time.Date(2025, 1, 5, 0, 0, 0, 0, time.UTC), queryEnd: time.Date(2025, 1, 31, 0, 0, 0, 0, time.UTC), wantDays: 6, }, { name: "partial overlap end", freezeStart: time.Date(2025, 1, 20, 0, 0, 0, 0, time.UTC), freezeEnd: time.Date(2025, 2, 5, 0, 0, 0, 0, time.UTC), queryStart: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC), queryEnd: time.Date(2025, 1, 31, 0, 0, 0, 0, time.UTC), wantDays: 12, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { freeze := model.HabitFreeze{ StartDate: tt.freezeStart, EndDate: tt.freezeEnd, } overlapStart := freeze.StartDate if tt.queryStart.After(freeze.StartDate) { overlapStart = tt.queryStart } overlapEnd := freeze.EndDate if tt.queryEnd.Before(freeze.EndDate) { overlapEnd = tt.queryEnd } days := 0 if !overlapEnd.Before(overlapStart) { days = int(overlapEnd.Sub(overlapStart).Hours()/24) + 1 } if days != tt.wantDays { t.Errorf("got %d frozen days, want %d", days, tt.wantDays) } }) } } func TestJoinStrings(t *testing.T) { tests := []struct { input []string sep string want string }{ {nil, ", ", ""}, {[]string{"a"}, ", ", "a"}, {[]string{"a", "b", "c"}, ", ", "a, b, c"}, {[]string{"x", "y"}, " AND ", "x AND y"}, } for _, tt := range tests { got := joinStrings(tt.input, tt.sep) if got != tt.want { t.Errorf("joinStrings(%v, %q) = %q, want %q", tt.input, tt.sep, got, tt.want) } } } func TestIsUniqueViolation(t *testing.T) { if isUniqueViolation(nil) { t.Error("nil error should not be unique violation") } }