use openmls::{prelude::*, test_utils::single_group_test_framework::*};
use openmls_test::openmls_test;
#[openmls_test]
fn treesync_leaf_credentials() {
let alice_party = CorePartyState::<Provider>::new("alice");
let bob_party = CorePartyState::<Provider>::new("bob");
let alice_pre_group = alice_party.generate_pre_group(ciphersuite);
let bob_pre_group = bob_party.generate_pre_group(ciphersuite);
let create_config = MlsGroupCreateConfig::test_default_from_ciphersuite(ciphersuite);
let join_config = create_config.join_config().clone();
let mut group_state = GroupState::new_from_party(
GroupId::from_slice(b"treesync test"),
alice_pre_group,
create_config,
)
.unwrap();
group_state
.add_member(AddMemberConfig {
adder: "alice",
addees: vec![bob_pre_group],
join_config,
tree: None,
})
.unwrap();
let [bob] = group_state.members_mut(&["bob"]);
let leaves: Vec<_> = bob.group.treesync().full_leaves().collect();
assert_eq!(leaves.len(), 2);
let (alice_index, alice_leaf) = &leaves[0];
let (bob_index, bob_leaf) = &leaves[1];
assert_eq!(alice_index.u32(), 0);
assert_eq!(bob_index.u32(), 1);
let alice_cred: BasicCredential = alice_leaf.credential().clone().try_into().unwrap();
assert_eq!(alice_cred.identity(), b"alice");
let bob_cred: BasicCredential = bob_leaf.credential().clone().try_into().unwrap();
assert_eq!(bob_cred.identity(), b"bob");
let parents: Vec<_> = bob.group.treesync().full_parents().collect();
assert_eq!(parents.len(), 1);
let (root_index, _root_node) = &parents[0];
assert_eq!(root_index.u32(), 0);
}
#[openmls_test]
fn treesync_blanks_after_remove() {
let alice_party = CorePartyState::<Provider>::new("alice");
let bob_party = CorePartyState::<Provider>::new("bob");
let charlie_party = CorePartyState::<Provider>::new("charlie");
let dana_party = CorePartyState::<Provider>::new("dana");
let alice_pre_group = alice_party.generate_pre_group(ciphersuite);
let bob_pre_group = bob_party.generate_pre_group(ciphersuite);
let charlie_pre_group = charlie_party.generate_pre_group(ciphersuite);
let dana_pre_group = dana_party.generate_pre_group(ciphersuite);
let create_config = MlsGroupCreateConfig::test_default_from_ciphersuite(ciphersuite);
let join_config = create_config.join_config().clone();
let mut group_state = GroupState::new_from_party(
GroupId::from_slice(b"treesync blanks test"),
alice_pre_group,
create_config,
)
.unwrap();
group_state
.add_member(AddMemberConfig {
adder: "alice",
addees: vec![bob_pre_group, charlie_pre_group, dana_pre_group],
join_config,
tree: None,
})
.unwrap();
let commit = {
let [alice] = group_state.members_mut(&["alice"]);
let (commit, _, _) = alice
.group
.remove_members(
&alice.party.core_state.provider,
&alice.party.signer,
&[LeafNodeIndex::new(1)],
)
.unwrap();
alice
.group
.merge_pending_commit(&alice.party.core_state.provider)
.unwrap();
commit
};
group_state
.deliver_and_apply_if(commit.into(), |member| {
matches!(member.party.core_state.name, "charlie" | "dana")
})
.unwrap();
let [charlie] = group_state.members_mut(&["charlie"]);
let treesync = charlie.group.treesync();
let blank_leaves: Vec<_> = treesync.blank_leaves().collect();
assert_eq!(blank_leaves.len(), 1, "blank leaves: {blank_leaves:?}");
assert_eq!(blank_leaves[0].u32(), 1);
let blank_parents: Vec<_> = treesync.blank_parents().collect();
assert_eq!(blank_parents.len(), 2, "blank parents: {blank_parents:?}");
assert_eq!(blank_parents[0].u32(), 0); assert_eq!(blank_parents[1].u32(), 2); }