refactor: rewrite todos and test
This commit is contained in:
parent
31b09a1c76
commit
0844cc5a17
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -691,6 +691,7 @@ dependencies = [
|
||||
"change-detection",
|
||||
"chrono",
|
||||
"dotenv",
|
||||
"fake",
|
||||
"futures-util",
|
||||
"idna 1.0.2",
|
||||
"insta",
|
||||
@ -1079,6 +1080,12 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@ -1208,6 +1215,16 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "661cb0601b5f4050d1e65452c5b0ea555c0b3e88fb5ed7855906adc6c42523ef"
|
||||
dependencies = [
|
||||
"deunicode",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fancy-regex"
|
||||
version = "0.13.0"
|
||||
|
@ -43,3 +43,4 @@ change-detection = "1.2.0"
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "1.41.1"
|
||||
fake = "3.0.1"
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rinja::Template;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::models::{Area, Location, Role, User};
|
||||
use crate::filters;
|
||||
@ -19,7 +19,7 @@ pub struct LocationTemplate {
|
||||
location: Option<Location>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct LocationForm {
|
||||
name: String,
|
||||
area: Option<i32>,
|
||||
|
@ -1,11 +1,16 @@
|
||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||
use brass_macros::db_test;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{
|
||||
endpoints::location::LocationForm,
|
||||
models::{Location, Role, User}, utils::ApplicationError,
|
||||
models::{Location, Role, User},
|
||||
utils::ApplicationError,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
use crate::utils::test_helper::{test_post, DbTestContext, RequestConfig, StatusCode};
|
||||
|
||||
#[actix_web::post("/locations/new")]
|
||||
pub async fn post(
|
||||
user: web::ReqData<User>,
|
||||
@ -22,17 +27,66 @@ pub async fn post(
|
||||
area_id = form.area.unwrap();
|
||||
}
|
||||
|
||||
// TODO: rework
|
||||
match Location::create(pool.get_ref(), &form.name, area_id).await {
|
||||
Ok(_) => {
|
||||
Location::create(pool.get_ref(), &form.name, area_id).await?;
|
||||
|
||||
return Ok(HttpResponse::Found()
|
||||
.insert_header((LOCATION, "/locations"))
|
||||
.insert_header(("HX-LOCATION", "/locations"))
|
||||
.finish())
|
||||
}
|
||||
Err(err) => {
|
||||
println!("{}", err);
|
||||
return Ok(HttpResponse::InternalServerError().finish());
|
||||
.finish());
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn works_when_user_is_admin(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig {
|
||||
uri: "/locations/new".to_string(),
|
||||
role: Role::Admin,
|
||||
function: crate::models::Function::Posten,
|
||||
user_area: 1,
|
||||
};
|
||||
|
||||
let form = LocationForm {
|
||||
name: "Hauptbahnhof".to_string(),
|
||||
area: Some(1),
|
||||
};
|
||||
|
||||
let response = test_post(&context.db_pool, app, &config, form).await;
|
||||
assert_eq!(StatusCode::FOUND, response.status());
|
||||
|
||||
assert_eq!(
|
||||
"Hauptbahnhof".to_string(),
|
||||
Location::read_by_id(&context.db_pool, 1)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.name
|
||||
);
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn uses_area_id_of_area_manager(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig {
|
||||
uri: "/locations/new".to_string(),
|
||||
role: Role::AreaManager,
|
||||
function: crate::models::Function::Posten,
|
||||
user_area: 1,
|
||||
};
|
||||
|
||||
let form = LocationForm {
|
||||
name: "Hauptbahnhof".to_string(),
|
||||
area: None,
|
||||
};
|
||||
|
||||
let response = test_post(&context.db_pool, app, &config, form).await;
|
||||
assert_eq!(StatusCode::FOUND, response.status());
|
||||
|
||||
assert_eq!(
|
||||
"Hauptbahnhof".to_string(),
|
||||
Location::read_by_id(&context.db_pool, 1)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.name
|
||||
);
|
||||
}
|
||||
|
@ -1,14 +1,24 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||
use serde::Deserialize;
|
||||
use brass_macros::db_test;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{
|
||||
endpoints::IdPath,
|
||||
models::{Function, Role, User},
|
||||
utils::ApplicationError,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[cfg(test)]
|
||||
use crate::utils::test_helper::{test_post, DbTestContext, RequestConfig, StatusCode};
|
||||
#[cfg(test)]
|
||||
use fake::{
|
||||
faker::{internet::raw::SafeEmail, name::raw::Name},
|
||||
locales::EN,
|
||||
Fake,
|
||||
};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct EditUserForm {
|
||||
email: String,
|
||||
name: String,
|
||||
@ -19,23 +29,25 @@ pub struct EditUserForm {
|
||||
|
||||
#[actix_web::post("/users/edit/{id}")]
|
||||
pub async fn post_edit(
|
||||
user: Identity,
|
||||
user: web::ReqData<User>,
|
||||
pool: web::Data<PgPool>,
|
||||
path: web::Path<IdPath>,
|
||||
form: web::Form<EditUserForm>,
|
||||
) -> impl Responder {
|
||||
// TODO: rewrite
|
||||
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap())
|
||||
.await
|
||||
.unwrap().unwrap();
|
||||
|
||||
if current_user.role != Role::AreaManager && current_user.role != Role::Admin {
|
||||
return HttpResponse::Unauthorized().finish();
|
||||
) -> Result<impl Responder, ApplicationError> {
|
||||
if user.role != Role::AreaManager && user.role != Role::Admin {
|
||||
return Err(ApplicationError::Unauthorized);
|
||||
}
|
||||
|
||||
if let Some(user_in_db) = User::read_by_id(pool.get_ref(), path.id).await.unwrap() {
|
||||
if current_user.role == Role::AreaManager && current_user.area_id != user_in_db.area_id {
|
||||
return HttpResponse::Unauthorized().finish();
|
||||
if user.id == path.id {
|
||||
return Ok(HttpResponse::BadRequest().finish());
|
||||
}
|
||||
|
||||
let Some(user_in_db) = User::read_by_id(pool.get_ref(), path.id).await? else {
|
||||
return Ok(HttpResponse::NotFound().finish());
|
||||
};
|
||||
|
||||
if user.role == Role::AreaManager && user.area_id != user_in_db.area_id {
|
||||
return Err(ApplicationError::Unauthorized);
|
||||
}
|
||||
|
||||
let mut changed = false;
|
||||
@ -76,7 +88,10 @@ pub async fn post_edit(
|
||||
None
|
||||
};
|
||||
|
||||
let area = if current_user.role == Role::Admin && form.area.is_some() && user_in_db.area_id != form.area.unwrap() {
|
||||
let area = if user.role == Role::Admin
|
||||
&& form.area.is_some()
|
||||
&& user_in_db.area_id != form.area.unwrap()
|
||||
{
|
||||
changed = true;
|
||||
Some(form.area.unwrap())
|
||||
} else {
|
||||
@ -84,12 +99,97 @@ pub async fn post_edit(
|
||||
};
|
||||
|
||||
if changed {
|
||||
match User::update(pool.get_ref(), path.id, email, name, None, None, role, function, area, None, None).await {
|
||||
Ok(_) => return HttpResponse::Found().insert_header((LOCATION, "/users")).finish(),
|
||||
Err(err) => println!("{}", err)
|
||||
}
|
||||
}
|
||||
User::update(
|
||||
pool.get_ref(),
|
||||
path.id,
|
||||
email,
|
||||
name,
|
||||
None,
|
||||
None,
|
||||
role,
|
||||
function,
|
||||
area,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
return HttpResponse::BadRequest().body("Fehler beim Bearbeiten des Nutzers");
|
||||
Ok(HttpResponse::Found()
|
||||
.insert_header((LOCATION, "/users"))
|
||||
.insert_header(("HX-LOCATION", "/users"))
|
||||
.finish())
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn works_when_user_is_admin(context: &DbTestContext) {
|
||||
User::create(
|
||||
&context.db_pool,
|
||||
&Name(EN).fake::<String>(),
|
||||
&SafeEmail(EN).fake::<String>(),
|
||||
Role::Staff,
|
||||
Function::Posten,
|
||||
1,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
crate::models::Area::create(&context.db_pool, "Süd")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig {
|
||||
uri: "/users/edit/1".to_string(),
|
||||
role: Role::Admin,
|
||||
function: crate::models::Function::Posten,
|
||||
user_area: 1,
|
||||
};
|
||||
|
||||
let new_name: String = Name(EN).fake();
|
||||
let new_mail: String = SafeEmail(EN).fake();
|
||||
|
||||
let form = EditUserForm {
|
||||
name: new_name.clone(),
|
||||
email: new_mail.clone(),
|
||||
role: Role::AreaManager as u8,
|
||||
function: Function::Fuehrungsassistent as u8,
|
||||
area: Some(2),
|
||||
};
|
||||
|
||||
let response = test_post(&context.db_pool, app, &config, form).await;
|
||||
assert_eq!(StatusCode::FOUND, response.status());
|
||||
|
||||
let updated_user = User::read_by_id(&context.db_pool, 1)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(new_name, updated_user.name);
|
||||
assert_eq!(new_mail, updated_user.email);
|
||||
assert_eq!(Role::AreaManager, updated_user.role);
|
||||
assert_eq!(Function::Fuehrungsassistent, updated_user.function);
|
||||
assert_eq!(2, updated_user.area_id);
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn cant_edit_oneself(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig {
|
||||
uri: "/users/edit/1".to_string(),
|
||||
role: Role::Admin,
|
||||
function: crate::models::Function::Posten,
|
||||
user_area: 1,
|
||||
};
|
||||
|
||||
let form = EditUserForm {
|
||||
name: "".to_string(),
|
||||
email: "".to_string(),
|
||||
role: Role::AreaManager as u8,
|
||||
function: Function::Fuehrungsassistent as u8,
|
||||
area: Some(1),
|
||||
};
|
||||
|
||||
let response = test_post(&context.db_pool, app, &config, form).await;
|
||||
assert_eq!(StatusCode::BAD_REQUEST, response.status());
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ impl TryFrom<u8> for Function {
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
1 => Ok(Function::Posten),
|
||||
5 => Ok(Function::Fuehrungsassistent),
|
||||
10 => Ok(Function::Wachhabender),
|
||||
_ => Err(ApplicationError::UnsupportedEnumValue {
|
||||
value: value.to_string(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user