Merge pull request #96 from michel/lib/room-roster-from-member-list
fix(rooms): start a room's roster from the member list, not the join echo
This commit is contained in:
@@ -100,10 +100,12 @@ impl ClientContext {
|
|||||||
// the whole board again on the next join.
|
// the whole board again on the next join.
|
||||||
self.room_tickers.remove(room);
|
self.room_tickers.remove(room);
|
||||||
}
|
}
|
||||||
|
// Only a roster the server has sent in full is kept current: the
|
||||||
|
// joiner hears of their own arrival before the member list.
|
||||||
RoomEvent::UserJoined { room, username } => {
|
RoomEvent::UserJoined { room, username } => {
|
||||||
let members =
|
if let Some(members) = self.room_members.get_mut(room)
|
||||||
self.room_members.entry(room.clone()).or_default();
|
&& let Err(at) = members.binary_search(username)
|
||||||
if let Err(at) = members.binary_search(username) {
|
{
|
||||||
members.insert(at, username.clone());
|
members.insert(at, username.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,25 @@ fn the_room_roster_follows_the_joins_and_leaves_the_server_reports() {
|
|||||||
assert!(context.room_members("lobby").is_empty());
|
assert!(context.room_members("lobby").is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_join_announced_before_the_member_list_does_not_start_a_roster() {
|
||||||
|
// soulfind tells a room about a joiner, the joiner included, before it
|
||||||
|
// sends them the member list. A roster started from that echo reads as a
|
||||||
|
// room holding nobody else.
|
||||||
|
let mut context = ClientContext::new();
|
||||||
|
context.apply_room_event(RoomEvent::UserJoined {
|
||||||
|
room: "lobby".to_string(),
|
||||||
|
username: "me".to_string(),
|
||||||
|
});
|
||||||
|
assert!(context.room_members("lobby").is_empty());
|
||||||
|
|
||||||
|
context.apply_room_event(RoomEvent::Joined {
|
||||||
|
room: "lobby".to_string(),
|
||||||
|
users: vec!["me".to_string(), "alice".to_string()],
|
||||||
|
});
|
||||||
|
assert_eq!(context.room_members("lobby"), ["alice", "me"]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_user_joining_twice_is_listed_once() {
|
fn a_user_joining_twice_is_listed_once() {
|
||||||
let mut context = ClientContext::new();
|
let mut context = ClientContext::new();
|
||||||
|
|||||||
@@ -2418,7 +2418,12 @@ fn room_users_lists_who_is_in_the_room() {
|
|||||||
let server = server_or_skip!();
|
let server = server_or_skip!();
|
||||||
let resident = server.client("cli_e2e_resident", Vec::new());
|
let resident = server.client("cli_e2e_resident", Vec::new());
|
||||||
resident.join_room("cli_e2e_roster").expect("join");
|
resident.join_room("cli_e2e_roster").expect("join");
|
||||||
settle();
|
// The member list reaches the resident once the server has them in.
|
||||||
|
let deadline = Instant::now() + Duration::from_secs(10);
|
||||||
|
while resident.room_members("cli_e2e_roster").is_empty() {
|
||||||
|
assert!(Instant::now() < deadline, "the resident never got in");
|
||||||
|
std::thread::sleep(Duration::from_millis(50));
|
||||||
|
}
|
||||||
|
|
||||||
let output = cli(
|
let output = cli(
|
||||||
&server,
|
&server,
|
||||||
|
|||||||
Reference in New Issue
Block a user