diff --git a/backend/src/openapi.rs b/backend/src/openapi.rs index 3bfeb72..b31f422 100644 --- a/backend/src/openapi.rs +++ b/backend/src/openapi.rs @@ -502,7 +502,10 @@ mod doc { post, path = "/api/folders", request_body = CreateFolderRequest, - responses((status = 200, description = "Folder created", body = FolderResponse)), + responses( + (status = 201, description = "Folder created", body = FolderResponse), + (status = 200, description = "Folder already existed", body = FolderResponse) + ), tag = "Folders" )] pub(super) fn create_folder() {} diff --git a/backend/src/routes/folders.rs b/backend/src/routes/folders.rs index 3ea7c02..be691e2 100644 --- a/backend/src/routes/folders.rs +++ b/backend/src/routes/folders.rs @@ -179,7 +179,7 @@ pub async fn create_folder( .. }: TenantScopedConn, Json(payload): Json, -) -> AppResult> { +) -> AppResult<(StatusCode, Json)> { if payload.name.trim().is_empty() { return Err(AppError::bad_request("name must not be empty")); } @@ -202,8 +202,8 @@ pub async fn create_folder( .optional()? }; - let folder: Folder = if let Some(folder) = existing { - folder + let (folder, created): (Folder, bool) = if let Some(folder) = existing { + (folder, false) } else { let new_folder = NewFolder { id: Uuid::new_v4(), @@ -220,28 +220,43 @@ pub async fn create_folder( .optional()?; if let Some(id) = inserted_id { - folders::table - .find(id) - .filter(folders::tenant_id.eq(tenant_id)) - .first(&mut conn)? + ( + folders::table + .find(id) + .filter(folders::tenant_id.eq(tenant_id)) + .first(&mut conn)?, + true, + ) } else if let Some(parent_id) = payload.parent_id { - folders::table - .filter(folders::tenant_id.eq(tenant_id)) - .filter(folders::parent_id.eq(Some(parent_id))) - .filter(folders::name.eq(name)) - .first(&mut conn)? + ( + folders::table + .filter(folders::tenant_id.eq(tenant_id)) + .filter(folders::parent_id.eq(Some(parent_id))) + .filter(folders::name.eq(name)) + .first(&mut conn)?, + false, + ) } else { - folders::table - .filter(folders::tenant_id.eq(tenant_id)) - .filter(folders::parent_id.is_null()) - .filter(folders::name.eq(name)) - .first(&mut conn)? + ( + folders::table + .filter(folders::tenant_id.eq(tenant_id)) + .filter(folders::parent_id.is_null()) + .filter(folders::name.eq(name)) + .first(&mut conn)?, + false, + ) } }; - Ok(Json(FolderResponse { + let response = Json(FolderResponse { folder: folder_to_info(folder), - })) + }); + + if created { + Ok((StatusCode::CREATED, response)) + } else { + Ok((StatusCode::OK, response)) + } } pub async fn list_folder_contents( diff --git a/backend/tests/folders_flow.rs b/backend/tests/folders_flow.rs index 7e74630..12d487b 100644 --- a/backend/tests/folders_flow.rs +++ b/backend/tests/folders_flow.rs @@ -73,7 +73,7 @@ async fn folder_move_and_delete_flow() -> Result<()> { Some(&token), ) .await?; - assert_eq!(folder_resp.status(), StatusCode::OK); + assert_eq!(folder_resp.status(), StatusCode::CREATED); let folder_body = body_to_vec(folder_resp.into_body()).await?; let folder: FolderResponse = serde_json::from_slice(&folder_body)?; @@ -164,7 +164,7 @@ async fn update_folder_parent_to_root() -> Result<()> { Some(&token), ) .await?; - assert_eq!(parent_resp.status(), StatusCode::OK); + assert_eq!(parent_resp.status(), StatusCode::CREATED); let parent_body = body_to_vec(parent_resp.into_body()).await?; let parent: FolderResponse = serde_json::from_slice(&parent_body)?; @@ -179,7 +179,7 @@ async fn update_folder_parent_to_root() -> Result<()> { Some(&token), ) .await?; - assert_eq!(child_resp.status(), StatusCode::OK); + assert_eq!(child_resp.status(), StatusCode::CREATED); let child_body = body_to_vec(child_resp.into_body()).await?; let child: FolderResponse = serde_json::from_slice(&child_body)?; @@ -310,14 +310,14 @@ async fn create_folder_is_idempotent() -> Result<()> { let first_resp = app .post_json("/api/folders", &payload, Some(&token)) .await?; - assert!(first_resp.status().is_success()); + assert_eq!(first_resp.status(), StatusCode::CREATED); let first_body = body_to_vec(first_resp.into_body()).await?; let first_folder: FolderResponse = serde_json::from_slice(&first_body)?; let second_resp = app .post_json("/api/folders", &payload, Some(&token)) .await?; - assert!(second_resp.status().is_success()); + assert_eq!(second_resp.status(), StatusCode::OK); let second_body = body_to_vec(second_resp.into_body()).await?; let second_folder: FolderResponse = serde_json::from_slice(&second_body)?; @@ -424,7 +424,7 @@ async fn folder_rename_updates_name_and_child_paths() -> Result<()> { Some(&token), ) .await?; - assert_eq!(parent_resp.status(), StatusCode::OK); + assert_eq!(parent_resp.status(), StatusCode::CREATED); let parent_body = body_to_vec(parent_resp.into_body()).await?; let parent: FolderResponse = serde_json::from_slice(&parent_body)?; @@ -438,7 +438,7 @@ async fn folder_rename_updates_name_and_child_paths() -> Result<()> { Some(&token), ) .await?; - assert_eq!(child_resp.status(), StatusCode::OK); + assert_eq!(child_resp.status(), StatusCode::CREATED); let child_body = body_to_vec(child_resp.into_body()).await?; let child: FolderResponse = serde_json::from_slice(&child_body)?;