Add put for updating a task.
This commit is contained in:
parent
e2284c7421
commit
026a8be707
3 changed files with 47 additions and 12 deletions
|
|
@ -13,6 +13,7 @@ pub enum AppError {
|
|||
InternalError(anyhow::Error),
|
||||
JsonExtractError(JsonRejection),
|
||||
PathError(PathRejection),
|
||||
Unprocessable(String),
|
||||
NotFound,
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +37,11 @@ impl IntoResponse for AppError {
|
|||
}),
|
||||
)
|
||||
.into_response(),
|
||||
Self::Unprocessable(msg) => (
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
Json(ErrorJson { error: msg }),
|
||||
)
|
||||
.into_response(),
|
||||
Self::PathError(rej) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(ErrorJson {
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ use serde::Deserialize;
|
|||
use sqlx::{Pool, Sqlite};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::models::TaskModel;
|
||||
use crate::models::{TaskModel, TaskStatus};
|
||||
|
||||
use super::AppError;
|
||||
|
||||
pub fn create_task_router() -> Router<Pool<Sqlite>> {
|
||||
Router::new()
|
||||
.route("/", post(create_task))
|
||||
.route("/{task_id}", get(get_task))
|
||||
.route("/{task_id}", get(get_task).put(update_task))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
|
@ -45,3 +45,40 @@ pub async fn get_task(
|
|||
|
||||
Ok((StatusCode::OK, Json(model)))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct UpdateTaskRequest {
|
||||
title: Option<String>,
|
||||
description: Option<String>,
|
||||
status: Option<TaskStatus>,
|
||||
}
|
||||
|
||||
pub async fn update_task(
|
||||
State(pool): State<Pool<Sqlite>>,
|
||||
WithRejection(Path(task_id), _): WithRejection<Path<Uuid>, AppError>,
|
||||
WithRejection(Json(input), _): WithRejection<Json<UpdateTaskRequest>, AppError>,
|
||||
) -> Result<(StatusCode, Json<TaskModel>), AppError> {
|
||||
let mut model = TaskModel::get_by_id(&pool, task_id).await?;
|
||||
|
||||
if let Some(title) = input.title {
|
||||
if title.len() == 0 {
|
||||
return Err(AppError::Unprocessable(
|
||||
"Title must not be empty".to_string(),
|
||||
));
|
||||
}
|
||||
model.title = title;
|
||||
}
|
||||
|
||||
if let Some(description) = input.description {
|
||||
model.description = Some(description);
|
||||
}
|
||||
|
||||
if let Some(status) = input.status {
|
||||
model.status = status;
|
||||
}
|
||||
|
||||
let model = model.update(&pool).await?;
|
||||
|
||||
Ok((StatusCode::OK, Json(model)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,13 +89,13 @@ jsonpath "$.completed_at" exists
|
|||
PUT {{host}}/api/tasks/{{task_id}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"description": null
|
||||
"description": ""
|
||||
}
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.id" == "{{task_id}}"
|
||||
jsonpath "$.description" == null
|
||||
jsonpath "$.description" == ""
|
||||
|
||||
# Setup: Create another task for error tests
|
||||
POST {{host}}/api/tasks
|
||||
|
|
@ -152,11 +152,3 @@ HTTP 422
|
|||
[Asserts]
|
||||
jsonpath "$.error" exists
|
||||
|
||||
# Test: Update with no fields (empty object)
|
||||
PUT {{host}}/api/tasks/{{error_test_task_id}}
|
||||
Content-Type: application/json
|
||||
{}
|
||||
|
||||
HTTP 422
|
||||
[Asserts]
|
||||
jsonpath "$.error" exists
|
||||
Loading…
Add table
Add a link
Reference in a new issue