//go:build test && dev // +build test,dev package bookings import ( "testing" "time" ) func TestCheckClosingHours_WithinHours(t *testing.T) { // Closing at 17:00, booking ends at 16:30 — should pass. london, err := time.LoadLocation("Europe/London") if err != nil { t.Fatalf("failed to load location: %v", err) } localEnd := time.Date(2026, 6, 24, 16, 30, 0, 0, london) if err := checkClosingHours(localEnd, "17:00"); err != nil { t.Errorf("expected no error for 16:30 end vs 17:00 close, got: %v", err) } } func TestCheckClosingHours_AtClosing(t *testing.T) { // Closing at 17:00, booking ends exactly at 17:00 — should pass. london, err := time.LoadLocation("Europe/London") if err != nil { t.Fatalf("failed to load location: %v", err) } localEnd := time.Date(2026, 6, 24, 17, 0, 0, 0, london) if err := checkClosingHours(localEnd, "17:00"); err != nil { t.Errorf("expected no error for 17:00 end vs 17:00 close, got: %v", err) } } func TestCheckClosingHours_PastClosing(t *testing.T) { // Closing at 17:00, booking ends at 17:01 — should return ErrPastClosing. london, err := time.LoadLocation("Europe/London") if err != nil { t.Fatalf("failed to load location: %v", err) } localEnd := time.Date(2026, 6, 24, 17, 1, 0, 0, london) if err := checkClosingHours(localEnd, "17:00"); !IsPastClosing(err) { t.Errorf("expected ErrPastClosing for 17:01 end vs 17:00 close, got: %v", err) } } func TestCheckClosingHours_WellPastClosing(t *testing.T) { // Closing at 17:00, booking ends at 18:00 — should return ErrPastClosing. london, err := time.LoadLocation("Europe/London") if err != nil { t.Fatalf("failed to load location: %v", err) } localEnd := time.Date(2026, 6, 24, 18, 0, 0, 0, london) if err := checkClosingHours(localEnd, "17:00"); !IsPastClosing(err) { t.Errorf("expected ErrPastClosing for 18:00 end vs 17:00 close, got: %v", err) } } func TestCheckClosingHours_InvalidFormat(t *testing.T) { // Malformed closing time string — should return a generic error, not ErrPastClosing. london, err := time.LoadLocation("Europe/London") if err != nil { t.Fatalf("failed to load location: %v", err) } localEnd := time.Date(2026, 6, 24, 14, 0, 0, 0, london) tests := []struct { name string closeStr string }{ {"empty string", ""}, {"no colon", "1700"}, {"non-numeric hour", "ab:00"}, {"non-numeric minute", "17:ab"}, {"only hour", "17"}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { err := checkClosingHours(localEnd, tc.closeStr) if err == nil { t.Error("expected error for invalid format, got nil") } if IsPastClosing(err) { t.Errorf("expected non-past-closing error for invalid format %q, got ErrPastClosing", tc.closeStr) } }) } } // IsPastClosing reports whether err indicates the booking extends beyond closing hours. // Exported helper for tests. func IsPastClosing(err error) bool { return err == ErrPastClosing }