bxcore: a turn's speaker, SessionUpdated's turn, the session-state messages
Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
//! The eight memory messages against byte-exact fixtures, each refusing an unknown key (M5a spec,
|
||||
//! section 7). Do not edit these or the fixtures.
|
||||
//! The memory messages against byte-exact fixtures, each refusing an unknown key: the eight of M5a
|
||||
//! (M5a spec, section 7) and the session-state question of M5c (M5c spec, section 7). Do not edit
|
||||
//! these or the fixtures.
|
||||
|
||||
use bxcore::{
|
||||
CallId, DataClass, Empty, Envelope, MemoryAdmin, MemoryAdminReply, MemoryBlockReply,
|
||||
MemoryCall, MemoryCommand, Message, Reindexed, SessionId, SessionUpdated, ToolRequest,
|
||||
MemoryCall, MemoryCommand, Message, Reindexed, SessionId, SessionState, SessionStateReply,
|
||||
SessionUpdated, ToolRequest,
|
||||
};
|
||||
|
||||
const SESSION: &str = "mm-r0000000000000000000000001";
|
||||
@@ -53,6 +55,7 @@ fn the_eight_messages() {
|
||||
1,
|
||||
Message::SessionUpdated(SessionUpdated {
|
||||
session: SessionId::new(SESSION).unwrap(),
|
||||
turn: 3,
|
||||
}),
|
||||
);
|
||||
check(
|
||||
@@ -96,6 +99,58 @@ fn the_eight_messages() {
|
||||
);
|
||||
}
|
||||
|
||||
/// `turn` has no default: a `session_updated` without it, as a `loopd` from before M5c sent, is
|
||||
/// refused, never read as turn 0 (M5c spec, section 5).
|
||||
#[test]
|
||||
fn a_session_updated_without_turn_is_refused() {
|
||||
let old = r#"{"v":1,"id":1,"final":true,"msg":{"kind":"session_updated","body":{"session":"mm-r0000000000000000000000001"}}}"#;
|
||||
let error = serde_json::from_str::<Envelope>(old).unwrap_err();
|
||||
assert!(
|
||||
error.to_string().contains("missing field `turn`"),
|
||||
"{error}"
|
||||
);
|
||||
}
|
||||
|
||||
/// `memoryd` asks `brokerd` for a session's state on `state.sock` (M5c spec, section 7).
|
||||
#[test]
|
||||
fn the_session_state_messages() {
|
||||
check(
|
||||
"session_state.json",
|
||||
1,
|
||||
Message::SessionState(SessionState {
|
||||
session: SessionId::new(SESSION).unwrap(),
|
||||
}),
|
||||
);
|
||||
check(
|
||||
"session_state_reply.json",
|
||||
1,
|
||||
Message::SessionStateReply(SessionStateReply {
|
||||
class: DataClass::Private,
|
||||
untrusted: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/// Neither field of the reply has a default: a reply without one is refused, never read as a
|
||||
/// clean or `public` session.
|
||||
#[test]
|
||||
fn a_session_state_reply_needs_both_fields() {
|
||||
let text = fixture("session_state_reply.json");
|
||||
for (field, without) in [
|
||||
("class", text.replacen(r#""class":"private","#, "", 1)),
|
||||
("untrusted", text.replacen(r#","untrusted":true"#, "", 1)),
|
||||
] {
|
||||
assert_ne!(without, text, "{field}: the fixture holds the field");
|
||||
let error = serde_json::from_str::<Envelope>(&without).unwrap_err();
|
||||
assert!(
|
||||
error
|
||||
.to_string()
|
||||
.contains(&format!("missing field `{field}`")),
|
||||
"{field}: {error}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_command_has_its_name() {
|
||||
for (command, name) in [
|
||||
|
||||
Reference in New Issue
Block a user