From 84fc66261438a129f197130d59f2012fbfa65d95 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Tue, 30 Jun 2020 17:09:10 +0200 Subject: [PATCH] Document and improve EventBuilder. EventBuilder now clears itself between `build_sync_response` calls so that each subsequent call will return an empty response if nothing was added. This allows reuse of a single EventBuilder instance which is important for correct sync token rotation. --- matrix_sdk_test/src/lib.rs | 53 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/matrix_sdk_test/src/lib.rs b/matrix_sdk_test/src/lib.rs index 80bba176..c07c1d33 100644 --- a/matrix_sdk_test/src/lib.rs +++ b/matrix_sdk_test/src/lib.rs @@ -47,7 +47,41 @@ pub enum EventsJson { Typing, } -/// Easily create events to stream into either a Client or a `Room` for testing. +/// The `EventBuilder` struct can be used to easily generate valid sync responses for testing. +/// These can be then fed into either `Client` or `Room`. +/// +/// It supports generated a number of canned events, such as a member entering a room, his power +/// level and display name changing and similar. It also supports insertion of custom events in the +/// form of `EventsJson` values. +/// +/// **Important** You *must* use the *same* builder when sending multiple sync responses to +/// a single client. Otherwise, the subsequent responses will be *ignored* by the client because +/// the `next_batch` sync token will not be rotated properly. +/// +/// # Example usage +/// +/// ```rust +/// use matrix_sdk_test::{EventBuilder, EventsJson}; +/// use matrix_sdk_common::events::collections::all::RoomEvent; +/// +/// let mut builder = EventBuilder::new(); +/// +/// // response1 now contains events that add an example member to the room and change their power +/// // level +/// let response1 = builder +/// .add_room_event(EventsJson::Member, RoomEvent::RoomMember) +/// .add_room_event(EventsJson::PowerLevels, RoomEvent::RoomPowerLevels) +/// .build_sync_response(); +/// +/// // response2 is now empty (nothing changed) +/// let response2 = builder.build_sync_response(); +/// +/// // response3 contains a display name change for member example +/// let response3 = builder +/// .add_room_event(EventsJson::MemberNameChange, RoomEvent::RoomMember) +/// .build_sync_response(); +/// ``` + #[derive(Default)] pub struct EventBuilder { /// The events that determine the state of a `Room`. @@ -226,7 +260,8 @@ impl EventBuilder { self } - /// Consumes `ResponseBuilder` and returns `SyncResponse`. + /// Builds a `SyncResponse` containing the events we queued so far. The next response returned + /// by `build_sync_response` will then be empty if no further events were queued. pub fn build_sync_response(&mut self) -> SyncResponse { let main_room_id = RoomId::try_from("!SVkFJHzfwvuaIEawgC:localhost").unwrap(); @@ -338,12 +373,26 @@ impl EventBuilder { let response = Response::builder() .body(serde_json::to_vec(&body).unwrap()) .unwrap(); + + // Clear state so that the next sync response will be empty if nothing was added. + self.clear(); + SyncResponse::try_from(response).unwrap() } fn generate_sync_token(&self) -> String { format!("t392-516_47314_0_7_1_1_1_11444_{}", self.batch_counter) } + + pub fn clear(&mut self) { + self.account_data.clear(); + self.ephemeral.clear(); + self.invited_room_events.clear(); + self.joined_room_events.clear(); + self.left_room_events.clear(); + self.presence_events.clear(); + self.state_events.clear(); + } } /// Embedded sync reponse files