app/src/api/application_categories.rs

365 lines
11 KiB
Rust

use tracing::instrument;
use crate::api::api_prelude::*;
use crate::error::{Error, Result};
#[instrument]
#[get("")]
pub async fn list_application_categories(state: web::Data<AppState>) -> Result<HttpResponse> {
let cats: Vec<application_category::Model> =
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<AppState>,
data: web::Json<application_category::Model>,
) -> Result<HttpResponse> {
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<AppState>,
id: web::Path<i32>,
) -> Result<HttpResponse> {
let id = id.into_inner();
let res: Option<application_category::Model> =
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<AppState>,
data: web::Json<application_category::Model>,
id: web::Path<i32>,
) -> Result<HttpResponse> {
let id = id.into_inner();
let res: Option<application_category::Model> =
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<AppState>,
id: web::Path<i32>,
) -> Result<HttpResponse> {
let cat_id = id.into_inner();
let recs: Vec<application::Model> = 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<AppState>,
id: web::Path<i32>,
) -> Result<HttpResponse> {
let recs: Vec<application::Model> = 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<crate::entity::application_category::Model>
);
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<crate::entity::application::Model>);
assert_eq!(2_usize, data.items.len());
Ok(())
}
}