Skip to content

Commit faeb683

Browse files
committed
Address PR review feedback
- Add hey todo/timetrack/journal list to API-COVERAGE.md recordings row - Guard against nil legacy client in TUI fetchTopic - Update legacy client comment to reflect current gap operations - Fix drafts agent_notes to reference subjects instead of kind - Add tests for calendar helpers (findPersonalCalendarID, unwrapCalendars, filterRecordingsByType)
1 parent d06fc1e commit faeb683

File tree

4 files changed

+88
-3
lines changed

4 files changed

+88
-3
lines changed

API-COVERAGE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The legacy `internal/client/` is used only for HTML-scraping gap operations mark
1414
| `/laterbox.json` | GET | SDK `Boxes().GetLaterbox` | `hey box laterbox` | covered |
1515
| `/bubblebox.json` | GET | SDK `Boxes().GetBubblebox` | `hey box bubblebox` | covered |
1616
| `/calendars.json` | GET | SDK `Calendars().List` | `hey calendars` | covered |
17-
| `/calendars/{id}/recordings.json` | GET | SDK `Calendars().GetRecordings` | `hey recordings <calendar-id>` | covered |
17+
| `/calendars/{id}/recordings.json` | GET | SDK `Calendars().GetRecordings` | `hey recordings <calendar-id>`, `hey todo list`, `hey timetrack list`, `hey journal list` | covered |
1818
| `/topics/{id}/entries` | GET (HTML) | Legacy `GetTopicEntries` | `hey threads <id>` | gap: SDK Entry lacks body |
1919
| `/entries/drafts.json` | GET | SDK `Entries().ListDrafts` | `hey drafts` | covered |
2020
| `/topics/messages` | POST | SDK `Messages().Create` | `hey compose` | covered |

internal/cmd/drafts.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func newDraftsCommand() *draftsCommand {
2222
Use: "drafts",
2323
Short: "List drafts",
2424
Annotations: map[string]string{
25-
"agent_notes": "Returns saved draft messages with IDs, summaries, and kind.",
25+
"agent_notes": "Returns saved draft messages with IDs, summaries, and subjects.",
2626
},
2727
Example: ` hey drafts
2828
hey drafts --limit 10

internal/cmd/sdk_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package cmd
33
import (
44
"testing"
55
"time"
6+
7+
"github.com/basecamp/hey-sdk/go/pkg/generated"
68
)
79

810
func TestFormatTimestampUTC(t *testing.T) {
@@ -51,3 +53,83 @@ func TestFormatDateZero(t *testing.T) {
5153
t.Errorf("formatDate(zero) = %q, want empty", got)
5254
}
5355
}
56+
57+
func TestFindPersonalCalendarIDByFlag(t *testing.T) {
58+
calendars := []generated.Calendar{
59+
{Id: 1, Name: "Work", Personal: false},
60+
{Id: 110, Name: "", Personal: true},
61+
}
62+
id, err := findPersonalCalendarID(calendars)
63+
if err != nil {
64+
t.Fatalf("unexpected error: %v", err)
65+
}
66+
if id != 110 {
67+
t.Errorf("findPersonalCalendarID = %d, want 110", id)
68+
}
69+
}
70+
71+
func TestFindPersonalCalendarIDByName(t *testing.T) {
72+
calendars := []generated.Calendar{
73+
{Id: 1, Name: "Work", Personal: false},
74+
{Id: 42, Name: "Personal", Personal: false},
75+
}
76+
id, err := findPersonalCalendarID(calendars)
77+
if err != nil {
78+
t.Fatalf("unexpected error: %v", err)
79+
}
80+
if id != 42 {
81+
t.Errorf("findPersonalCalendarID = %d, want 42", id)
82+
}
83+
}
84+
85+
func TestFindPersonalCalendarIDNotFound(t *testing.T) {
86+
calendars := []generated.Calendar{
87+
{Id: 1, Name: "Work", Personal: false},
88+
}
89+
_, err := findPersonalCalendarID(calendars)
90+
if err == nil {
91+
t.Fatal("expected error, got nil")
92+
}
93+
}
94+
95+
func TestUnwrapCalendarsNil(t *testing.T) {
96+
result := unwrapCalendars(nil)
97+
if result != nil {
98+
t.Errorf("unwrapCalendars(nil) = %v, want nil", result)
99+
}
100+
}
101+
102+
func TestUnwrapCalendars(t *testing.T) {
103+
payload := &generated.CalendarListPayload{
104+
Calendars: []generated.CalendarWithRecordingChangesUrl{
105+
{Calendar: generated.Calendar{Id: 1, Name: "Work"}},
106+
{Calendar: generated.Calendar{Id: 2, Name: "Personal"}},
107+
},
108+
}
109+
result := unwrapCalendars(payload)
110+
if len(result) != 2 {
111+
t.Fatalf("len = %d, want 2", len(result))
112+
}
113+
if result[0].Id != 1 || result[1].Id != 2 {
114+
t.Errorf("IDs = [%d, %d], want [1, 2]", result[0].Id, result[1].Id)
115+
}
116+
}
117+
118+
func TestFilterRecordingsByType(t *testing.T) {
119+
resp := &generated.CalendarRecordingsResponse{
120+
"Calendar::Todo": {{Id: 1, Title: "Todo"}},
121+
"Calendar::JournalEntry": {{Id: 2, Title: "Journal"}},
122+
}
123+
todos := filterRecordingsByType(resp, "Calendar::Todo")
124+
if len(todos) != 1 || todos[0].Id != 1 {
125+
t.Errorf("unexpected todos: %v", todos)
126+
}
127+
missing := filterRecordingsByType(resp, "Calendar::TimeTrack")
128+
if missing != nil {
129+
t.Errorf("expected nil for missing type, got %v", missing)
130+
}
131+
nilResult := filterRecordingsByType(nil, "Calendar::Todo")
132+
if nilResult != nil {
133+
t.Errorf("expected nil for nil resp, got %v", nilResult)
134+
}
135+
}

internal/tui/tui.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ type model struct {
7373
width int
7474
height int
7575
sdk *hey.Client
76-
legacy *client.Client // kept for gap operations (topic entry bodies)
76+
legacy *client.Client // kept for gap operations (topic entries, journal fallback, relative URL fetches)
7777
ctx context.Context
7878
cancel context.CancelFunc
7979
styles styles
@@ -570,6 +570,9 @@ func (m model) fetchBox(boxID int) tea.Cmd {
570570
// fetchTopic uses the legacy client — SDK entries lack body content (Gap 1).
571571
func (m model) fetchTopic(topicID int, title string) tea.Cmd {
572572
return func() tea.Msg {
573+
if m.legacy == nil {
574+
return errMsg{fmt.Errorf("topic view requires legacy client (SDK entries lack body content)")}
575+
}
573576
entries, err := m.legacy.GetTopicEntries(topicID)
574577
if err != nil {
575578
return errMsg{err}

0 commit comments

Comments
 (0)