use alloc::vec;
use super::{
ObserverProgressRetireDecision, ObserverProgressRetireError, ObserverProgressTrackDecision,
ObserverRecoveryAggregate,
};
fn three_with_an_arm() -> Result<ObserverRecoveryAggregate, &'static str> {
ObserverRecoveryAggregate::restore(&[(1, 4), (2, 5), (3, 6)], &[(3, 6)])
.map_err(|_| "the fixture's restore was refused")
}
#[test]
fn retire_removes_exactly_its_row_and_leaves_every_other_row_and_arm() -> Result<(), &'static str> {
let ObserverProgressRetireDecision::Commit(transaction) = three_with_an_arm()?.decide_retire(2)
else {
return Err("the retirement of a tracked, unarmed conversation was refused");
};
assert_eq!(transaction.conversation_id(), 2);
let aggregate = transaction.commit();
assert_eq!(aggregate.progress_rows(), vec![(1, 4), (3, 6)]);
assert_eq!(aggregate.armed_rows(), vec![(3, 6)]);
assert_eq!(aggregate.observer_progress(2), None);
Ok(())
}
#[test]
fn an_untracked_conversation_refuses_unknown_with_the_aggregate_unchanged()
-> Result<(), &'static str> {
let before = three_with_an_arm()?;
let decision = three_with_an_arm()?.decide_retire(9);
assert_eq!(
decision,
ObserverProgressRetireDecision::Refuse {
aggregate: before,
error: ObserverProgressRetireError::ConversationUnknown { conversation_id: 9 },
}
);
Ok(())
}
#[test]
fn an_armed_conversation_refuses_armed_with_the_aggregate_unchanged() -> Result<(), &'static str> {
let before = three_with_an_arm()?;
let decision = three_with_an_arm()?.decide_retire(3);
assert_eq!(
decision,
ObserverProgressRetireDecision::Refuse {
aggregate: before,
error: ObserverProgressRetireError::Armed {
conversation_id: 3,
epoch: 6,
},
}
);
Ok(())
}
#[test]
fn an_aborted_retirement_keeps_the_row() -> Result<(), &'static str> {
let before = three_with_an_arm()?;
let ObserverProgressRetireDecision::Commit(transaction) = three_with_an_arm()?.decide_retire(1)
else {
return Err("the retirement of a tracked, unarmed conversation was refused");
};
assert_eq!(transaction.abort(), before);
Ok(())
}
#[test]
fn the_aggregate_does_not_remember_a_retired_id() -> Result<(), &'static str> {
let ObserverProgressRetireDecision::Commit(transaction) = three_with_an_arm()?.decide_retire(1)
else {
return Err("the retirement of a tracked, unarmed conversation was refused");
};
let retired = transaction.commit();
let ObserverProgressTrackDecision::Commit(track) = retired.decide_track(1, 0) else {
return Err("a retired id was refused a fresh track");
};
assert_eq!(track.commit().observer_progress(1), Some(0));
Ok(())
}