diff --git a/internal/ticktick/focus.go b/internal/ticktick/focus.go index c1919e7..b69e33c 100644 --- a/internal/ticktick/focus.go +++ b/internal/ticktick/focus.go @@ -2,6 +2,7 @@ package ticktick import ( "context" + "encoding/json" "fmt" "net/http" "time" @@ -10,21 +11,38 @@ import ( ) type focusDTO struct { - ID string `json:"id"` - Type int `json:"type"` - Status int `json:"status"` - Note string `json:"note"` - TaskID string `json:"taskId"` - StartTime string `json:"startTime"` - EndTime string `json:"endTime"` - Duration int64 `json:"duration"` - PauseDuration int `json:"pauseDuration"` + ID string `json:"id"` + Type int `json:"type"` + Status int `json:"status"` + Note string `json:"note"` + TaskID string `json:"taskId"` + StartTime string `json:"startTime"` + EndTime string `json:"endTime"` + Duration int64 `json:"duration"` + PauseDuration int `json:"pauseDuration"` } type focusListResponse struct { Focuses []focusDTO `json:"focuses"` } +func (r *focusListResponse) UnmarshalJSON(data []byte) error { + var items []focusDTO + if err := json.Unmarshal(data, &items); err == nil { + r.Focuses = items + return nil + } + + var wrapped struct { + Focuses []focusDTO `json:"focuses"` + } + if err := json.Unmarshal(data, &wrapped); err != nil { + return err + } + r.Focuses = wrapped.Focuses + return nil +} + func mapFocus(dto focusDTO) domain.Focus { return domain.Focus{ ID: dto.ID, diff --git a/internal/ticktick/focus_test.go b/internal/ticktick/focus_test.go index 62b45b5..32ab97a 100644 --- a/internal/ticktick/focus_test.go +++ b/internal/ticktick/focus_test.go @@ -73,6 +73,30 @@ func TestListFocus(t *testing.T) { } } +func TestListFocusAcceptsArrayResponse(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + resp := []focusDTO{ + {ID: "f1", Note: "Focus 1", Type: 1, Status: 1}, + } + _ = json.NewEncoder(w).Encode(resp) + })) + defer server.Close() + + client := New(server.URL, server.Client()) + start := time.Now() + end := start.Add(24 * time.Hour) + focuses, err := client.ListFocus(context.Background(), "token", start, end, 1) + if err != nil { + t.Fatalf("ListFocus() error = %v", err) + } + if len(focuses) != 1 { + t.Fatalf("len(focuses) = %d, want 1", len(focuses)) + } + if focuses[0].Mode != domain.FocusModeTimer { + t.Fatalf("Mode = %v, want timer", focuses[0].Mode) + } +} + func TestGetFocusReturnsError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "not found", http.StatusNotFound)