diff --git a/Cargo.lock b/Cargo.lock index 88a44ebe..b73a8c3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1463,8 +1463,11 @@ name = "example-form" version = "0.1.0" dependencies = [ "axum", + "http-body-util", + "mime", "serde", "tokio", + "tower 0.5.2", "tracing", "tracing-subscriber", ] @@ -2479,12 +2482,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http 1.2.0", "http-body 1.0.1", "pin-project-lite", diff --git a/examples/form/Cargo.toml b/examples/form/Cargo.toml index a1b8f0ab..43e66dbd 100644 --- a/examples/form/Cargo.toml +++ b/examples/form/Cargo.toml @@ -10,3 +10,8 @@ serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.0", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } + +[dev-dependencies] +http-body-util = "0.1.3" +mime = "0.3.17" +tower = "0.5.2" diff --git a/examples/form/src/main.rs b/examples/form/src/main.rs index 02ea2352..cd6ff32f 100644 --- a/examples/form/src/main.rs +++ b/examples/form/src/main.rs @@ -19,7 +19,7 @@ async fn main() { .init(); // build our application with some routes - let app = Router::new().route("/", get(show_form).post(accept_form)); + let app = app(); // run it let listener = tokio::net::TcpListener::bind("127.0.0.1:3000") @@ -29,6 +29,10 @@ async fn main() { axum::serve(listener, app).await.unwrap(); } +fn app() -> Router { + Router::new().route("/", get(show_form).post(accept_form)) +} + async fn show_form() -> Html<&'static str> { Html( r#" @@ -62,6 +66,65 @@ struct Input { email: String, } -async fn accept_form(Form(input): Form) { +async fn accept_form(Form(input): Form) -> Html { dbg!(&input); + Html(format!( + "email='{}'\nname='{}'\n", + &input.email, &input.name + )) +} + +#[cfg(test)] +mod tests { + use super::*; + use axum::{ + body::Body, + http::{self, Request, StatusCode}, + }; + use http_body_util::BodyExt; + use tower::ServiceExt; // for `call`, `oneshot`, and `ready` // for `collect` + + #[tokio::test] + async fn test_get() { + let app = app(); + + let response = app + .oneshot(Request::builder().uri("/").body(Body::empty()).unwrap()) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + + let body = response.into_body().collect().await.unwrap().to_bytes(); + let body = std::str::from_utf8(&body).unwrap(); + + assert!(body.contains(r#""#)); + } + + #[tokio::test] + async fn test_post() { + let app = app(); + + let response = app + .oneshot( + Request::builder() + .method(http::Method::POST) + .uri("/") + .header( + http::header::CONTENT_TYPE, + mime::APPLICATION_WWW_FORM_URLENCODED.as_ref(), + ) + .body(Body::from("name=foo&email=bar@axum")) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + + let body = response.into_body().collect().await.unwrap().to_bytes(); + let body = std::str::from_utf8(&body).unwrap(); + + assert_eq!(body, "email='bar@axum'\nname='foo'\n"); + } }