use crate::channels::telegram::flow::{
MAX_RICH_TRANSPORT_RETRIES, RichEditError, classify_rich_edit_error, is_transport_failure,
};
const TRANSPORT: &str =
"error sending request for url (https://api.telegram.org/bot123:SECRET/editMessageText)";
#[test]
fn a_transport_failure_is_not_a_fallback() {
assert_eq!(
classify_rich_edit_error(TRANSPORT),
RichEditError::Transport
);
assert_ne!(classify_rich_edit_error(TRANSPORT), RichEditError::Fallback);
}
#[test]
fn the_transport_shapes_seen_in_practice_all_classify() {
for msg in [
TRANSPORT,
"connection closed before message completed",
"connection reset by peer",
"tcp connect error: Connection refused (os error 61)",
"Broken pipe (os error 32)",
"dns error: failed to lookup address information",
"operation timed out",
] {
assert!(is_transport_failure(msg), "should be transport: {msg}");
assert_eq!(
classify_rich_edit_error(msg),
RichEditError::Transport,
"should classify as transport: {msg}"
);
}
}
#[test]
fn content_errors_still_fall_back() {
for msg in [
"Bad Request: can't parse entities",
"Bad Request: message text is empty",
"Bad Request: MESSAGE_TOO_LONG",
"Forbidden: bot was blocked by the user",
] {
assert!(!is_transport_failure(msg), "not transport: {msg}");
assert_eq!(
classify_rich_edit_error(msg),
RichEditError::Fallback,
"content errors must keep falling back: {msg}"
);
}
}
#[test]
fn rate_limits_are_untouched() {
for msg in [
"(429): Too Many Requests: retry after 17",
"Too Many Requests",
] {
assert_eq!(classify_rich_edit_error(msg), RichEditError::RateLimited);
}
}
#[test]
fn a_not_modified_response_is_still_a_no_op() {
assert_eq!(
classify_rich_edit_error("Bad Request: message is not modified"),
RichEditError::NotModified
);
}
#[test]
fn a_429_wins_over_transport_wording() {
assert_eq!(
classify_rich_edit_error("429 Too Many Requests while error sending request"),
RichEditError::RateLimited
);
}
#[test]
fn the_transport_retry_budget_is_bounded() {
const { assert!(MAX_RICH_TRANSPORT_RETRIES >= 1, "must retry at least once") };
const { assert!(MAX_RICH_TRANSPORT_RETRIES <= 10, "budget must stay small") };
}
#[test]
fn the_streak_downgrades_only_after_the_budget_is_spent() {
let retries_at = |streak: u8| streak <= MAX_RICH_TRANSPORT_RETRIES;
for streak in 1..=MAX_RICH_TRANSPORT_RETRIES {
assert!(
retries_at(streak),
"attempt {streak} should still retry rich"
);
}
assert!(
!retries_at(MAX_RICH_TRANSPORT_RETRIES + 1),
"the attempt past the budget must downgrade to HTML"
);
}