use axum::body::Body; use axum::extract::rejection::PathRejection; use axum::extract::Request; use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use axum_extra::routing::RouterExt; use better_routes::routes; use http_body_util::BodyExt; use serde::Deserialize; use tower::ServiceExt; #[test] fn test_all() { let t = trybuild::TestCases::new(); t.pass("tests/trybuild/pass/*.rs"); t.compile_fail("tests/trybuild/fail/*.rs"); } fn make_request(path: &'static str, method: &'static str) -> Request
{ Request::builder() .uri(path) .method(method) .body(Body::empty()) .unwrap() } #[tokio::test] async fn should_only_allow_get_request() { #[derive(Deserialize)] struct HomePath; async fn home(_: HomePath) {} routes! { name => AllRoutes, "/" => HomePath { get => home }, } let router = AllRoutes::routes(); let get_req = make_request("/", "GET"); let post_req = make_request("/", "POST"); let put_req = make_request("/", "PUT"); let delete_req = make_request("/", "DELETE"); let patch_req = make_request("/", "PATCH"); let get_res = router.clone().oneshot(get_req).await.unwrap(); let post_res = router.clone().oneshot(post_req).await.unwrap(); let put_res = router.clone().oneshot(put_req).await.unwrap(); let delete_res = router.clone().oneshot(delete_req).await.unwrap(); let patch_res = router.clone().oneshot(patch_req).await.unwrap(); assert_eq!(get_res.status(), StatusCode::OK); assert_eq!(post_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(put_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(delete_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(patch_res.status(), StatusCode::METHOD_NOT_ALLOWED); } #[tokio::test] async fn should_only_allow_post_request() { #[derive(Deserialize)] struct HomePath; async fn home(_: HomePath) {} routes! { name => AllRoutes, "/" => HomePath { post => home }, } let router = AllRoutes::routes(); let get_req = make_request("/", "GET"); let post_req = make_request("/", "POST"); let put_req = make_request("/", "PUT"); let delete_req = make_request("/", "DELETE"); let patch_req = make_request("/", "PATCH"); let get_res = router.clone().oneshot(get_req).await.unwrap(); let post_res = router.clone().oneshot(post_req).await.unwrap(); let put_res = router.clone().oneshot(put_req).await.unwrap(); let delete_res = router.clone().oneshot(delete_req).await.unwrap(); let patch_res = router.clone().oneshot(patch_req).await.unwrap(); assert_eq!(get_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(post_res.status(), StatusCode::OK); assert_eq!(put_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(delete_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(patch_res.status(), StatusCode::METHOD_NOT_ALLOWED); } #[tokio::test] async fn should_only_allow_put_request() { #[derive(Deserialize)] struct HomePath; async fn home(_: HomePath) {} routes! { name => AllRoutes, "/" => HomePath { put => home }, } let router = AllRoutes::routes(); let get_req = make_request("/", "GET"); let post_req = make_request("/", "POST"); let put_req = make_request("/", "PUT"); let delete_req = make_request("/", "DELETE"); let patch_req = make_request("/", "PATCH"); let get_res = router.clone().oneshot(get_req).await.unwrap(); let post_res = router.clone().oneshot(post_req).await.unwrap(); let put_res = router.clone().oneshot(put_req).await.unwrap(); let delete_res = router.clone().oneshot(delete_req).await.unwrap(); let patch_res = router.clone().oneshot(patch_req).await.unwrap(); assert_eq!(get_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(post_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(put_res.status(), StatusCode::OK); assert_eq!(delete_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(patch_res.status(), StatusCode::METHOD_NOT_ALLOWED); } #[tokio::test] async fn should_only_allow_del_request() { #[derive(Deserialize)] struct HomePath; async fn home(_: HomePath) {} routes! { name => AllRoutes, "/" => HomePath{ delete => home }, } let router = AllRoutes::routes(); let get_req = make_request("/", "GET"); let post_req = make_request("/", "POST"); let put_req = make_request("/", "PUT"); let delete_req = make_request("/", "DELETE"); let patch_req = make_request("/", "PATCH"); let get_res = router.clone().oneshot(get_req).await.unwrap(); let post_res = router.clone().oneshot(post_req).await.unwrap(); let put_res = router.clone().oneshot(put_req).await.unwrap(); let delete_res = router.clone().oneshot(delete_req).await.unwrap(); let patch_res = router.clone().oneshot(patch_req).await.unwrap(); assert_eq!(get_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(post_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(put_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(delete_res.status(), StatusCode::OK); assert_eq!(patch_res.status(), StatusCode::METHOD_NOT_ALLOWED); } #[tokio::test] async fn should_only_allow_patch_request() { #[derive(Deserialize)] struct HomePath; async fn home(_: HomePath) {} routes! { name => AllRoutes, "/" => HomePath{ patch => home }, } let router = AllRoutes::routes(); let get_req = make_request("/", "GET"); let post_req = make_request("/", "POST"); let put_req = make_request("/", "PUT"); let delete_req = make_request("/", "DELETE"); let patch_req = make_request("/", "PATCH"); let get_res = router.clone().oneshot(get_req).await.unwrap(); let post_res = router.clone().oneshot(post_req).await.unwrap(); let put_res = router.clone().oneshot(put_req).await.unwrap(); let delete_res = router.clone().oneshot(delete_req).await.unwrap(); let patch_res = router.clone().oneshot(patch_req).await.unwrap(); assert_eq!(get_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(post_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(put_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(delete_res.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(patch_res.status(), StatusCode::OK); } #[tokio::test] async fn should_reject_with_global_rejection() { #[derive(Default)] struct GlobalRejection; impl From