Initial commit
CI / test (push) Canceled after 0s

This commit is contained in:
2026-09-12 22:22:17 +02:00
commit 904d14b64c
314 changed files with 31884 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
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)
}
}
}