mirror of
https://github.com/chatmail/core.git
synced 2026-05-09 01:46:30 +03:00
api: add CallState
This commit is contained in:
130
src/calls.rs
130
src/calls.rs
@@ -33,10 +33,20 @@ use tokio::time::sleep;
|
|||||||
/// as the callee won't start the call afterwards.
|
/// as the callee won't start the call afterwards.
|
||||||
const RINGING_SECONDS: i64 = 60;
|
const RINGING_SECONDS: i64 = 60;
|
||||||
|
|
||||||
/// For persisting parameters in the call, we use Param::Arg*
|
// For persisting parameters in the call, we use Param::Arg*
|
||||||
|
|
||||||
const CALL_ACCEPTED_TIMESTAMP: Param = Param::Arg;
|
const CALL_ACCEPTED_TIMESTAMP: Param = Param::Arg;
|
||||||
const CALL_ENDED_TIMESTAMP: Param = Param::Arg4;
|
const CALL_ENDED_TIMESTAMP: Param = Param::Arg4;
|
||||||
|
|
||||||
|
/// Set if incoming call was ended explicitly
|
||||||
|
/// by the other side before we accepted it.
|
||||||
|
///
|
||||||
|
/// It is used to distinguish "ended" calls
|
||||||
|
/// that are rejected by us from the calls
|
||||||
|
/// cancelled by the other side
|
||||||
|
/// immediately after ringing started.
|
||||||
|
const CALL_CANCELLED_TIMESTAMP: Param = Param::Arg2;
|
||||||
|
|
||||||
/// Information about the status of a call.
|
/// Information about the status of a call.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct CallInfo {
|
pub struct CallInfo {
|
||||||
@@ -109,12 +119,38 @@ impl CallInfo {
|
|||||||
self.msg.param.exists(CALL_ACCEPTED_TIMESTAMP)
|
self.msg.param.exists(CALL_ACCEPTED_TIMESTAMP)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the call is missed
|
||||||
|
/// because the caller cancelled it
|
||||||
|
/// explicitly before ringing stopped.
|
||||||
|
///
|
||||||
|
/// For outgoing calls this means
|
||||||
|
/// the receiver has rejected the call
|
||||||
|
/// explicitly.
|
||||||
|
pub fn is_cancelled(&self) -> bool {
|
||||||
|
self.msg.param.exists(CALL_CANCELLED_TIMESTAMP)
|
||||||
|
}
|
||||||
|
|
||||||
async fn mark_as_ended(&mut self, context: &Context) -> Result<()> {
|
async fn mark_as_ended(&mut self, context: &Context) -> Result<()> {
|
||||||
self.msg.param.set_i64(CALL_ENDED_TIMESTAMP, time());
|
self.msg.param.set_i64(CALL_ENDED_TIMESTAMP, time());
|
||||||
self.msg.update_param(context).await?;
|
self.msg.update_param(context).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Explicitly mark the call as cancelled.
|
||||||
|
///
|
||||||
|
/// For incoming calls this should be called
|
||||||
|
/// when "call ended" message is received
|
||||||
|
/// from the caller before we picked up the call.
|
||||||
|
/// In this case the call becomes "missed" early
|
||||||
|
/// before the ringing timeout.
|
||||||
|
async fn mark_as_cancelled(&mut self, context: &Context) -> Result<()> {
|
||||||
|
let now = time();
|
||||||
|
self.msg.param.set_i64(CALL_ENDED_TIMESTAMP, now);
|
||||||
|
self.msg.param.set_i64(CALL_CANCELLED_TIMESTAMP, now);
|
||||||
|
self.msg.update_param(context).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the call is ended.
|
/// Returns true if the call is ended.
|
||||||
pub fn is_ended(&self) -> bool {
|
pub fn is_ended(&self) -> bool {
|
||||||
self.msg.param.exists(CALL_ENDED_TIMESTAMP)
|
self.msg.param.exists(CALL_ENDED_TIMESTAMP)
|
||||||
@@ -209,15 +245,17 @@ impl Context {
|
|||||||
info!(self, "Call already ended");
|
info!(self, "Call already ended");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
call.mark_as_ended(self).await?;
|
|
||||||
|
|
||||||
if !call.is_accepted() {
|
if !call.is_accepted() {
|
||||||
if call.is_incoming() {
|
if call.is_incoming() {
|
||||||
|
call.mark_as_ended(self).await?;
|
||||||
call.update_text(self, "Declined call").await?;
|
call.update_text(self, "Declined call").await?;
|
||||||
} else {
|
} else {
|
||||||
|
call.mark_as_cancelled(self).await?;
|
||||||
call.update_text(self, "Cancelled call").await?;
|
call.update_text(self, "Cancelled call").await?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
call.mark_as_ended(self).await?;
|
||||||
call.update_text_duration(self).await?;
|
call.update_text_duration(self).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,10 +284,11 @@ impl Context {
|
|||||||
sleep(Duration::from_secs(wait)).await;
|
sleep(Duration::from_secs(wait)).await;
|
||||||
let mut call = context.load_call_by_id(call_id).await?;
|
let mut call = context.load_call_by_id(call_id).await?;
|
||||||
if !call.is_accepted() && !call.is_ended() {
|
if !call.is_accepted() && !call.is_ended() {
|
||||||
call.mark_as_ended(&context).await?;
|
|
||||||
if call.is_incoming() {
|
if call.is_incoming() {
|
||||||
|
call.mark_as_cancelled(&context).await?;
|
||||||
call.update_text(&context, "Missed call").await?;
|
call.update_text(&context, "Missed call").await?;
|
||||||
} else {
|
} else {
|
||||||
|
call.mark_as_ended(&context).await?;
|
||||||
call.update_text(&context, "Cancelled call").await?;
|
call.update_text(&context, "Cancelled call").await?;
|
||||||
}
|
}
|
||||||
context.emit_msgs_changed(call.msg.chat_id, call_id);
|
context.emit_msgs_changed(call.msg.chat_id, call_id);
|
||||||
@@ -332,23 +371,27 @@ impl Context {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
call.mark_as_ended(self).await?;
|
|
||||||
if !call.is_accepted() {
|
if !call.is_accepted() {
|
||||||
if call.is_incoming() {
|
if call.is_incoming() {
|
||||||
if from_id == ContactId::SELF {
|
if from_id == ContactId::SELF {
|
||||||
|
call.mark_as_ended(self).await?;
|
||||||
call.update_text(self, "Declined call").await?;
|
call.update_text(self, "Declined call").await?;
|
||||||
} else {
|
} else {
|
||||||
|
call.mark_as_cancelled(self).await?;
|
||||||
call.update_text(self, "Missed call").await?;
|
call.update_text(self, "Missed call").await?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// outgoing
|
// outgoing
|
||||||
if from_id == ContactId::SELF {
|
if from_id == ContactId::SELF {
|
||||||
|
call.mark_as_cancelled(self).await?;
|
||||||
call.update_text(self, "Cancelled call").await?;
|
call.update_text(self, "Cancelled call").await?;
|
||||||
} else {
|
} else {
|
||||||
|
call.mark_as_ended(self).await?;
|
||||||
call.update_text(self, "Declined call").await?;
|
call.update_text(self, "Declined call").await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
call.mark_as_ended(self).await?;
|
||||||
call.update_text_duration(self).await?;
|
call.update_text_duration(self).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,6 +444,85 @@ fn sdp_has_video(sdp: &str) -> Result<bool> {
|
|||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// State of the call for display in the message bubble.
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum CallState {
|
||||||
|
/// Fresh incoming or outgoing call that is still ringing.
|
||||||
|
///
|
||||||
|
/// There is no separate state for outgoing call
|
||||||
|
/// that has been dialled but not ringing on the other side yet
|
||||||
|
/// as we don't know whether the other side received our call.
|
||||||
|
Alerting,
|
||||||
|
|
||||||
|
/// Active call.
|
||||||
|
Active,
|
||||||
|
|
||||||
|
/// Completed call that was once active
|
||||||
|
/// and then was terminated for any reason.
|
||||||
|
Completed {
|
||||||
|
/// Call duration in seconds.
|
||||||
|
duration: i64,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Incoming call that was not picked up within a timeout
|
||||||
|
/// or was explicitly ended by the caller before we picked up.
|
||||||
|
Missed,
|
||||||
|
|
||||||
|
/// Incoming call that was explicitly ended on our side
|
||||||
|
/// before picking up or outgoing call
|
||||||
|
/// that was declined before the timeout.
|
||||||
|
Declined,
|
||||||
|
|
||||||
|
/// Outgoing call that has been cancelled on our side
|
||||||
|
/// before receiving a response.
|
||||||
|
///
|
||||||
|
/// Incoming calls cannot be cancelled,
|
||||||
|
/// on the receiver side cancelled calls
|
||||||
|
/// usually result in missed calls.
|
||||||
|
Cancelled,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns call state given the message ID.
|
||||||
|
pub async fn call_state(context: &Context, msg_id: MsgId) -> Result<CallState> {
|
||||||
|
let call = context.load_call_by_id(msg_id).await?;
|
||||||
|
let state = if call.is_incoming() {
|
||||||
|
if call.is_accepted() {
|
||||||
|
if call.is_ended() {
|
||||||
|
CallState::Completed {
|
||||||
|
duration: call.duration_seconds(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CallState::Active
|
||||||
|
}
|
||||||
|
} else if call.is_cancelled() {
|
||||||
|
// Call was explicitly cancelled
|
||||||
|
// by the caller before we picked it up.
|
||||||
|
CallState::Missed
|
||||||
|
} else if call.is_ended() {
|
||||||
|
CallState::Declined
|
||||||
|
} else if call.is_stale() {
|
||||||
|
CallState::Missed
|
||||||
|
} else {
|
||||||
|
CallState::Alerting
|
||||||
|
}
|
||||||
|
} else if call.is_accepted() {
|
||||||
|
if call.is_ended() {
|
||||||
|
CallState::Completed {
|
||||||
|
duration: call.duration_seconds(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CallState::Active
|
||||||
|
}
|
||||||
|
} else if call.is_cancelled() {
|
||||||
|
CallState::Cancelled
|
||||||
|
} else if call.is_ended() || call.is_stale() {
|
||||||
|
CallState::Declined
|
||||||
|
} else {
|
||||||
|
CallState::Alerting
|
||||||
|
};
|
||||||
|
Ok(state)
|
||||||
|
}
|
||||||
|
|
||||||
/// ICE server for JSON serialization.
|
/// ICE server for JSON serialization.
|
||||||
#[derive(Serialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||||
struct IceServer {
|
struct IceServer {
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ async fn setup_call() -> Result<CallSetup> {
|
|||||||
assert!(!info.is_accepted());
|
assert!(!info.is_accepted());
|
||||||
assert_eq!(info.place_call_info, PLACE_INFO);
|
assert_eq!(info.place_call_info, PLACE_INFO);
|
||||||
assert_text(t, m.id, "Outgoing call").await?;
|
assert_text(t, m.id, "Outgoing call").await?;
|
||||||
|
assert_eq!(call_state(t, m.id).await?, CallState::Alerting);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bob receives the message referring to the call on two devices;
|
// Bob receives the message referring to the call on two devices;
|
||||||
@@ -74,6 +75,7 @@ async fn setup_call() -> Result<CallSetup> {
|
|||||||
assert!(!info.is_accepted());
|
assert!(!info.is_accepted());
|
||||||
assert_eq!(info.place_call_info, PLACE_INFO);
|
assert_eq!(info.place_call_info, PLACE_INFO);
|
||||||
assert_text(t, m.id, "Incoming call").await?;
|
assert_text(t, m.id, "Incoming call").await?;
|
||||||
|
assert_eq!(call_state(t, m.id).await?, CallState::Alerting);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CallSetup {
|
Ok(CallSetup {
|
||||||
@@ -111,6 +113,7 @@ async fn accept_call() -> Result<CallSetup> {
|
|||||||
let info = bob.load_call_by_id(bob_call.id).await?;
|
let info = bob.load_call_by_id(bob_call.id).await?;
|
||||||
assert!(info.is_accepted());
|
assert!(info.is_accepted());
|
||||||
assert_eq!(info.place_call_info, PLACE_INFO);
|
assert_eq!(info.place_call_info, PLACE_INFO);
|
||||||
|
assert_eq!(call_state(&bob, bob_call.id).await?, CallState::Active);
|
||||||
|
|
||||||
bob2.recv_msg_trash(&sent2).await;
|
bob2.recv_msg_trash(&sent2).await;
|
||||||
assert_text(&bob, bob_call.id, "Incoming call").await?;
|
assert_text(&bob, bob_call.id, "Incoming call").await?;
|
||||||
@@ -119,6 +122,7 @@ async fn accept_call() -> Result<CallSetup> {
|
|||||||
.await;
|
.await;
|
||||||
let info = bob2.load_call_by_id(bob2_call.id).await?;
|
let info = bob2.load_call_by_id(bob2_call.id).await?;
|
||||||
assert!(info.is_accepted());
|
assert!(info.is_accepted());
|
||||||
|
assert_eq!(call_state(&bob2, bob2_call.id).await?, CallState::Active);
|
||||||
|
|
||||||
// Alice receives the acceptance message
|
// Alice receives the acceptance message
|
||||||
alice.recv_msg_trash(&sent2).await;
|
alice.recv_msg_trash(&sent2).await;
|
||||||
@@ -137,6 +141,7 @@ async fn accept_call() -> Result<CallSetup> {
|
|||||||
let info = alice.load_call_by_id(alice_call.id).await?;
|
let info = alice.load_call_by_id(alice_call.id).await?;
|
||||||
assert!(info.is_accepted());
|
assert!(info.is_accepted());
|
||||||
assert_eq!(info.place_call_info, PLACE_INFO);
|
assert_eq!(info.place_call_info, PLACE_INFO);
|
||||||
|
assert_eq!(call_state(&alice, alice_call.id).await?, CallState::Active);
|
||||||
|
|
||||||
alice2.recv_msg_trash(&sent2).await;
|
alice2.recv_msg_trash(&sent2).await;
|
||||||
assert_text(&alice2, alice2_call.id, "Outgoing call").await?;
|
assert_text(&alice2, alice2_call.id, "Outgoing call").await?;
|
||||||
@@ -144,6 +149,10 @@ async fn accept_call() -> Result<CallSetup> {
|
|||||||
.evtracker
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::OutgoingCallAccepted { .. }))
|
.get_matching(|evt| matches!(evt, EventType::OutgoingCallAccepted { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
call_state(&alice2, alice2_call.id).await?,
|
||||||
|
CallState::Active
|
||||||
|
);
|
||||||
|
|
||||||
Ok(CallSetup {
|
Ok(CallSetup {
|
||||||
alice,
|
alice,
|
||||||
@@ -179,12 +188,20 @@ async fn test_accept_call_callee_ends() -> Result<()> {
|
|||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
let sent3 = bob.pop_sent_msg().await;
|
let sent3 = bob.pop_sent_msg().await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&bob, bob_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
bob2.recv_msg_trash(&sent3).await;
|
bob2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&bob2, bob2_call.id, "Incoming call\n<1 minute").await?;
|
assert_text(&bob2, bob2_call.id, "Incoming call\n<1 minute").await?;
|
||||||
bob2.evtracker
|
bob2.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&bob2, bob2_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
// Alice receives the ending message
|
// Alice receives the ending message
|
||||||
alice.recv_msg_trash(&sent3).await;
|
alice.recv_msg_trash(&sent3).await;
|
||||||
@@ -193,6 +210,10 @@ async fn test_accept_call_callee_ends() -> Result<()> {
|
|||||||
.evtracker
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&alice, alice_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
alice2.recv_msg_trash(&sent3).await;
|
alice2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&alice2, alice2_call.id, "Outgoing call\n<1 minute").await?;
|
assert_text(&alice2, alice2_call.id, "Outgoing call\n<1 minute").await?;
|
||||||
@@ -200,6 +221,10 @@ async fn test_accept_call_callee_ends() -> Result<()> {
|
|||||||
.evtracker
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&alice2, alice2_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -227,6 +252,10 @@ async fn test_accept_call_caller_ends() -> Result<()> {
|
|||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
let sent3 = alice.pop_sent_msg().await;
|
let sent3 = alice.pop_sent_msg().await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&alice, alice_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
alice2.recv_msg_trash(&sent3).await;
|
alice2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&alice2, alice2_call.id, "Outgoing call\n<1 minute").await?;
|
assert_text(&alice2, alice2_call.id, "Outgoing call\n<1 minute").await?;
|
||||||
@@ -234,6 +263,10 @@ async fn test_accept_call_caller_ends() -> Result<()> {
|
|||||||
.evtracker
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&alice2, alice2_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
// Bob receives the ending message
|
// Bob receives the ending message
|
||||||
bob.recv_msg_trash(&sent3).await;
|
bob.recv_msg_trash(&sent3).await;
|
||||||
@@ -241,12 +274,20 @@ async fn test_accept_call_caller_ends() -> Result<()> {
|
|||||||
bob.evtracker
|
bob.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&bob, bob_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
bob2.recv_msg_trash(&sent3).await;
|
bob2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&bob2, bob2_call.id, "Incoming call\n<1 minute").await?;
|
assert_text(&bob2, bob2_call.id, "Incoming call\n<1 minute").await?;
|
||||||
bob2.evtracker
|
bob2.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert!(matches!(
|
||||||
|
call_state(&bob2, bob2_call.id).await?,
|
||||||
|
CallState::Completed { .. }
|
||||||
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -274,12 +315,14 @@ async fn test_callee_rejects_call() -> Result<()> {
|
|||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
let sent3 = bob.pop_sent_msg().await;
|
let sent3 = bob.pop_sent_msg().await;
|
||||||
|
assert_eq!(call_state(&bob, bob_call.id).await?, CallState::Declined);
|
||||||
|
|
||||||
bob2.recv_msg_trash(&sent3).await;
|
bob2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&bob2, bob2_call.id, "Declined call").await?;
|
assert_text(&bob2, bob2_call.id, "Declined call").await?;
|
||||||
bob2.evtracker
|
bob2.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert_eq!(call_state(&bob2, bob2_call.id).await?, CallState::Declined);
|
||||||
|
|
||||||
// Alice receives decline message
|
// Alice receives decline message
|
||||||
alice.recv_msg_trash(&sent3).await;
|
alice.recv_msg_trash(&sent3).await;
|
||||||
@@ -288,6 +331,10 @@ async fn test_callee_rejects_call() -> Result<()> {
|
|||||||
.evtracker
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
call_state(&alice, alice_call.id).await?,
|
||||||
|
CallState::Declined
|
||||||
|
);
|
||||||
|
|
||||||
alice2.recv_msg_trash(&sent3).await;
|
alice2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&alice2, alice2_call.id, "Declined call").await?;
|
assert_text(&alice2, alice2_call.id, "Declined call").await?;
|
||||||
@@ -295,6 +342,10 @@ async fn test_callee_rejects_call() -> Result<()> {
|
|||||||
.evtracker
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
call_state(&alice2, alice2_call.id).await?,
|
||||||
|
CallState::Declined
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -322,6 +373,10 @@ async fn test_caller_cancels_call() -> Result<()> {
|
|||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
let sent3 = alice.pop_sent_msg().await;
|
let sent3 = alice.pop_sent_msg().await;
|
||||||
|
assert_eq!(
|
||||||
|
call_state(&alice, alice_call.id).await?,
|
||||||
|
CallState::Cancelled
|
||||||
|
);
|
||||||
|
|
||||||
alice2.recv_msg_trash(&sent3).await;
|
alice2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&alice2, alice2_call.id, "Cancelled call").await?;
|
assert_text(&alice2, alice2_call.id, "Cancelled call").await?;
|
||||||
@@ -329,6 +384,10 @@ async fn test_caller_cancels_call() -> Result<()> {
|
|||||||
.evtracker
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
call_state(&alice2, alice2_call.id).await?,
|
||||||
|
CallState::Cancelled
|
||||||
|
);
|
||||||
|
|
||||||
// Bob receives the ending message
|
// Bob receives the ending message
|
||||||
bob.recv_msg_trash(&sent3).await;
|
bob.recv_msg_trash(&sent3).await;
|
||||||
@@ -336,12 +395,14 @@ async fn test_caller_cancels_call() -> Result<()> {
|
|||||||
bob.evtracker
|
bob.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert_eq!(call_state(&bob, bob_call.id).await?, CallState::Missed);
|
||||||
|
|
||||||
bob2.recv_msg_trash(&sent3).await;
|
bob2.recv_msg_trash(&sent3).await;
|
||||||
assert_text(&bob2, bob2_call.id, "Missed call").await?;
|
assert_text(&bob2, bob2_call.id, "Missed call").await?;
|
||||||
bob2.evtracker
|
bob2.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||||
.await;
|
.await;
|
||||||
|
assert_eq!(call_state(&bob2, bob2_call.id).await?, CallState::Missed);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user