package handlers import ( "net/http" "net/http/httptest" "testing" "time" "task-dashboard/internal/config" "task-dashboard/internal/models" ) func TestHandleDeferAtom_ReturnsActiveBucketItemToDormant(t *testing.T) { db, cleanup := setupTestDB(t) defer cleanup() h := &Handler{store: db, config: &config.Config{}} // pick_n=1 plus a reserve item added after the cycle runs, so deferring // task-1 backfills with the reserve rather than immediately re-picking // task-1 itself (the only-item-in-pool case is a degenerate edge case // covered at the store layer). bucket, err := h.store.CreateBucket("Gutters", 30, 1) if err != nil { t.Fatal(err) } if err := h.store.CreateNativeTask(models.Task{ID: "task-1", Content: "Clean gutters", Priority: 1}); err != nil { t.Fatal(err) } if err := h.store.AddBucketItem(bucket.ID, "task-1"); err != nil { t.Fatal(err) } if _, err := h.store.RunBucketCycles(time.Now()); err != nil { t.Fatal(err) } if err := h.store.CreateNativeTask(models.Task{ID: "reserve", Content: "reserve", Priority: 1}); err != nil { t.Fatal(err) } if err := h.store.AddBucketItem(bucket.ID, "reserve"); err != nil { t.Fatal(err) } req := httptest.NewRequest("POST", "/defer-atom", nil) req.Form = map[string][]string{"id": {"task-1"}} w := httptest.NewRecorder() h.HandleDeferAtom(w, req) if w.Code != http.StatusOK { t.Fatalf("status = %d, want 200, body=%s", w.Code, w.Body.String()) } if w.Header().Get("HX-Trigger") != "refresh-tasks" { t.Errorf("HX-Trigger = %q, want refresh-tasks", w.Header().Get("HX-Trigger")) } updated, err := h.store.GetNativeTaskByID("task-1") if err != nil { t.Fatal(err) } if updated.BucketState != "dormant" { t.Errorf("BucketState = %q, want dormant", updated.BucketState) } } func TestHandleDeferAtom_MissingID_Returns400(t *testing.T) { db, cleanup := setupTestDB(t) defer cleanup() h := &Handler{store: db, config: &config.Config{}} req := httptest.NewRequest("POST", "/defer-atom", nil) req.Form = map[string][]string{"id": {""}} w := httptest.NewRecorder() h.HandleDeferAtom(w, req) if w.Code != http.StatusBadRequest { t.Fatalf("status = %d, want 400", w.Code) } } func TestHandleDeferAtom_NotABucketItem_Returns500(t *testing.T) { db, cleanup := setupTestDB(t) defer cleanup() h := &Handler{store: db, config: &config.Config{}} if err := h.store.CreateNativeTask(models.Task{ID: "task-1", Content: "Plain task", Priority: 1}); err != nil { t.Fatal(err) } req := httptest.NewRequest("POST", "/defer-atom", nil) req.Form = map[string][]string{"id": {"task-1"}} w := httptest.NewRecorder() h.HandleDeferAtom(w, req) if w.Code != http.StatusInternalServerError { t.Fatalf("status = %d, want 500", w.Code) } }