diff --git a/api/src/routes/rest/routes/collections/delete_collection.rs b/api/src/routes/rest/routes/collections/delete_collection.rs index 6d4ba8f51..a80ef0610 100644 --- a/api/src/routes/rest/routes/collections/delete_collection.rs +++ b/api/src/routes/rest/routes/collections/delete_collection.rs @@ -1,14 +1,33 @@ -use axum::{http::StatusCode, Extension, Json}; +use axum::{extract::Path, http::StatusCode, Extension, Json}; use handlers::collections::{ delete_collection_handler, DeleteCollectionRequest, DeleteCollectionResponse, }; use middleware::AuthenticatedUser; use uuid::Uuid; -/// Delete a collection +/// Delete a collection by ID /// -/// This endpoint deletes one or more collections by their IDs. -pub async fn delete_collection( +/// This endpoint deletes a single collection by its ID. +pub async fn delete_collection_by_id( + Path(id): Path, + Extension(user): Extension, +) -> Result, (StatusCode, String)> { + let user_organization = match user.organizations.first() { + Some(org) => org, + None => return Err((StatusCode::NOT_FOUND, "User not found".to_string())), + }; + + // Call the handler with a single ID in a vector + match delete_collection_handler(&user.id, &user_organization.id, vec![id]).await { + Ok(response) => Ok(Json(response)), + Err(e) => handle_error(e) + } +} + +/// Delete multiple collections +/// +/// This endpoint deletes one or more collections by their IDs provided in the request body. +pub async fn delete_collections( Extension(user): Extension, Json(req): Json, ) -> Result, (StatusCode, String)> { @@ -20,23 +39,26 @@ pub async fn delete_collection( // Call the handler match delete_collection_handler(&user.id, &user_organization.id, req.ids).await { Ok(response) => Ok(Json(response)), - Err(e) => { - tracing::error!("Error deleting collection: {}", e); - - // Return appropriate error response based on the error - if e.to_string().contains("not found") { - Err(( - StatusCode::NOT_FOUND, - format!("Collection not found: {}", e), - )) - } else if e.to_string().contains("permission") { - Err((StatusCode::FORBIDDEN, format!("Permission denied: {}", e))) - } else { - Err(( - StatusCode::INTERNAL_SERVER_ERROR, - format!("Error deleting collection: {}", e), - )) - } - } + Err(e) => handle_error(e) + } +} + +// Helper function to handle errors +fn handle_error(e: anyhow::Error) -> Result, (StatusCode, String)> { + tracing::error!("Error deleting collection: {}", e); + + // Return appropriate error response based on the error + if e.to_string().contains("not found") { + Err(( + StatusCode::NOT_FOUND, + format!("Collection not found: {}", e), + )) + } else if e.to_string().contains("permission") { + Err((StatusCode::FORBIDDEN, format!("Permission denied: {}", e))) + } else { + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Error deleting collection: {}", e), + )) } } diff --git a/api/src/routes/rest/routes/collections/mod.rs b/api/src/routes/rest/routes/collections/mod.rs index 3ba47d4fb..c780f6870 100644 --- a/api/src/routes/rest/routes/collections/mod.rs +++ b/api/src/routes/rest/routes/collections/mod.rs @@ -18,9 +18,10 @@ pub fn router() -> Router { Router::new() .route("/", get(list_collections::list_collections)) .route("/", post(create_collection::create_collection)) + .route("/", delete(delete_collection::delete_collections)) .route("/:id", get(get_collection::get_collection)) .route("/:id", put(update_collection::update_collection)) - .route("/:id", delete(delete_collection::delete_collection)) + .route("/:id", delete(delete_collection::delete_collection_by_id)) .route("/:id/assets", post(add_assets_to_collection::add_assets_to_collection)) .route("/:id/dashboards", post(add_dashboards_to_collection::add_dashboards_to_collection)) .route("/:id/assets", delete(remove_assets_from_collection::remove_assets_from_collection)) diff --git a/api/tests/integration/collections/delete_collection_test.rs b/api/tests/integration/collections/delete_collection_test.rs new file mode 100644 index 000000000..6c5ec62fe --- /dev/null +++ b/api/tests/integration/collections/delete_collection_test.rs @@ -0,0 +1,59 @@ +use uuid::Uuid; +use serde_json::json; + +use crate::common::{ + fixtures::users::create_test_user, + http::test_app::TestApp, +}; + +#[tokio::test] +async fn test_delete_collections_bulk() { + // Set up test app + let app = TestApp::new().await; + + // Create test user + let user = create_test_user(); + + // Test IDs + let id1 = Uuid::new_v4(); + let id2 = Uuid::new_v4(); + + // Call the API to delete collections in bulk + let response = app + .delete("/api/v1/collections") + .with_auth(&user) + .json(&json!({ + "ids": [id1, id2] + })) + .send() + .await; + + // Verify response status (we're not actually deleting real collections here) + // Since we're not creating test collections, it might fail with 404 or succeed with 200 + // We're mainly testing that the endpoint accepts the request format correctly + assert!(response.status().is_client_error() || response.status().is_success()); +} + +#[tokio::test] +async fn test_delete_collection_by_id() { + // Set up test app + let app = TestApp::new().await; + + // Create test user + let user = create_test_user(); + + // Test ID + let id = Uuid::new_v4(); + + // Call the API to delete a collection by ID + let response = app + .delete(&format!("/api/v1/collections/{}", id)) + .with_auth(&user) + .send() + .await; + + // Verify response status (we're not actually deleting a real collection here) + // Since we're not creating a test collection, it might fail with 404 or succeed with 200 + // We're mainly testing that the endpoint accepts the request format correctly + assert!(response.status().is_client_error() || response.status().is_success()); +} \ No newline at end of file diff --git a/api/tests/integration/collections/mod.rs b/api/tests/integration/collections/mod.rs index e22dba865..590fc930a 100644 --- a/api/tests/integration/collections/mod.rs +++ b/api/tests/integration/collections/mod.rs @@ -1,6 +1,7 @@ pub mod sharing; pub mod add_assets_to_collection_test; pub mod add_dashboards_to_collection_test; +pub mod delete_collection_test; pub mod get_collection_test; pub mod remove_assets_from_collection_test; pub mod remove_metrics_from_collection_test; \ No newline at end of file