use axum::body::Body;
use axum::extract::Path;
use axum::http::{Request, StatusCode};
use axum::routing::{any, get};
use axum::Router;
use tower::ServiceExt;
fn worktree_router() -> Router {
Router::new()
.route(
"/api/v1/issues/:owner/:repo",
get(|Path((owner, repo)): Path<(String, String)>| async move {
format!("{owner}|{repo}")
}),
)
.route("/api/v1/version", get(|| async { "version" }))
.route(
"/api/v1/query",
get(|request: Request<Body>| async move {
request.uri().query().unwrap_or_default().to_string()
}),
)
}
async fn through_the_machine(path: &str) -> (StatusCode, String) {
let machine = Router::new().route(
"/api/v1/worktrees/:worktree/*rest",
any(
|Path((_worktree, rest)): Path<(String, String)>, request: Request<Body>| async move {
let inner = super::inner_request(&rest, request).expect("a rewritable request");
worktree_router().oneshot(inner).await.expect("the worktree router answers")
},
),
);
let response = machine
.oneshot(Request::builder().uri(path).body(Body::empty()).expect("a request"))
.await
.expect("the machine answers");
let status = response.status();
let body = hyper::body::to_bytes(response.into_body()).await.expect("a body");
(status, String::from_utf8_lossy(&body).into_owned())
}
#[tokio::test]
async fn test10023_a_forwarded_request_carries_only_its_own_path() {
let (status, body) =
through_the_machine("/api/v1/worktrees/machinefabric:fix/issues/machinefabric/macfloom?state=all").await;
assert_eq!(status, StatusCode::OK);
assert_eq!(
body, "machinefabric|macfloom",
"the handler must see its own two segments, not the worktree id"
);
}
#[tokio::test]
async fn test10024_the_query_survives_the_rewrite() {
let (status, body) = through_the_machine("/api/v1/worktrees/machinefabric:main/query?state=all&x=1").await;
assert_eq!(status, StatusCode::OK);
assert_eq!(body, "state=all&x=1", "every query parameter must reach the worktree");
}
#[tokio::test]
async fn test10025_a_plain_route_still_resolves() {
let (status, body) = through_the_machine("/api/v1/worktrees/~0123456789abcdef/version").await;
assert_eq!(status, StatusCode::OK);
assert_eq!(body, "version");
}