mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 12:56:30 +03:00
feat: Add EventType::CallMissed and emit it for missed calls (#7840)
Before, only `CallEnded` was emitted for missed calls, or, if a call arrives already being stale, `IncomingMsg`. Now: - `CallMissed` is emitted in addition to `CallEnded`. - `IncomingMsg` is replaced with `CallMissed` for stale calls. Having only one event type for missed calls should simplify handling them in the apps. This doesn't emit `CallMissed` for those who aren't allowed to call us. Also, don't emit `CallEnded` if the caller isn't allowed to call us and the call wasn't accepted, as there's no previous `IncomingCall` event in this case.
This commit is contained in:
@@ -5,6 +5,7 @@ use crate::constants::DC_CHAT_ID_TRASH;
|
||||
use crate::message::MessageState;
|
||||
use crate::receive_imf::receive_imf;
|
||||
use crate::test_utils::{TestContext, TestContextManager};
|
||||
use crate::tools::SystemTime;
|
||||
|
||||
struct CallSetup {
|
||||
pub alice: TestContext,
|
||||
@@ -490,6 +491,9 @@ async fn test_caller_cancels_call() -> Result<()> {
|
||||
// Bob receives the ending message
|
||||
bob.recv_msg_trash(&sent3).await;
|
||||
assert_text(&bob, bob_call.id, "Missed call").await?;
|
||||
bob.evtracker
|
||||
.get_matching(|evt| matches!(evt, EventType::CallMissed { .. }))
|
||||
.await;
|
||||
bob.evtracker
|
||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||
.await;
|
||||
@@ -502,6 +506,9 @@ async fn test_caller_cancels_call() -> Result<()> {
|
||||
|
||||
bob2.recv_msg_trash(&sent3).await;
|
||||
assert_text(&bob2, bob2_call.id, "Missed call").await?;
|
||||
bob2.evtracker
|
||||
.get_matching(|evt| matches!(evt, EventType::CallMissed { .. }))
|
||||
.await;
|
||||
bob2.evtracker
|
||||
.get_matching(|evt| matches!(evt, EventType::CallEnded { .. }))
|
||||
.await;
|
||||
@@ -510,6 +517,95 @@ async fn test_caller_cancels_call() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_stale_call() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
for accepted in [false, true] {
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
info!(bob, "Alice is accepted: {accepted}.");
|
||||
if accepted {
|
||||
bob.create_chat(alice).await;
|
||||
}
|
||||
let alice_chat = alice.create_chat(bob).await;
|
||||
alice
|
||||
.place_outgoing_call(alice_chat.id, PLACE_INFO.to_string(), true)
|
||||
.await?;
|
||||
let sent1 = alice.pop_sent_msg().await;
|
||||
|
||||
SystemTime::shift(Duration::from_secs(3600));
|
||||
let bob_call = bob.recv_msg(&sent1).await;
|
||||
let EventType::MsgsChanged { msg_id, chat_id } = bob
|
||||
.evtracker
|
||||
.get_matching(|evt| {
|
||||
matches!(
|
||||
evt,
|
||||
EventType::MsgsChanged { .. }
|
||||
| EventType::CallMissed { .. }
|
||||
| EventType::CallEnded { .. }
|
||||
)
|
||||
})
|
||||
.await
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
assert_eq!(chat_id, bob_call.chat_id);
|
||||
let msg = Message::load_from_db(bob, msg_id).await?;
|
||||
assert_eq!(msg.text, stock_str::messages_e2ee_info_msg(bob));
|
||||
if accepted {
|
||||
let EventType::CallMissed { msg_id, chat_id } = bob
|
||||
.evtracker
|
||||
.get_matching(|evt| {
|
||||
matches!(
|
||||
evt,
|
||||
EventType::CallMissed { .. } | EventType::CallEnded { .. }
|
||||
)
|
||||
})
|
||||
.await
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
assert_eq!(msg_id, bob_call.id);
|
||||
assert_eq!(chat_id, bob_call.chat_id);
|
||||
}
|
||||
let EventType::MsgsChanged { msg_id, chat_id } = bob
|
||||
.evtracker
|
||||
.get_matching(|evt| {
|
||||
matches!(
|
||||
evt,
|
||||
EventType::MsgsChanged { .. }
|
||||
| EventType::CallMissed { .. }
|
||||
| EventType::CallEnded { .. }
|
||||
)
|
||||
})
|
||||
.await
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
assert_eq!(msg_id, bob_call.id);
|
||||
assert_eq!(chat_id, bob_call.chat_id);
|
||||
let evt = bob
|
||||
.evtracker
|
||||
.get_matching_opt(bob, |evt| {
|
||||
matches!(
|
||||
evt,
|
||||
EventType::CallMissed { .. } | EventType::CallEnded { .. }
|
||||
)
|
||||
})
|
||||
.await;
|
||||
assert!(evt.is_none());
|
||||
assert_text(bob, bob_call.id, "Missed call").await?;
|
||||
assert_eq!(call_state(bob, bob_call.id).await?, CallState::Missed);
|
||||
|
||||
// Test that message summary says it is a missed call.
|
||||
let bob_call_msg = Message::load_from_db(bob, bob_call.id).await?;
|
||||
let summary = bob_call_msg.get_summary(bob, None).await?;
|
||||
assert_eq!(summary.text, "🎥 Missed call");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_is_stale_call() -> Result<()> {
|
||||
// a call started now is not stale
|
||||
|
||||
Reference in New Issue
Block a user