Fire accepted routines every interval, not once (Vikunja #366)
The tick loop now reads accepted routines from the store and nudges when their interval has passed; accepting no longer builds a one-shot reminder. Look at routine.DueAccepted for the schedule rule (no catch-up backlog) and at fireAcceptedRoutines for the restraint gate — routines do not bypass it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGeSZxh1DCtRxmFVSYVGvJ
This commit is contained in:
@@ -5,6 +5,40 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDueAcceptedFiresOncePerInterval(t *testing.T) {
|
||||
accepted := time.Date(2026, 7, 1, 9, 0, 0, 0, time.UTC)
|
||||
fired := accepted.Add(3 * 24 * time.Hour)
|
||||
rs := []Accepted{
|
||||
{ID: 1, Name: "полить цветы", IntervalDays: 3, Accepted: accepted},
|
||||
{ID: 2, Name: "покормить рыб", IntervalDays: 3, Accepted: accepted, LastFired: &fired},
|
||||
{ID: 3, Name: "битый интервал", IntervalDays: 0, Accepted: accepted},
|
||||
}
|
||||
|
||||
// One day in: nothing has waited a full interval.
|
||||
if got := DueAccepted(rs, accepted.Add(24*time.Hour)); len(got) != 0 {
|
||||
t.Fatalf("want nothing due after 1 day, got %+v", got)
|
||||
}
|
||||
|
||||
// Three days in: the never-fired one is due. The one that already fired at
|
||||
// day 3 starts its next three days from there. A zero interval never fires.
|
||||
got := DueAccepted(rs, fired)
|
||||
if len(got) != 1 || got[0].ID != 1 {
|
||||
t.Fatalf("want only routine 1 due at day 3, got %+v", got)
|
||||
}
|
||||
|
||||
// Six days in: both real routines are due.
|
||||
if got := DueAccepted(rs, accepted.Add(6*24*time.Hour)); len(got) != 2 {
|
||||
t.Fatalf("want both routines due at day 6, got %+v", got)
|
||||
}
|
||||
|
||||
// A month later the zero-interval routine is still silent.
|
||||
for _, r := range DueAccepted(rs, accepted.Add(30*24*time.Hour)) {
|
||||
if r.ID == 3 {
|
||||
t.Fatal("a routine with a zero interval must never fire")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidate(t *testing.T) {
|
||||
ok := []Routine{{Name: "morning", Cron: "0 8 * * *", Body: "доброе утро"}}
|
||||
if err := Validate(ok); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user