diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-07-12 11:06:32 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-07-12 11:06:32 +0000 |
| commit | f31b4722243b8b69564c94e47e07678153c31815 (patch) | |
| tree | 9b66a2132b7c40c3ca189aa151327aeec33cc18b /internal/handlers | |
| parent | b1c76cdf30b7d491f3791588c8aa8c66ee5a0950 (diff) | |
feat(widget): capture and forward RecurringEventID for calendar events
Diffstat (limited to 'internal/handlers')
| -rw-r--r-- | internal/handlers/timeline_logic.go | 21 | ||||
| -rw-r--r-- | internal/handlers/timeline_logic_test.go | 1 | ||||
| -rw-r--r-- | internal/handlers/widget.go | 13 | ||||
| -rw-r--r-- | internal/handlers/widget_test.go | 38 |
4 files changed, 57 insertions, 16 deletions
diff --git a/internal/handlers/timeline_logic.go b/internal/handlers/timeline_logic.go index e7c1279..6fddd1d 100644 --- a/internal/handlers/timeline_logic.go +++ b/internal/handlers/timeline_logic.go @@ -81,16 +81,17 @@ func BuildTimeline(ctx context.Context, s *store.Store, start, end time.Time) ([ for _, event := range events { endTime := event.End item := models.TimelineItem{ - ID: event.ID, - Type: models.TimelineItemTypeEvent, - Title: event.Summary, - Time: event.Start, - EndTime: &endTime, - Description: event.Description, - URL: event.HTMLLink, - OriginalItem: event, - IsCompleted: false, - Source: "calendar", + ID: event.ID, + Type: models.TimelineItemTypeEvent, + Title: event.Summary, + Time: event.Start, + EndTime: &endTime, + Description: event.Description, + URL: event.HTMLLink, + OriginalItem: event, + IsCompleted: false, + Source: "calendar", + RecurringEventID: event.RecurringEventID, } item.ComputeDaySection(now) items = append(items, item) diff --git a/internal/handlers/timeline_logic_test.go b/internal/handlers/timeline_logic_test.go index 7d3f6b5..9ddaeda 100644 --- a/internal/handlers/timeline_logic_test.go +++ b/internal/handlers/timeline_logic_test.go @@ -82,6 +82,7 @@ func setupTestStore(t *testing.T) *store.Store { start_time DATETIME NOT NULL, end_time DATETIME NOT NULL, html_link TEXT, + recurring_event_id TEXT DEFAULT '', updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS google_tasks ( diff --git a/internal/handlers/widget.go b/internal/handlers/widget.go index 0c88c16..29124fb 100644 --- a/internal/handlers/widget.go +++ b/internal/handlers/widget.go @@ -32,12 +32,13 @@ 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, - IsOverdue: item.IsOverdue, - URL: item.URL, + ID: item.ID, + Title: item.Title, + Source: item.Source, + IsAllDay: item.IsAllDay, + IsOverdue: item.IsOverdue, + URL: item.URL, + RecurringEventID: item.RecurringEventID, } switch item.Type { diff --git a/internal/handlers/widget_test.go b/internal/handlers/widget_test.go index e4a1d16..efe6858 100644 --- a/internal/handlers/widget_test.go +++ b/internal/handlers/widget_test.go @@ -386,3 +386,41 @@ func TestWidgetAuthMiddleware_EmptyToken(t *testing.T) { t.Fatalf("expected 401 with empty token, got %d", w.Code) } } + +// TestTimelineItemToWidgetItem_ForwardsRecurringEventID proves the +// 2026-07-12 recurrence-display fix's data plumbing: a calendar event's +// RecurringEventId (captured from Google's API, which only puts the RRULE +// itself on the master event, not on expanded instances) must reach the +// client so it can look up the human-readable schedule on demand. +func TestTimelineItemToWidgetItem_ForwardsRecurringEventID(t *testing.T) { + item := models.TimelineItem{ + ID: "cal-1", + Title: "Team sync", + Source: "calendar", + Type: models.TimelineItemTypeEvent, + Time: time.Now(), + RecurringEventID: "master-123", + } + + wi := TimelineItemToWidgetItem(item) + + if wi.RecurringEventID != "master-123" { + t.Errorf("RecurringEventID = %q, want %q", wi.RecurringEventID, "master-123") + } +} + +func TestTimelineItemToWidgetItem_NonRecurring_EmptyRecurringEventID(t *testing.T) { + item := models.TimelineItem{ + ID: "cal-2", + Title: "One-off meeting", + Source: "calendar", + Type: models.TimelineItemTypeEvent, + Time: time.Now(), + } + + wi := TimelineItemToWidgetItem(item) + + if wi.RecurringEventID != "" { + t.Errorf("expected empty RecurringEventID for a non-recurring event, got %q", wi.RecurringEventID) + } +} |
