@@ -0,0 +1,339 @@
+// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+package lunatask_test
+
+import (
+ "encoding/json"
+ "testing"
+
+ lunatask "git.secluded.site/go-lunatask"
+)
+
+// --- Priority Type Constants ---
+
+func TestPriority_Constants(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ value lunatask.Priority
+ want int
+ }{
+ {"lowest", lunatask.PriorityLowest, -2},
+ {"low", lunatask.PriorityLow, -1},
+ {"normal", lunatask.PriorityNormal, 0},
+ {"high", lunatask.PriorityHigh, 1},
+ {"highest", lunatask.PriorityHighest, 2},
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+
+ if int(tc.value) != tc.want {
+ t.Errorf("Priority constant = %d, want %d", tc.value, tc.want)
+ }
+ })
+ }
+}
+
+// --- Priority String Method ---
+
+func TestPriority_String(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ value lunatask.Priority
+ want string
+ }{
+ {"lowest", lunatask.PriorityLowest, "lowest"},
+ {"low", lunatask.PriorityLow, "low"},
+ {"normal", lunatask.PriorityNormal, "normal"},
+ {"high", lunatask.PriorityHigh, "high"},
+ {"highest", lunatask.PriorityHighest, "highest"},
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+
+ if got := tc.value.String(); got != tc.want {
+ t.Errorf("Priority(%d).String() = %q, want %q", tc.value, got, tc.want)
+ }
+ })
+ }
+}
+
+func TestPriority_String_Unknown(t *testing.T) {
+ t.Parallel()
+
+ p := lunatask.Priority(99)
+ if got := p.String(); got != "Priority(99)" {
+ t.Errorf("Priority(99).String() = %q, want %q", got, "Priority(99)")
+ }
+}
+
+// --- Priority Valid Method ---
+
+func TestPriority_Valid(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ value lunatask.Priority
+ want bool
+ }{
+ {"lowest", lunatask.PriorityLowest, true},
+ {"low", lunatask.PriorityLow, true},
+ {"normal", lunatask.PriorityNormal, true},
+ {"high", lunatask.PriorityHigh, true},
+ {"highest", lunatask.PriorityHighest, true},
+ {"below_range", lunatask.Priority(-3), false},
+ {"above_range", lunatask.Priority(3), false},
+ {"way_above", lunatask.Priority(99), false},
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+
+ if got := tc.value.Valid(); got != tc.want {
+ t.Errorf("Priority(%d).Valid() = %v, want %v", tc.value, got, tc.want)
+ }
+ })
+ }
+}
+
+// --- ParsePriority Function ---
+
+func TestParsePriority(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ input string
+ want lunatask.Priority
+ wantErr bool
+ }{
+ {"lowest_lower", "lowest", lunatask.PriorityLowest, false},
+ {"lowest_upper", "LOWEST", lunatask.PriorityLowest, false},
+ {"lowest_mixed", "LoWeSt", lunatask.PriorityLowest, false},
+ {"low_lower", "low", lunatask.PriorityLow, false},
+ {"low_upper", "LOW", lunatask.PriorityLow, false},
+ {"normal_lower", "normal", lunatask.PriorityNormal, false},
+ {"normal_upper", "NORMAL", lunatask.PriorityNormal, false},
+ {"high_lower", "high", lunatask.PriorityHigh, false},
+ {"high_upper", "HIGH", lunatask.PriorityHigh, false},
+ {"highest_lower", "highest", lunatask.PriorityHighest, false},
+ {"highest_upper", "HIGHEST", lunatask.PriorityHighest, false},
+ {"invalid", "invalid", 0, true},
+ {"empty", "", 0, true},
+ {"numeric", "1", 0, true},
+ }
+
+ for _, testCase := range tests {
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ got, err := lunatask.ParsePriority(testCase.input)
+ if (err != nil) != testCase.wantErr {
+ t.Errorf("ParsePriority(%q) error = %v, wantErr %v", testCase.input, err, testCase.wantErr)
+
+ return
+ }
+
+ if !testCase.wantErr && got != testCase.want {
+ t.Errorf("ParsePriority(%q) = %d, want %d", testCase.input, got, testCase.want)
+ }
+ })
+ }
+}
+
+// --- Priority JSON Marshaling ---
+
+func TestPriority_MarshalJSON(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ value lunatask.Priority
+ want string
+ }{
+ {"lowest", lunatask.PriorityLowest, "-2"},
+ {"low", lunatask.PriorityLow, "-1"},
+ {"normal", lunatask.PriorityNormal, "0"},
+ {"high", lunatask.PriorityHigh, "1"},
+ {"highest", lunatask.PriorityHighest, "2"},
+ }
+
+ for _, testCase := range tests {
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ got, err := json.Marshal(testCase.value)
+ if err != nil {
+ t.Fatalf("Marshal error: %v", err)
+ }
+
+ if string(got) != testCase.want {
+ t.Errorf("json.Marshal(Priority) = %s, want %s", got, testCase.want)
+ }
+ })
+ }
+}
+
+func TestPriority_UnmarshalJSON(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ input string
+ want lunatask.Priority
+ wantErr bool
+ }{
+ {"lowest", "-2", lunatask.PriorityLowest, false},
+ {"low", "-1", lunatask.PriorityLow, false},
+ {"normal", "0", lunatask.PriorityNormal, false},
+ {"high", "1", lunatask.PriorityHigh, false},
+ {"highest", "2", lunatask.PriorityHighest, false},
+ {"null", "null", lunatask.PriorityNormal, false},
+ {"out_of_range_high", "5", 0, true},
+ {"out_of_range_low", "-5", 0, true},
+ {"string", `"high"`, 0, true},
+ }
+
+ for _, testCase := range tests {
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ var got lunatask.Priority
+
+ err := json.Unmarshal([]byte(testCase.input), &got)
+
+ if (err != nil) != testCase.wantErr {
+ t.Errorf("Unmarshal error = %v, wantErr %v", err, testCase.wantErr)
+
+ return
+ }
+
+ if !testCase.wantErr && got != testCase.want {
+ t.Errorf("Unmarshal(%s) = %d, want %d", testCase.input, got, testCase.want)
+ }
+ })
+ }
+}
+
+// --- TaskBuilder Priority Method ---
+
+func TestTaskBuilder_Priority(t *testing.T) {
+ t.Parallel()
+
+ server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
+ defer server.Close()
+
+ client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
+
+ _, err := client.NewTask("High priority task").
+ Priority(lunatask.PriorityHigh).
+ Create(ctx())
+ if err != nil {
+ t.Fatalf("error = %v", err)
+ }
+
+ assertBodyFieldFloat(t, capture.Body, "priority", 1)
+}
+
+func TestTaskBuilder_Priority_AllValues(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ priority lunatask.Priority
+ want float64
+ }{
+ {"lowest", lunatask.PriorityLowest, -2},
+ {"low", lunatask.PriorityLow, -1},
+ {"normal", lunatask.PriorityNormal, 0},
+ {"high", lunatask.PriorityHigh, 1},
+ {"highest", lunatask.PriorityHighest, 2},
+ }
+
+ for _, testCase := range tests {
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ server, capture := newPOSTServer(t, "/tasks", singleTaskResponseBody)
+ defer server.Close()
+
+ client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
+
+ _, err := client.NewTask("Task").
+ Priority(testCase.priority).
+ Create(ctx())
+ if err != nil {
+ t.Fatalf("error = %v", err)
+ }
+
+ assertBodyFieldFloat(t, capture.Body, "priority", testCase.want)
+ })
+ }
+}
+
+// --- TaskUpdateBuilder Priority Method ---
+
+func TestTaskUpdateBuilder_Priority(t *testing.T) {
+ t.Parallel()
+
+ server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
+ defer server.Close()
+
+ client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
+
+ _, err := client.NewTaskUpdate(taskID).
+ Priority(lunatask.PriorityLowest).
+ Update(ctx())
+ if err != nil {
+ t.Fatalf("error = %v", err)
+ }
+
+ assertBodyFieldFloat(t, capture.Body, "priority", -2)
+}
+
+func TestTaskUpdateBuilder_Priority_AllValues(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ priority lunatask.Priority
+ want float64
+ }{
+ {"lowest", lunatask.PriorityLowest, -2},
+ {"low", lunatask.PriorityLow, -1},
+ {"normal", lunatask.PriorityNormal, 0},
+ {"high", lunatask.PriorityHigh, 1},
+ {"highest", lunatask.PriorityHighest, 2},
+ }
+
+ for _, testCase := range tests {
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ server, capture := newPUTServer(t, "/tasks/"+taskID, singleTaskResponseBody)
+ defer server.Close()
+
+ client := lunatask.NewClient(testToken, lunatask.BaseURL(server.URL))
+
+ _, err := client.NewTaskUpdate(taskID).
+ Priority(testCase.priority).
+ Update(ctx())
+ if err != nil {
+ t.Fatalf("error = %v", err)
+ }
+
+ assertBodyFieldFloat(t, capture.Body, "priority", testCase.want)
+ })
+ }
+}