add tests for ValidEx::arguments

This commit is contained in:
gengteng
2023-09-29 12:15:42 +08:00
parent 123f983476
commit b0fe4cacda
2 changed files with 83 additions and 11 deletions

View File

@@ -116,10 +116,25 @@ impl<T: Display> Display for Valid<T> {
} }
impl<E, A> ValidEx<E, A> { impl<E, A> ValidEx<E, A> {
/// Consume the `ValidEx` extractor and returns the inner type. /// Consumes the `ValidEx` and returns the validated data within.
///
/// This returns the `E` type which represents the data that has been
/// successfully validated.
pub fn into_inner(self) -> E { pub fn into_inner(self) -> E {
self.0 self.0
} }
/// Returns a reference to the validation arguments.
///
/// This provides access to the `A` type which contains the arguments used
/// to validate the data. These arguments were passed to the validation
/// function.
pub fn arguments<'a>(&'a self) -> <<A as Arguments<'a>>::T as ValidateArgs<'a>>::Args
where
A: Arguments<'a>,
{
self.1.get()
}
} }
fn response_builder(ve: ValidationErrors) -> Response { fn response_builder(ve: ValidationErrors) -> Response {
@@ -298,13 +313,13 @@ where
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use crate::{Valid, ValidRejection}; use crate::{Arguments, Valid, ValidEx, ValidRejection};
use reqwest::{RequestBuilder, StatusCode}; use reqwest::{RequestBuilder, StatusCode};
use serde::Serialize; use serde::Serialize;
use std::error::Error; use std::error::Error;
use std::io; use std::io;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use validator::{ValidationError, ValidationErrors}; use validator::{Validate, ValidateArgs, ValidationError, ValidationErrors};
/// # Valid test parameter /// # Valid test parameter
pub trait ValidTestParameter: Serialize + 'static { pub trait ValidTestParameter: Serialize + 'static {
@@ -349,7 +364,7 @@ pub mod tests {
const TEST: &str = "test"; const TEST: &str = "test";
#[test] #[test]
fn deref_deref_mut_into_inner() { fn valid_deref_deref_mut_into_inner() {
let mut inner = String::from(TEST); let mut inner = String::from(TEST);
let mut v = Valid(inner.clone()); let mut v = Valid(inner.clone());
assert_eq!(&inner, v.deref()); assert_eq!(&inner, v.deref());
@@ -359,6 +374,46 @@ pub mod tests {
assert_eq!(inner, v.into_inner()); assert_eq!(inner, v.into_inner());
} }
#[test]
fn valid_ex_deref_deref_mut_into_inner_arguments() {
let mut inner = String::from(TEST);
let mut v = ValidEx(inner.clone(), ());
assert_eq!(&inner, v.deref());
inner.push_str(TEST);
v.deref_mut().push_str(TEST);
assert_eq!(&inner, v.deref());
assert_eq!(inner, v.into_inner());
fn validate(_v: i32, _args: i32) -> Result<(), ValidationError> {
Ok(())
}
#[derive(Validate)]
struct Data {
#[validate(custom(function = "validate", arg = "i32"))]
v: i32,
}
struct DataVA {
a: i32,
}
impl<'a> Arguments<'a> for DataVA {
type T = Data;
fn get(&'a self) -> <<Self as Arguments<'a>>::T as ValidateArgs<'a>>::Args {
self.a
}
}
let data = Data { v: 12 };
let args = DataVA { a: 123 };
let ve = ValidEx(data, args);
assert_eq!(ve.v, 12);
let a = ve.arguments();
assert_eq!(a, 123);
}
#[test] #[test]
fn display_error() { fn display_error() {
// ValidRejection::Valid Display // ValidRejection::Valid Display

View File

@@ -1,4 +1,3 @@
use crate::test::extra_typed_path::TypedPathParamExValidationArguments;
use crate::tests::{ValidTest, ValidTestParameter}; use crate::tests::{ValidTest, ValidTestParameter};
use crate::{Arguments, HasValidate, Valid, ValidEx, VALIDATION_ERROR_STATUS}; use crate::{Arguments, HasValidate, Valid, ValidEx, VALIDATION_ERROR_STATUS};
use axum::extract::{FromRef, Path, Query}; use axum::extract::{FromRef, Path, Query};
@@ -118,14 +117,16 @@ impl HasValidate for Parameters {
#[derive(Debug, Clone, FromRef)] #[derive(Debug, Clone, FromRef)]
struct MyState { struct MyState {
param_validation_ctx: ParametersExValidationArguments, param_validation_ctx: ParametersExValidationArguments,
typed_path_validation_ctx: TypedPathParamExValidationArguments, #[cfg(feature = "extra_typed_path")]
typed_path_validation_ctx: extra_typed_path::TypedPathParamExValidationArguments,
} }
#[tokio::test] #[tokio::test]
async fn test_main() -> anyhow::Result<()> { async fn test_main() -> anyhow::Result<()> {
let state = MyState { let state = MyState {
param_validation_ctx: ParametersExValidationArguments::default(), param_validation_ctx: ParametersExValidationArguments::default(),
typed_path_validation_ctx: TypedPathParamExValidationArguments::default(), #[cfg(feature = "extra_typed_path")]
typed_path_validation_ctx: extra_typed_path::TypedPathParamExValidationArguments::default(),
}; };
let router = Router::new() let router = Router::new()
@@ -133,6 +134,7 @@ async fn test_main() -> anyhow::Result<()> {
.route(route::QUERY, get(extract_query)) .route(route::QUERY, get(extract_query))
.route(route::FORM, post(extract_form)) .route(route::FORM, post(extract_form))
.route(route::JSON, post(extract_json)) .route(route::JSON, post(extract_json))
.route(route::PATH_EX, get(extract_path_ex))
.route(route::QUERY_EX, get(extract_query_ex)) .route(route::QUERY_EX, get(extract_query_ex))
.route(route::FORM_EX, post(extract_form_ex)) .route(route::FORM_EX, post(extract_form_ex))
.route(route::JSON_EX, post(extract_json_ex)); .route(route::JSON_EX, post(extract_json_ex));
@@ -259,12 +261,16 @@ async fn test_main() -> anyhow::Result<()> {
let server_url = format!("http://{}", server_addr); let server_url = format!("http://{}", server_addr);
let test_executor = TestExecutor::from(Url::parse(&format!("http://{}", server_addr))?); let test_executor = TestExecutor::from(Url::parse(&format!("http://{}", server_addr))?);
{ async fn test_extra_path(
test_executor: &TestExecutor,
route: &str,
server_url: &str,
) -> anyhow::Result<()> {
let path_type_name = type_name::<Path<Parameters>>(); let path_type_name = type_name::<Path<Parameters>>();
let valid_path_response = test_executor let valid_path_response = test_executor
.client() .client()
.get(format!( .get(format!(
"{}/path/{}/{}", "{}/{route}/{}/{}",
server_url, VALID_PARAMETERS.v0, VALID_PARAMETERS.v1 server_url, VALID_PARAMETERS.v0, VALID_PARAMETERS.v1
)) ))
.send() .send()
@@ -278,7 +284,7 @@ async fn test_main() -> anyhow::Result<()> {
let error_path_response = test_executor let error_path_response = test_executor
.client() .client()
.get(format!("{}/path/not_i32/path", server_url)) .get(format!("{}/{route}/not_i32/path", server_url))
.send() .send()
.await?; .await?;
assert_eq!( assert_eq!(
@@ -291,7 +297,7 @@ async fn test_main() -> anyhow::Result<()> {
let invalid_path_response = test_executor let invalid_path_response = test_executor
.client() .client()
.get(format!( .get(format!(
"{}/path/{}/{}", "{}/{route}/{}/{}",
server_url, INVALID_PARAMETERS.v0, INVALID_PARAMETERS.v1 server_url, INVALID_PARAMETERS.v0, INVALID_PARAMETERS.v1
)) ))
.send() .send()
@@ -305,8 +311,12 @@ async fn test_main() -> anyhow::Result<()> {
#[cfg(feature = "into_json")] #[cfg(feature = "into_json")]
check_json(path_type_name, invalid_path_response).await; check_json(path_type_name, invalid_path_response).await;
println!("All {} tests passed.", path_type_name); println!("All {} tests passed.", path_type_name);
Ok(())
} }
test_extra_path(&test_executor, "path", &server_url).await?;
test_extra_path(&test_executor, "path_ex", &server_url).await?;
// Valid // Valid
test_executor test_executor
.execute::<Query<Parameters>>(Method::GET, route::QUERY) .execute::<Query<Parameters>>(Method::GET, route::QUERY)
@@ -621,6 +631,7 @@ pub async fn check_json(type_name: &'static str, response: reqwest::Response) {
mod route { mod route {
pub const PATH: &str = "/path/:v0/:v1"; pub const PATH: &str = "/path/:v0/:v1";
pub const PATH_EX: &str = "/path_ex/:v0/:v1";
pub const QUERY: &str = "/query"; pub const QUERY: &str = "/query";
pub const QUERY_EX: &str = "/query_ex"; pub const QUERY_EX: &str = "/query_ex";
pub const FORM: &str = "/form"; pub const FORM: &str = "/form";
@@ -633,6 +644,12 @@ async fn extract_path(Valid(Path(parameters)): Valid<Path<Parameters>>) -> Statu
validate_again(parameters) validate_again(parameters)
} }
async fn extract_path_ex(
ValidEx(Path(parameters), args): ValidEx<Path<ParametersEx>, ParametersExValidationArguments>,
) -> StatusCode {
validate_again_ex(parameters, args.get())
}
async fn extract_query(Valid(Query(parameters)): Valid<Query<Parameters>>) -> StatusCode { async fn extract_query(Valid(Query(parameters)): Valid<Query<Parameters>>) -> StatusCode {
validate_again(parameters) validate_again(parameters)
} }