Add put task endpoint #33
| @@ -357,3 +357,31 @@ func TestGetTaskBadId(t *testing.T) { | ||||
| 	createTestTask(e) | ||||
| 	e.GET("/task/invalid").Expect().Status(400) | ||||
| } | ||||
|  | ||||
| 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) | ||||
| } | ||||
|   | ||||
| @@ -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() | ||||
| } | ||||
|   | ||||
| @@ -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"` | ||||
| } | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user