use std::sync::Arc;
use axum::{
Extension, Json,
extract::{Path, State},
response::Redirect,
};
use pib_service_api_auth::user::UserInfo;
use pib_service_api_types::body::by_id::organization::post::RequestBody;
use pib_service_core_types::BodyId;
use pib_service_facade::Service;
use crate::Result;
pub(crate) async fn handle<E: Into<pib_service_facade::Error> + Send + Sync>(
State(service): State<Arc<dyn Service<E>>>,
Extension(user): Extension<UserInfo>,
Path(body_id): Path<BodyId>,
Json(payload): Json<RequestBody>,
) -> Result<Redirect>
where
crate::Error: From<E>,
{
let organization_id = service
.handle_body_by_id_organization_post(user, body_id, payload)
.await?;
Ok(Redirect::to(&format!(
"/body/{body_id}/organization/{organization_id}"
)))
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::Error;
use super::{RequestBody, handle};
use axum::{
Extension, Json,
extract::{Path, State},
};
use http::StatusCode;
use mockall::predicate::eq;
use pib_service_api_auth::user::{Issuer, OidcSub, UserInfo};
use pib_service_core_types::{BodyId, OrganizationId, UserId};
use pib_service_facade::MockService;
use pretty_assertions::{assert_eq, assert_matches};
#[tokio::test]
async fn valid() {
let mut service = MockService::<pib_service_facade::Error>::new();
let user_info = UserInfo {
id: UserId::from_u128(0x5555),
issuer: Issuer(String::from("http://auth.example.com")),
sub: OidcSub("max.mustermann".to_string()),
display_name: Some("Max Mustermann".to_string()),
is_superuser: false,
};
let body_id = BodyId::from_u128(0x9955);
let organization_id = OrganizationId::from_u128(0x4444);
let payload = RequestBody {
name: "Gemeinderat".parse().unwrap(),
short_name: None,
classification: None,
start_date: None,
end_date: None,
website: None,
};
service
.expect_handle_body_by_id_organization_post()
.times(1)
.with(eq(user_info), eq(body_id), eq(payload.clone()))
.return_once(move |_, _, _| Ok(organization_id));
let response = handle(
State(Arc::new(service)),
Extension(UserInfo {
id: UserId::from_u128(0x5555),
issuer: Issuer("http://auth.example.com".to_string()),
sub: OidcSub("max.mustermann".to_string()),
display_name: Some("Max Mustermann".to_string()),
is_superuser: false,
}),
Path(body_id),
Json(payload),
)
.await
.unwrap();
assert_eq!(response.status_code(), StatusCode::SEE_OTHER);
assert_eq!(
response.location(),
"/body/00000000-0000-0000-0000-000000009955/organization/00000000-0000-0000-0000-000000004444"
);
}
#[tokio::test]
async fn invalid() {
let mut service = MockService::new();
let user_info = UserInfo {
id: UserId::from_u128(0x5555),
issuer: Issuer(String::from("http://auth.example.com")),
sub: OidcSub("max.mustermann".to_string()),
display_name: Some("Max Mustermann".to_string()),
is_superuser: false,
};
let body_id = BodyId::from_u128(0x9955);
let payload = RequestBody {
name: "Gemeinderat".parse().unwrap(),
short_name: None,
classification: None,
start_date: None,
end_date: None,
website: None,
};
service
.expect_handle_body_by_id_organization_post()
.times(1)
.with(eq(user_info.clone()), eq(body_id), eq(payload.clone()))
.return_once(|_, _, _| Err(pib_service_facade::Error::NotFound));
assert_matches!(
handle(
State(Arc::new(service)),
Extension(user_info.clone()),
Path(body_id),
Json(payload)
)
.await,
Err(Error::Service {
source: pib_service_facade::Error::NotFound
})
);
}
}