1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
|