1use std::sync::Arc;
5
6use axum::response::IntoResponse;
7use axum::routing::get;
8use axum::{Json, Router};
9
10use crate::state::SharedState;
11
12pub fn router() -> Router<Arc<SharedState>> {
14 Router::new().route("/api/vars", get(list_vars))
15}
16
17async fn list_vars() -> impl IntoResponse {
20 Json(serde_json::json!({ "vars": crate::vars::catalog::var_catalog() }))
21}
22
23#[cfg(test)]
24mod tests {
25 use super::*;
26 use axum::body::Body;
27 use axum::http::{Request, StatusCode};
28 use tower::ServiceExt;
29
30 #[tokio::test]
31 async fn test_list_vars_shape() {
32 let app: Router = Router::new().route("/api/vars", get(list_vars));
34 let resp = app
35 .oneshot(Request::get("/api/vars").body(Body::empty()).unwrap())
36 .await
37 .unwrap();
38 assert_eq!(resp.status(), StatusCode::OK);
39 let bytes = axum::body::to_bytes(resp.into_body(), usize::MAX)
40 .await
41 .unwrap();
42 let v: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
43 let vars = v["vars"].as_array().unwrap();
44 assert!(vars
45 .iter()
46 .any(|e| e["name"] == "uri" && e["kind"] == "static"));
47 assert!(vars.iter().any(|e| e["name"] == "http_*"
48 && e["kind"] == "family"
49 && e["family_source"] == "request_headers"));
50 assert!(vars.iter().any(|e| e["name"] == "sent_http_*"));
51 assert!(vars.iter().any(|e| e["name"] == "request_body"));
52 }
53}