diff --git a/crates/spacesh-proto/src/message.rs b/crates/spacesh-proto/src/message.rs index dc26265..3c682ba 100644 --- a/crates/spacesh-proto/src/message.rs +++ b/crates/spacesh-proto/src/message.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use crate::event::{EventRecord, MarkReadTarget}; use crate::ids::{GroupId, SurfaceId, WorkspaceId}; use crate::layout::LayoutNode; use crate::status::SurfaceState; @@ -116,6 +117,11 @@ pub enum Cmd { }, DeleteGroup { group_id: GroupId }, SetState { surface_id: SurfaceId, state: SurfaceState }, + EventLog { + #[serde(default, skip_serializing_if = "Option::is_none")] + limit: Option, + }, + MarkRead { target: MarkReadTarget }, Status, Shutdown, } @@ -134,6 +140,8 @@ pub enum Evt { GroupsChanged { groups: Vec }, SurfaceRestarted { surface_id: SurfaceId }, State { surface_id: SurfaceId, state: SurfaceState }, + Event { record: EventRecord }, + EventsRead { ids: Vec }, } #[cfg(test)] @@ -262,4 +270,77 @@ mod tests { let back: Envelope = serde_json::from_str(&j).unwrap(); assert_eq!(back, evt); } + + #[test] + fn event_log_cmd_round_trips() { + let env = Envelope::Req { id: 1, cmd: Cmd::EventLog { limit: Some(50) } }; + let j = serde_json::to_string(&env).unwrap(); + assert!(j.contains(r#""cmd":"event_log""#)); + let back: Envelope = serde_json::from_str(&j).unwrap(); + assert_eq!(back, env); + } + + #[test] + fn mark_read_cmd_round_trips() { + let env = Envelope::Req { + id: 2, + cmd: Cmd::MarkRead { target: crate::event::MarkReadTarget::All }, + }; + let j = serde_json::to_string(&env).unwrap(); + assert!(j.contains(r#""cmd":"mark_read""#)); + let back: Envelope = serde_json::from_str(&j).unwrap(); + assert_eq!(back, env); + } + + #[test] + fn event_evt_round_trips() { + let evt = Envelope::Evt(Evt::Event { + record: crate::event::EventRecord { + id: 3, + surface_id: SurfaceId("s_1".into()), + workspace_id: WorkspaceId("w_1".into()), + workspace_name: "p".into(), + agent_label: None, + kind: crate::event::EventKind::Done, + ts: 1, + read: false, + }, + }); + let j = serde_json::to_string(&evt).unwrap(); + assert!(j.contains(r#""evt":"event""#)); + let back: Envelope = serde_json::from_str(&j).unwrap(); + assert_eq!(back, evt); + } + + #[test] + fn events_read_evt_round_trips() { + let evt = Envelope::Evt(Evt::EventsRead { ids: vec![1, 2, 3] }); + let j = serde_json::to_string(&evt).unwrap(); + assert!(j.contains(r#""evt":"events_read""#)); + let back: Envelope = serde_json::from_str(&j).unwrap(); + assert_eq!(back, evt); + } + + #[test] + fn event_log_cmd_no_limit_round_trips() { + let env = Envelope::Req { id: 9, cmd: Cmd::EventLog { limit: None } }; + let j = serde_json::to_string(&env).unwrap(); + assert!(j.contains(r#""cmd":"event_log""#)); + assert!(j.contains(r#""args":{}"#), "no-limit serializes to empty args, got: {j}"); + let back: Envelope = serde_json::from_str(&j).unwrap(); + assert_eq!(back, env); + } + + #[test] + fn mark_read_cmd_ids_and_surface_round_trip() { + let ids = Envelope::Req { id: 10, cmd: Cmd::MarkRead { target: crate::event::MarkReadTarget::Ids(vec![1, 2]) } }; + let j = serde_json::to_string(&ids).unwrap(); + assert!(j.contains(r#""target":"ids""#)); + assert_eq!(serde_json::from_str::(&j).unwrap(), ids); + + let surf = Envelope::Req { id: 11, cmd: Cmd::MarkRead { target: crate::event::MarkReadTarget::Surface(SurfaceId("s_3".into())) } }; + let j = serde_json::to_string(&surf).unwrap(); + assert!(j.contains(r#""target":"surface""#)); + assert_eq!(serde_json::from_str::(&j).unwrap(), surf); + } }