1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
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)
}
}
|