use super::*;
use std::error::Error as _;
use std::io::{Error as IoError, ErrorKind};
#[test]
fn user_message_collapses_traversal_into_the_miss_message() {
let miss = StaticError::NotFound("/etc/passwd".into());
let traversal = StaticError::Traversal("/../../etc/passwd".into());
assert_eq!(miss.user_message(), "not found");
assert_eq!(traversal.user_message(), miss.user_message());
}
#[test]
fn user_message_never_carries_the_offending_path() {
let secret = "deploy-secrets/id_rsa";
for error in [
StaticError::NotFound(secret.into()),
StaticError::Traversal(secret.into()),
StaticError::Config(secret.into()),
] {
assert!(
!error.user_message().contains(secret),
"user_message leaked its payload: {}",
error.user_message()
);
}
}
#[test]
fn user_message_reports_internal_failures_as_internal() {
let io = StaticError::Io(IoError::new(ErrorKind::PermissionDenied, "denied"));
let config = StaticError::Config("ETag is computed per response".into());
assert_eq!(io.user_message(), "internal server error");
assert_eq!(config.user_message(), "internal server error");
}
#[test]
fn display_keeps_the_detail_user_message_withholds() {
let path = "public/missing.html";
assert_eq!(
StaticError::NotFound(path.into()).to_string(),
format!("not found: {path}")
);
assert_eq!(
StaticError::Traversal(path.into()).to_string(),
format!("path traversal denied: {path}")
);
assert_eq!(
StaticError::Config("ETag is computed".into()).to_string(),
"invalid configuration: ETag is computed"
);
}
#[test]
fn display_of_an_io_error_includes_the_underlying_cause() {
let error = StaticError::Io(IoError::new(ErrorKind::NotFound, "no such file"));
assert_eq!(error.to_string(), "io error: no such file");
}
#[test]
fn only_the_io_variant_exposes_a_source() {
let io = StaticError::Io(IoError::other("inner"));
assert_eq!(io.source().map(ToString::to_string), Some("inner".into()));
for error in [
StaticError::NotFound("p".into()),
StaticError::Traversal("p".into()),
StaticError::Config("m".into()),
] {
assert!(error.source().is_none(), "unexpected source on {error}");
}
}
#[test]
fn an_io_error_converts_into_the_io_variant_preserving_its_kind() {
let error: StaticError = IoError::new(ErrorKind::PermissionDenied, "denied").into();
let StaticError::Io(inner) = &error else {
panic!("io::Error must convert into StaticError::Io, got: {error}");
};
assert_eq!(inner.kind(), ErrorKind::PermissionDenied);
}