271 lines
7 KiB
Go
271 lines
7 KiB
Go
|
|
package kanboard
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestNewTaskUpdate(t *testing.T) {
|
||
|
|
params := NewTaskUpdate()
|
||
|
|
|
||
|
|
if params == nil {
|
||
|
|
t.Fatal("expected non-nil TaskUpdateParams")
|
||
|
|
}
|
||
|
|
if params.title != nil {
|
||
|
|
t.Error("expected title to be nil")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_Chaining(t *testing.T) {
|
||
|
|
dueDate := time.Date(2025, 12, 31, 0, 0, 0, 0, time.UTC)
|
||
|
|
|
||
|
|
params := NewTaskUpdate().
|
||
|
|
SetTitle("Updated Title").
|
||
|
|
SetDescription("New description").
|
||
|
|
SetColor("red").
|
||
|
|
SetOwner(10).
|
||
|
|
SetCategory(5).
|
||
|
|
SetPriority(2).
|
||
|
|
SetDueDate(dueDate).
|
||
|
|
SetReference("JIRA-456").
|
||
|
|
SetTags("urgent", "review")
|
||
|
|
|
||
|
|
if *params.title != "Updated Title" {
|
||
|
|
t.Errorf("expected title='Updated Title', got %s", *params.title)
|
||
|
|
}
|
||
|
|
if *params.description != "New description" {
|
||
|
|
t.Errorf("expected description='New description', got %s", *params.description)
|
||
|
|
}
|
||
|
|
if *params.colorID != "red" {
|
||
|
|
t.Errorf("expected colorID='red', got %s", *params.colorID)
|
||
|
|
}
|
||
|
|
if *params.ownerID != 10 {
|
||
|
|
t.Errorf("expected ownerID=10, got %d", *params.ownerID)
|
||
|
|
}
|
||
|
|
if *params.categoryID != 5 {
|
||
|
|
t.Errorf("expected categoryID=5, got %d", *params.categoryID)
|
||
|
|
}
|
||
|
|
if *params.priority != 2 {
|
||
|
|
t.Errorf("expected priority=2, got %d", *params.priority)
|
||
|
|
}
|
||
|
|
if *params.dueDate != dueDate.Unix() {
|
||
|
|
t.Errorf("expected dueDate=%d, got %d", dueDate.Unix(), *params.dueDate)
|
||
|
|
}
|
||
|
|
if *params.reference != "JIRA-456" {
|
||
|
|
t.Errorf("expected reference='JIRA-456', got %s", *params.reference)
|
||
|
|
}
|
||
|
|
if len(params.tags) != 2 || params.tags[0] != "urgent" {
|
||
|
|
t.Errorf("expected tags=['urgent', 'review'], got %v", params.tags)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_SetScore(t *testing.T) {
|
||
|
|
params := NewTaskUpdate().SetScore(5)
|
||
|
|
|
||
|
|
if *params.score != 5 {
|
||
|
|
t.Errorf("expected score=5, got %d", *params.score)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_SetStartDate(t *testing.T) {
|
||
|
|
startDate := time.Date(2025, 6, 15, 0, 0, 0, 0, time.UTC)
|
||
|
|
params := NewTaskUpdate().SetStartDate(startDate)
|
||
|
|
|
||
|
|
if *params.startDate != startDate.Unix() {
|
||
|
|
t.Errorf("expected startDate=%d, got %d", startDate.Unix(), *params.startDate)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_ClearDueDate(t *testing.T) {
|
||
|
|
params := NewTaskUpdate().ClearDueDate()
|
||
|
|
|
||
|
|
if params.dueDate == nil {
|
||
|
|
t.Fatal("expected dueDate to be set")
|
||
|
|
}
|
||
|
|
if *params.dueDate != 0 {
|
||
|
|
t.Errorf("expected dueDate=0, got %d", *params.dueDate)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_ClearStartDate(t *testing.T) {
|
||
|
|
params := NewTaskUpdate().ClearStartDate()
|
||
|
|
|
||
|
|
if *params.startDate != 0 {
|
||
|
|
t.Errorf("expected startDate=0, got %d", *params.startDate)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_ClearOwner(t *testing.T) {
|
||
|
|
params := NewTaskUpdate().ClearOwner()
|
||
|
|
|
||
|
|
if *params.ownerID != 0 {
|
||
|
|
t.Errorf("expected ownerID=0, got %d", *params.ownerID)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_ClearCategory(t *testing.T) {
|
||
|
|
params := NewTaskUpdate().ClearCategory()
|
||
|
|
|
||
|
|
if *params.categoryID != 0 {
|
||
|
|
t.Errorf("expected categoryID=0, got %d", *params.categoryID)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_toUpdateTaskRequest(t *testing.T) {
|
||
|
|
dueDate := time.Date(2025, 12, 31, 0, 0, 0, 0, time.UTC)
|
||
|
|
|
||
|
|
params := NewTaskUpdate().
|
||
|
|
SetTitle("Updated Title").
|
||
|
|
SetDescription("Details").
|
||
|
|
SetPriority(2).
|
||
|
|
SetDueDate(dueDate).
|
||
|
|
SetTags("urgent")
|
||
|
|
|
||
|
|
req := params.toUpdateTaskRequest(42)
|
||
|
|
|
||
|
|
if req.ID != 42 {
|
||
|
|
t.Errorf("expected ID=42, got %d", req.ID)
|
||
|
|
}
|
||
|
|
if *req.Title != "Updated Title" {
|
||
|
|
t.Errorf("expected Title='Updated Title', got %s", *req.Title)
|
||
|
|
}
|
||
|
|
if *req.Description != "Details" {
|
||
|
|
t.Errorf("expected Description='Details', got %s", *req.Description)
|
||
|
|
}
|
||
|
|
if *req.Priority != 2 {
|
||
|
|
t.Errorf("expected Priority=2, got %d", *req.Priority)
|
||
|
|
}
|
||
|
|
if *req.DateDue != dueDate.Unix() {
|
||
|
|
t.Errorf("expected DateDue=%d, got %d", dueDate.Unix(), *req.DateDue)
|
||
|
|
}
|
||
|
|
if len(req.Tags) != 1 || req.Tags[0] != "urgent" {
|
||
|
|
t.Errorf("expected Tags=['urgent'], got %v", req.Tags)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_toUpdateTaskRequest_PartialUpdate(t *testing.T) {
|
||
|
|
// Only set title, nothing else
|
||
|
|
params := NewTaskUpdate().SetTitle("New Title")
|
||
|
|
|
||
|
|
req := params.toUpdateTaskRequest(42)
|
||
|
|
|
||
|
|
if *req.Title != "New Title" {
|
||
|
|
t.Errorf("expected Title='New Title', got %s", *req.Title)
|
||
|
|
}
|
||
|
|
// Unset fields should be nil
|
||
|
|
if req.Description != nil {
|
||
|
|
t.Error("expected Description to be nil")
|
||
|
|
}
|
||
|
|
if req.Priority != nil {
|
||
|
|
t.Error("expected Priority to be nil")
|
||
|
|
}
|
||
|
|
if req.OwnerID != nil {
|
||
|
|
t.Error("expected OwnerID to be nil")
|
||
|
|
}
|
||
|
|
if req.Tags != nil {
|
||
|
|
t.Error("expected Tags to be nil")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskUpdateParams_SetTags_Empty(t *testing.T) {
|
||
|
|
// Explicitly clearing tags
|
||
|
|
params := NewTaskUpdate().SetTags()
|
||
|
|
|
||
|
|
if !params.tagsSet {
|
||
|
|
t.Error("expected tagsSet to be true")
|
||
|
|
}
|
||
|
|
if len(params.tags) != 0 {
|
||
|
|
t.Errorf("expected empty tags, got %v", params.tags)
|
||
|
|
}
|
||
|
|
|
||
|
|
req := params.toUpdateTaskRequest(42)
|
||
|
|
if req.Tags == nil {
|
||
|
|
t.Error("expected Tags to be non-nil (empty slice)")
|
||
|
|
}
|
||
|
|
if len(req.Tags) != 0 {
|
||
|
|
t.Errorf("expected 0 tags, got %d", len(req.Tags))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_UpdateTaskFromParams(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
if req.Method != "updateTask" {
|
||
|
|
t.Errorf("expected method=updateTask, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["id"].(float64) != 42 {
|
||
|
|
t.Errorf("expected id=42, got %v", params["id"])
|
||
|
|
}
|
||
|
|
if params["title"] != "Updated via Params" {
|
||
|
|
t.Errorf("expected title='Updated via Params', got %v", params["title"])
|
||
|
|
}
|
||
|
|
if params["priority"].(float64) != 3 {
|
||
|
|
t.Errorf("expected priority=3, got %v", params["priority"])
|
||
|
|
}
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`true`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
params := NewTaskUpdate().
|
||
|
|
SetTitle("Updated via Params").
|
||
|
|
SetPriority(3)
|
||
|
|
|
||
|
|
err := client.UpdateTaskFromParams(context.Background(), 42, params)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_UpdateTaskFromParams_OnlySetFieldsSent(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
|
||
|
|
// Only title should be present, not priority or other fields
|
||
|
|
if _, hasTitle := params["title"]; !hasTitle {
|
||
|
|
t.Error("expected title to be present")
|
||
|
|
}
|
||
|
|
if _, hasPriority := params["priority"]; hasPriority {
|
||
|
|
t.Error("expected priority to NOT be present")
|
||
|
|
}
|
||
|
|
if _, hasOwner := params["owner_id"]; hasOwner {
|
||
|
|
t.Error("expected owner_id to NOT be present")
|
||
|
|
}
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`true`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
// Only set title
|
||
|
|
params := NewTaskUpdate().SetTitle("Only Title")
|
||
|
|
|
||
|
|
err := client.UpdateTaskFromParams(context.Background(), 42, params)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
}
|