summaryrefslogtreecommitdiff
path: root/internal/store/sqlite_test.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-07-13 07:11:04 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-13 07:11:04 +0000
commit44abf42ed45aa8f285e7ce031cbb9ef1ade667ea (patch)
treedbc21cadc2750c6e39e7f7613be0b3f73790c445 /internal/store/sqlite_test.go
parent8310f802dd9fc6ef5dff0be7f640f79c5b39987f (diff)
parent4126fe4f56a6eb9703a084d4793a597f37bf2867 (diff)
Merge github/master: reconcile with parallel widget work
Another session pushed 27 commits in parallel covering quick-add, event detail popups, recurrence display, overdue badges, a manual refresh button, and its own fix for the same overdue-tasks bug (via a separate GetOverdueNativeTasks fetch folded into BuildTimeline, rather than widening GetNativeTasksByDateRange's bound directly). Reconciled rather than blindly taking one side: - Reverted GetNativeTasksByDateRange to its original bounded query and kept upstream's GetOverdueNativeTasks + BuildTimeline fold-in as the sole overdue mechanism for native tasks, to avoid double-counting overdue items (my widened query + their separate fetch would have both returned them). Re-pointed the regression test at the now-correct contract and added a store-level test for GetOverdueNativeTasks directly. - Kept my GetGoogleTasksByDateRange fix as-is (single unbounded query) -- upstream never touched Google Tasks overdue handling, so there's no duplication risk there. - Rewove WidgetRoot's LazyColumn structure (added for scrolling) around upstream's new header buttons, pinned all-day event rows, and the enhanced TomorrowSection, none of which were written LazyColumn-aware since that work landed on this side only. - Combined both sides' additions to TaskDetailActivity/TaskDetailSheet (description-edit detail popup + due-date reschedule label) and WidgetRepository/Actions (optimistic local removal + refresh button wiring) -- these were independent, non-overlapping features that both needed to survive. - Renumbered the migration collision: both sides independently added a migration numbered 022. Card-description was already applied to the live production DB under that filename earlier this session (migrations are tracked by filename), so it keeps 022; the recurring-event-id migration, never deployed under any name here, moves to 023. Verified: go build clean, full test suite passes (only the two pre-existing agent-handler failures and the pre-existing models package build error remain, both confirmed unrelated via git stash before this session began), and a dry run against a copy of the live production database applies both migrations cleanly with no re-run conflicts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
Diffstat (limited to 'internal/store/sqlite_test.go')
-rw-r--r--internal/store/sqlite_test.go45
1 files changed, 39 insertions, 6 deletions
diff --git a/internal/store/sqlite_test.go b/internal/store/sqlite_test.go
index 4d3c8f8..e8af436 100644
--- a/internal/store/sqlite_test.go
+++ b/internal/store/sqlite_test.go
@@ -188,10 +188,12 @@ func setupTestStoreWithNativeTasks(t *testing.T) *Store {
return store
}
-// TestGetNativeTasksByDateRange_IncludesOverdue guards against a regression where a native task
-// due before the window's start (e.g. yesterday, still incomplete) silently dropped out of the
-// widget/timeline the moment the day rolled over, because the query required due_date >= start.
-func TestGetNativeTasksByDateRange_IncludesOverdue(t *testing.T) {
+// TestGetNativeTasksByDateRange_ExcludesOverdue documents the deliberate contract after
+// 2026-07-13's reconciliation: GetNativeTasksByDateRange is scoped to [start, end) only.
+// Overdue tasks (due before start) are BuildTimeline's job to fetch separately via
+// GetOverdueNativeTasks -- see that test below and timeline_logic.go's "6." section --
+// so this function must NOT also return them, or BuildTimeline would double them up.
+func TestGetNativeTasksByDateRange_ExcludesOverdue(t *testing.T) {
store := setupTestStoreWithNativeTasks(t)
now := time.Now()
@@ -221,8 +223,8 @@ func TestGetNativeTasksByDateRange_IncludesOverdue(t *testing.T) {
for _, r := range results {
ids[r.ID] = true
}
- if !ids["t-overdue"] {
- t.Error("expected overdue task to be included, but it was excluded")
+ if ids["t-overdue"] {
+ t.Error("expected overdue task to be excluded from the ranged fetch")
}
if !ids["t-today"] {
t.Error("expected today's task to be included")
@@ -232,6 +234,37 @@ func TestGetNativeTasksByDateRange_IncludesOverdue(t *testing.T) {
}
}
+// TestGetOverdueNativeTasks_IncludesOnlyPastDue is the store-level counterpart to
+// TestGetNativeTasksByDateRange_ExcludesOverdue: this is the function BuildTimeline relies on
+// to actually surface overdue tasks (see timeline_logic.go's "6." section and
+// TestBuildTimeline_IncludesOverdueNativeTasks for the integration-level proof).
+func TestGetOverdueNativeTasks_IncludesOnlyPastDue(t *testing.T) {
+ store := setupTestStoreWithNativeTasks(t)
+
+ now := time.Now()
+ overdue := now.Add(-48 * time.Hour)
+ today := now
+
+ for _, task := range []models.Task{
+ {ID: "t-overdue", Content: "Overdue task", DueDate: &overdue},
+ {ID: "t-today", Content: "Today task", DueDate: &today},
+ } {
+ if err := store.CreateNativeTask(task); err != nil {
+ t.Fatalf("CreateNativeTask(%s) failed: %v", task.ID, err)
+ }
+ }
+
+ start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
+
+ results, err := store.GetOverdueNativeTasks(start)
+ if err != nil {
+ t.Fatalf("GetOverdueNativeTasks failed: %v", err)
+ }
+ if len(results) != 1 || results[0].ID != "t-overdue" {
+ t.Errorf("expected only the overdue task, got %+v", results)
+ }
+}
+
// TestSaveAndGetGoogleTasks_RoundTripsTimestamps guards against a regression where
// due_date/updated_at (TEXT columns, not DATETIME) failed to scan back into time.Time
// via sql.NullTime whenever a row had a non-null timestamp.