diff --git a/deltachat-jsonrpc/src/api.rs b/deltachat-jsonrpc/src/api.rs index 1861807d9..15dab9255 100644 --- a/deltachat-jsonrpc/src/api.rs +++ b/deltachat-jsonrpc/src/api.rs @@ -152,6 +152,13 @@ impl CommandApi { tokio::time::sleep(std::time::Duration::from_secs_f64(delay)).await } + /// Emit the test checkpoint event, used for tests. + /// Returns a unique id of the emitted `TestCheckpointEvent`. + async fn trigger_checkpoint_event(&self, account_id: u32) -> Result { + let ctx = self.get_context(account_id).await?; + Ok(ctx.emit_test_checkpoint_event().await) + } + // --------------------------------------------- // Misc top level functions // --------------------------------------------- diff --git a/deltachat-jsonrpc/src/api/types/events.rs b/deltachat-jsonrpc/src/api/types/events.rs index 7aa2e394e..405042007 100644 --- a/deltachat-jsonrpc/src/api/types/events.rs +++ b/deltachat-jsonrpc/src/api/types/events.rs @@ -259,6 +259,13 @@ pub enum EventType { /// If `chat_id` is set to None, then all currently visible chats need to be rerendered, and all not-visible items need to be cleared from cache if the UI has a cache. #[serde(rename_all = "camelCase")] ChatlistItemChanged { chat_id: Option }, + + /// Tests can trigger this event and then wait for it, to make sure all events before it were consumed. + /// Useful for tests that test whether a specific event is emitted, + TestCheckpointEvent { + /// unique id to recognize the event + id: usize, + }, } impl From for EventType { @@ -370,6 +377,7 @@ impl From for EventType { chat_id: chat_id.map(|id| id.to_u32()), }, CoreEventType::ChatlistChanged => ChatlistChanged, + CoreEventType::TestCheckpointEvent { id } => TestCheckpointEvent { id }, } } } diff --git a/src/context.rs b/src/context.rs index 5586c4c7f..81b44dae2 100644 --- a/src/context.rs +++ b/src/context.rs @@ -4,7 +4,7 @@ use std::collections::{BTreeMap, HashMap}; use std::ffi::OsString; use std::ops::Deref; use std::path::{Path, PathBuf}; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicI64, AtomicU64, Ordering}; use std::sync::Arc; use std::time::Duration; @@ -288,6 +288,9 @@ pub struct InnerContext { /// True if account has subscribed to push notifications via IMAP. pub(crate) push_subscribed: AtomicBool, + + /// Counter for the id for the test checkpoint event that is used by tests. + pub(crate) test_event_checkpoint_counter: Mutex, } /// The state of ongoing process. @@ -445,6 +448,7 @@ impl Context { debug_logging: std::sync::RwLock::new(None), push_subscriber, push_subscribed: AtomicBool::new(false), + test_event_checkpoint_counter: Mutex::new(0), }; let ctx = Context { @@ -1362,6 +1366,15 @@ impl Context { wal_fname.push("-wal"); dbfile.with_file_name(wal_fname) } + + /// Emit the test checkpoint event, used for tests. + /// Returns a unique id of the emitted `TestCheckpointEvent`. + pub async fn emit_test_checkpoint_event(&self) -> usize { + let mut counter = self.inner.test_event_checkpoint_counter.lock().await; + *counter = counter.wrapping_add(1); + self.emit_event(EventType::TestCheckpointEvent { id: *counter }); + *counter + } } /// Returns core version as a string. diff --git a/src/events/payload.rs b/src/events/payload.rs index 47e3526c2..bddc23d28 100644 --- a/src/events/payload.rs +++ b/src/events/payload.rs @@ -302,4 +302,11 @@ pub enum EventType { /// ID of the changed chat chat_id: Option, }, + + /// Tests can trigger this event and then wait for it, to make sure all events before it were consumed. + /// Useful for tests that test whether a specific event is emitted, + TestCheckpointEvent { + /// unique id to recognize the event + id: usize, + }, }