test(e2e): resigning a private room, disbanding it, gifting privileges
Three messages that were implemented and only encoder-tested: a member giving up their own membership (136), an owner disbanding the room and freeing its name (137), and a privileged account handing time to another user (123), which the recipient then sees as privilege time of their own.
This commit is contained in:
@@ -58,13 +58,13 @@ Message names and codes follow the Soulseek protocol as implemented by
|
|||||||
| 117 / 118 | AddThingIHate / Remove | yes | e2e — hates come back in UserInterests |
|
| 117 / 118 | AddThingIHate / Remove | yes | e2e — hates come back in UserInterests |
|
||||||
| 120 | RoomSearch | yes | e2e — a member of the room answers |
|
| 120 | RoomSearch | yes | e2e — a member of the room answers |
|
||||||
| 121 | SendUploadSpeed | yes | e2e — the server records a finished upload |
|
| 121 | SendUploadSpeed | yes | e2e — the server records a finished upload |
|
||||||
| 123 | GivePrivileges | yes | unit — needs privileges to exercise |
|
| 123 | GivePrivileges | yes | e2e — a privileged account hands time over |
|
||||||
| 126 / 127 | BranchLevel / BranchRoot | yes | e2e — leaf adoption, and children |
|
| 126 / 127 | BranchLevel / BranchRoot | yes | e2e — leaf adoption, and children |
|
||||||
| 130 | ResetDistributed | yes | unit — a new session starts parentless |
|
| 130 | ResetDistributed | yes | unit — a new session starts parentless |
|
||||||
| 133 | RoomMembers | yes | e2e — a private room's roster |
|
| 133 | RoomMembers | yes | e2e — a private room's roster |
|
||||||
| 134 / 135 | AddRoomMember / Remove | yes | e2e — granted and revoked |
|
| 134 / 135 | AddRoomMember / Remove | yes | e2e — granted and revoked |
|
||||||
| 136 | CancelRoomMembership | yes | unit |
|
| 136 | CancelRoomMembership | yes | e2e — a member resigns |
|
||||||
| 137 | CancelRoomOwnership | yes | unit |
|
| 137 | CancelRoomOwnership | yes | e2e — the owner disbands the room |
|
||||||
| 139 / 140 | RoomMembershipGranted / Revoked | yes | e2e — the guest is told |
|
| 139 / 140 | RoomMembershipGranted / Revoked | yes | e2e — the guest is told |
|
||||||
| 141 | EnableRoomInvitations | yes | e2e — set before an invitation |
|
| 141 | EnableRoomInvitations | yes | e2e — set before an invitation |
|
||||||
| 142 | ChangePassword | yes | e2e — the next login needs the new one |
|
| 142 | ChangePassword | yes | e2e — the next login needs the new one |
|
||||||
|
|||||||
@@ -5284,3 +5284,129 @@ fn a_room_reports_members_arriving_and_leaving() {
|
|||||||
alice.room_members(room)
|
alice.room_members(room)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_member_can_give_up_a_private_room_and_an_owner_can_disband_it() {
|
||||||
|
use soulseek_rs::types::RoomEvent;
|
||||||
|
let server = server_or_skip!();
|
||||||
|
|
||||||
|
let room = "e2e_private_leaving";
|
||||||
|
let mut owner =
|
||||||
|
Client::with_settings(server.settings("e2e_leave_owner", "pw"));
|
||||||
|
let mut guest =
|
||||||
|
Client::with_settings(server.settings("e2e_leave_guest", "pw"));
|
||||||
|
owner.connect().expect("owner connect");
|
||||||
|
guest.connect().expect("guest connect");
|
||||||
|
assert!(owner.login().expect("owner login"));
|
||||||
|
assert!(guest.login().expect("guest login"));
|
||||||
|
|
||||||
|
guest
|
||||||
|
.set_room_invitations_enabled(true)
|
||||||
|
.expect("guest accepts invitations");
|
||||||
|
owner
|
||||||
|
.join_private_room(room)
|
||||||
|
.expect("owner creates the room");
|
||||||
|
std::thread::sleep(Duration::from_millis(750));
|
||||||
|
owner
|
||||||
|
.add_room_member(room, "e2e_leave_guest")
|
||||||
|
.expect("owner invites the guest");
|
||||||
|
|
||||||
|
let granted = await_room_event(&guest, Duration::from_secs(5), |event| {
|
||||||
|
matches!(event, RoomEvent::OwnStandingChanged {
|
||||||
|
room: r, members: true, granted: true
|
||||||
|
} if r == room)
|
||||||
|
.then_some(())
|
||||||
|
});
|
||||||
|
assert!(granted.is_some(), "the guest should be a member first");
|
||||||
|
|
||||||
|
// The guest gives up their own membership (code 136): the owner's roster
|
||||||
|
// loses them.
|
||||||
|
guest.leave_private_room(room).expect("guest resigns");
|
||||||
|
let deadline = Instant::now() + Duration::from_secs(10);
|
||||||
|
while Instant::now() < deadline
|
||||||
|
&& owner
|
||||||
|
.private_room_members(room)
|
||||||
|
.iter()
|
||||||
|
.any(|u| u == "e2e_leave_guest")
|
||||||
|
{
|
||||||
|
std::thread::sleep(Duration::from_millis(200));
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
!owner
|
||||||
|
.private_room_members(room)
|
||||||
|
.iter()
|
||||||
|
.any(|u| u == "e2e_leave_guest"),
|
||||||
|
"a member who resigned should leave the roster, got {:?}",
|
||||||
|
owner.private_room_members(room)
|
||||||
|
);
|
||||||
|
|
||||||
|
// The owner disbands the room (code 137), which frees the name: someone
|
||||||
|
// else asking for it is not refused as they would be for a room that
|
||||||
|
// still belongs to another user.
|
||||||
|
owner.disband_private_room(room).expect("owner disbands");
|
||||||
|
std::thread::sleep(Duration::from_secs(1));
|
||||||
|
|
||||||
|
let mut newcomer =
|
||||||
|
Client::with_settings(server.settings("e2e_leave_newcomer", "pw"));
|
||||||
|
newcomer.connect().expect("newcomer connect");
|
||||||
|
assert!(newcomer.login().expect("newcomer login"));
|
||||||
|
newcomer
|
||||||
|
.join_private_room(room)
|
||||||
|
.expect("newcomer asks for the name");
|
||||||
|
|
||||||
|
let refused =
|
||||||
|
await_room_event(&newcomer, Duration::from_secs(3), |event| {
|
||||||
|
matches!(event, RoomEvent::CantCreate { room: r } if r == room)
|
||||||
|
.then_some(())
|
||||||
|
});
|
||||||
|
assert!(
|
||||||
|
refused.is_none(),
|
||||||
|
"a disbanded room's name should be free again"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn privileges_can_be_handed_to_another_user() {
|
||||||
|
let server = server_or_skip!();
|
||||||
|
|
||||||
|
// Only a privileged account can give privileges away, and privileges
|
||||||
|
// themselves are granted in soulfind's own database.
|
||||||
|
let giver = "e2e_gift_giver";
|
||||||
|
let mut giving = Client::with_settings(server.settings(giver, "pw"));
|
||||||
|
giving.connect().expect("giver connect");
|
||||||
|
assert!(giving.login().expect("giver login"));
|
||||||
|
if !grant(&server, giver, "privileges") {
|
||||||
|
println!("e2e skipped: cannot grant privileges on this server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drop(giving);
|
||||||
|
std::thread::sleep(Duration::from_secs(1));
|
||||||
|
|
||||||
|
let mut giving = Client::with_settings(server.settings(giver, "pw"));
|
||||||
|
giving.connect().expect("giver reconnect");
|
||||||
|
assert!(giving.login().expect("giver re-login"));
|
||||||
|
|
||||||
|
let mut receiver =
|
||||||
|
Client::with_settings(server.settings("e2e_gift_receiver", "pw"));
|
||||||
|
receiver.connect().expect("receiver connect");
|
||||||
|
assert!(receiver.login().expect("receiver login"));
|
||||||
|
|
||||||
|
giving
|
||||||
|
.give_privileges("e2e_gift_receiver", 1)
|
||||||
|
.expect("hand over a day of privileges");
|
||||||
|
|
||||||
|
// The recipient now has privilege time of their own to check (code 92).
|
||||||
|
let deadline = Instant::now() + Duration::from_secs(10);
|
||||||
|
let mut left = 0;
|
||||||
|
while Instant::now() < deadline && left == 0 {
|
||||||
|
receiver
|
||||||
|
.check_privileges()
|
||||||
|
.expect("ask how much time we have");
|
||||||
|
std::thread::sleep(Duration::from_millis(500));
|
||||||
|
left = receiver.own_privilege_seconds().unwrap_or(0);
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
left > 0,
|
||||||
|
"the gifted privileges should show up as time of our own"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user