use super::{Completion, Pending, answered};
use crate::link::calls::{CallError, CallExecution, CallReply};
use liminal::protocol::Frame;
type TestResult = Result<(), Box<dyn std::error::Error>>;
#[derive(Debug)]
struct Unretirable;
impl CallExecution for Unretirable {
fn finish(&mut self) -> Result<(), CallError> {
Err(CallError::Unavailable)
}
}
fn refusal(code: u16) -> Frame {
Frame::ConversationError {
flags: 0,
stream_id: 2,
conversation_id: 1,
reason_code: code,
message: None,
}
}
#[test]
fn a_retirement_that_fails_never_withholds_the_answer_in_hand() -> TestResult {
let mut pending = Pending {
subject: "embed.bge".to_owned(),
correlation: (2, 1),
execution: Box::new(Unretirable),
};
let completion = Completion {
id: 7,
subject: "embed.bge".to_owned(),
answer: Ok(CallReply::new(7, refusal(42))?),
};
let reply = answered(&mut pending, completion, |_| Ok(()))
.map_err(|error| format!("the answer in hand was withheld: {error}"))?;
assert_eq!(reply.id(), 7);
assert!(matches!(
reply.into_frame(),
Frame::ConversationError {
reason_code: 42,
..
}
));
Ok(())
}
#[test]
fn a_subject_that_differs_from_the_call_is_a_correlation_refusal() -> TestResult {
let mut pending = Pending {
subject: "embed.bge".to_owned(),
correlation: (2, 1),
execution: Box::new(Unretirable),
};
let completion = Completion {
id: 7,
subject: "embed.other".to_owned(),
answer: Ok(CallReply::new(7, refusal(1))?),
};
assert_eq!(
answered(&mut pending, completion, |_| Ok(())).err(),
Some(CallError::Correlation)
);
Ok(())
}