Skip to content

Commit

Permalink
test(policy): update policies of an empty group (#1494)
Browse files Browse the repository at this point in the history
* test(policy): update policies of an empty group

* Sync solo group after create in bindings (#1501)

* sync solo group after create in bindings

* fix node bindings style

---------

Co-authored-by: cameronvoell <[email protected]>

---------

Co-authored-by: Cameron Voell <[email protected]>
Co-authored-by: cameronvoell <[email protected]>
  • Loading branch information
3 people authored Jan 14, 2025
1 parent 6af3546 commit 07ccf0b
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 6 deletions.
54 changes: 52 additions & 2 deletions bindings_ffi/src/mls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,8 +906,11 @@ impl FfiConversations {
};

let convo = if account_addresses.is_empty() {
self.inner_client
.create_group(group_permissions, metadata_options)?
let group = self
.inner_client
.create_group(group_permissions, metadata_options)?;
group.sync().await?;
group
} else {
self.inner_client
.create_group_with_members(&account_addresses, group_permissions, metadata_options)
Expand Down Expand Up @@ -5650,4 +5653,51 @@ mod tests {
FfiReactionSchema::Unicode
));
}

#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
async fn test_update_policies_empty_group() {
let amal = new_test_client().await;
let bola = new_test_client().await;

// Create a group with amal and bola with admin-only permissions
let admin_only_options = FfiCreateGroupOptions {
permissions: Some(FfiGroupPermissionsOptions::AdminOnly),
..Default::default()
};
let amal_group = amal
.conversations()
.create_group(
vec![bola.account_address.clone()],
admin_only_options.clone(),
)
.await
.unwrap();

// Verify we can update the group name without syncing first
amal_group
.update_group_name("New Group Name 1".to_string())
.await
.unwrap();

// Verify the name is updated
amal_group.sync().await.unwrap();
assert_eq!(amal_group.group_name().unwrap(), "New Group Name 1");

// Create a group with just amal
let amal_solo_group = amal
.conversations()
.create_group(vec![], admin_only_options)
.await
.unwrap();

// Verify we can update the group name
amal_solo_group
.update_group_name("New Group Name 2".to_string())
.await
.unwrap();

// Verify the name is updated
amal_solo_group.sync().await.unwrap();
assert_eq!(amal_solo_group.group_name().unwrap(), "New Group Name 2");
}
}
9 changes: 7 additions & 2 deletions bindings_node/src/conversations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,15 @@ impl Conversations {
};

let convo = if account_addresses.is_empty() {
self
let group = self
.inner_client
.create_group(group_permissions, metadata_options)
.map_err(|e| Error::from_reason(format!("ClientError: {}", e)))?
.map_err(|e| Error::from_reason(format!("ClientError: {}", e)))?;
group
.sync()
.await
.map_err(|e| Error::from_reason(format!("ClientError: {}", e)))?;
group
} else {
self
.inner_client
Expand Down
33 changes: 33 additions & 0 deletions bindings_node/test/Conversations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -619,4 +619,37 @@ describe('Conversations', () => {
await group2.send(encodeTextMessage('gm!'))
expect(group2.consentState()).toBe(ConsentState.Allowed)
})

it('should update group metadata in empty group', async () => {
const user1 = createUser()
const client1 = await createRegisteredClient(user1)

// Create empty group with admin-only permissions
const group = await client1.conversations().createGroup([], {
permissions: GroupPermissionsOptions.AdminOnly,
})
expect(group).toBeDefined()

// Update group name without syncing first
await group.updateGroupName('New Group Name 1')
expect(group.groupName()).toBe('New Group Name 1')

// Verify name persists after sync
await group.sync()
expect(group.groupName()).toBe('New Group Name 1')

// Create another empty group
const soloGroup = await client1.conversations().createGroup([], {
permissions: GroupPermissionsOptions.AdminOnly,
})
expect(soloGroup).toBeDefined()

// Update and verify name
await soloGroup.updateGroupName('New Group Name 2')
expect(soloGroup.groupName()).toBe('New Group Name 2')

// Verify name persists after sync
await soloGroup.sync()
expect(soloGroup.groupName()).toBe('New Group Name 2')
})
})
9 changes: 7 additions & 2 deletions bindings_wasm/src/conversations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,15 @@ impl Conversations {
};

let convo = if account_addresses.is_empty() {
self
let group = self
.inner_client
.create_group(group_permissions, metadata_options)
.map_err(|e| JsError::new(format!("{}", e).as_str()))?
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
group
.sync()
.await
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
group
} else {
self
.inner_client
Expand Down
67 changes: 67 additions & 0 deletions xmtp_mls/src/groups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2742,6 +2742,73 @@ pub(crate) mod tests {
assert_eq!(bola_group_name, "New Group Name 1");
}

#[wasm_bindgen_test(unsupported = tokio::test(flavor = "current_thread"))]
async fn test_update_policies_empty_group() {
let amal = ClientBuilder::new_test_client(&generate_local_wallet()).await;
let bola_wallet = generate_local_wallet();
let _bola = ClientBuilder::new_test_client(&bola_wallet).await;

// Create a group with amal and bola
let policy_set = Some(PreconfiguredPolicies::AdminsOnly.to_policy_set());
let amal_group = amal
.create_group_with_members(
&[bola_wallet.get_address()],
policy_set,
GroupMetadataOptions::default(),
)
.await
.unwrap();

// Verify we can update the group name without syncing first
amal_group
.update_group_name("New Group Name 1".to_string())
.await
.unwrap();

// Verify the name is updated
amal_group.sync().await.unwrap();
let group_mutable_metadata = amal_group
.mutable_metadata(&amal_group.mls_provider().unwrap())
.unwrap();
let group_name_1 = group_mutable_metadata
.attributes
.get(&MetadataField::GroupName.to_string())
.unwrap();
assert_eq!(group_name_1, "New Group Name 1");

// Create a group with just amal
let policy_set_2 = Some(PreconfiguredPolicies::AdminsOnly.to_policy_set());
let amal_group_2 = amal
.create_group(policy_set_2, GroupMetadataOptions::default())
.unwrap();

// Verify empty group fails to update metadata before syncing
amal_group_2
.update_group_name("New Group Name 2".to_string())
.await
.expect_err("Should fail to update group name before first sync");

// Sync the group
amal_group_2.sync().await.unwrap();

//Verify we can now update the group name
amal_group_2
.update_group_name("New Group Name 2".to_string())
.await
.unwrap();

// Verify the name is updated
amal_group_2.sync().await.unwrap();
let group_mutable_metadata = amal_group_2
.mutable_metadata(&amal_group_2.mls_provider().unwrap())
.unwrap();
let group_name_2 = group_mutable_metadata
.attributes
.get(&MetadataField::GroupName.to_string())
.unwrap();
assert_eq!(group_name_2, "New Group Name 2");
}

#[wasm_bindgen_test(unsupported = tokio::test(flavor = "current_thread"))]
async fn test_update_group_image_url_square() {
let amal = ClientBuilder::new_test_client(&generate_local_wallet()).await;
Expand Down

0 comments on commit 07ccf0b

Please sign in to comment.