diff --git a/core/conversations/src/conversation.rs b/core/conversations/src/conversation.rs index 6f17892..a440aa4 100644 --- a/core/conversations/src/conversation.rs +++ b/core/conversations/src/conversation.rs @@ -2,6 +2,7 @@ mod direct_v1; pub mod group_v1; mod group_v2; mod privatev1; +mod privatev2; pub use crate::errors::ChatError; use crate::outcomes::ConvoOutcome; @@ -11,6 +12,7 @@ pub use direct_v1::DirectV1Convo; pub use group_v1::GroupV1Convo; pub use group_v2::GroupV2Convo; pub use privatev1::PrivateV1Convo; +pub use privatev2::PrivateV2Convo; use shared_traits::IdentIdRef; pub type ConversationId = String; diff --git a/core/conversations/src/conversation/privatev2.rs b/core/conversations/src/conversation/privatev2.rs new file mode 100644 index 0000000..4f2095d --- /dev/null +++ b/core/conversations/src/conversation/privatev2.rs @@ -0,0 +1,57 @@ +use chat_proto::logoschat::encryption::EncryptedPayload; +use shared_traits::IdentIdRef; + +use crate::{ + ChatError, ExternalServices, + conversation::{ConversationIdRef, Convo, GroupConvo, GroupV1Convo, Identified}, + service_context::ServiceContext, +}; + +type DelegateGroup = GroupV1Convo; + +#[derive(Debug)] +pub struct PrivateV2Convo { + inner_group: DelegateGroup, +} + +impl PrivateV2Convo { + pub fn new( + cx: &mut ServiceContext, + participant: IdentIdRef, + ) -> Result { + let mut inner_group = DelegateGroup::new(cx)?; + inner_group.add_member(cx, &[participant])?; + Ok(Self { inner_group }) + } +} + +impl Identified for PrivateV2Convo { + fn id(&self) -> ConversationIdRef<'_> { + self.inner_group.id() + } +} + +impl Convo for PrivateV2Convo +where + S: ExternalServices, +{ + fn send_content( + &mut self, + cx: &mut ServiceContext, + content: &[u8], + ) -> Result<(), super::ChatError> { + self.inner_group.send_content(cx, content) + } + + fn handle_frame( + &mut self, + cx: &mut ServiceContext, + enc: EncryptedPayload, + ) -> Result { + self.inner_group.handle_frame(cx, enc) + } + + fn wakeup(&mut self, service_ctx: &mut ServiceContext) -> Result<(), ChatError> { + self.inner_group.wakeup(service_ctx) + } +} diff --git a/core/integration_tests_core/tests/test_private_v2.rs b/core/integration_tests_core/tests/test_private_v2.rs new file mode 100644 index 0000000..da050d1 --- /dev/null +++ b/core/integration_tests_core/tests/test_private_v2.rs @@ -0,0 +1,43 @@ +use integration_tests_core::TestHarness; +use tracing::info; + +#[test] +fn happypath_roundtrip() { + let _ = tracing_subscriber::fmt() + .with_max_level(tracing::Level::INFO) + .with_test_writer() + .try_init(); + + const S_M1: &[u8] = b"Marco"; + const R_M1: &[u8] = b"Polo"; + + // Initialize TestHarness with 2 clients + let mut harness = TestHarness::<2>::new(|_, _| {}); + + //Saro Create Convo + let particpant = harness.raya().addr(); + let convo_id = harness + .saro() + .create_direct_convo_v1(&[&particpant]) + .expect("saro create group"); + + // Carry the invite through (commit, WelcomeReady, routing to Raya's inbox, + // accept_welcome); settle until Raya has joined. + harness.process_until_label("Saro Send", |h| h.raya().convo_count() == 1); + + // Saro sends a message; settle until Raya receives it. + info!(target: "chat", "Saro -> sending: {S_M1:?}"); + harness + .saro() + .send_content(&convo_id, S_M1) + .expect("saro send"); + + harness.process_until(|h| h.raya().check(&convo_id, S_M1)); + + // Raya replies; settle until Saro receives it. + info!(target: "chat", "Raya -> sending:{R_M1:?}"); + harness.raya().send_content(&convo_id, R_M1).unwrap(); + harness.process_until(|h| h.saro().check(&convo_id, R_M1)); + + assert!(harness.saro().check(&convo_id, R_M1)); +}