Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions internal/app/habit.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,28 @@ func (a HabitApp) List(ctx context.Context) ([]domain.Habit, error) {
}

func (a HabitApp) Get(ctx context.Context, ref string) (domain.Habit, error) {
token, err := a.Auth.AccessToken(ctx)
if err != nil {
return domain.Habit{}, err
}
if looksLikeID(ref) {
token, err := a.Auth.AccessToken(ctx)
if err != nil {
return domain.Habit{}, err
}
return a.Client.GetHabit(ctx, token, ref)
}
habits, err := a.List(ctx)
if err != nil {
return domain.Habit{}, err
}
return ResolveHabit(ref, habits)
habit, err := ResolveHabit(ref, habits)
if err == nil {
return habit, nil
}
// Fallback: the habit may be archived and ListHabits only returns active habits.
// Try a direct API call in case ref is actually an ID.
h, apiErr := a.Client.GetHabit(ctx, token, ref)
if apiErr == nil {
return h, nil
}
return domain.Habit{}, err
}

func looksLikeID(ref string) bool {
Expand Down
47 changes: 47 additions & 0 deletions internal/app/habit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,58 @@ func TestHabitGetByName(t *testing.T) {
}
}

func TestHabitGetByID(t *testing.T) {
client := &stubHabitAPI{
getHabit: func(_ context.Context, _, id string) (domain.Habit, error) {
if id == "abc123def456789012345678" {
return domain.Habit{ID: "abc123def456789012345678", Name: "Exercise"}, nil
}
return domain.Habit{}, errors.New("not found")
},
}
app := newTestHabitApp(client)
habit, err := app.Get(context.Background(), "abc123def456789012345678")
if err != nil {
t.Fatalf("Get() error = %v", err)
}
if habit.ID != "abc123def456789012345678" {
t.Fatalf("habit.ID = %q, want abc123def456789012345678", habit.ID)
}
}

func TestHabitGetFallbackToAPI(t *testing.T) {
client := &stubHabitAPI{
listHabits: func(_ context.Context, _ string) ([]domain.Habit, error) {
return []domain.Habit{{ID: "h1", Name: "Other"}}, nil
},
getHabit: func(_ context.Context, _, id string) (domain.Habit, error) {
if id == "archived-habit" {
return domain.Habit{ID: "archived-habit", Name: "Archived Habit", Status: domain.HabitStatusArchived}, nil
}
return domain.Habit{}, errors.New("not found")
},
}
app := newTestHabitApp(client)
habit, err := app.Get(context.Background(), "archived-habit")
if err != nil {
t.Fatalf("Get() error = %v", err)
}
if habit.ID != "archived-habit" {
t.Fatalf("habit.ID = %q, want archived-habit", habit.ID)
}
if habit.Status != domain.HabitStatusArchived {
t.Fatalf("habit.Status = %v, want archived", habit.Status)
}
}

func TestHabitGetNotFound(t *testing.T) {
client := &stubHabitAPI{
listHabits: func(_ context.Context, _ string) ([]domain.Habit, error) {
return []domain.Habit{}, nil
},
getHabit: func(_ context.Context, _, _ string) (domain.Habit, error) {
return domain.Habit{}, errors.New("not found")
},
}
app := newTestHabitApp(client)
_, err := app.Get(context.Background(), "Missing")
Expand Down
Loading