feat: candidate details validation

This commit is contained in:
Sebastian Pravda 2023-01-20 13:07:58 +01:00
parent ddb07a342d
commit 7bf6d7e938
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
5 changed files with 36 additions and 3 deletions

View file

@ -102,6 +102,7 @@ pub async fn post_details(
) -> Result<Json<ApplicationDetails>, Custom<String>> { ) -> Result<Json<ApplicationDetails>, Custom<String>> {
let db = conn.into_inner(); let db = conn.into_inner();
let form = details.into_inner(); let form = details.into_inner();
form.candidate.validate_self().map_err(to_custom_error)?;
let application: application::Model = session.into(); let application: application::Model = session.into();
let candidate = ApplicationService::find_related_candidate(&db, &application).await.map_err(to_custom_error)?; // TODO let candidate = ApplicationService::find_related_candidate(&db, &application).await.map_err(to_custom_error)?; // TODO

View file

@ -16,6 +16,8 @@ pub enum ServiceError {
ExpiredSession, ExpiredSession,
#[error("Missing details")] #[error("Missing details")]
MissingDetails, MissingDetails,
#[error("Validation error: {0}")]
ValidationError(#[from] validator::ValidationErrors),
#[error("User already exists")] #[error("User already exists")]
UserAlreadyExists, UserAlreadyExists,
#[error("Candidate not found")] #[error("Candidate not found")]
@ -85,6 +87,7 @@ impl ServiceError {
ServiceError::InvalidApplicationId => 400, ServiceError::InvalidApplicationId => 400,
ServiceError::ParentOverflow => 400, ServiceError::ParentOverflow => 400,
ServiceError::MissingDetails => 400, ServiceError::MissingDetails => 400,
ServiceError::ValidationError(_) => 400,
ServiceError::Unauthorized => 401, ServiceError::Unauthorized => 401,
ServiceError::InvalidCredentials => 401, ServiceError::InvalidCredentials => 401,
ServiceError::ExpiredSession => 401, ServiceError::ExpiredSession => 401,

View file

@ -1,6 +1,7 @@
use chrono::NaiveDate; use chrono::NaiveDate;
use entity::{application, candidate}; use entity::{application, candidate};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use validator::Validate;
use crate::{ use crate::{
error::ServiceError, error::ServiceError,
@ -57,28 +58,47 @@ pub struct CreateCandidateResponse {
pub password: String, pub password: String,
} }
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Validate, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CandidateDetails { pub struct CandidateDetails {
#[validate(length(min = 1, max = 255))]
pub name: String, pub name: String,
#[validate(length(min = 1, max = 255))]
pub surname: String, pub surname: String,
#[validate(length(min = 1, max = 255))]
pub birth_surname: String, pub birth_surname: String,
#[validate(length(min = 1, max = 255))]
pub birthplace: String, pub birthplace: String,
pub birthdate: NaiveDate, pub birthdate: NaiveDate,
#[validate(length(min = 1, max = 255))]
pub address: String, pub address: String,
pub letter_address: String, pub letter_address: String,
#[validate(length(min = 1, max = 31))]
pub telephone: String, pub telephone: String,
#[validate(length(min = 1, max = 255))]
pub citizenship: String, pub citizenship: String,
#[validate(email)]
pub email: String, pub email: String,
pub sex: String, pub sex: String,
#[validate(length(min = 1, max = 255))]
pub personal_id_number: String, pub personal_id_number: String,
#[validate(length(min = 1, max = 255))]
pub school_name: String, pub school_name: String,
#[validate(length(min = 1, max = 255))]
pub health_insurance: String, pub health_insurance: String,
pub grades: GradeList, pub grades: GradeList,
pub first_school: School, pub first_school: School,
pub second_school: School, pub second_school: School,
pub test_language: String, pub test_language: String,
} }
impl CandidateDetails {
pub fn validate_self(&self) -> Result<(), ServiceError> {
self.first_school.validate()?;
self.second_school.validate()?;
self.validate()
.map_err(ServiceError::ValidationError)
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ParentDetails { pub struct ParentDetails {

View file

@ -227,7 +227,6 @@ impl EncryptedCandidateDetails {
self.personal_id_number.is_some() && self.personal_id_number.is_some() &&
self.school_name.is_some() && self.school_name.is_some() &&
self.health_insurance.is_some() && self.health_insurance.is_some() &&
self.grades_json.is_some() &&
self.first_school.is_some() && self.first_school.is_some() &&
self.second_school.is_some() self.second_school.is_some()

View file

@ -1,8 +1,13 @@
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] use crate::error::ServiceError;
#[derive(Debug, Clone, Serialize, Deserialize, Validate, PartialEq, Eq)]
pub struct School { pub struct School {
#[validate(length(min = 1, max = 255))]
name: String, name: String,
#[validate(length(min = 1, max = 255))]
field: String, field: String,
} }
@ -13,6 +18,11 @@ impl School {
) )
} }
pub fn validate_self(&self) -> Result<(), ServiceError> {
self.validate()
.map_err(ServiceError::ValidationError)
}
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
&self.name &self.name
} }