An easy-to-host PDS on the ATProtocol, MacOS. Grandma-approved.

fix(relay): address PR review issues for MM-73 health endpoint

- Log error details when DB health check fails (tracing::error!)
- Assert content-type: application/json on 503 response in test
- Add health_post_returns_405 test (consistent with existing XRPC pattern)
- Clarify SELECT 1 scope in handler comment (liveness only, not schema)
- Fix test_state() doc comment to note pool is fully migrated

authored by malpercio.dev and committed by

Tangled 8545763d a83e7a27

+32 -9
+1 -1
crates/relay/src/app.rs
··· 39 39 } 40 40 41 41 /// Build a minimal `AppState` backed by an in-memory SQLite database. 42 - /// Available to all test modules in this crate via `crate::app::test_state()`. 42 + /// The pool is fully migrated, so the schema is present and ready for handler tests. 43 43 #[cfg(test)] 44 44 pub(crate) async fn test_state() -> AppState { 45 45 use common::{BlobsConfig, IrohConfig, OAuthConfig};
+31 -8
crates/relay/src/routes/health.rs
··· 1 1 // pattern: Imperative Shell 2 2 // 3 - // Gathers: DB health via SELECT 1 3 + // Gathers: DB health via SELECT 1 (pool liveness only — does not verify schema or migrations) 4 4 // Processes: none (response shape is trivial — no pure core to extract) 5 5 // Returns: JSON response with version and db status 6 6 ··· 22 22 StatusCode::OK, 23 23 Json(HealthResponse { version, db: "ok" }), 24 24 ), 25 - Err(_) => ( 26 - StatusCode::SERVICE_UNAVAILABLE, 27 - Json(HealthResponse { 28 - version, 29 - db: "error", 30 - }), 31 - ), 25 + Err(e) => { 26 + tracing::error!(error = %e, "db health check failed"); 27 + ( 28 + StatusCode::SERVICE_UNAVAILABLE, 29 + Json(HealthResponse { 30 + version, 31 + db: "error", 32 + }), 33 + ) 34 + } 32 35 } 33 36 } 34 37 ··· 117 120 .unwrap(); 118 121 119 122 assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE); 123 + assert_eq!( 124 + response.headers().get("content-type").unwrap(), 125 + "application/json" 126 + ); 120 127 121 128 let body = axum::body::to_bytes(response.into_body(), 4096) 122 129 .await ··· 124 131 let json: serde_json::Value = serde_json::from_slice(&body).unwrap(); 125 132 assert_eq!(json["db"], "error"); 126 133 assert_eq!(json["version"], env!("CARGO_PKG_VERSION")); 134 + } 135 + 136 + #[tokio::test] 137 + async fn health_post_returns_405() { 138 + let response = app(test_state().await) 139 + .oneshot( 140 + Request::builder() 141 + .method("POST") 142 + .uri("/xrpc/_health") 143 + .body(Body::empty()) 144 + .unwrap(), 145 + ) 146 + .await 147 + .unwrap(); 148 + 149 + assert_eq!(response.status(), StatusCode::METHOD_NOT_ALLOWED); 127 150 } 128 151 }