internal/task/schedule_list_test.go
Rama main · réplica de lectura del repositorio original.
package task
import (
"errors"
"strconv"
"testing"
"time"
)
func scheduleListFixture(count int, referenceTime time.Time) []Schedule {
nextRunAt := referenceTime.Add(time.Hour)
createdAt := referenceTime.Add(-time.Hour)
schedules := []Schedule{}
for index := range count {
schedules = append(schedules, Schedule{
ScheduleID: "schedule-" + strconv.Itoa(index),
Prompt: "instruction " + strconv.Itoa(index),
Kind: ScheduleKindOnce,
NextRunAt: &nextRunAt,
CreatedAt: createdAt.Add(-time.Duration(index/3) * time.Minute),
})
}
return schedules
}
func readEverySchedulePage(t *testing.T, schedules []Schedule, input ScheduleListInput, referenceTime time.Time) ([]string, []ScheduleListOutput) {
t.Helper()
seen := []string{}
pages := []ScheduleListOutput{}
for {
output, errorValue := ProjectScheduleList(schedules, input, referenceTime)
if errorValue != nil {
t.Fatalf("listing failed: %v", errorValue)
}
pages = append(pages, output)
for _, item := range output.Schedules {
seen = append(seen, item.ScheduleID)
}
if output.NextCursor == "" {
return seen, pages
}
input.Cursor = output.NextCursor
}
}
func TestScheduleListPagesReadEveryScheduleOnceNewestFirst(t *testing.T) {
referenceTime := time.Date(2026, 10, 29, 9, 0, 0, 0, time.UTC)
schedules := scheduleListFixture(7, referenceTime)
seen, pages := readEverySchedulePage(t, schedules, ScheduleListInput{Limit: 3}, referenceTime)
if len(pages) != 3 || len(seen) != 7 {
t.Fatalf("seven schedules at three a page are three pages, got %d pages holding %v", len(pages), seen)
}
unique := map[string]bool{}
for _, scheduleID := range seen {
if unique[scheduleID] {
t.Fatalf("%s came back twice across pages: %v", scheduleID, seen)
}
unique[scheduleID] = true
}
if seen[0] != "schedule-0" || seen[1] != "schedule-1" || seen[3] != "schedule-3" {
t.Fatalf("newest first, ties broken by ID, got %v", seen)
}
for _, page := range pages {
if page.TotalCount != 7 {
t.Fatalf("every page states the whole count, got %d", page.TotalCount)
}
}
if pages[len(pages)-1].NextCursor != "" {
t.Fatalf("the last page carries no cursor, got %q", pages[len(pages)-1].NextCursor)
}
}
func TestScheduleListCountsAndPagesOnlyTheRequestedStatus(t *testing.T) {
referenceTime := time.Date(2026, 10, 29, 9, 0, 0, 0, time.UTC)
schedules := scheduleListFixture(30, referenceTime)
for index := range schedules {
if index%3 == 0 {
schedules[index].LastError = "temporary failure"
}
}
seen, pages := readEverySchedulePage(t, schedules, ScheduleListInput{Status: "failed", Limit: 4}, referenceTime)
if len(seen) != 10 || pages[0].TotalCount != 10 {
t.Fatalf("ten failed schedules are all reachable and counted, got %v of %d", seen, pages[0].TotalCount)
}
}
func TestScheduleListDefaultsToFiftyAndCapsAtOneHundred(t *testing.T) {
referenceTime := time.Date(2026, 10, 29, 9, 0, 0, 0, time.UTC)
schedules := scheduleListFixture(150, referenceTime)
byDefault, _ := ProjectScheduleList(schedules, ScheduleListInput{}, referenceTime)
atMost, _ := ProjectScheduleList(schedules, ScheduleListInput{Limit: 500}, referenceTime)
if len(byDefault.Schedules) != 50 || byDefault.NextCursor == "" {
t.Fatalf("an unset limit answers fifty and says more remain, got %d", len(byDefault.Schedules))
}
if len(atMost.Schedules) != 100 {
t.Fatalf("a limit above one hundred answers one hundred, got %d", len(atMost.Schedules))
}
}
func TestScheduleListRefusesACursorItNeverGave(t *testing.T) {
referenceTime := time.Date(2026, 10, 29, 9, 0, 0, 0, time.UTC)
for _, cursor := range []string{"not-base64!", "e30", "bm90IGpzb24"} {
_, errorValue := ProjectScheduleList(scheduleListFixture(3, referenceTime), ScheduleListInput{Cursor: cursor}, referenceTime)
if !errors.Is(errorValue, ErrScheduleListCursor) {
t.Fatalf("cursor %q should be refused, got %v", cursor, errorValue)
}
}
}