webxdc: synchronous state for read-only-chats

already before,
we did _not_ sent updates to contact requests or other read-only-chats.
however, we _did_ modify the local database,
so that getAllUpdates() returns an update that was not sent out to other peers.

this is fixed by checking can_send() soon.

that way, all peers have the same state
also for contact requests or other read-only-chats
and webxdc in contact requests can be opened as usual.

further ui improvements may be needed for contact requests
(maybe allow the webxdc to know about that state or
maybe show a warning in the ui somewhere),
however, this is not part of this pr.
This commit is contained in:
B. Petersen
2022-01-22 16:58:02 +01:00
committed by bjoern
parent f21691c122
commit 05a3c0c89b
3 changed files with 54 additions and 1 deletions

View File

@@ -1,5 +1,6 @@
//! # Handle webxdc messages.
use crate::chat::Chat;
use crate::constants::Viewtype;
use crate::context::Context;
use crate::dc_tools::{dc_create_smeared_timestamp, dc_open_file_std};
@@ -246,6 +247,9 @@ impl Context {
bail!("send_webxdc_status_update: is no webxdc message");
}
let chat = Chat::load_from_db(self, instance.chat_id).await?;
ensure!(chat.can_send(self).await?, "cannot send to {}", chat.id);
let status_update_id = self
.create_status_update_record(
&mut instance,
@@ -683,6 +687,48 @@ mod tests {
Ok(())
}
#[async_std::test]
async fn test_webxdc_contact_request() -> Result<()> {
let alice = TestContext::new_alice().await;
let bob = TestContext::new_bob().await;
// Alice sends an webxdc instance to Bob
let alice_chat = alice.create_chat(&bob).await;
let _alice_instance = send_webxdc_instance(&alice, alice_chat.id).await?;
bob.recv_msg(&alice.pop_sent_msg().await).await;
// Bob can start the webxdc from a contact request (get index.html)
// but cannot send updates to contact requests
let bob_instance = bob.get_last_msg().await;
let bob_chat = Chat::load_from_db(&bob, bob_instance.chat_id).await?;
assert!(bob_chat.is_contact_request());
assert!(bob_instance
.get_webxdc_blob(&bob, "index.html")
.await
.is_ok());
assert!(bob
.send_webxdc_status_update(bob_instance.id, r#"{"payload":42}"#, "descr")
.await
.is_err());
assert_eq!(
bob.get_webxdc_status_updates(bob_instance.id, None).await?,
"[]"
);
// Once the contact request is accepted, Bob can send updates
bob_chat.id.accept(&bob).await?;
assert!(bob
.send_webxdc_status_update(bob_instance.id, r#"{"payload":42}"#, "descr")
.await
.is_ok());
assert_eq!(
bob.get_webxdc_status_updates(bob_instance.id, None).await?,
r#"[{"payload":42}]"#
);
Ok(())
}
#[async_std::test]
async fn test_delete_webxdc_instance() -> Result<()> {
let t = TestContext::new_alice().await;