1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# Phase 3 Step 1: Trello Write Operations
**Status:** Active
**Priority:** High
**Feature:** Interactive Dashboard (Write Ops)
## Description
Currently, the Trello client is read-only. We need to implement `CreateCard` and `UpdateCard` to enable interactivity (adding tasks, moving cards, completing items).
## Requirements
1. **CreateCard:**
* Method: `POST /1/cards`
* Parameters: `name`, `idList`, `desc` (optional), `due` (optional).
* Returns: Created `models.Card`.
2. **UpdateCard:**
* Method: `PUT /1/cards/{id}`
* Parameters: Flexible map of updates (e.g., `idList` to move, `closed=true` to archive).
* Returns: Updated `models.Card` (or just error).
## Reproduction / Test Plan
Since we cannot hit the real Trello API in tests, we will use `httptest.Server` to mock the API responses.
### `internal/api/trello_test.go`
```go
package api
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"task-dashboard/internal/models"
)
func TestTrelloClient_CreateCard(t *testing.T) {
// Mock Server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
t.Errorf("Expected POST, got %s", r.Method)
}
if r.URL.Path != "/1/cards" {
t.Errorf("Expected /1/cards, got %s", r.URL.Path)
}
// Verify params
r.ParseForm()
if r.Form.Get("name") != "New Task" {
t.Errorf("Expected name='New Task', got %s", r.Form.Get("name"))
}
// Return mock response
card := models.Card{
ID: "new-card-id",
Name: "New Task",
}
json.NewEncoder(w).Encode(card)
}))
defer server.Close()
client := &TrelloClient{
BaseURL: server.URL,
Key: "test-key",
Token: "test-token",
Client: server.Client(),
}
card, err := client.CreateCard("list-id", "New Task", "Description", nil)
if err != nil {
t.Fatalf("CreateCard failed: %v", err)
}
if card.ID != "new-card-id" {
t.Errorf("Expected ID 'new-card-id', got %s", card.ID)
}
}
```
|