1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later
4
5package lunatask_test
6
7import (
8 "testing"
9
10 lunatask "git.secluded.site/go-lunatask"
11)
12
13// --- Eisenhower String Method ---
14
15func TestEisenhower_String(t *testing.T) {
16 t.Parallel()
17
18 tests := []struct {
19 name string
20 value lunatask.Eisenhower
21 want string
22 }{
23 {"uncategorized", lunatask.EisenhowerUncategorized, "uncategorized"},
24 {"do_now", lunatask.EisenhowerDoNow, "do now (important + urgent)"},
25 {"delegate", lunatask.EisenhowerDelegate, "delegate (urgent)"},
26 {"do_later", lunatask.EisenhowerDoLater, "do later (important)"},
27 {"eliminate", lunatask.EisenhowerEliminate, "eliminate"},
28 }
29
30 for _, tc := range tests {
31 t.Run(tc.name, func(t *testing.T) {
32 t.Parallel()
33
34 if got := tc.value.String(); got != tc.want {
35 t.Errorf("Eisenhower(%d).String() = %q, want %q", tc.value, got, tc.want)
36 }
37 })
38 }
39}
40
41func TestEisenhower_String_Unknown(t *testing.T) {
42 t.Parallel()
43
44 unknown := lunatask.Eisenhower(99)
45 want := "Eisenhower(99)"
46
47 if got := unknown.String(); got != want {
48 t.Errorf("Eisenhower(99).String() = %q, want %q", got, want)
49 }
50}
51
52// --- Eisenhower Type Constants ---
53
54func TestEisenhower_Constants(t *testing.T) {
55 t.Parallel()
56
57 tests := []struct {
58 name string
59 value lunatask.Eisenhower
60 want int
61 }{
62 {"uncategorized", lunatask.EisenhowerUncategorized, 0},
63 {"do_now", lunatask.EisenhowerDoNow, 1},
64 {"delegate", lunatask.EisenhowerDelegate, 2},
65 {"do_later", lunatask.EisenhowerDoLater, 3},
66 {"eliminate", lunatask.EisenhowerEliminate, 4},
67 }
68
69 for _, tc := range tests {
70 t.Run(tc.name, func(t *testing.T) {
71 t.Parallel()
72
73 if int(tc.value) != tc.want {
74 t.Errorf("Eisenhower constant = %d, want %d", tc.value, tc.want)
75 }
76 })
77 }
78}
79
80// --- Eisenhower Helper Methods ---
81
82func TestEisenhower_IsUrgent(t *testing.T) {
83 t.Parallel()
84
85 tests := []struct {
86 name string
87 value lunatask.Eisenhower
88 want bool
89 }{
90 {"uncategorized", lunatask.EisenhowerUncategorized, false},
91 {"do_now", lunatask.EisenhowerDoNow, true}, // urgent + important
92 {"delegate", lunatask.EisenhowerDelegate, true}, // urgent only
93 {"do_later", lunatask.EisenhowerDoLater, false}, // important only
94 {"eliminate", lunatask.EisenhowerEliminate, false}, // neither
95 }
96
97 for _, tc := range tests {
98 t.Run(tc.name, func(t *testing.T) {
99 t.Parallel()
100
101 if got := tc.value.IsUrgent(); got != tc.want {
102 t.Errorf("Eisenhower(%d).IsUrgent() = %v, want %v", tc.value, got, tc.want)
103 }
104 })
105 }
106}
107
108func TestEisenhower_IsImportant(t *testing.T) {
109 t.Parallel()
110
111 tests := []struct {
112 name string
113 value lunatask.Eisenhower
114 want bool
115 }{
116 {"uncategorized", lunatask.EisenhowerUncategorized, false},
117 {"do_now", lunatask.EisenhowerDoNow, true}, // urgent + important
118 {"delegate", lunatask.EisenhowerDelegate, false}, // urgent only
119 {"do_later", lunatask.EisenhowerDoLater, true}, // important only
120 {"eliminate", lunatask.EisenhowerEliminate, false}, // neither
121 }
122
123 for _, tc := range tests {
124 t.Run(tc.name, func(t *testing.T) {
125 t.Parallel()
126
127 if got := tc.value.IsImportant(); got != tc.want {
128 t.Errorf("Eisenhower(%d).IsImportant() = %v, want %v", tc.value, got, tc.want)
129 }
130 })
131 }
132}
133
134// --- Eisenhower Helper Function ---
135
136func TestNewEisenhower(t *testing.T) {
137 t.Parallel()
138
139 tests := []struct {
140 name string
141 important bool
142 urgent bool
143 want lunatask.Eisenhower
144 }{
145 {"both", true, true, lunatask.EisenhowerDoNow},
146 {"urgent_only", false, true, lunatask.EisenhowerDelegate},
147 {"important_only", true, false, lunatask.EisenhowerDoLater},
148 {"neither", false, false, lunatask.EisenhowerEliminate},
149 }
150
151 for _, testCase := range tests {
152 t.Run(testCase.name, func(t *testing.T) {
153 t.Parallel()
154
155 got := lunatask.NewEisenhower(testCase.important, testCase.urgent)
156 if got != testCase.want {
157 t.Errorf("NewEisenhower(%v, %v) = %d, want %d", testCase.important, testCase.urgent, got, testCase.want)
158 }
159 })
160 }
161}
162
163// --- TaskBuilder Semantic Methods ---
164
165func TestTaskBuilder_Important(t *testing.T) {
166 t.Parallel()
167
168 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
169 defer server.Close()
170
171 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
172
173 _, err := client.NewTask("Important task").
174 Important().
175 Create(ctx())
176 if err != nil {
177 t.Fatalf("error = %v", err)
178 }
179
180 // Important only = 3 (DoLater)
181 assertBodyFieldFloat(t, capture.Body, "eisenhower", 3)
182}
183
184func TestTaskBuilder_Urgent(t *testing.T) {
185 t.Parallel()
186
187 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
188 defer server.Close()
189
190 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
191
192 _, err := client.NewTask("Urgent task").
193 Urgent().
194 Create(ctx())
195 if err != nil {
196 t.Fatalf("error = %v", err)
197 }
198
199 // Urgent only = 2 (Delegate)
200 assertBodyFieldFloat(t, capture.Body, "eisenhower", 2)
201}
202
203func TestTaskBuilder_ImportantAndUrgent(t *testing.T) {
204 t.Parallel()
205
206 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
207 defer server.Close()
208
209 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
210
211 _, err := client.NewTask("Do now task").
212 Important().
213 Urgent().
214 Create(ctx())
215 if err != nil {
216 t.Fatalf("error = %v", err)
217 }
218
219 // Both = 1 (DoNow)
220 assertBodyFieldFloat(t, capture.Body, "eisenhower", 1)
221}
222
223func TestTaskBuilder_UrgentAndImportant_ReverseOrder(t *testing.T) {
224 t.Parallel()
225
226 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
227 defer server.Close()
228
229 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
230
231 _, err := client.NewTask("Do now task").
232 Urgent().
233 Important().
234 Create(ctx())
235 if err != nil {
236 t.Fatalf("error = %v", err)
237 }
238
239 // Both = 1 (DoNow), order shouldn't matter
240 assertBodyFieldFloat(t, capture.Body, "eisenhower", 1)
241}
242
243func TestTaskBuilder_NeitherImportantNorUrgent(t *testing.T) {
244 t.Parallel()
245
246 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
247 defer server.Close()
248
249 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
250
251 // Explicitly set neither - should result in Eliminate (4)
252 _, err := client.NewTask("Eliminate task").
253 NotImportant().
254 NotUrgent().
255 Create(ctx())
256 if err != nil {
257 t.Fatalf("error = %v", err)
258 }
259
260 // Neither = 4 (Eliminate)
261 assertBodyFieldFloat(t, capture.Body, "eisenhower", 4)
262}
263
264// --- TaskUpdateBuilder Semantic Methods ---
265
266func TestTaskUpdateBuilder_Important(t *testing.T) {
267 t.Parallel()
268
269 server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
270 defer server.Close()
271
272 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
273
274 _, err := client.NewTaskUpdate(taskID).
275 Important().
276 Update(ctx())
277 if err != nil {
278 t.Fatalf("error = %v", err)
279 }
280
281 // Important only = 3 (DoLater)
282 assertBodyFieldFloat(t, capture.Body, "eisenhower", 3)
283}
284
285func TestTaskUpdateBuilder_Urgent(t *testing.T) {
286 t.Parallel()
287
288 server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
289 defer server.Close()
290
291 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
292
293 _, err := client.NewTaskUpdate(taskID).
294 Urgent().
295 Update(ctx())
296 if err != nil {
297 t.Fatalf("error = %v", err)
298 }
299
300 // Urgent only = 2 (Delegate)
301 assertBodyFieldFloat(t, capture.Body, "eisenhower", 2)
302}
303
304func TestTaskUpdateBuilder_ImportantAndUrgent(t *testing.T) {
305 t.Parallel()
306
307 server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
308 defer server.Close()
309
310 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
311
312 _, err := client.NewTaskUpdate(taskID).
313 Important().
314 Urgent().
315 Update(ctx())
316 if err != nil {
317 t.Fatalf("error = %v", err)
318 }
319
320 // Both = 1 (DoNow)
321 assertBodyFieldFloat(t, capture.Body, "eisenhower", 1)
322}
323
324func TestTaskUpdateBuilder_NeitherImportantNorUrgent(t *testing.T) {
325 t.Parallel()
326
327 server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
328 defer server.Close()
329
330 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
331
332 _, err := client.NewTaskUpdate(taskID).
333 NotImportant().
334 NotUrgent().
335 Update(ctx())
336 if err != nil {
337 t.Fatalf("error = %v", err)
338 }
339
340 // Neither = 4 (Eliminate)
341 assertBodyFieldFloat(t, capture.Body, "eisenhower", 4)
342}
343
344// --- WithEisenhower still works with typed constant ---
345
346func TestTaskBuilder_WithEisenhowerTyped(t *testing.T) {
347 t.Parallel()
348
349 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
350 defer server.Close()
351
352 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
353
354 _, err := client.NewTask("Typed eisenhower").
355 WithEisenhower(lunatask.EisenhowerDoNow).
356 Create(ctx())
357 if err != nil {
358 t.Fatalf("error = %v", err)
359 }
360
361 assertBodyFieldFloat(t, capture.Body, "eisenhower", 1)
362}
363
364func TestTaskUpdateBuilder_WithEisenhowerTyped(t *testing.T) {
365 t.Parallel()
366
367 server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
368 defer server.Close()
369
370 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
371
372 _, err := client.NewTaskUpdate(taskID).
373 WithEisenhower(lunatask.EisenhowerDelegate).
374 Update(ctx())
375 if err != nil {
376 t.Fatalf("error = %v", err)
377 }
378
379 assertBodyFieldFloat(t, capture.Body, "eisenhower", 2)
380}