From 9c5560ea1f1751417e6fed86a2668e0f58726fec Mon Sep 17 00:00:00 2001 From: alwenn charpentier Date: Thu, 4 May 2023 10:41:05 +0200 Subject: [PATCH] editoast: add delete endpoint to rollingstock api --- editoast/openapi.yaml | 14 ++++ editoast/src/views/rolling_stocks.rs | 90 +++++++++++++++++++------ front/src/common/api/osrdEditoastApi.ts | 11 +++ 3 files changed, 95 insertions(+), 20 deletions(-) diff --git a/editoast/openapi.yaml b/editoast/openapi.yaml index 19013c0ca7e..e6ea066c772 100644 --- a/editoast/openapi.yaml +++ b/editoast/openapi.yaml @@ -1093,6 +1093,20 @@ paths: application/json: schema: $ref: "#/components/schemas/RollingStock" + delete: + tags: + - rolling_stock + summary: Delete a rolling_stock and all entities linked to it + parameters: + - in: path + name: id + schema: + type: integer + description: rolling_stock id + required: true + responses: + 204: + description: No content /rolling_stock/{id}/livery/: post: diff --git a/editoast/src/views/rolling_stocks.rs b/editoast/src/views/rolling_stocks.rs index bd0c0bf3155..5cd72a34e71 100644 --- a/editoast/src/views/rolling_stocks.rs +++ b/editoast/src/views/rolling_stocks.rs @@ -1,7 +1,7 @@ use crate::error::Result; use crate::models::rolling_stock::RollingStockSeparatedImageModel; use crate::models::{ - Create, Document, Retrieve, RollingStockLiveryModel, RollingStockModel, Update, + Create, Delete, Document, Retrieve, RollingStockLiveryModel, RollingStockModel, Update, }; use crate::schema::rolling_stock::rolling_stock_livery::RollingStockLivery; use crate::schema::rolling_stock::{ @@ -11,8 +11,8 @@ use crate::schema::rolling_stock::{ use crate::DbPool; use actix_multipart::form::text::Text; use actix_web::dev::HttpServiceFactory; -use actix_web::web::{self, scope, Data, Json, Path}; -use actix_web::{get, patch, post}; +use actix_web::web::{scope, Data, Json, Path}; +use actix_web::{delete, get, patch, post, HttpResponse}; use diesel_json::Json as DieselJson; use editoast_derive::EditoastError; use image::io::Reader as ImageReader; @@ -42,8 +42,8 @@ pub enum RollingStockError { } pub fn routes() -> impl HttpServiceFactory { - web::scope("/rolling_stock") - .service((get, create, update)) + scope("/rolling_stock") + .service((get, create, update, delete)) .service(scope("/{rolling_stock_id}").service(create_livery)) } @@ -55,8 +55,8 @@ async fn get(db_pool: Data, path: Path) -> Result rolling_stock, None => return Err(RollingStockError::NotFound { rolling_stock_id }.into()), }; - let rollig_stock_with_liveries = rolling_stock.with_liveries(db_pool).await?; - Ok(Json(rollig_stock_with_liveries)) + let rolling_stock_with_liveries = rolling_stock.with_liveries(db_pool).await?; + Ok(Json(rolling_stock_with_liveries)) } #[derive(Deserialize, Serialize)] @@ -162,6 +162,15 @@ struct RollingStockLiveryCreateForm { pub images: Vec, } +#[delete("/{rolling_stock_id}")] +async fn delete(db_pool: Data, path: Path) -> Result { + let rolling_stock_id = path.into_inner(); + if !RollingStockModel::delete(db_pool, rolling_stock_id).await? { + return Err(RollingStockError::NotFound { rolling_stock_id }.into()); + } + Ok(HttpResponse::NoContent().finish()) +} + #[post("/livery")] async fn create_livery( db_pool: Data, @@ -290,39 +299,51 @@ async fn create_compound_image( mod tests { use super::RollingStockError; use crate::error::InternalError; - use crate::fixtures::tests::{db_pool, fast_rolling_stock, other_rolling_stock, TestFixture}; + use crate::fixtures::tests::{fast_rolling_stock, other_rolling_stock, TestFixture}; use crate::models::rolling_stock::tests::{ get_fast_rolling_stock, get_invalid_effort_curves, get_other_rolling_stock, }; - use crate::models::{Delete, RollingStockModel}; + use crate::models::RollingStockModel; use crate::views::rolling_stocks::RollingStock; use crate::views::tests::create_test_service; - use actix_http::StatusCode; + use actix_http::{Request, StatusCode}; use actix_web::http::header::ContentType; use actix_web::test::{call_service, read_body_json, TestRequest}; - use actix_web::web::Data; - use diesel::r2d2::{ConnectionManager, Pool}; use rstest::rstest; use serde_json::{to_value, Value as JsonValue}; #[rstest] - async fn get_rolling_stock(#[future] fast_rolling_stock: TestFixture) { + async fn get_returns_corresponding_rolling_stock( + #[future] fast_rolling_stock: TestFixture, + ) { let app = create_test_service().await; let rolling_stock = fast_rolling_stock.await; let req = TestRequest::get() .uri(format!("/rolling_stock/{}", rolling_stock.id()).as_str()) .to_request(); + let response = call_service(&app, req).await; assert_eq!(response.status(), StatusCode::OK); + let rolling_stock: RollingStock = read_body_json(response).await; + assert_eq!(rolling_stock.name, "fast_rolling_stock"); } #[rstest] - async fn create_rolling_stock(db_pool: Data>>) { + async fn get_unexisting_rolling_stock_returns_not_found() { + let app = create_test_service().await; + let get_request = rolling_stock_get_request(0); + let get_response = call_service(&app, get_request).await; + + assert_eq!(get_response.status(), StatusCode::NOT_FOUND); + } + + #[rstest] + async fn create_and_delete_rolling_stock_successfully() { let app = create_test_service().await; let rolling_stock: RollingStockModel = get_fast_rolling_stock(); - let response = call_service( + let post_response = call_service( &app, TestRequest::post() .uri("/rolling_stock") @@ -330,13 +351,42 @@ mod tests { .to_request(), ) .await; - assert_eq!(response.status(), StatusCode::OK); - let rolling_stock: RollingStock = read_body_json(response).await; + //Check rolling_stock creation + assert_eq!(post_response.status(), StatusCode::OK); + let rolling_stock: RollingStock = read_body_json(post_response).await; assert_eq!(rolling_stock.name, "fast_rolling_stock"); - assert!(RollingStockModel::delete(db_pool.clone(), rolling_stock.id) - .await - .is_ok()); + + //Check rolling_stock deletion + let delete_request = rolling_stock_delete_request(rolling_stock.id); + let delete_response = call_service(&app, delete_request).await; + assert_eq!(delete_response.status(), StatusCode::NO_CONTENT); + + //Check object does not exist anymore + let get_request = rolling_stock_get_request(0); + let get_response = call_service(&app, get_request).await; + assert_eq!(get_response.status(), StatusCode::NOT_FOUND); + } + + #[rstest] + async fn delete_unexisting_rolling_stock_returns_not_found() { + let app = create_test_service().await; + let delete_request = rolling_stock_delete_request(0); + let delete_response = call_service(&app, delete_request).await; + + assert_eq!(delete_response.status(), StatusCode::NOT_FOUND); + } + + fn rolling_stock_get_request(rolling_stock_id: i64) -> Request { + TestRequest::get() + .uri(format!("/rolling_stock/{rolling_stock_id}").as_str()) + .to_request() + } + + fn rolling_stock_delete_request(rolling_stock_id: i64) -> Request { + TestRequest::delete() + .uri(format!("/rolling_stock/{rolling_stock_id}").as_str()) + .to_request() } #[rstest] diff --git a/front/src/common/api/osrdEditoastApi.ts b/front/src/common/api/osrdEditoastApi.ts index 476dd127458..66223b62d07 100644 --- a/front/src/common/api/osrdEditoastApi.ts +++ b/front/src/common/api/osrdEditoastApi.ts @@ -227,6 +227,12 @@ const injectedRtkApi = api.injectEndpoints({ body: queryArg.rollingStockUpsertPayload, }), }), + deleteRollingStockById: build.mutation< + DeleteRollingStockByIdApiResponse, + DeleteRollingStockByIdApiArg + >({ + query: (queryArg) => ({ url: `/rolling_stock/${queryArg.id}/`, method: 'DELETE' }), + }), postRollingStockByIdLivery: build.mutation< PostRollingStockByIdLiveryApiResponse, PostRollingStockByIdLiveryApiArg @@ -700,6 +706,11 @@ export type PatchRollingStockByIdApiArg = { id: number; rollingStockUpsertPayload: RollingStockUpsertPayload; }; +export type DeleteRollingStockByIdApiResponse = unknown; +export type DeleteRollingStockByIdApiArg = { + /** rolling_stock id */ + id: number; +}; export type PostRollingStockByIdLiveryApiResponse = /** status 200 The rolling stock livery */ RollingStockLivery; export type PostRollingStockByIdLiveryApiArg = {