package engine import ( "testing" "time" ) func TestAnnotate(t *testing.T) { task, err := CreateTask("Annotation test task") if err != nil { t.Fatalf("Failed to create task: %v", err) } defer func() { task.Delete(true) }() // Initially no annotations if len(task.Annotations) != 0 { t.Fatalf("new task should have 0 annotations, got %d", len(task.Annotations)) } // Add first annotation if err := task.Annotate("First note"); err != nil { t.Fatalf("Annotate failed: %v", err) } if len(task.Annotations) != 1 { t.Fatalf("expected 1 annotation, got %d", len(task.Annotations)) } if task.Annotations[0].Text != "First note" { t.Errorf("annotation text = %q, want %q", task.Annotations[0].Text, "First note") } if task.Annotations[0].Timestamp == 0 { t.Error("annotation timestamp should be non-zero") } // Add second annotation if err := task.Annotate("Second note"); err != nil { t.Fatalf("Annotate failed: %v", err) } if len(task.Annotations) != 2 { t.Fatalf("expected 2 annotations, got %d", len(task.Annotations)) } if task.Annotations[1].Text != "Second note" { t.Errorf("second annotation text = %q, want %q", task.Annotations[1].Text, "Second note") } } func TestAnnotate_Persistence(t *testing.T) { task, err := CreateTask("Annotation persistence test") if err != nil { t.Fatalf("Failed to create task: %v", err) } defer func() { task.Delete(true) }() if err := task.Annotate("Persisted note"); err != nil { t.Fatalf("Annotate failed: %v", err) } // Reload from DB loaded, err := GetTask(task.UUID) if err != nil { t.Fatalf("GetTask failed: %v", err) } if len(loaded.Annotations) != 1 { t.Fatalf("loaded task: expected 1 annotation, got %d", len(loaded.Annotations)) } if loaded.Annotations[0].Text != "Persisted note" { t.Errorf("loaded annotation text = %q, want %q", loaded.Annotations[0].Text, "Persisted note") } } func TestAnnotate_TimestampOrdering(t *testing.T) { origTimeNow := timeNow defer func() { timeNow = origTimeNow }() task, err := CreateTask("Timestamp ordering test") if err != nil { t.Fatalf("Failed to create task: %v", err) } defer func() { timeNow = origTimeNow; task.Delete(true) }() // Add annotations at different times t1 := time.Date(2026, 1, 1, 10, 0, 0, 0, time.UTC) t2 := time.Date(2026, 1, 1, 11, 0, 0, 0, time.UTC) timeNow = func() time.Time { return t1 } task.Annotate("First") timeNow = func() time.Time { return t2 } task.Annotate("Second") if task.Annotations[0].Timestamp >= task.Annotations[1].Timestamp { t.Error("annotations should be in chronological order") } } func TestDenotate(t *testing.T) { task, err := CreateTask("Denotate test task") if err != nil { t.Fatalf("Failed to create task: %v", err) } defer func() { task.Delete(true) }() task.Annotate("First") task.Annotate("Second") task.Annotate("Third") // Denotate removes the last removed, err := task.Denotate() if err != nil { t.Fatalf("Denotate failed: %v", err) } if removed.Text != "Third" { t.Errorf("removed text = %q, want %q", removed.Text, "Third") } if len(task.Annotations) != 2 { t.Fatalf("expected 2 annotations after denotate, got %d", len(task.Annotations)) } // Remove second removed, err = task.Denotate() if err != nil { t.Fatalf("Denotate failed: %v", err) } if removed.Text != "Second" { t.Errorf("removed text = %q, want %q", removed.Text, "Second") } // Remove first removed, err = task.Denotate() if err != nil { t.Fatalf("Denotate failed: %v", err) } if removed.Text != "First" { t.Errorf("removed text = %q, want %q", removed.Text, "First") } // Nothing left — should error _, err = task.Denotate() if err == nil { t.Error("Denotate on empty annotations should return error") } } func TestDenotate_Empty(t *testing.T) { task, err := CreateTask("Denotate empty test") if err != nil { t.Fatalf("Failed to create task: %v", err) } defer func() { task.Delete(true) }() _, err = task.Denotate() if err == nil { t.Error("Denotate on task with no annotations should return error") } } func TestDenotate_Persistence(t *testing.T) { task, err := CreateTask("Denotate persistence test") if err != nil { t.Fatalf("Failed to create task: %v", err) } defer func() { task.Delete(true) }() task.Annotate("Keep this") task.Annotate("Remove this") task.Denotate() // Reload and verify loaded, err := GetTask(task.UUID) if err != nil { t.Fatalf("GetTask failed: %v", err) } if len(loaded.Annotations) != 1 { t.Fatalf("loaded: expected 1 annotation, got %d", len(loaded.Annotations)) } if loaded.Annotations[0].Text != "Keep this" { t.Errorf("remaining annotation = %q, want %q", loaded.Annotations[0].Text, "Keep this") } }