test(axum): prove registry dispatch boundary
Exercise registered sync and async handles through public dispatch_async, prove membership semantics, and serialize shared-boundary tests so mutation workers remain deterministic. req: axum_integration/003 req: public_api/001
This commit is contained in:
@@ -19,6 +19,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use tower::ServiceExt;
|
||||
|
||||
static MUTATION_CALLS: AtomicUsize = AtomicUsize::new(0);
|
||||
static BOUNDARY_TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
|
||||
|
||||
async fn bounded_mutation(_: InteractionRequest) -> StatusCode {
|
||||
MUTATION_CALLS.fetch_add(1, Ordering::SeqCst);
|
||||
@@ -40,6 +41,9 @@ async fn multipart_mutation(request: InteractionRequest) -> StatusCode {
|
||||
#[tokio::test]
|
||||
async fn interaction_boundary_honors_media_type_and_host_body_limit() {
|
||||
// test req: security/003
|
||||
let _guard = BOUNDARY_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|error| error.into_inner());
|
||||
MUTATION_CALLS.store(0, Ordering::SeqCst);
|
||||
let app = Router::new()
|
||||
.route("/mutate", post(bounded_mutation))
|
||||
@@ -100,6 +104,9 @@ async fn interaction_boundary_honors_media_type_and_host_body_limit() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn interaction_boundary_extracts_multipart_fields_and_files() {
|
||||
let _guard = BOUNDARY_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|error| error.into_inner());
|
||||
let boundary = "hemx-boundary";
|
||||
let body = concat!(
|
||||
"--hemx-boundary\r\n",
|
||||
@@ -134,6 +141,9 @@ async fn interaction_boundary_extracts_multipart_fields_and_files() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn interaction_boundary_skips_unnamed_parts_and_rejects_invalid_multipart() {
|
||||
let _guard = BOUNDARY_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|error| error.into_inner());
|
||||
let accepted = concat!(
|
||||
"--b\r\n",
|
||||
"Content-Disposition: form-data; filename=\"ignored.txt\"\r\n\r\n",
|
||||
@@ -781,6 +791,32 @@ fn interactions_dispatch_by_checked_handle() {
|
||||
assert_eq!(response.batch.ops, vec![title.text("Hello")]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn registry_contains_registered_sync_and_async_handles_and_async_falls_back_to_sync() {
|
||||
let sync = Handle::<()>::new(21);
|
||||
let asynchronous = Handle::<()>::new(22);
|
||||
let registry = interactions(BuildFingerprint(55))
|
||||
.on(sync, |_| Slot::<String>::new(1).text("sync"))
|
||||
.on_async(asynchronous, |_| async {
|
||||
Slot::<String>::new(1).text("async")
|
||||
});
|
||||
|
||||
assert!(registry.contains(sync.id().id));
|
||||
assert!(registry.contains(asynchronous.id().id));
|
||||
assert!(!registry.contains(99));
|
||||
|
||||
let sync_response = InteractionRequest::from(InteractionForm::for_handle(sync, []))
|
||||
.dispatch_async(registry)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(sync_response.batch.fingerprint, BuildFingerprint(55));
|
||||
assert_eq!(
|
||||
sync_response.batch.ops,
|
||||
vec![Slot::<String>::new(1).text("sync")]
|
||||
);
|
||||
// test req: axum_integration/003 req: public_api/001
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interactions_reject_unknown_handle_ids() {
|
||||
let request = InteractionRequest::from(InteractionForm::new(9, []));
|
||||
|
||||
Reference in New Issue
Block a user