#![allow(clippy::unwrap_used)]
use super::*;
use rig_core::serve::{Observe, Origin};
#[test]
fn cancellation_and_terminal_observation_have_one_recording_boundary() {
for terminal_first in [false, true] {
let recorder = rig_cassette::effect_log::EffectLogRecorder::keeping_stream_events();
let recording = Recording::new(recorder.clone());
let id = EffectId::from_raw(0);
let kind = EffectKind::Custom {
kind: "test".into(),
payload: serde_json::Value::Null,
};
recording.begin(id, "test".into(), kind.clone(), Origin::default());
let observed = Arc::new(ObservedState::default());
let mut observer = WorldObserver {
adapter: None,
id,
recording: Some(recording.clone()),
published: None,
witness: None,
observed: observed.clone(),
};
let final_item = Ok(rig_core::streaming::Relayed::Done(Box::new(
rig_core::completion::CompletionResponse::new(
Vec::new(),
Default::default(),
rig_core::message::Origin::new("test.api", "test", ""),
serde_json::json!({}),
),
)));
let answer = rig_core::serve::StreamTap::new()
.observe(&final_item)
.unwrap();
if terminal_first {
observer.stream_item(&final_item, Some(&answer));
}
let original = observed.take_outcome();
assert_eq!(original.is_some(), terminal_first);
recording.resolve(id, original.unwrap_or_else(|| Err(cancelled())));
let closed = serde_json::to_value(recorder.log()).unwrap();
observer.stream_item(&final_item, Some(&answer));
observer.event(&rig_core::streaming::Item::Unknown(
serde_json::Value::Null.into(),
));
observer.stream_error(&cancelled());
observer.outcome(&answer);
observer.patch(&kind);
observer.discard("layer");
assert_eq!(serde_json::to_value(recorder.log()).unwrap(), closed);
assert!(!observed.is_discarded());
}
}
#[test]
fn a_despawn_from_the_outcome_observer_still_closes_the_record() {
use crate::bus::{Handlers, InFlight, PendingEffect, WorldOutcome};
use rig_core::effect::FamilyDescriptor;
let mut world = World::new();
crate::bus::BusPlugin::with_policy(Default::default()).install(&mut world);
let recorder = rig_cassette::effect_log::EffectLogRecorder::new();
Recording::install(&mut world, recorder.clone());
Handlers::with(&mut world, |handlers| {
handlers.register_open(
"open",
FamilyDescriptor::Custom {
kind: "test".into(),
},
)
})
.unwrap()
.unwrap();
world.add_observer(|added: On<Add, EffectOutcome>, mut commands: Commands| {
commands.entity(added.event().entity).despawn();
});
let kind = EffectKind::Custom {
kind: "test".into(),
payload: serde_json::Value::Null,
};
let effect = world.spawn(PendingEffect::new("open", kind)).id();
world.run_schedule(crate::bus::RigSchedule);
assert!(
world.get::<InFlight>(effect).is_some(),
"issued to the open key"
);
let answer = Outcome::Custom {
payload: serde_json::json!("answered"),
};
world
.entity_mut(effect)
.insert(WorldOutcome::new(Ok(answer.clone())));
world.run_schedule(crate::bus::RigSchedule);
assert!(
world.get_entity(effect).is_err(),
"the observer despawned the effect as its outcome landed"
);
let log = recorder.log();
assert_eq!(log.len(), 1, "the record closed: {log:?}");
let record = log.first().unwrap();
assert_eq!(
serde_json::to_value(&record.outcome).unwrap(),
serde_json::to_value(Ok::<_, ErrorReport>(answer)).unwrap(),
"the record holds the handler's answer, not a cancellation"
);
}