use tracing::instrument; use crate::api::api_prelude::*; use crate::error::{Error, Result}; #[instrument] #[get("")] pub async fn list_application_categories(state: web::Data) -> Result { let cats: Vec = ApplicationCategory::find().all(&state.db).await.unwrap(); let count = cats.len(); Ok(HttpResponse::Ok().json(ListObjects::new(cats, count))) } #[instrument] #[post("")] pub async fn new_application_category( state: web::Data, data: web::Json, ) -> Result { let model = application_category::ActiveModel { id: NotSet, glyph: Set(data.0.glyph), category_name: Set(data.0.category_name), active: Set(data.0.active), }; let rec = model.insert(&state.db).await?; Ok(HttpResponse::Ok().json(rec)) } #[instrument] #[get("{id}")] pub async fn get_application_category( state: web::Data, id: web::Path, ) -> Result { let id = id.into_inner(); let res: Option = ApplicationCategory::find_by_id(id).one(&state.db).await?; match res { Some(rec) => Ok(HttpResponse::Ok().json(rec)), None => Err(Error::not_found()), } } #[instrument] #[put("{id}")] pub async fn update_application_category( state: web::Data, data: web::Json, id: web::Path, ) -> Result { let id = id.into_inner(); let res: Option = ApplicationCategory::find_by_id(id).one(&state.db).await?; match res { Some(_rec) => { let data = data.into_inner(); let ret = application_category::ActiveModel { id: Set(id), glyph: Set(data.glyph), active: Set(data.active), category_name: Set(data.category_name), }; let model = ret.update(&state.db).await?; Ok(HttpResponse::Ok().json(model)) } None => Err(Error::not_found()), } } #[instrument] #[delete("{id}")] pub async fn delete_application_category( state: web::Data, id: web::Path, ) -> Result { let cat_id = id.into_inner(); let recs: Vec = Application::find() .filter(application::Column::ApplicationCategoryId.eq(cat_id)) .all(&state.db) .await .unwrap_or_default(); for rec in recs { application::ActiveModel { id: Set(rec.id), application_category_id: Set(None), ..Default::default() } .save(&state.db) .await?; } ApplicationCategory::delete_many() .filter(application_category::Column::Id.eq(cat_id)) .exec(&state.db) .await?; Ok(HttpResponse::Ok().body("")) } #[instrument] #[get("{id}/applications")] pub async fn application_category_applications( state: web::Data, id: web::Path, ) -> Result { let recs: Vec = Application::find() .filter(application::Column::ApplicationCategoryId.eq(id.into_inner())) .all(&state.db) .await .unwrap(); let count = recs.len(); Ok(HttpResponse::Ok().json(ListObjects::new(recs, count))) } /// Routes for the application endpoints. This binds up a scope with all endpoints for applications, to make it easier to add them to the server. pub fn routes() -> Scope { web::scope("/application_categories") .service(application_category_applications) .service(list_application_categories) .service(update_application_category) .service(delete_application_category) .service(new_application_category) .service(get_application_category) } #[cfg(test)] mod tests { use crate::api::test_prelude::*; use actix_web::http::Method; #[actix_rt::test] async fn test_list_application_categories() -> Result<()> { let state = setup_state().await?; application_category::ActiveModel { category_name: Set("Application 1".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; application_category::ActiveModel { category_name: Set("Application 2".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; let mut req = actix_web::test::TestRequest::with_uri("/api/application_categories") .method(Method::GET) .to_request(); let resp = call_endpoint!(req, state); assert_eq!(resp.status(), 200); let data = get_response!( resp, ListObjects ); assert_eq!(2_usize, data.items.len()); Ok(()) } #[actix_rt::test] async fn test_get_application_categories() -> Result<()> { let state = setup_state().await?; let model = application_category::ActiveModel { category_name: Set("Application 1".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; let mut req = actix_web::test::TestRequest::with_uri(&format!( "/api/application_categories/{}", model.id )) .method(Method::GET) .to_request(); let resp = call_endpoint!(req, state); let status = resp.status(); let mut data = get_response!(resp, crate::entity::application_category::Model); data.id = model.id; assert_eq!(model, data); assert_eq!(status, 200); Ok(()) } #[actix_rt::test] async fn test_new_application_category() -> Result<()> { let model = application_category::Model { id: 0, category_name: "Some name".into(), glyph: None, active: true, }; let state = setup_state().await?; let mut req = actix_web::test::TestRequest::with_uri("/api/application_categories") .method(Method::POST) .set_json(model.clone()) .to_request(); let resp = call_endpoint!(req, state); assert_eq!(resp.status(), 200); let data = get_response!(resp, crate::entity::application_category::Model); assert_eq!(model, data); assert_eq!( application_category::Entity::find() .count(&state.db) .await?, 1 ); Ok(()) } #[actix_rt::test] async fn test_update_application_category() -> Result<()> { let state = setup_state().await?; application_category::ActiveModel { category_name: Set("Some name".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; let mut model = application_category::ActiveModel { category_name: Set("Some name".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; model.category_name = "Another name".into(); let mut req = actix_web::test::TestRequest::with_uri(&format!( "/api/application_categories/{}", model.id )) .method(Method::PUT) .set_json(model.clone()) .to_request(); let resp = call_endpoint!(req, state); assert_eq!(resp.status(), 200); let mut data = get_response!(resp, crate::entity::application_category::Model); data.id = model.id; assert_eq!(model, data, "Check API"); let db_model = application_category::Entity::find_by_id(model.id) .one(&state.db) .await? .unwrap(); assert_eq!(db_model, model, "Check DB"); Ok(()) } #[actix_rt::test] async fn test_delete_application_category() -> Result<()> { let state = setup_state().await?; let model = application_category::ActiveModel { category_name: Set("Some name".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; let app = application::ActiveModel { app_name: Set("Application 1".into()), url: Set("http://somewhere/".into()), active: Set(true), application_category_id: Set(Some(model.id)), ..Default::default() } .insert(&state.db) .await?; let mut req = actix_web::test::TestRequest::with_uri(&format!( "/api/application_categories/{}", model.id )) .method(Method::DELETE) .to_request(); let resp = call_endpoint!(req, state); let status = resp.status(); let body = test::read_body(resp).await; assert_eq!(body, ""); assert_eq!(status, 200); assert_eq!( application_category::Entity::find() .count(&state.db) .await?, 0 ); let app = application::Entity::find_by_id(app.id) .one(&state.db) .await? .unwrap(); assert_eq!(app.application_category_id, None); Ok(()) } #[actix_rt::test] async fn test_application_categories_applications() -> Result<()> { let state = setup_state().await?; let category = application_category::ActiveModel { category_name: Set("Application 1".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; application::ActiveModel { app_name: Set("Application 1".into()), url: Set("http://somewhere/".into()), active: Set(true), application_category_id: Set(Some(category.id)), ..Default::default() } .insert(&state.db) .await?; application::ActiveModel { app_name: Set("Application 2".into()), url: Set("http://somewhere/".into()), application_category_id: Set(Some(category.id)), active: Set(true), ..Default::default() } .insert(&state.db) .await?; application::ActiveModel { app_name: Set("Application 2".into()), url: Set("http://somewhere/".into()), active: Set(true), ..Default::default() } .insert(&state.db) .await?; let mut req = actix_web::test::TestRequest::with_uri(&format!( "/api/application_categories/{}/applications", category.id )) .method(Method::GET) .to_request(); let resp = call_endpoint!(req, state); assert_eq!(resp.status(), 200); let data = get_response!(resp, ListObjects); assert_eq!(2_usize, data.items.len()); Ok(()) } }