Skip to content

Commit 87e08a1

Browse files
committed
Add testcase
1 parent c386459 commit 87e08a1

3 files changed

Lines changed: 1007 additions & 4 deletions

File tree

crates/vespera/src/multipart.rs

Lines changed: 153 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,9 @@ impl std::error::Error for TypedMultipartError {}
135135
impl IntoResponse for TypedMultipartError {
136136
fn into_response(self) -> Response {
137137
let status = match &self {
138-
Self::InvalidRequest { .. } | Self::InvalidRequestBody { .. } => {
139-
StatusCode::BAD_REQUEST
140-
}
141-
Self::MissingField { .. }
138+
Self::InvalidRequest { .. }
139+
| Self::InvalidRequestBody { .. }
140+
| Self::MissingField { .. }
142141
| Self::DuplicateField { .. }
143142
| Self::UnknownField { .. }
144143
| Self::InvalidEnumValue { .. }
@@ -507,6 +506,8 @@ impl<S: Send + Sync> TryFromFieldWithState<S> for tempfile::NamedTempFile {
507506
#[cfg(test)]
508507
mod tests {
509508
use super::*;
509+
use axum::http::StatusCode;
510+
use axum::response::IntoResponse;
510511

511512
#[test]
512513
fn test_str_to_bool_truthy() {
@@ -533,6 +534,8 @@ mod tests {
533534
}
534535
}
535536

537+
// ─── Display tests for all error variants ───────────────────────────
538+
536539
#[test]
537540
fn test_error_display() {
538541
let err = TypedMultipartError::MissingField {
@@ -559,4 +562,150 @@ mod tests {
559562
"Wrong type for field `age` (expected i32): invalid digit"
560563
);
561564
}
565+
566+
#[test]
567+
fn test_error_display_duplicate_field() {
568+
let err = TypedMultipartError::DuplicateField {
569+
field_name: "email".to_string(),
570+
};
571+
assert_eq!(err.to_string(), "Duplicate field: `email`");
572+
}
573+
574+
#[test]
575+
fn test_error_display_unknown_field() {
576+
let err = TypedMultipartError::UnknownField {
577+
field_name: "foo".to_string(),
578+
};
579+
assert_eq!(err.to_string(), "Unknown field: `foo`");
580+
}
581+
582+
#[test]
583+
fn test_error_display_invalid_enum_value() {
584+
let err = TypedMultipartError::InvalidEnumValue {
585+
field_name: "status".to_string(),
586+
value: "maybe".to_string(),
587+
};
588+
assert_eq!(
589+
err.to_string(),
590+
"Invalid enum value `maybe` for field `status`"
591+
);
592+
}
593+
594+
#[test]
595+
fn test_error_display_nameless_field() {
596+
let err = TypedMultipartError::NamelessField;
597+
assert_eq!(err.to_string(), "Encountered a field without a name");
598+
}
599+
600+
#[test]
601+
fn test_error_display_other() {
602+
let err = TypedMultipartError::Other {
603+
source: "something went wrong".to_string(),
604+
};
605+
assert_eq!(err.to_string(), "something went wrong");
606+
}
607+
608+
// ─── IntoResponse status code tests ─────────────────────────────────
609+
610+
#[test]
611+
fn test_into_response_duplicate_field() {
612+
let err = TypedMultipartError::DuplicateField {
613+
field_name: "x".to_string(),
614+
};
615+
let resp = err.into_response();
616+
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
617+
}
618+
619+
#[test]
620+
fn test_into_response_unknown_field() {
621+
let err = TypedMultipartError::UnknownField {
622+
field_name: "x".to_string(),
623+
};
624+
let resp = err.into_response();
625+
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
626+
}
627+
628+
#[test]
629+
fn test_into_response_invalid_enum_value() {
630+
let err = TypedMultipartError::InvalidEnumValue {
631+
field_name: "x".to_string(),
632+
value: "bad".to_string(),
633+
};
634+
let resp = err.into_response();
635+
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
636+
}
637+
638+
#[test]
639+
fn test_into_response_nameless_field() {
640+
let err = TypedMultipartError::NamelessField;
641+
let resp = err.into_response();
642+
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
643+
}
644+
645+
#[test]
646+
fn test_into_response_wrong_field_type() {
647+
let err = TypedMultipartError::WrongFieldType {
648+
field_name: "age".to_string(),
649+
wanted: "i32".to_string(),
650+
source: "err".to_string(),
651+
};
652+
let resp = err.into_response();
653+
assert_eq!(resp.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
654+
}
655+
656+
#[test]
657+
fn test_into_response_field_too_large() {
658+
let err = TypedMultipartError::FieldTooLarge {
659+
field_name: "file".to_string(),
660+
limit_bytes: 100,
661+
};
662+
let resp = err.into_response();
663+
assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
664+
}
665+
666+
#[test]
667+
fn test_into_response_other() {
668+
let err = TypedMultipartError::Other {
669+
source: "err".to_string(),
670+
};
671+
let resp = err.into_response();
672+
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
673+
}
674+
675+
#[test]
676+
fn test_into_response_missing_field() {
677+
let err = TypedMultipartError::MissingField {
678+
field_name: "x".to_string(),
679+
};
680+
let resp = err.into_response();
681+
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
682+
}
683+
684+
// ─── Error trait ────────────────────────────────────────────────────
685+
686+
#[test]
687+
fn test_error_trait_is_implemented() {
688+
let err: Box<dyn std::error::Error> = Box::new(TypedMultipartError::Other {
689+
source: "test".to_string(),
690+
});
691+
assert_eq!(err.to_string(), "test");
692+
}
693+
694+
// ─── TypedMultipart Deref / DerefMut ────────────────────────────────
695+
696+
#[test]
697+
fn test_typed_multipart_deref() {
698+
let tm = TypedMultipart("hello".to_string());
699+
// Deref: &TypedMultipart<String> → &String
700+
assert_eq!(&*tm, "hello");
701+
assert_eq!(tm.len(), 5); // auto-deref to String method
702+
}
703+
704+
#[test]
705+
fn test_typed_multipart_deref_mut() {
706+
let mut tm = TypedMultipart(vec![1, 2, 3]);
707+
// DerefMut: &mut TypedMultipart<Vec<i32>> → &mut Vec<i32>
708+
tm.push(4);
709+
assert_eq!(&*tm, &[1, 2, 3, 4]);
710+
}
562711
}

0 commit comments

Comments
 (0)