diff options
Diffstat (limited to 'tests/test_axum.rs')
-rw-r--r-- | tests/test_axum.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/tests/test_axum.rs b/tests/test_axum.rs new file mode 100644 index 0000000..0a07b19 --- /dev/null +++ b/tests/test_axum.rs @@ -0,0 +1,142 @@ +#![cfg(feature = "axum")] + +extern crate serde; + +#[macro_use] +extern crate serde_derive; +extern crate axum_framework as axum; +extern crate serde_qs as qs; + +use axum::{ + extract::{FromRequest, RequestParts}, + http::StatusCode, + response::IntoResponse, +}; +use qs::axum::{QsQuery, QsQueryConfig, QsQueryRejection}; +use serde::de::Error; + +fn from_str<'de, D, S>(deserializer: D) -> Result<S, D::Error> +where + D: serde::Deserializer<'de>, + S: std::str::FromStr, +{ + let s = <&str as serde::Deserialize>::deserialize(deserializer)?; + S::from_str(s).map_err(|_| D::Error::custom("could not parse string")) +} + +#[derive(Deserialize, Serialize, Debug, PartialEq)] +struct Query { + foo: u64, + bars: Vec<u64>, + #[serde(flatten)] + common: CommonParams, +} + +#[derive(Deserialize, Serialize, Debug, PartialEq)] +struct CommonParams { + #[serde(deserialize_with = "from_str")] + limit: u64, + #[serde(deserialize_with = "from_str")] + offset: u64, + #[serde(deserialize_with = "from_str")] + remaining: bool, +} + +#[test] +fn test_default_error_handler() { + futures::executor::block_on(async { + let req = axum::http::Request::builder() + .uri("/test") + .body(()) + .unwrap(); + let mut req_parts = RequestParts::new(req); + + let e = QsQuery::<Query>::from_request(&mut req_parts) + .await + .unwrap_err(); + + assert_eq!(e.into_response().status(), StatusCode::BAD_REQUEST); + }) +} + +#[test] +fn test_custom_error_handler() { + futures::executor::block_on(async { + let req = + axum::http::Request::builder() + .uri("/test?foo=1&bars%5B%5D=3&limit=100&offset=50&remaining=true") + .extension(QsQueryConfig::default().error_handler(|err| { + QsQueryRejection::new(err, StatusCode::UNPROCESSABLE_ENTITY) + })) + .body(()) + .unwrap(); + let mut req_parts = RequestParts::new(req); + + let query = QsQuery::<Query>::from_request(&mut req_parts).await; + + assert!(query.is_err()); + assert_eq!( + query.unwrap_err().into_response().status(), + StatusCode::UNPROCESSABLE_ENTITY + ); + }) +} + +#[test] +fn test_composite_querystring_extractor() { + futures::executor::block_on(async { + let req = axum::http::Request::builder() + .uri("/test?foo=1&bars[]=0&bars[]=1&limit=100&offset=50&remaining=true") + .body(()) + .unwrap(); + let mut req_parts = RequestParts::new(req); + + let s = QsQuery::<Query>::from_request(&mut req_parts) + .await + .unwrap(); + assert_eq!(s.foo, 1); + assert_eq!(s.bars, vec![0, 1]); + assert_eq!(s.common.limit, 100); + assert_eq!(s.common.offset, 50); + assert!(s.common.remaining); + }) +} + +#[test] +fn test_default_qs_config() { + futures::executor::block_on(async { + let req = axum::http::Request::builder() + .uri("/test?foo=1&bars%5B%5D=3&limit=100&offset=50&remaining=true") + .body(()) + .unwrap(); + let mut req_parts = RequestParts::new(req); + + let e = QsQuery::<Query>::from_request(&mut req_parts) + .await + .unwrap_err(); + + assert_eq!(e.into_response().status(), StatusCode::BAD_REQUEST); + }) +} + +#[test] +fn test_custom_qs_config() { + futures::executor::block_on(async { + let req = axum::http::Request::builder() + .uri("/test?foo=1&bars%5B%5D=3&limit=100&offset=50&remaining=true") + .extension(QsQueryConfig::new(5, false)) + .body(()) + .unwrap(); + + let mut req_parts = RequestParts::new(req); + + let s = QsQuery::<Query>::from_request(&mut req_parts) + .await + .unwrap(); + assert_eq!(s.foo, 1); + assert_eq!(s.bars, vec![3]); + assert_eq!(s.common.limit, 100); + assert_eq!(s.common.offset, 50); + assert!(s.common.remaining); + }) +} |