141 lines
3.9 KiB
Go
141 lines
3.9 KiB
Go
package dyzurbot
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// week is a small helper to build a DutyWeek from a YYYY-MM-DD start.
|
|
func week(t *testing.T, start, p1, p2 string) DutyWeek {
|
|
t.Helper()
|
|
ws, err := time.Parse("2006-01-02", start)
|
|
if err != nil {
|
|
t.Fatalf("bad date %q: %v", start, err)
|
|
}
|
|
return DutyWeek{WeekStart: ws, Person1: p1, Person2: p2}
|
|
}
|
|
|
|
func day(t *testing.T, d string) time.Time {
|
|
t.Helper()
|
|
tm, err := time.Parse("2006-01-02", d)
|
|
if err != nil {
|
|
t.Fatalf("bad date %q: %v", d, err)
|
|
}
|
|
return tm
|
|
}
|
|
|
|
func TestAllowSync(t *testing.T) {
|
|
base := time.Date(2026, 6, 17, 12, 0, 0, 0, time.UTC)
|
|
h := &botHandlers{}
|
|
|
|
// First attempt is always allowed and starts the cooldown.
|
|
if ok, _ := h.allowSync(base); !ok {
|
|
t.Fatal("first /sync should be allowed")
|
|
}
|
|
// A second attempt inside the window is denied, reporting the remaining wait.
|
|
if ok, wait := h.allowSync(base.Add(20 * time.Second)); ok || wait != syncCooldown-20*time.Second {
|
|
t.Errorf("within cooldown: ok=%v wait=%v, want denied with wait=%v", ok, wait, syncCooldown-20*time.Second)
|
|
}
|
|
// Once the cooldown elapses, /sync is allowed again.
|
|
if ok, _ := h.allowSync(base.Add(syncCooldown)); !ok {
|
|
t.Error("attempt after cooldown should be allowed")
|
|
}
|
|
}
|
|
|
|
func TestCurrentDuty(t *testing.T) {
|
|
rota := Rota{Weeks: []DutyWeek{
|
|
week(t, "2026-06-15", "Ala", "Bartek"),
|
|
week(t, "2026-06-22", "Celina", "Darek"),
|
|
}}
|
|
|
|
tests := []struct {
|
|
name string
|
|
today time.Time
|
|
wantOK bool
|
|
wantStart string // WeekStart of the matched week, when wantOK
|
|
}{
|
|
{"inside first week", day(t, "2026-06-17"), true, "2026-06-15"},
|
|
{"first day of first week", day(t, "2026-06-15"), true, "2026-06-15"},
|
|
{"last day of first week", day(t, "2026-06-21"), true, "2026-06-15"},
|
|
{"first day of second week", day(t, "2026-06-22"), true, "2026-06-22"},
|
|
{"before all weeks", day(t, "2026-06-14"), false, ""},
|
|
{"after all weeks", day(t, "2026-06-29"), false, ""},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got, ok := currentDuty(rota, tc.today)
|
|
if ok != tc.wantOK {
|
|
t.Fatalf("ok = %v, want %v", ok, tc.wantOK)
|
|
}
|
|
if ok && got.WeekStart.Format("2006-01-02") != tc.wantStart {
|
|
t.Errorf("matched week %s, want %s",
|
|
got.WeekStart.Format("2006-01-02"), tc.wantStart)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCurrentDutyEmptyRota(t *testing.T) {
|
|
if _, ok := currentDuty(Rota{}, day(t, "2026-06-17")); ok {
|
|
t.Error("empty rota should not match any week")
|
|
}
|
|
}
|
|
|
|
// A local time just after midnight in a +02:00 zone is still the previous day
|
|
// in UTC. currentDuty must match on the local calendar date, so 2026-06-15
|
|
// (Poland) lands in the week starting 2026-06-15, not the prior week.
|
|
func TestCurrentDutyLocalMidnight(t *testing.T) {
|
|
rota := Rota{Weeks: []DutyWeek{week(t, "2026-06-15", "Ala", "Bartek")}}
|
|
today := time.Date(2026, 6, 15, 0, 30, 0, 0, time.FixedZone("CEST", 2*3600))
|
|
|
|
got, ok := currentDuty(rota, today)
|
|
if !ok {
|
|
t.Fatal("expected a match for local 2026-06-15")
|
|
}
|
|
if got.Person1 != "Ala" {
|
|
t.Errorf("matched wrong week: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestFormatDuty(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
week DutyWeek
|
|
ok bool
|
|
want string
|
|
}{
|
|
{
|
|
"both people",
|
|
week(t, "2026-06-15", "Ala", "Bartek"), true,
|
|
"Dyżur w tym tygodniu (od 2026-06-15): Ala i Bartek",
|
|
},
|
|
{
|
|
"only person1",
|
|
week(t, "2026-06-15", "Ala", ""), true,
|
|
"Dyżur w tym tygodniu (od 2026-06-15): Ala",
|
|
},
|
|
{
|
|
"only person2",
|
|
week(t, "2026-06-15", "", "Bartek"), true,
|
|
"Dyżur w tym tygodniu (od 2026-06-15): Bartek",
|
|
},
|
|
{
|
|
"nobody assigned",
|
|
week(t, "2026-06-15", "", ""), true,
|
|
"Dyżur w tym tygodniu (od 2026-06-15): brak przypisania",
|
|
},
|
|
{
|
|
"not found",
|
|
DutyWeek{}, false,
|
|
"Nie znalazłem dyżuru na ten tydzień.",
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := formatDuty(tc.week, tc.ok); got != tc.want {
|
|
t.Errorf("formatDuty = %q, want %q", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|