Working on creating tasks

This commit is contained in:
Sebastiaan de Schaetzen 2025-05-08 16:09:41 +02:00
parent 0668228139
commit fc32fa89c8
4 changed files with 168 additions and 3 deletions

View File

@ -205,3 +205,84 @@ func TestDeleteUserGoalInvalidId(t *testing.T) {
Status(400). Status(400).
JSON().Object().Value("error").IsEqual("Invalid goal ID") JSON().Object().Value("error").IsEqual("Invalid goal ID")
} }
func TestCreateTask(t *testing.T) {
e := startServer(t)
// Create a new task without assigned user
requestBody := map[string]interface{}{
"name": "Test Task",
"reward": 100,
}
response := e.POST("/tasks").
WithJSON(requestBody).
Expect().
Status(201). // Expect Created status
JSON().Object()
// Verify the response has an ID
response.ContainsKey("id")
taskId := response.Value("id").Number().Raw()
// Create a new task with assigned user
assignedUserId := 1
requestBodyWithUser := map[string]interface{}{
"name": "Test Task Assigned",
"reward": 200,
"assigned": assignedUserId,
}
responseWithUser := e.POST("/tasks").
WithJSON(requestBodyWithUser).
Expect().
Status(201).
JSON().Object()
responseWithUser.ContainsKey("id")
responseWithUser.Value("id").Number().NotEqual(taskId) // Ensure different ID
}
func TestCreateTaskNoName(t *testing.T) {
e := startServer(t)
requestBody := map[string]interface{}{
"reward": 100,
}
e.POST("/tasks").
WithJSON(requestBody).
Expect().
Status(400). // Expect Bad Request
JSON().Object().Value("error").IsEqual("Task name cannot be empty")
}
func TestCreateTaskInvalidAssignedUser(t *testing.T) {
e := startServer(t)
requestBody := map[string]interface{}{
"name": "Test Task Invalid User",
"reward": 100,
"assigned": 999, // Non-existent user ID
}
e.POST("/tasks").
WithJSON(requestBody).
Expect().
Status(404). // Expect Not Found
JSON().Object().Value("error").IsEqual(ErrUserNotFound)
}
func TestCreateTaskInvalidRequestBody(t *testing.T) {
e := startServer(t)
// Test with missing fields (name is required)
invalidRequest := map[string]interface{}{
"reward": 5000,
}
e.POST("/tasks").
WithJSON(invalidRequest).
Expect().
Status(400)
}

View File

@ -150,3 +150,35 @@ func (db *Db) DeleteGoal(userId int, goalId int) error {
return nil return nil
} }
func (db *Db) CreateTask(task *CreateTaskRequest) (int, error) {
tx, err := db.db.Begin()
if err != nil {
return 0, err
}
defer tx.Rollback()
// Insert the new task
err = tx.Query("insert into tasks (name, reward, assigned) values (?, ?, ?)").
Bind(task.Name, task.Reward, task.Assigned).
Exec()
if err != nil {
return 0, err
}
// Get the last inserted ID
var lastId int
err = tx.Query("select last_insert_rowid()").ScanSingle(&lastId)
if err != nil {
return 0, err
}
// Commit the transaction
err = tx.Commit()
if err != nil {
return 0, err
}
return lastId, nil
}

View File

@ -10,11 +10,12 @@ type Allowance struct {
Goals []Goal `json:"goals"` Goals []Goal `json:"goals"`
} }
type Schema struct { // Task represents a task in the system.
Id int `json:"id"` type Task struct {
ID int `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Reward int `json:"reward"` Reward int `json:"reward"`
Assigned *int `json:"assigned"` Assigned *int `json:"assigned"` // Pointer to allow null
} }
type Goal struct { type Goal struct {
@ -34,3 +35,15 @@ type CreateGoalRequest struct {
type CreateGoalResponse struct { type CreateGoalResponse struct {
ID int `json:"id"` 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"`
}

View File

@ -183,6 +183,44 @@ func deleteUserGoal(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Goal deleted successfully"}) c.JSON(http.StatusOK, gin.H{"message": "Goal deleted successfully"})
} }
func createTask(c *gin.Context) {
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
}
if taskRequest.Name == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Task name cannot be empty"})
return
}
// If assigned is not nil, check if user exists
if taskRequest.Assigned != nil {
exists, err := db.UserExists(*taskRequest.Assigned)
if err != nil {
log.Printf("Error checking user existence: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": ErrInternalServerError})
return
}
if !exists {
c.JSON(http.StatusNotFound, gin.H{"error": ErrUserNotFound})
return
}
}
taskId, err := db.CreateTask(&taskRequest)
if err != nil {
log.Printf("Error creating task: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create task"})
return
}
response := CreateTaskResponse{ID: taskId}
c.IndentedJSON(http.StatusCreated, response)
}
/* /*
* *
Initialises the database, and then starts the server. Initialises the database, and then starts the server.
@ -198,6 +236,7 @@ func start(ctx context.Context, config *ServerConfig) {
router.GET("/api/user/:userId/goals", getUserGoals) router.GET("/api/user/:userId/goals", getUserGoals)
router.POST("/api/user/:userId/goals", createUserGoal) router.POST("/api/user/:userId/goals", createUserGoal)
router.DELETE("/api/user/:userId/goal/:goalId", deleteUserGoal) router.DELETE("/api/user/:userId/goal/:goalId", deleteUserGoal)
router.POST("/api/tasks", createTask)
srv := &http.Server{ srv := &http.Server{
Addr: ":" + config.Port, Addr: ":" + config.Port,