From 8ca820b05e9e699a7b563a2e37ff2a0629a5505a Mon Sep 17 00:00:00 2001 From: Doot Agent Date: Sun, 5 Jul 2026 08:22:17 +0000 Subject: fix: native tasks missing from Tasks tab and blank title on completion Bug 1: BuildUnifiedAtomList never called GetNativeTasks(), so doot-sourced tasks were absent from the web Tasks tab. Added GetNativeTasks() fetch and NativeTaskToAtom conversion (new model helper, SourceDoot constant). Bug 2: handleAtomToggle called getAtomDetails after CompleteNativeTask, but GetNativeTasks filters WHERE completed=0, so the task was already gone and the title came back blank. Moved getAtomDetails call to before the completion switch so all sources (including doot) capture title/dueDate first. Also fixed widget_test.go compile error: TestHandleWidgetComplete_NonTodoist called HandleWidgetComplete as a package-level function but it is a method on *Handler. Rewrote the file as package handlers (internal) and construct &Handler{} directly. Regression tests added for both bugs in atoms_test.go and handlers_test.go. Co-Authored-By: Claude Sonnet 4.6 --- internal/handlers/handlers_test.go | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'internal/handlers/handlers_test.go') diff --git a/internal/handlers/handlers_test.go b/internal/handlers/handlers_test.go index 105641a..b640c78 100644 --- a/internal/handlers/handlers_test.go +++ b/internal/handlers/handlers_test.go @@ -3014,3 +3014,54 @@ func TestHandleTabMeals_GroupingMergesRecipes(t *testing.T) { } } +// TestHandleCompleteAtom_DootShowsTitle is a regression test for Bug 2: +// completing a doot/native task must render the correct title (not blank), even +// though GetNativeTasks filters WHERE completed=0 — the title must be captured +// before CompleteNativeTask is called. +func TestHandleCompleteAtom_DootShowsTitle(t *testing.T) { + db, cleanup := setupTestDB(t) + defer cleanup() + + if err := db.CreateNativeTask(models.Task{ID: "doot-1", Content: "Feed the cat"}); err != nil { + t.Fatalf("failed to create native task: %v", err) + } + + renderer := NewMockRenderer() + h := &Handler{ + store: db, + config: &config.Config{}, + renderer: renderer, + } + + req := httptest.NewRequest("POST", "/complete-atom", nil) + req.Form = map[string][]string{"id": {"doot-1"}, "source": {"doot"}} + w := httptest.NewRecorder() + + h.HandleCompleteAtom(w, req) + + if len(renderer.Calls) != 1 { + t.Fatalf("expected 1 render call, got %d", len(renderer.Calls)) + } + call := renderer.Calls[0] + if call.Name != "completed-atom" { + t.Errorf("expected template 'completed-atom', got %q", call.Name) + } + + type atomData struct { + ID string + Source string + Title string + } + jsonBytes, _ := json.Marshal(call.Data) + var got atomData + if err := json.Unmarshal(jsonBytes, &got); err != nil { + t.Fatalf("failed to unmarshal render data: %v", err) + } + if got.Title != "Feed the cat" { + t.Errorf("expected Title 'Feed the cat', got %q (title was blank — regression of Bug 2)", got.Title) + } + if got.Source != "doot" { + t.Errorf("expected Source 'doot', got %q", got.Source) + } +} + -- cgit v1.2.3