415 lines
11 KiB
Go
415 lines
11 KiB
Go
|
|
package kanboard
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"errors"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestClient_GetAllComments(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 != "getAllComments" {
|
||
|
|
t.Errorf("expected method=getAllComments, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["task_id"].(float64) != 42 {
|
||
|
|
t.Errorf("expected task_id=42, got %v", params["task_id"])
|
||
|
|
}
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`[
|
||
|
|
{"id": "1", "task_id": "42", "user_id": "1", "comment": "First comment", "username": "admin"},
|
||
|
|
{"id": "2", "task_id": "42", "user_id": "2", "comment": "Second comment", "username": "user"}
|
||
|
|
]`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
comments, err := client.GetAllComments(context.Background(), 42)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(comments) != 2 {
|
||
|
|
t.Errorf("expected 2 comments, got %d", len(comments))
|
||
|
|
}
|
||
|
|
if comments[0].Content != "First comment" {
|
||
|
|
t.Errorf("expected first comment='First comment', got %s", comments[0].Content)
|
||
|
|
}
|
||
|
|
if comments[0].Username != "admin" {
|
||
|
|
t.Errorf("expected username='admin', got %s", comments[0].Username)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_GetAllComments_Empty(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`[]`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
comments, err := client.GetAllComments(context.Background(), 42)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(comments) != 0 {
|
||
|
|
t.Errorf("expected 0 comments, got %d", len(comments))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_GetComment(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 != "getComment" {
|
||
|
|
t.Errorf("expected method=getComment, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["comment_id"].(float64) != 5 {
|
||
|
|
t.Errorf("expected comment_id=5, got %v", params["comment_id"])
|
||
|
|
}
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`{"id": "5", "task_id": "42", "user_id": "1", "comment": "Test comment", "username": "admin"}`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
comment, err := client.GetComment(context.Background(), 5)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if int(comment.ID) != 5 {
|
||
|
|
t.Errorf("expected ID=5, got %d", comment.ID)
|
||
|
|
}
|
||
|
|
if comment.Content != "Test comment" {
|
||
|
|
t.Errorf("expected content='Test comment', got %s", comment.Content)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_GetComment_NotFound(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`null`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
_, err := client.GetComment(context.Background(), 999)
|
||
|
|
if err == nil {
|
||
|
|
t.Fatal("expected error for non-existent comment")
|
||
|
|
}
|
||
|
|
|
||
|
|
if !errors.Is(err, ErrCommentNotFound) {
|
||
|
|
t.Errorf("expected ErrCommentNotFound, got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_CreateComment(t *testing.T) {
|
||
|
|
callCount := 0
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
callCount++
|
||
|
|
if callCount == 1 {
|
||
|
|
// First call: createComment
|
||
|
|
if req.Method != "createComment" {
|
||
|
|
t.Errorf("expected method=createComment, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["task_id"].(float64) != 42 {
|
||
|
|
t.Errorf("expected task_id=42, got %v", params["task_id"])
|
||
|
|
}
|
||
|
|
if params["user_id"].(float64) != 1 {
|
||
|
|
t.Errorf("expected user_id=1, got %v", params["user_id"])
|
||
|
|
}
|
||
|
|
if params["content"] != "New comment" {
|
||
|
|
t.Errorf("expected content='New comment', got %v", params["content"])
|
||
|
|
}
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`10`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
} else {
|
||
|
|
// Second call: getComment to fetch created comment
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`{"id": "10", "task_id": "42", "user_id": "1", "comment": "New comment", "username": "admin"}`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
comment, err := client.CreateComment(context.Background(), 42, 1, "New comment")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if int(comment.ID) != 10 {
|
||
|
|
t.Errorf("expected ID=10, got %d", comment.ID)
|
||
|
|
}
|
||
|
|
if comment.Content != "New comment" {
|
||
|
|
t.Errorf("expected content='New comment', got %s", comment.Content)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_CreateComment_Failure(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`0`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
_, err := client.CreateComment(context.Background(), 42, 1, "New comment")
|
||
|
|
if err == nil {
|
||
|
|
t.Fatal("expected error for failed comment creation")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_UpdateComment(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 != "updateComment" {
|
||
|
|
t.Errorf("expected method=updateComment, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["id"].(float64) != 5 {
|
||
|
|
t.Errorf("expected id=5, got %v", params["id"])
|
||
|
|
}
|
||
|
|
if params["content"] != "Updated content" {
|
||
|
|
t.Errorf("expected content='Updated content', got %v", params["content"])
|
||
|
|
}
|
||
|
|
|
||
|
|
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")
|
||
|
|
|
||
|
|
err := client.UpdateComment(context.Background(), 5, "Updated content")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_UpdateComment_Failure(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`false`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
err := client.UpdateComment(context.Background(), 5, "Updated content")
|
||
|
|
if err == nil {
|
||
|
|
t.Fatal("expected error for failed update")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_RemoveComment(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 != "removeComment" {
|
||
|
|
t.Errorf("expected method=removeComment, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["comment_id"].(float64) != 5 {
|
||
|
|
t.Errorf("expected comment_id=5, got %v", params["comment_id"])
|
||
|
|
}
|
||
|
|
|
||
|
|
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")
|
||
|
|
|
||
|
|
err := client.RemoveComment(context.Background(), 5)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClient_RemoveComment_Failure(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`false`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
err := client.RemoveComment(context.Background(), 5)
|
||
|
|
if err == nil {
|
||
|
|
t.Fatal("expected error for failed delete")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskScope_GetComments(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 != "getAllComments" {
|
||
|
|
t.Errorf("expected method=getAllComments, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["task_id"].(float64) != 42 {
|
||
|
|
t.Errorf("expected task_id=42, got %v", params["task_id"])
|
||
|
|
}
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`[{"id": "1", "task_id": "42", "comment": "Test", "username": "admin"}]`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
comments, err := client.Task(42).GetComments(context.Background())
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(comments) != 1 {
|
||
|
|
t.Errorf("expected 1 comment, got %d", len(comments))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTaskScope_AddComment(t *testing.T) {
|
||
|
|
callCount := 0
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req JSONRPCRequest
|
||
|
|
json.NewDecoder(r.Body).Decode(&req)
|
||
|
|
|
||
|
|
callCount++
|
||
|
|
if callCount == 1 {
|
||
|
|
// First call: createComment
|
||
|
|
if req.Method != "createComment" {
|
||
|
|
t.Errorf("expected method=createComment, got %s", req.Method)
|
||
|
|
}
|
||
|
|
|
||
|
|
params := req.Params.(map[string]any)
|
||
|
|
if params["task_id"].(float64) != 42 {
|
||
|
|
t.Errorf("expected task_id=42, got %v", params["task_id"])
|
||
|
|
}
|
||
|
|
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`10`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
} else {
|
||
|
|
// Second call: getComment
|
||
|
|
resp := JSONRPCResponse{
|
||
|
|
JSONRPC: "2.0",
|
||
|
|
ID: req.ID,
|
||
|
|
Result: json.RawMessage(`{"id": "10", "task_id": "42", "comment": "Added via scope", "username": "admin"}`),
|
||
|
|
}
|
||
|
|
json.NewEncoder(w).Encode(resp)
|
||
|
|
}
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL).WithAPIToken("test-token")
|
||
|
|
|
||
|
|
comment, err := client.Task(42).AddComment(context.Background(), 1, "Added via scope")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if int(comment.ID) != 10 {
|
||
|
|
t.Errorf("expected ID=10, got %d", comment.ID)
|
||
|
|
}
|
||
|
|
}
|