use larust_http::axum::body::Body;
use larust_http::axum::extract::Request;
use larust_http::axum::http::{HeaderName, HeaderValue};
use larust_http::axum::middleware::{from_fn, Next};
use larust_http::axum::response::Response;
use larust_http::{Route, Router};
use tower::ServiceExt;
async fn index() -> &'static str {
"index"
}
async fn create() -> &'static str {
"create"
}
async fn store() -> &'static str {
"store"
}
async fn show() -> &'static str {
"show"
}
async fn edit() -> &'static str {
"edit"
}
async fn update() -> &'static str {
"update"
}
async fn destroy() -> &'static str {
"destroy"
}
#[test]
fn resource_registers_all_seven_routes_with_laravel_naming() {
let router = Route::resource(
"posts", "post", index, create, store, show, edit, update, destroy,
);
let routes = router.routes();
assert_eq!(routes.len(), 7);
let find = |method: &str, path: &str| {
routes
.iter()
.find(|r| r.method == method && r.path == path)
.unwrap_or_else(|| panic!("no {method} {path} route registered"))
};
assert_eq!(find("GET", "/posts").name.as_deref(), Some("posts.index"));
assert_eq!(
find("GET", "/posts/create").name.as_deref(),
Some("posts.create")
);
assert_eq!(find("POST", "/posts").name.as_deref(), Some("posts.store"));
assert_eq!(
find("GET", "/posts/{post}").name.as_deref(),
Some("posts.show")
);
assert_eq!(
find("GET", "/posts/{post}/edit").name.as_deref(),
Some("posts.edit")
);
assert_eq!(
find("PUT", "/posts/{post}").name.as_deref(),
Some("posts.update")
);
assert_eq!(
find("DELETE", "/posts/{post}").name.as_deref(),
Some("posts.destroy")
);
}
async fn mark(req: Request, next: Next) -> Response {
let mut response = next.run(req).await;
response.headers_mut().append(
HeaderName::from_static("x-marked"),
HeaderValue::from_static("1"),
);
response
}
#[test]
fn resource_composes_with_other_routes_and_a_shared_prefix_group() {
async fn home() -> &'static str {
"home"
}
let router = Route::get("/", home).group("/admin", |r: Router| {
r.middleware(from_fn(mark)).resource(
"posts", "post", index, create, store, show, edit, update, destroy,
)
});
let routes = router.routes();
assert_eq!(routes.len(), 8);
assert!(routes.iter().any(|r| r.path == "/" && r.method == "GET"));
assert!(routes.iter().any(|r| r.path == "/admin/posts"
&& r.method == "GET"
&& r.name.as_deref() == Some("posts.index")));
assert!(routes.iter().any(|r| r.path == "/admin/posts/{post}/edit"
&& r.method == "GET"
&& r.name.as_deref() == Some("posts.edit")));
}
#[tokio::test]
async fn resource_routes_are_wrapped_by_group_middleware() {
async fn home() -> &'static str {
"home"
}
let router = Route::get("/", home)
.group("/admin", |r: Router| {
r.middleware(from_fn(mark)).resource(
"posts", "post", index, create, store, show, edit, update, destroy,
)
})
.into_axum_router();
let posts_response = router
.clone()
.oneshot(Request::get("/admin/posts").body(Body::empty()).unwrap())
.await
.unwrap();
assert!(posts_response.headers().contains_key("x-marked"));
let post_response = router
.clone()
.oneshot(Request::get("/admin/posts/1").body(Body::empty()).unwrap())
.await
.unwrap();
assert!(post_response.headers().contains_key("x-marked"));
let home_response = router
.oneshot(Request::get("/").body(Body::empty()).unwrap())
.await
.unwrap();
assert!(!home_response.headers().contains_key("x-marked"));
}