wip(bridge): retained FIFA request/response mapper + docker packaging
RETAINED PRE-EXISTING WIP (brought forward after verification, not authored
here, not production-ready). Substantive mapper.rs proxy expansion plus a
multi-stage Dockerfile/.dockerignore (rustls, self-signed cert at startup).
No secrets/captures staged. Preserved off the detached base c58e7326a1.
This commit is contained in:
+59
-16
@@ -1,3 +1,4 @@
|
||||
use axum::routing::{any, delete, get, post};
|
||||
use axum::{
|
||||
body::Body,
|
||||
http::{Request, StatusCode},
|
||||
@@ -9,7 +10,6 @@ use openfut_bridge::{
|
||||
proxy::ProxyState,
|
||||
routes,
|
||||
};
|
||||
use axum::routing::{any, delete, get, post};
|
||||
use tower::ServiceExt;
|
||||
|
||||
// ── Unit tests ────────────────────────────────────────────────────────────────
|
||||
@@ -96,9 +96,15 @@ fn build_test_app() -> axum::Router {
|
||||
.route("/_bridge/dashboard", get(routes::health::get_dashboard))
|
||||
.route("/_bridge/captures", get(routes::admin::get_captures))
|
||||
.route("/_bridge/captures", delete(routes::admin::delete_captures))
|
||||
.route("/_bridge/unknown", get(routes::admin::get_unknown_endpoints))
|
||||
.route(
|
||||
"/_bridge/unknown",
|
||||
get(routes::admin::get_unknown_endpoints),
|
||||
)
|
||||
.route("/_bridge/status", get(routes::admin::get_endpoint_status))
|
||||
.route("/_bridge/captures/:id/replay", post(routes::admin::post_replay_capture))
|
||||
.route(
|
||||
"/_bridge/captures/:id/replay",
|
||||
post(routes::admin::post_replay_capture),
|
||||
)
|
||||
.fallback(any(openfut_bridge::proxy::catch_all_handler))
|
||||
.with_state(state)
|
||||
}
|
||||
@@ -107,11 +113,18 @@ fn build_test_app() -> axum::Router {
|
||||
async fn test_bridge_health_endpoint() {
|
||||
let app = build_test_app();
|
||||
let resp = app
|
||||
.oneshot(Request::builder().uri("/_bridge/health").body(Body::empty()).unwrap())
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.uri("/_bridge/health")
|
||||
.body(Body::empty())
|
||||
.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let json: serde_json::Value = serde_json::from_slice(&body).unwrap();
|
||||
assert_eq!(json["status"], "ok");
|
||||
assert_eq!(json["service"], "openfut-bridge");
|
||||
@@ -131,7 +144,9 @@ async fn test_bridge_placeholder_mode_returns_ok() {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let json: serde_json::Value = serde_json::from_slice(&body).unwrap();
|
||||
assert_eq!(json["status"], "ok");
|
||||
assert!(json["openfut_note"].is_string());
|
||||
@@ -150,7 +165,9 @@ async fn test_bridge_captures_endpoint_returns_list() {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let json: serde_json::Value = serde_json::from_slice(&body).unwrap();
|
||||
assert!(json["captures"].is_array());
|
||||
assert!(json["total"].is_number());
|
||||
@@ -170,7 +187,9 @@ async fn test_bridge_delete_captures() {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let json: serde_json::Value = serde_json::from_slice(&body).unwrap();
|
||||
assert!(json["deleted"].is_number());
|
||||
}
|
||||
@@ -188,7 +207,9 @@ async fn test_bridge_status_endpoint() {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let json: serde_json::Value = serde_json::from_slice(&body).unwrap();
|
||||
assert!(json["endpoints"].is_array());
|
||||
}
|
||||
@@ -208,15 +229,25 @@ async fn test_dashboard_returns_html() {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let ct = resp.headers().get("content-type").unwrap().to_str().unwrap();
|
||||
let ct = resp
|
||||
.headers()
|
||||
.get("content-type")
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap();
|
||||
assert!(ct.contains("text/html"), "expected text/html, got {ct}");
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let html = String::from_utf8(body.to_vec()).unwrap();
|
||||
assert!(html.contains("OpenFUT Dashboard"), "title missing");
|
||||
assert!(html.contains("const CORE ="), "core URL injection missing");
|
||||
// Placeholder URL injected in test mode
|
||||
assert!(html.contains("127.0.0.1:9999"), "core URL not injected");
|
||||
assert!(!html.contains("{{CORE_URL}}"), "template placeholder was not replaced");
|
||||
assert!(
|
||||
!html.contains("{{CORE_URL}}"),
|
||||
"template placeholder was not replaced"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -231,7 +262,9 @@ async fn test_dashboard_contains_key_sections() {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let html = String::from_utf8(body.to_vec()).unwrap();
|
||||
// Verify all major tab sections are present
|
||||
assert!(html.contains("tab-club"), "club tab missing");
|
||||
@@ -250,8 +283,14 @@ async fn test_dashboard_contains_key_sections() {
|
||||
assert!(html.contains("tab-statistics"), "statistics tab missing");
|
||||
assert!(html.contains("tab-catalog"), "card catalog tab missing");
|
||||
assert!(html.contains("tab-settings"), "settings tab missing");
|
||||
assert!(html.contains("tab-notifications"), "notifications tab missing");
|
||||
assert!(html.contains("tab-achievements"), "achievements tab missing");
|
||||
assert!(
|
||||
html.contains("tab-notifications"),
|
||||
"notifications tab missing"
|
||||
);
|
||||
assert!(
|
||||
html.contains("tab-achievements"),
|
||||
"achievements tab missing"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -272,5 +311,9 @@ async fn test_tls_cert_generation() {
|
||||
async fn test_tls_acceptor_construction() {
|
||||
let (cert_pem, key_pem) = openfut_bridge::tls::generate_self_signed_cert().unwrap();
|
||||
let acceptor = openfut_bridge::tls::make_tls_acceptor(&cert_pem, &key_pem);
|
||||
assert!(acceptor.is_ok(), "acceptor construction failed: {:?}", acceptor.err());
|
||||
assert!(
|
||||
acceptor.is_ok(),
|
||||
"acceptor construction failed: {:?}",
|
||||
acceptor.err()
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user