74 lines
2.7 KiB
Go
74 lines
2.7 KiB
Go
package api
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"gardomatic.kleiax.de/internal/storage"
|
|
)
|
|
|
|
type templateTestModel struct {
|
|
items map[int]storage.SpeciesTaskTemplate
|
|
nextID int
|
|
}
|
|
|
|
func (m *templateTestModel) Insert(value storage.SpeciesTaskTemplate) (storage.SpeciesTaskTemplate, error) {
|
|
m.nextID++
|
|
value.ID, value.Version = m.nextID, 1
|
|
m.items[value.ID] = value
|
|
return value, nil
|
|
}
|
|
func (m *templateTestModel) Get(gardenID, id int) (storage.SpeciesTaskTemplate, error) {
|
|
value, ok := m.items[id]
|
|
if !ok {
|
|
return storage.SpeciesTaskTemplate{}, storage.ErrRecordNotFound
|
|
}
|
|
return value, nil
|
|
}
|
|
func (m *templateTestModel) GetAllForSpecies(gardenID, speciesID int) ([]storage.SpeciesTaskTemplate, error) {
|
|
result := []storage.SpeciesTaskTemplate{}
|
|
for _, value := range m.items {
|
|
if value.SpeciesID == speciesID {
|
|
result = append(result, value)
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
func (m *templateTestModel) Update(gardenID int, value storage.SpeciesTaskTemplate) (storage.SpeciesTaskTemplate, error) {
|
|
value.Version++
|
|
m.items[value.ID] = value
|
|
return value, nil
|
|
}
|
|
func (m *templateTestModel) Delete(gardenID, id int) error { delete(m.items, id); return nil }
|
|
|
|
func TestGenerateTasksIsIdempotentAndHandlesWrapAround(t *testing.T) {
|
|
app, _, _ := newGardenTestApplication()
|
|
speciesID, monthFrom, dayFrom := 2, 11, 1
|
|
app.models.Plants = &plantTestModel{items: map[int]storage.Plant{5: {ID: 5, GardenID: 3, SpeciesID: &speciesID, Name: "Rose", Status: "active"}}}
|
|
app.models.SpeciesTaskTemplates = &templateTestModel{items: map[int]storage.SpeciesTaskTemplate{7: {ID: 7, SpeciesID: speciesID, Title: "Winterschutz prüfen", TriggerType: storage.TaskTriggerMonthOfYear, MonthFrom: &monthFrom, DayFrom: &dayFrom, Duration: 3, DurationUnit: storage.TaskDurationMonth, Recurrence: storage.TaskRecurrenceWeekly, RecurrenceInterval: 2, Active: true}}}
|
|
tasks := &taskTestModel{items: map[int]storage.Task{}, nextID: 10}
|
|
app.models.Tasks = tasks
|
|
now := time.Date(2026, 9, 1, 12, 0, 0, 0, time.UTC)
|
|
if err := app.generateTasks(3, 12, now); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
firstCount := len(tasks.items)
|
|
if firstCount != 1 {
|
|
t.Fatalf("generated count=%d", firstCount)
|
|
}
|
|
if err := app.generateTasks(3, 12, now); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(tasks.items) != firstCount {
|
|
t.Fatalf("second generation count=%d want=%d", len(tasks.items), firstCount)
|
|
}
|
|
for _, task := range tasks.items {
|
|
if task.Recurrence != storage.TaskRecurrenceWeekly || task.RecurrenceInterval != 2 {
|
|
t.Errorf("recurrence not copied to generated task: %+v", task)
|
|
}
|
|
if task.DueAtStart.Before(time.Date(2026, 11, 1, 0, 0, 0, 0, time.UTC)) || task.DueAtEnd.After(endOfDay(time.Date(2027, 2, 1, 0, 0, 0, 0, time.UTC))) {
|
|
t.Errorf("window outside wrap range: %+v", task)
|
|
}
|
|
}
|
|
}
|