1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later
4
5package lunatask_test
6
7import (
8 "encoding/json"
9 "testing"
10
11 lunatask "git.secluded.site/go-lunatask"
12)
13
14// --- AllPriorities Function ---
15
16func TestAllPriorities(t *testing.T) {
17 t.Parallel()
18
19 priorities := lunatask.AllPriorities()
20
21 // Check count
22 if got := len(priorities); got != 5 {
23 t.Fatalf("AllPriorities() returned %d values, want 5", got)
24 }
25
26 // Check order (lowest to highest)
27 expected := []lunatask.Priority{
28 lunatask.PriorityLowest,
29 lunatask.PriorityLow,
30 lunatask.PriorityNormal,
31 lunatask.PriorityHigh,
32 lunatask.PriorityHighest,
33 }
34 for i, want := range expected {
35 if priorities[i] != want {
36 t.Errorf("AllPriorities()[%d] = %d, want %d", i, priorities[i], want)
37 }
38 }
39
40 // Check roundtrip: each value should be parseable
41 for _, priority := range priorities {
42 parsed, err := lunatask.ParsePriority(priority.String())
43 if err != nil {
44 t.Errorf("ParsePriority(%q) failed: %v", priority.String(), err)
45 }
46
47 if parsed != priority {
48 t.Errorf("ParsePriority(%q) = %d, want %d", priority.String(), parsed, priority)
49 }
50 }
51}
52
53// --- Priority Type Constants ---
54
55func TestPriority_Constants(t *testing.T) {
56 t.Parallel()
57
58 tests := []struct {
59 name string
60 value lunatask.Priority
61 want int
62 }{
63 {"lowest", lunatask.PriorityLowest, -2},
64 {"low", lunatask.PriorityLow, -1},
65 {"normal", lunatask.PriorityNormal, 0},
66 {"high", lunatask.PriorityHigh, 1},
67 {"highest", lunatask.PriorityHighest, 2},
68 }
69
70 for _, tc := range tests {
71 t.Run(tc.name, func(t *testing.T) {
72 t.Parallel()
73
74 if int(tc.value) != tc.want {
75 t.Errorf("Priority constant = %d, want %d", tc.value, tc.want)
76 }
77 })
78 }
79}
80
81// --- Priority String Method ---
82
83func TestPriority_String(t *testing.T) {
84 t.Parallel()
85
86 tests := []struct {
87 name string
88 value lunatask.Priority
89 want string
90 }{
91 {"lowest", lunatask.PriorityLowest, "lowest"},
92 {"low", lunatask.PriorityLow, "low"},
93 {"normal", lunatask.PriorityNormal, "normal"},
94 {"high", lunatask.PriorityHigh, "high"},
95 {"highest", lunatask.PriorityHighest, "highest"},
96 }
97
98 for _, tc := range tests {
99 t.Run(tc.name, func(t *testing.T) {
100 t.Parallel()
101
102 if got := tc.value.String(); got != tc.want {
103 t.Errorf("Priority(%d).String() = %q, want %q", tc.value, got, tc.want)
104 }
105 })
106 }
107}
108
109func TestPriority_String_Unknown(t *testing.T) {
110 t.Parallel()
111
112 p := lunatask.Priority(99)
113 if got := p.String(); got != "Priority(99)" {
114 t.Errorf("Priority(99).String() = %q, want %q", got, "Priority(99)")
115 }
116}
117
118// --- Priority Valid Method ---
119
120func TestPriority_Valid(t *testing.T) {
121 t.Parallel()
122
123 tests := []struct {
124 name string
125 value lunatask.Priority
126 want bool
127 }{
128 {"lowest", lunatask.PriorityLowest, true},
129 {"low", lunatask.PriorityLow, true},
130 {"normal", lunatask.PriorityNormal, true},
131 {"high", lunatask.PriorityHigh, true},
132 {"highest", lunatask.PriorityHighest, true},
133 {"below_range", lunatask.Priority(-3), false},
134 {"above_range", lunatask.Priority(3), false},
135 {"way_above", lunatask.Priority(99), false},
136 }
137
138 for _, tc := range tests {
139 t.Run(tc.name, func(t *testing.T) {
140 t.Parallel()
141
142 if got := tc.value.Valid(); got != tc.want {
143 t.Errorf("Priority(%d).Valid() = %v, want %v", tc.value, got, tc.want)
144 }
145 })
146 }
147}
148
149// --- ParsePriority Function ---
150
151func TestParsePriority(t *testing.T) {
152 t.Parallel()
153
154 tests := []struct {
155 name string
156 input string
157 want lunatask.Priority
158 wantErr bool
159 }{
160 {"lowest_lower", "lowest", lunatask.PriorityLowest, false},
161 {"lowest_upper", "LOWEST", lunatask.PriorityLowest, false},
162 {"lowest_mixed", "LoWeSt", lunatask.PriorityLowest, false},
163 {"low_lower", "low", lunatask.PriorityLow, false},
164 {"low_upper", "LOW", lunatask.PriorityLow, false},
165 {"normal_lower", "normal", lunatask.PriorityNormal, false},
166 {"normal_upper", "NORMAL", lunatask.PriorityNormal, false},
167 {"high_lower", "high", lunatask.PriorityHigh, false},
168 {"high_upper", "HIGH", lunatask.PriorityHigh, false},
169 {"highest_lower", "highest", lunatask.PriorityHighest, false},
170 {"highest_upper", "HIGHEST", lunatask.PriorityHighest, false},
171 {"invalid", "invalid", 0, true},
172 {"empty", "", 0, true},
173 {"numeric", "1", 0, true},
174 }
175
176 for _, testCase := range tests {
177 t.Run(testCase.name, func(t *testing.T) {
178 t.Parallel()
179
180 got, err := lunatask.ParsePriority(testCase.input)
181 if (err != nil) != testCase.wantErr {
182 t.Errorf("ParsePriority(%q) error = %v, wantErr %v", testCase.input, err, testCase.wantErr)
183
184 return
185 }
186
187 if !testCase.wantErr && got != testCase.want {
188 t.Errorf("ParsePriority(%q) = %d, want %d", testCase.input, got, testCase.want)
189 }
190 })
191 }
192}
193
194// --- Priority JSON Marshaling ---
195
196func TestPriority_MarshalJSON(t *testing.T) {
197 t.Parallel()
198
199 tests := []struct {
200 name string
201 value lunatask.Priority
202 want string
203 }{
204 {"lowest", lunatask.PriorityLowest, "-2"},
205 {"low", lunatask.PriorityLow, "-1"},
206 {"normal", lunatask.PriorityNormal, "0"},
207 {"high", lunatask.PriorityHigh, "1"},
208 {"highest", lunatask.PriorityHighest, "2"},
209 }
210
211 for _, testCase := range tests {
212 t.Run(testCase.name, func(t *testing.T) {
213 t.Parallel()
214
215 got, err := json.Marshal(testCase.value)
216 if err != nil {
217 t.Fatalf("Marshal error: %v", err)
218 }
219
220 if string(got) != testCase.want {
221 t.Errorf("json.Marshal(Priority) = %s, want %s", got, testCase.want)
222 }
223 })
224 }
225}
226
227func TestPriority_UnmarshalJSON(t *testing.T) {
228 t.Parallel()
229
230 tests := []struct {
231 name string
232 input string
233 want lunatask.Priority
234 wantErr bool
235 }{
236 {"lowest", "-2", lunatask.PriorityLowest, false},
237 {"low", "-1", lunatask.PriorityLow, false},
238 {"normal", "0", lunatask.PriorityNormal, false},
239 {"high", "1", lunatask.PriorityHigh, false},
240 {"highest", "2", lunatask.PriorityHighest, false},
241 {"null", "null", lunatask.PriorityNormal, false},
242 {"out_of_range_high", "5", 0, true},
243 {"out_of_range_low", "-5", 0, true},
244 {"string", `"high"`, 0, true},
245 }
246
247 for _, testCase := range tests {
248 t.Run(testCase.name, func(t *testing.T) {
249 t.Parallel()
250
251 var got lunatask.Priority
252
253 err := json.Unmarshal([]byte(testCase.input), &got)
254
255 if (err != nil) != testCase.wantErr {
256 t.Errorf("Unmarshal error = %v, wantErr %v", err, testCase.wantErr)
257
258 return
259 }
260
261 if !testCase.wantErr && got != testCase.want {
262 t.Errorf("Unmarshal(%s) = %d, want %d", testCase.input, got, testCase.want)
263 }
264 })
265 }
266}
267
268// --- TaskBuilder Priority Method ---
269
270func TestTaskBuilder_Priority(t *testing.T) {
271 t.Parallel()
272
273 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
274 defer server.Close()
275
276 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
277
278 _, err := client.NewTask("High priority task").
279 Priority(lunatask.PriorityHigh).
280 Create(ctx())
281 if err != nil {
282 t.Fatalf("error = %v", err)
283 }
284
285 assertBodyFieldFloat(t, capture.Body, "priority", 1)
286}
287
288func TestTaskBuilder_Priority_AllValues(t *testing.T) {
289 t.Parallel()
290
291 tests := []struct {
292 name string
293 priority lunatask.Priority
294 want float64
295 }{
296 {"lowest", lunatask.PriorityLowest, -2},
297 {"low", lunatask.PriorityLow, -1},
298 {"normal", lunatask.PriorityNormal, 0},
299 {"high", lunatask.PriorityHigh, 1},
300 {"highest", lunatask.PriorityHighest, 2},
301 }
302
303 for _, testCase := range tests {
304 t.Run(testCase.name, func(t *testing.T) {
305 t.Parallel()
306
307 server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
308 defer server.Close()
309
310 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
311
312 _, err := client.NewTask("Task").
313 Priority(testCase.priority).
314 Create(ctx())
315 if err != nil {
316 t.Fatalf("error = %v", err)
317 }
318
319 assertBodyFieldFloat(t, capture.Body, "priority", testCase.want)
320 })
321 }
322}
323
324// --- TaskUpdateBuilder Priority Method ---
325
326func TestTaskUpdateBuilder_Priority(t *testing.T) {
327 t.Parallel()
328
329 server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
330 defer server.Close()
331
332 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
333
334 _, err := client.NewTaskUpdate(taskID).
335 Priority(lunatask.PriorityLowest).
336 Update(ctx())
337 if err != nil {
338 t.Fatalf("error = %v", err)
339 }
340
341 assertBodyFieldFloat(t, capture.Body, "priority", -2)
342}
343
344func TestTaskUpdateBuilder_Priority_AllValues(t *testing.T) {
345 t.Parallel()
346
347 tests := []struct {
348 name string
349 priority lunatask.Priority
350 want float64
351 }{
352 {"lowest", lunatask.PriorityLowest, -2},
353 {"low", lunatask.PriorityLow, -1},
354 {"normal", lunatask.PriorityNormal, 0},
355 {"high", lunatask.PriorityHigh, 1},
356 {"highest", lunatask.PriorityHighest, 2},
357 }
358
359 for _, testCase := range tests {
360 t.Run(testCase.name, func(t *testing.T) {
361 t.Parallel()
362
363 server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
364 defer server.Close()
365
366 client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
367
368 _, err := client.NewTaskUpdate(taskID).
369 Priority(testCase.priority).
370 Update(ctx())
371 if err != nil {
372 t.Fatalf("error = %v", err)
373 }
374
375 assertBodyFieldFloat(t, capture.Body, "priority", testCase.want)
376 })
377 }
378}