From 82dc642c161087b8d5bfc6c9513c7b7a0b06605a Mon Sep 17 00:00:00 2001 From: gengteng Date: Fri, 4 Aug 2023 22:45:34 +0800 Subject: [PATCH] add tests for msgpack and yaml --- Cargo.toml | 6 +++-- README.md | 36 ++++++++++++------------- src/msgpack.rs | 62 +++++++++++++++++++++++++++++++++++++++++++ src/test.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/yaml.rs | 35 +++++++++++++++++++++++++ 5 files changed, 190 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9a68e1d..b1925e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,9 +47,11 @@ reqwest = { version = "0.11.18", features = ["json"] } serde = { version = "1.0.181", features = ["derive"] } validator = { version = "0.16.0", features = ["derive"] } serde_json = "1.0.104" +serde_yaml = "0.9.25" mime = "0.3.17" prost = "0.11.9" once_cell = "1.18.0" +rmp-serde = "1.1.2" [features] default = ["json", "form", "query"] @@ -65,6 +67,6 @@ extra = ["axum-extra"] extra_query = ["axum-extra/query"] extra_form = ["axum-extra/form"] extra_protobuf = ["axum-extra/protobuf"] -extra_all = ["extra", "extra_query", "extra_form", "extra_protobuf"] -all_types = ["json", "form", "query", "typed_header", "msgpack", "yaml", "extra_all"] +all_extra_types = ["extra", "extra_query", "extra_form", "extra_protobuf"] +all_types = ["json", "form", "query", "typed_header", "msgpack", "yaml", "all_extra_types"] full = ["all_types", "422", "into_json"] diff --git a/README.md b/README.md index 6726879..a8b929a 100644 --- a/README.md +++ b/README.md @@ -50,24 +50,24 @@ When validation errors occur, the extractor will automatically return 400 with v ## Features -| Feature | Description | Default | Tests | -|----------------|------------------------------------------------------------------------------------------------------|---------|-------| -| default | Enables support for `Path`, `Query`, `Json` and `Form` | ✅ | ✅ | -| json | Enables support for `Json` | ✅ | ✅ | -| query | Enables support for `Query` | ✅ | ✅ | -| form | Enables support for `Form` | ✅ | ✅ | -| typed_header | Enables support for `TypedHeader` | ❌ | ✅ | -| msgpack | Enables support for `MsgPack` and `MsgPackRaw` from `axum-msgpack` | ❌ | ❌ | -| yaml | Enables support for `Yaml` from `axum-yaml` | ❌ | ❌ | -| extra | Enables support for `Cached`, `WithRejection` from `axum-extra` | ❌ | ✅ | -| extra_query | Enables support for `Query` from `axum-extra` | ❌ | ✅ | -| extra_form | Enables support for `Form` from `axum-extra` | ❌ | ✅ | -| extra_protobuf | Enables support for `Protobuf` from `axum-extra` | ❌ | ✅ | -| extra_all | Enables support for all extractors above from `axum-extra` | ❌ | ✅ | -| all | Enables support for all extractors above | ❌ | 🚧 | -| 422 | Use `422 Unprocessable Entity` instead of `400 Bad Request` as the status code when validation fails | ❌ | ✅ | -| into_json | Validation errors will be serialized into JSON format and returned as the HTTP body | ❌ | ✅ | -| full | Enables all features | ❌ | 🚧 | +| Feature | Description | Default | Tests | +|-----------------|------------------------------------------------------------------------------------------------------|---------|-------| +| default | Enables support for `Path`, `Query`, `Json` and `Form` | ✅ | ✅ | +| json | Enables support for `Json` | ✅ | ✅ | +| query | Enables support for `Query` | ✅ | ✅ | +| form | Enables support for `Form` | ✅ | ✅ | +| typed_header | Enables support for `TypedHeader` | ❌ | ✅ | +| msgpack | Enables support for `MsgPack` and `MsgPackRaw` from `axum-msgpack` | ❌ | ❌ | +| yaml | Enables support for `Yaml` from `axum-yaml` | ❌ | ❌ | +| extra | Enables support for `Cached`, `WithRejection` from `axum-extra` | ❌ | ✅ | +| extra_query | Enables support for `Query` from `axum-extra` | ❌ | ✅ | +| extra_form | Enables support for `Form` from `axum-extra` | ❌ | ✅ | +| extra_protobuf | Enables support for `Protobuf` from `axum-extra` | ❌ | ✅ | +| all_extra_types | Enables support for all extractors above from `axum-extra` | ❌ | ✅ | +| all_types | Enables support for all extractors above | ❌ | 🚧 | +| 422 | Use `422 Unprocessable Entity` instead of `400 Bad Request` as the status code when validation fails | ❌ | ✅ | +| into_json | Validation errors will be serialized into JSON format and returned as the HTTP body | ❌ | ✅ | +| full | Enables all features | ❌ | 🚧 | ## License This project is licensed under the MIT License. diff --git a/src/msgpack.rs b/src/msgpack.rs index 195172c..bf0ea46 100644 --- a/src/msgpack.rs +++ b/src/msgpack.rs @@ -18,3 +18,65 @@ impl HasValidate for MsgPackRaw { &self.0 } } + +#[cfg(test)] +mod tests { + use crate::tests::{ValidTest, ValidTestParameter}; + use axum::http::StatusCode; + use axum_msgpack::{MsgPack, MsgPackRaw}; + use reqwest::RequestBuilder; + + impl ValidTest for MsgPack { + const ERROR_STATUS_CODE: StatusCode = StatusCode::BAD_REQUEST; + + fn set_valid_request(builder: RequestBuilder) -> RequestBuilder { + builder + .header(reqwest::header::CONTENT_TYPE, "application/msgpack") + .body( + rmp_serde::to_vec_named(T::valid()) + .expect("Failed to serialize parameters to msgpack"), + ) + } + + fn set_error_request(builder: RequestBuilder) -> RequestBuilder { + // `Content-Type` not set, `MsgPack` should return `415 Unsupported Media Type` + builder + } + + fn set_invalid_request(builder: RequestBuilder) -> RequestBuilder { + builder + .header(reqwest::header::CONTENT_TYPE, "application/msgpack") + .body( + rmp_serde::to_vec_named(T::invalid()) + .expect("Failed to serialize parameters to msgpack"), + ) + } + } + + impl ValidTest for MsgPackRaw { + const ERROR_STATUS_CODE: StatusCode = StatusCode::BAD_REQUEST; + + fn set_valid_request(builder: RequestBuilder) -> RequestBuilder { + builder + .header(reqwest::header::CONTENT_TYPE, "application/msgpack") + .body( + rmp_serde::to_vec(T::valid()) + .expect("Failed to serialize parameters to msgpack"), + ) + } + + fn set_error_request(builder: RequestBuilder) -> RequestBuilder { + // `Content-Type` not set, `MsgPack` should return `415 Unsupported Media Type` + builder + } + + fn set_invalid_request(builder: RequestBuilder) -> RequestBuilder { + builder + .header(reqwest::header::CONTENT_TYPE, "application/msgpack") + .body( + rmp_serde::to_vec(T::invalid()) + .expect("Failed to serialize parameters to msgpack"), + ) + } + } +} diff --git a/src/test.rs b/src/test.rs index 49a7c9d..85d7a70 100644 --- a/src/test.rs +++ b/src/test.rs @@ -87,6 +87,17 @@ async fn test_main() -> anyhow::Result<()> { post(extra_protobuf::extract_extra_protobuf), ); + #[cfg(feature = "yaml")] + let router = router.route(yaml::route::YAML, post(yaml::extract_yaml)); + + #[cfg(feature = "msgpack")] + let router = router + .route(msgpack::route::MSGPACK, post(msgpack::extract_msgpack)) + .route( + msgpack::route::MSGPACK_RAW, + post(msgpack::extract_msgpack_raw), + ); + let server = axum::Server::bind(&SocketAddr::from(([0u8, 0, 0, 0], 0u16))) .serve(router.into_make_service()); let server_addr = server.local_addr(); @@ -207,6 +218,25 @@ async fn test_main() -> anyhow::Result<()> { .await?; } + #[cfg(feature = "yaml")] + { + use axum_yaml::Yaml; + test_executor + .execute::>(Method::POST, yaml::route::YAML) + .await?; + } + + #[cfg(feature = "msgpack")] + { + use axum_msgpack::{MsgPack, MsgPackRaw}; + test_executor + .execute::>(Method::POST, msgpack::route::MSGPACK) + .await?; + test_executor + .execute::>(Method::POST, msgpack::route::MSGPACK_RAW) + .await?; + } + drop(server_guard); server_handle.await??; Ok(()) @@ -561,3 +591,44 @@ mod extra_protobuf { validate_again(parameters) } } + +#[cfg(feature = "yaml")] +mod yaml { + use crate::test::{validate_again, Parameters}; + use crate::Valid; + use axum::http::StatusCode; + use axum_yaml::Yaml; + + pub mod route { + pub const YAML: &str = "/yaml"; + } + + pub async fn extract_yaml(Valid(Yaml(parameters)): Valid>) -> StatusCode { + validate_again(parameters) + } +} + +#[cfg(feature = "msgpack")] +mod msgpack { + use crate::test::{validate_again, Parameters}; + use crate::Valid; + use axum::http::StatusCode; + use axum_msgpack::{MsgPack, MsgPackRaw}; + + pub mod route { + pub const MSGPACK: &str = "/msgpack"; + pub const MSGPACK_RAW: &str = "/msgpack_raw"; + } + + pub async fn extract_msgpack( + Valid(MsgPack(parameters)): Valid>, + ) -> StatusCode { + validate_again(parameters) + } + + pub async fn extract_msgpack_raw( + Valid(MsgPackRaw(parameters)): Valid>, + ) -> StatusCode { + validate_again(parameters) + } +} diff --git a/src/yaml.rs b/src/yaml.rs index f6190c1..cea4049 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -11,3 +11,38 @@ impl HasValidate for Yaml { &self.0 } } + +#[cfg(test)] +mod tests { + use crate::tests::{ValidTest, ValidTestParameter}; + use axum::http::StatusCode; + use axum_yaml::Yaml; + use reqwest::RequestBuilder; + + impl ValidTest for Yaml { + const ERROR_STATUS_CODE: StatusCode = StatusCode::UNSUPPORTED_MEDIA_TYPE; + + fn set_valid_request(builder: RequestBuilder) -> RequestBuilder { + builder + .header(reqwest::header::CONTENT_TYPE, "application/yaml") + .body( + serde_yaml::to_string(&T::valid()) + .expect("Failed to serialize parameters to yaml"), + ) + } + + fn set_error_request(builder: RequestBuilder) -> RequestBuilder { + // `Content-Type` not set, `Yaml` should return `415 Unsupported Media Type` + builder + } + + fn set_invalid_request(builder: RequestBuilder) -> RequestBuilder { + builder + .header(reqwest::header::CONTENT_TYPE, "application/yaml") + .body( + serde_yaml::to_string(&T::invalid()) + .expect("Failed to serialize parameters to yaml"), + ) + } + } +}