diff --git a/deltachat-rpc-client/tests/test_calls.py b/deltachat-rpc-client/tests/test_calls.py index 6ea4810fcf..e83d736f04 100644 --- a/deltachat-rpc-client/tests/test_calls.py +++ b/deltachat-rpc-client/tests/test_calls.py @@ -9,6 +9,7 @@ def test_calls(acfactory) -> None: alice_contact_bob = alice.create_contact(bob, "Bob") alice_chat_bob = alice_contact_bob.create_chat() + bob.create_chat(alice) # Accept the chat so incoming call causes a notification. outgoing_call_message = alice_chat_bob.place_outgoing_call(place_call_info) assert outgoing_call_message.get_call_info().state.kind == "Alerting" @@ -67,6 +68,7 @@ def test_video_call(acfactory) -> None: alice, bob = acfactory.get_online_accounts(2) + bob.create_chat(alice) # Accept the chat so incoming call causes a notification. alice_contact_bob = alice.create_contact(bob, "Bob") alice_chat_bob = alice_contact_bob.create_chat() alice_chat_bob.place_outgoing_call(place_call_info) @@ -84,3 +86,24 @@ def test_ice_servers(acfactory) -> None: ice_servers = alice.ice_servers() assert len(ice_servers) == 1 + + +def test_no_contact_request_call(acfactory) -> None: + alice, bob = acfactory.get_online_accounts(2) + + alice_chat_bob = alice.create_chat(bob) + alice_chat_bob.place_outgoing_call("offer") + alice_chat_bob.send_text("Hello!") + + # Notification for "Hello!" message should arrive + # without the call ringing. + while True: + event = bob.wait_for_event() + + # There should be no incoming call notification. + assert event.kind != EventType.INCOMING_CALL + + if event.kind == EventType.INCOMING_MSG: + msg = bob.get_message_by_id(event.msg_id) + assert msg.get_snapshot().text == "Hello!" + break diff --git a/src/calls.rs b/src/calls.rs index 2daf0e8eca..88cefb8e15 100644 --- a/src/calls.rs +++ b/src/calls.rs @@ -2,8 +2,9 @@ //! //! Internally, calls are bound a user-visible message initializing the call. //! This means, the "Call ID" is a "Message ID" - similar to Webxdc IDs. +use crate::chat::ChatIdBlocked; use crate::chat::{Chat, ChatId, send_msg}; -use crate::constants::Chattype; +use crate::constants::{Blocked, Chattype}; use crate::contact::ContactId; use crate::context::Context; use crate::events::EventType; @@ -345,12 +346,27 @@ impl Context { false } }; - self.emit_event(EventType::IncomingCall { - msg_id: call.msg.id, - chat_id: call.msg.chat_id, - place_call_info: call.place_call_info.to_string(), - has_video, - }); + if let Some(chat_id_blocked) = + ChatIdBlocked::lookup_by_contact(self, from_id).await? + { + match chat_id_blocked.blocked { + Blocked::Not => { + self.emit_event(EventType::IncomingCall { + msg_id: call.msg.id, + chat_id: call.msg.chat_id, + place_call_info: call.place_call_info.to_string(), + has_video, + }); + } + Blocked::Yes | Blocked::Request => { + // Do not notify about incoming calls + // from contact requests and blocked contacts. + // + // User can still access the call and accept it + // via the chat in case of contact requests. + } + } + } let wait = call.remaining_ring_seconds(); task::spawn(Context::emit_end_call_if_unaccepted( self.clone(), diff --git a/src/calls/calls_tests.rs b/src/calls/calls_tests.rs index 9ad40efeb1..3f983d8438 100644 --- a/src/calls/calls_tests.rs +++ b/src/calls/calls_tests.rs @@ -45,6 +45,12 @@ async fn setup_call() -> Result { // Alice creates a chat with Bob and places an outgoing call there. // Alice's other device sees the same message as an outgoing call. let alice_chat = alice.create_chat(&bob).await; + + // Create chat on Bob's side + // so incoming call causes a notification. + bob.create_chat(&alice).await; + bob2.create_chat(&alice).await; + let test_msg_id = alice .place_outgoing_call(alice_chat.id, PLACE_INFO.to_string()) .await?;