diff options
Diffstat (limited to 'internal/handlers/widget_test.go')
| -rw-r--r-- | internal/handlers/widget_test.go | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/internal/handlers/widget_test.go b/internal/handlers/widget_test.go new file mode 100644 index 0000000..a82a070 --- /dev/null +++ b/internal/handlers/widget_test.go @@ -0,0 +1,127 @@ +package handlers_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "task-dashboard/internal/handlers" + "task-dashboard/internal/models" +) + +func TestWidgetAuthMiddleware_NoToken(t *testing.T) { + called := false + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { called = true }) + h := handlers.WidgetAuthMiddleware("secret", inner) + + req := httptest.NewRequest("GET", "/api/widget", nil) + w := httptest.NewRecorder() + h.ServeHTTP(w, req) + + if w.Code != http.StatusUnauthorized { + t.Fatalf("expected 401, got %d", w.Code) + } + if called { + t.Fatal("inner handler should not have been called") + } +} + +func TestWidgetAuthMiddleware_WrongToken(t *testing.T) { + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}) + h := handlers.WidgetAuthMiddleware("secret", inner) + + req := httptest.NewRequest("GET", "/api/widget", nil) + req.Header.Set("Authorization", "Bearer wrong") + w := httptest.NewRecorder() + h.ServeHTTP(w, req) + + if w.Code != http.StatusUnauthorized { + t.Fatalf("expected 401, got %d", w.Code) + } +} + +func TestWidgetAuthMiddleware_CorrectToken(t *testing.T) { + called := false + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { called = true }) + h := handlers.WidgetAuthMiddleware("secret", inner) + + req := httptest.NewRequest("GET", "/api/widget", nil) + req.Header.Set("Authorization", "Bearer secret") + w := httptest.NewRecorder() + h.ServeHTTP(w, req) + + if !called { + t.Fatal("inner handler should have been called") + } +} + +func TestTimelineItemToWidgetItem_Task(t *testing.T) { + now := time.Now() + item := models.TimelineItem{ + ID: "abc", + Title: "Write notes", + Source: "todoist", + Type: models.TimelineItemTypeTask, + Time: now, + IsAllDay: true, + URL: "https://todoist.com/task/abc", + } + + wi := handlers.TimelineItemToWidgetItem(item) + + if wi.ID != "abc" { + t.Errorf("ID: got %q, want %q", wi.ID, "abc") + } + if wi.Type != "task" { + t.Errorf("Type: got %q, want %q", wi.Type, "task") + } + if !wi.Completable { + t.Error("todoist task should be completable") + } + if wi.Start != nil { + t.Error("all-day item should have nil Start") + } +} + +func TestTimelineItemToWidgetItem_Event(t *testing.T) { + start := time.Now() + end := start.Add(time.Hour) + item := models.TimelineItem{ + ID: "cal1", + Title: "Team sync", + Source: "calendar", + Type: models.TimelineItemTypeEvent, + Time: start, + EndTime: &end, + } + + wi := handlers.TimelineItemToWidgetItem(item) + + if wi.Type != "event" { + t.Errorf("Type: got %q, want %q", wi.Type, "event") + } + if wi.Completable { + t.Error("calendar event should not be completable") + } + if wi.Start == nil { + t.Error("timed event should have non-nil Start") + } +} + +func TestHandleWidgetComplete_NonTodoist(t *testing.T) { + h := handlers.HandleWidgetComplete(nil) + body := `{"id":"x","source":"calendar"}` + req := httptest.NewRequest("POST", "/api/widget/complete", strings.NewReader(body)) + w := httptest.NewRecorder() + h.ServeHTTP(w, req) + + if w.Code != http.StatusBadRequest { + t.Fatalf("expected 400, got %d", w.Code) + } +} + +// Ensure json import is used (WidgetResponse roundtrip sanity check). +var _ = json.Marshal |
