diff --git a/crates/matrix-sdk-base/src/sliding_sync/mod.rs b/crates/matrix-sdk-base/src/sliding_sync/mod.rs index 1f97eb1f526..77a52b702e6 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/mod.rs @@ -999,6 +999,7 @@ mod tests { assert!(sync_resp.rooms.join.contains_key(room_id)); assert!(!sync_resp.rooms.leave.contains_key(room_id)); assert!(!sync_resp.rooms.invite.contains_key(room_id)); + assert!(!sync_resp.rooms.knocked.contains_key(room_id)); } #[async_test] @@ -1084,6 +1085,76 @@ mod tests { assert_eq!(client_room.compute_display_name().await.unwrap().to_string(), "The Name"); } + #[async_test] + async fn test_knocked_room_membership_event() { + // Given a logged-in client, + let client = logged_in_base_client(None).await; + let room_id = room_id!("!r:e.uk"); + let user_id = client.session_meta().unwrap().user_id.to_owned(); + + // When the room is properly set as knocked with the current user id as state + // key, + let mut room = http::response::Room::new(); + set_room_knocked(&mut room, &user_id); + + let response = response_with_room(room_id, room); + client.process_sliding_sync(&response, &(), true).await.expect("Failed to process sync"); + + // The room is knocked. + let client_room = client.get_room(room_id).expect("No room found"); + assert_eq!(client_room.state(), RoomState::Knocked); + } + + #[async_test] + async fn test_knocked_room_membership_event_with_wrong_state_key() { + // Given a logged-in client, + let client = logged_in_base_client(None).await; + let room_id = room_id!("!r:e.uk"); + let user_id = user_id!("@w:e.uk"); + + // When the room is set as knocked with a random user id as state key, + let mut room = http::response::Room::new(); + set_room_knocked(&mut room, &user_id); + + let response = response_with_room(room_id, room); + client.process_sliding_sync(&response, &(), true).await.expect("Failed to process sync"); + + // The room is invited since the membership event doesn't belong to the current + // user. + let client_room = client.get_room(room_id).expect("No room found"); + assert_eq!(client_room.state(), RoomState::Invited); + } + + #[async_test] + async fn test_unknown_room_membership_event_in_invite_state() { + // Given a logged-in client, + let client = logged_in_base_client(None).await; + let room_id = room_id!("!r:e.uk"); + let user_id = client.session_meta().unwrap().user_id.to_owned(); + + // When the room has the wrong membership state in its invite_state + let mut room = http::response::Room::new(); + let event = Raw::new(&json!({ + "type": "m.room.member", + "sender": user_id, + "content": { + "is_direct": true, + "membership": "join", + }, + "state_key": user_id, + })) + .expect("Failed to make raw event") + .cast(); + room.invite_state = Some(vec![event]); + + let response = response_with_room(room_id, room); + client.process_sliding_sync(&response, &(), true).await.expect("Failed to process sync"); + + // The room is marked as invited. + let client_room = client.get_room(room_id).expect("No room found"); + assert_eq!(client_room.state(), RoomState::Invited); + } + #[async_test] async fn test_left_a_room_from_required_state_event() { // Given a logged-in client @@ -1114,6 +1185,7 @@ mod tests { assert!(!sync_resp.rooms.join.contains_key(room_id)); assert!(sync_resp.rooms.leave.contains_key(room_id)); assert!(!sync_resp.rooms.invite.contains_key(room_id)); + assert!(!sync_resp.rooms.knocked.contains_key(room_id)); } #[async_test] @@ -1155,6 +1227,7 @@ mod tests { assert!(!sync_resp.rooms.join.contains_key(room_id)); assert!(sync_resp.rooms.leave.contains_key(room_id)); assert!(!sync_resp.rooms.invite.contains_key(room_id)); + assert!(!sync_resp.rooms.knocked.contains_key(room_id)); } } @@ -2597,6 +2670,25 @@ mod tests { )); } + fn set_room_knocked(room: &mut http::response::Room, knocker: &UserId) { + // MSC3575 shows an almost-empty event to indicate that we are invited to a + // room. Just the type is supplied. + + let evt = Raw::new(&json!({ + "type": "m.room.member", + "sender": knocker, + "content": { + "is_direct": true, + "membership": "knock", + }, + "state_key": knocker, + })) + .expect("Failed to make raw event") + .cast(); + + room.invite_state = Some(vec![evt]); + } + fn set_room_joined(room: &mut http::response::Room, user_id: &UserId) { room.required_state.push(make_membership_event(user_id, MembershipState::Join)); }