package task import ( "os" "testing" "time" ) func newTestStore(t *testing.T) (*Store, func()) { t.Helper() f, err := os.CreateTemp("", "tasks_test_*.json") if err != nil { t.Fatalf("temp-Datei erstellen: %v", err) } name := f.Name() f.Close() os.Remove(name) // Datei entfernen → loadLocked gibt leeres Slice zurück s := &Store{path: name} return s, func() { os.Remove(name) } } func TestStore_AddAndLoad(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() task, err := s.Add("Test Task", "hoch", nil) if err != nil { t.Fatalf("Add: %v", err) } if task.Text != "Test Task" { t.Errorf("Text: got %q, want %q", task.Text, "Test Task") } if task.Priority != "hoch" { t.Errorf("Priority: got %q, want %q", task.Priority, "hoch") } if task.Done { t.Error("neuer Task sollte nicht Done sein") } tasks, err := s.Load() if err != nil { t.Fatalf("Load: %v", err) } if len(tasks) != 1 { t.Fatalf("len: got %d, want 1", len(tasks)) } } func TestStore_AddWithDueDate(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() due := time.Date(2026, 12, 31, 0, 0, 0, 0, time.UTC) task, err := s.Add("Frist-Task", "mittel", &due) if err != nil { t.Fatalf("Add: %v", err) } if task.DueDate == nil { t.Fatal("DueDate sollte gesetzt sein") } if !task.DueDate.Equal(due) { t.Errorf("DueDate: got %v, want %v", task.DueDate, due) } } func TestStore_MarkDone(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() task, _ := s.Add("Erledigbarer Task", "", nil) if err := s.MarkDone(task.ID); err != nil { t.Fatalf("MarkDone: %v", err) } tasks, _ := s.Load() if !tasks[0].Done { t.Error("Task sollte Done=true sein") } if tasks[0].DoneAt == nil { t.Error("DoneAt sollte gesetzt sein") } } func TestStore_MarkDone_NotFound(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() err := s.MarkDone("nichtexistent") if err == nil { t.Error("erwartet Fehler für unbekannte ID") } } func TestStore_Delete(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() t1, _ := s.Add("Task 1", "", nil) s.Add("Task 2", "", nil) if err := s.Delete(t1.ID); err != nil { t.Fatalf("Delete: %v", err) } tasks, _ := s.Load() if len(tasks) != 1 { t.Fatalf("nach Delete: got %d, want 1", len(tasks)) } if tasks[0].Text != "Task 2" { t.Errorf("falscher Task verblieben: %q", tasks[0].Text) } } func TestStore_Delete_NotFound(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() err := s.Delete("nichtexistent") if err == nil { t.Error("erwartet Fehler für unbekannte ID") } } func TestStore_OpenTasks(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() t1, _ := s.Add("Offen", "", nil) s.Add("Auch offen", "", nil) s.MarkDone(t1.ID) open, err := s.OpenTasks() if err != nil { t.Fatalf("OpenTasks: %v", err) } if len(open) != 1 { t.Fatalf("OpenTasks: got %d, want 1", len(open)) } if open[0].Text != "Auch offen" { t.Errorf("falscher offener Task: %q", open[0].Text) } } func TestStore_EmptyFile(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() tasks, err := s.Load() if err != nil { t.Fatalf("Load auf leerer Datei: %v", err) } if len(tasks) != 0 { t.Errorf("erwartet leer, got %d", len(tasks)) } } func TestStore_Idempotent_MultipleAdds(t *testing.T) { s, cleanup := newTestStore(t) defer cleanup() s.Add("A", "", nil) s.Add("B", "niedrig", nil) s.Add("C", "hoch", nil) tasks, _ := s.Load() if len(tasks) != 3 { t.Fatalf("erwartet 3 Tasks, got %d", len(tasks)) } }