summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/handlers/widget.go11
-rw-r--r--internal/handlers/widget_test.go40
-rw-r--r--internal/models/widget.go1
3 files changed, 47 insertions, 5 deletions
diff --git a/internal/handlers/widget.go b/internal/handlers/widget.go
index dc10db6..f8a63a0 100644
--- a/internal/handlers/widget.go
+++ b/internal/handlers/widget.go
@@ -32,11 +32,12 @@ func WidgetAuthMiddleware(token string, next http.Handler) http.Handler {
// Exported for testability.
func TimelineItemToWidgetItem(item models.TimelineItem) models.WidgetItem {
wi := models.WidgetItem{
- ID: item.ID,
- Title: item.Title,
- Source: item.Source,
- IsAllDay: item.IsAllDay,
- URL: item.URL,
+ ID: item.ID,
+ Title: item.Title,
+ Source: item.Source,
+ IsAllDay: item.IsAllDay,
+ IsOverdue: item.IsOverdue,
+ URL: item.URL,
}
switch item.Type {
diff --git a/internal/handlers/widget_test.go b/internal/handlers/widget_test.go
index 6d741d2..06e1749 100644
--- a/internal/handlers/widget_test.go
+++ b/internal/handlers/widget_test.go
@@ -170,6 +170,46 @@ func TestTimelineItemToWidgetItem_AllDayTask_KeepsFloatingBehavior(t *testing.T)
}
}
+// TestTimelineItemToWidgetItem_ForwardsIsOverdue proves the 2026-07-12
+// overdue-badge fix: TimelineItem.IsOverdue (already computed correctly by
+// ComputeDaySection, confirmed by the earlier fix that made overdue tasks
+// appear in the timeline at all) must be forwarded onto WidgetItem so the
+// Android client can render it distinctly -- previously it was silently
+// dropped, so an overdue task looked identical to a normal one on the
+// widget.
+func TestTimelineItemToWidgetItem_ForwardsIsOverdue(t *testing.T) {
+ item := models.TimelineItem{
+ ID: "overdue-1",
+ Title: "Pay the water bill",
+ Source: "doot",
+ Type: models.TimelineItemTypeTask,
+ Time: time.Now(),
+ IsOverdue: true,
+ }
+
+ wi := TimelineItemToWidgetItem(item)
+
+ if !wi.IsOverdue {
+ t.Error("expected IsOverdue to be forwarded as true")
+ }
+}
+
+func TestTimelineItemToWidgetItem_NotOverdueByDefault(t *testing.T) {
+ item := models.TimelineItem{
+ ID: "today-1",
+ Title: "Water the plants",
+ Source: "doot",
+ Type: models.TimelineItemTypeTask,
+ Time: time.Now(),
+ }
+
+ wi := TimelineItemToWidgetItem(item)
+
+ if wi.IsOverdue {
+ t.Error("expected IsOverdue to be false when the source item isn't overdue")
+ }
+}
+
func TestHandleWidgetComplete_NonCompletable(t *testing.T) {
h := &Handler{}
body := `{"id":"x","source":"calendar"}`
diff --git a/internal/models/widget.go b/internal/models/widget.go
index 8d0bdd6..e2876b0 100644
--- a/internal/models/widget.go
+++ b/internal/models/widget.go
@@ -13,6 +13,7 @@ type WidgetItem struct {
Start *time.Time `json:"start,omitempty"` // nil = no specific time (floating task)
End *time.Time `json:"end,omitempty"`
IsAllDay bool `json:"is_all_day"`
+ IsOverdue bool `json:"is_overdue"`
URL string `json:"url,omitempty"`
Completable bool `json:"completable"` // true = doot task (checkbox shown)
}