#![expect(
clippy::unwrap_used,
clippy::uninlined_format_args,
reason = "legacy endpoint tests use static fixtures; cleanup is tracked in policy/clippy-debt.toml"
)]
use axum::{
body::Body,
http::{Request, StatusCode},
};
use tower::ServiceExt;
mod common;
#[tokio::test]
async fn test_404_for_unknown_route() {
let app = common::create_test_router();
let response = app
.oneshot(
Request::builder()
.extension(axum::extract::ConnectInfo(std::net::SocketAddr::from((
[127, 0, 0, 1],
8080,
))))
.uri("/this/route/does/not/exist")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(
response.status(),
StatusCode::NOT_FOUND,
"Unknown routes should return 404 Not Found"
);
}
#[tokio::test]
async fn test_cors_headers_present() {
let app = common::create_test_router();
let response = app
.oneshot(
Request::builder()
.extension(axum::extract::ConnectInfo(std::net::SocketAddr::from((
[127, 0, 0, 1],
8080,
))))
.uri("/health")
.header("Origin", "http://example.com")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
let cors_header = response.headers().get("access-control-allow-origin");
assert!(
cors_header.is_some(),
"CORS headers should be present in responses"
);
}
#[tokio::test]
async fn test_content_type_validation() {
let app = common::create_test_router();
let response = app
.oneshot(
Request::builder()
.extension(axum::extract::ConnectInfo(std::net::SocketAddr::from((
[127, 0, 0, 1],
8080,
))))
.uri("/hl7/parse")
.method("POST")
.header("Content-Type", "text/plain")
.body(Body::from("some text"))
.unwrap(),
)
.await
.unwrap();
assert!(
response.status() != StatusCode::OK,
"Wrong content type should be rejected"
);
}
#[tokio::test]
async fn test_large_request_handling() {
let app = common::create_test_router();
let mut large_message = String::from(
"MSH|^~\\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231119120000||ADT^A01|MSG001|P|2.5\r",
);
for i in 0..100 {
large_message.push_str(&format!("NTE|{}||This is note number {}\r", i, i));
}
let request_body = serde_json::json!({
"message": large_message,
"mllp_framed": false
});
let response = app
.oneshot(
Request::builder()
.extension(axum::extract::ConnectInfo(std::net::SocketAddr::from((
[127, 0, 0, 1],
8080,
))))
.uri("/hl7/parse")
.method("POST")
.header("Content-Type", "application/json")
.body(Body::from(serde_json::to_string(&request_body).unwrap()))
.unwrap(),
)
.await
.unwrap();
assert!(
response.status() == StatusCode::OK || response.status().is_client_error(),
"Should either parse large message or reject it gracefully"
);
}
#[tokio::test]
async fn test_missing_content_type_header() {
let app = common::create_test_router();
let response = app
.oneshot(
Request::builder()
.extension(axum::extract::ConnectInfo(std::net::SocketAddr::from((
[127, 0, 0, 1],
8080,
))))
.uri("/hl7/parse")
.method("POST")
.body(Body::from("{}"))
.unwrap(),
)
.await
.unwrap();
assert!(
response.status() != StatusCode::INTERNAL_SERVER_ERROR,
"Missing content-type should not cause 500 error"
);
}
#[tokio::test]
async fn test_options_request_for_cors() {
let app = common::create_test_router();
let response = app
.oneshot(
Request::builder()
.extension(axum::extract::ConnectInfo(std::net::SocketAddr::from((
[127, 0, 0, 1],
8080,
))))
.uri("/hl7/parse")
.method("OPTIONS")
.header("Origin", "http://example.com")
.header("Access-Control-Request-Method", "POST")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_ne!(
response.status(),
StatusCode::INTERNAL_SERVER_ERROR,
"OPTIONS request should be handled properly"
);
}
#[tokio::test]
async fn test_gzip_compression_accepted() {
let app = common::create_test_router();
let response = app
.oneshot(
Request::builder()
.extension(axum::extract::ConnectInfo(std::net::SocketAddr::from((
[127, 0, 0, 1],
8080,
))))
.uri("/health")
.header("Accept-Encoding", "gzip")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(
response.status(),
StatusCode::OK,
"Compression header should not cause errors"
);
}