From 649c7aab2f75f5405d47539a6abe393ab3ea3ea1 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Schaetzen Date: Tue, 13 May 2025 13:00:18 +0200 Subject: [PATCH] Add put task endpoint --- backend/api_test.go | 28 ++++++++++++++++++++++++++++ backend/db.go | 30 ++++++++++++++++++++++++++++-- backend/dto.go | 2 -- backend/main.go | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/backend/api_test.go b/backend/api_test.go index 9f3c527..cf1ffe3 100644 --- a/backend/api_test.go +++ b/backend/api_test.go @@ -351,3 +351,31 @@ func TestGetTaskInvalidId(t *testing.T) { createTestTask(e) e.GET("/task/2").Expect().Status(404) } + +func TestPutTaskModifiesTask(t *testing.T) { + e := startServer(t) + createTestTask(e) + requestBody := map[string]interface{}{ + "name": "Updated Task", + "reward": 100, + } + e.PUT("/task/1").WithJSON(requestBody).Expect(). + Status(200). + JSON().Object() + + // Verify the task is updated + result := e.GET("/task/1").Expect().Status(200).JSON().Object() + result.Value("id").IsEqual(1) + result.Value("name").IsEqual("Updated Task") + result.Value("reward").IsEqual(100) +} + +func TestPutTaskInvalidTaskId(t *testing.T) { + e := startServer(t) + createTestTask(e) + + requestBody := map[string]interface{}{ + "name": "Updated Task", + } + e.PUT("/task/999").WithJSON(requestBody).Expect().Status(404) +} diff --git a/backend/db.go b/backend/db.go index dc9aa36..b707dce 100644 --- a/backend/db.go +++ b/backend/db.go @@ -102,7 +102,7 @@ func (db *Db) CreateGoal(userId int, goal *CreateGoalRequest) (int, error) { if err != nil { return 0, err } - defer tx.Rollback() + defer tx.MustRollback() // Insert the new goal err = tx.Query("insert into goals (user_id, name, target, progress, weight) values (?, ?, ?, 0, ?)"). @@ -156,7 +156,7 @@ func (db *Db) CreateTask(task *CreateTaskRequest) (int, error) { if err != nil { return 0, err } - defer tx.Rollback() + defer tx.MustRollback() // Insert the new task err = tx.Query("insert into tasks (name, reward, assigned) values (?, ?, ?)"). @@ -211,3 +211,29 @@ func (db *Db) GetTask(id int) (Task, error) { } return task, nil } + +func (db *Db) HasTask(id int) (bool, error) { + count := 0 + err := db.db.Query("select count(*) from tasks where id = ?"). + Bind(id).ScanSingle(&count) + if err != nil { + return false, err + } + return count > 0, nil +} + +func (db *Db) UpdateTask(id int, task *CreateTaskRequest) error { + tx, err := db.db.Begin() + if err != nil { + return err + } + defer tx.MustRollback() + + err = tx.Query("update tasks set name=?, reward=?, assigned=? where id = ?"). + Bind(task.Name, task.Reward, task.Assigned, id). + Exec() + if err != nil { + return err + } + return tx.Commit() +} diff --git a/backend/dto.go b/backend/dto.go index 3fe211f..756df6e 100644 --- a/backend/dto.go +++ b/backend/dto.go @@ -36,14 +36,12 @@ type CreateGoalResponse struct { ID int `json:"id"` } -// CreateTaskRequest represents the request body for creating a new task. type CreateTaskRequest struct { Name string `json:"name" binding:"required"` Reward int `json:"reward"` Assigned *int `json:"assigned"` } -// CreateTaskResponse represents the response body after creating a new task. type CreateTaskResponse struct { ID int `json:"id"` } diff --git a/backend/main.go b/backend/main.go index 7bc6355..f9b6059 100644 --- a/backend/main.go +++ b/backend/main.go @@ -257,6 +257,38 @@ func getTask(c *gin.Context) { c.JSON(http.StatusOK, &response) } +func putTask(c *gin.Context) { + taskIdStr := c.Param("taskId") + taskId, err := strconv.Atoi(taskIdStr) + if err != nil { + log.Printf("Invalid task ID: %v", err) + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid task ID"}) + return + } + + var taskRequest CreateTaskRequest + if err := c.ShouldBindJSON(&taskRequest); err != nil { + log.Printf("Error parsing request body: %v", err) + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) + return + } + + _, err = db.GetTask(taskId) + if errors.Is(err, mysqlite.ErrNoRows) { + c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"}) + return + } + + err = db.UpdateTask(taskId, &taskRequest) + if err != nil { + log.Printf("Error updating task: %v", err) + c.JSON(http.StatusInternalServerError, gin.H{"error": ErrInternalServerError}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "Task updated successfully"}) +} + /* * Initialises the database, and then starts the server. @@ -275,6 +307,7 @@ func start(ctx context.Context, config *ServerConfig) { router.POST("/api/tasks", createTask) router.GET("/api/tasks", getTasks) router.GET("/api/task/:taskId", getTask) + router.PUT("/api/task/:taskId", putTask) srv := &http.Server{ Addr: config.Addr,