Skip to content

Commit

Permalink
added pinned frame metadata field
Browse files Browse the repository at this point in the history
  • Loading branch information
cameronvoell committed Jul 2, 2024
1 parent cdbebc9 commit 8e827c6
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 3 deletions.
41 changes: 41 additions & 0 deletions bindings_ffi/src/mls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ pub struct FfiPermissionPolicySet {
pub update_group_name_policy: FfiPermissionPolicy,
pub update_group_description_policy: FfiPermissionPolicy,
pub update_group_image_url_square_policy: FfiPermissionPolicy,
pub update_pinned_frame_policy: FfiPermissionPolicy,
}

impl From<PreconfiguredPolicies> for FfiGroupPermissionsOptions {
Expand All @@ -464,6 +465,7 @@ pub enum FfiMetadataField {
GroupName,
Description,
ImageUrlSquare,
PinnedFrame,
}

impl From<&FfiMetadataField> for MetadataField {
Expand All @@ -472,6 +474,7 @@ impl From<&FfiMetadataField> for MetadataField {
FfiMetadataField::GroupName => MetadataField::GroupName,
FfiMetadataField::Description => MetadataField::Description,
FfiMetadataField::ImageUrlSquare => MetadataField::GroupImageUrlSquare,
FfiMetadataField::PinnedFrame => MetadataField::PinnedFrame,
}
}
}
Expand Down Expand Up @@ -639,6 +642,7 @@ pub struct FfiCreateGroupOptions {
pub group_name: Option<String>,
pub group_image_url_square: Option<String>,
pub group_description: Option<String>,
pub pinned_frame: Option<String>,
}

impl FfiCreateGroupOptions {
Expand All @@ -647,6 +651,7 @@ impl FfiCreateGroupOptions {
name: self.group_name,
image_url_square: self.group_image_url_square,
description: self.group_description,
pinned_frame: self.pinned_frame,
}
}
}
Expand Down Expand Up @@ -897,6 +902,35 @@ impl FfiGroup {
Ok(group_description)
}

pub async fn update_pinned_frame(
&self,
pinned_frame: String,
) -> Result<(), GenericError> {
let group = MlsGroup::new(
self.inner_client.context().clone(),
self.group_id.clone(),
self.created_at_ns,
);

group
.update_pinned_frame(&self.inner_client, pinned_frame)
.await?;

Ok(())
}

pub fn group_pinned_frame(&self) -> Result<String, GenericError> {
let group = MlsGroup::new(
self.inner_client.context().clone(),
self.group_id.clone(),
self.created_at_ns,
);

let group_pinned_frame = group.group_pinned_frame()?;

Ok(group_pinned_frame)
}

pub fn admin_list(&self) -> Result<Vec<String>, GenericError> {
let group = MlsGroup::new(
self.inner_client.context().clone(),
Expand Down Expand Up @@ -1241,6 +1275,7 @@ impl FfiGroupPermissions {
update_group_image_url_square_policy: get_policy(
MetadataField::GroupImageUrlSquare.as_str(),
),
update_pinned_frame_policy: get_policy(MetadataField::PinnedFrame.as_str()),
})
}
}
Expand Down Expand Up @@ -1570,6 +1605,7 @@ mod tests {
group_name: Some("Group Name".to_string()),
group_image_url_square: Some("url".to_string()),
group_description: Some("group description".to_string()),
pinned_frame: Some("pinned frame".to_string()),
},
)
.await
Expand All @@ -1580,6 +1616,7 @@ mod tests {
assert_eq!(group.group_name().unwrap(), "Group Name");
assert_eq!(group.group_image_url_square().unwrap(), "url");
assert_eq!(group.group_description().unwrap(), "group description");
assert_eq!(group.group_pinned_frame().unwrap(), "pinned frame");
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
Expand Down Expand Up @@ -2131,6 +2168,7 @@ mod tests {
update_group_name_policy: FfiPermissionPolicy::Admin,
update_group_description_policy: FfiPermissionPolicy::Admin,
update_group_image_url_square_policy: FfiPermissionPolicy::Admin,
update_pinned_frame_policy: FfiPermissionPolicy::Admin,
};
assert_eq!(alix_permission_policy_set, expected_permission_policy_set);

Expand Down Expand Up @@ -2159,6 +2197,7 @@ mod tests {
update_group_name_policy: FfiPermissionPolicy::Allow,
update_group_description_policy: FfiPermissionPolicy::Allow,
update_group_image_url_square_policy: FfiPermissionPolicy::Allow,
update_pinned_frame_policy: FfiPermissionPolicy::Allow,
};
assert_eq!(alix_permission_policy_set, expected_permission_policy_set);
}
Expand Down Expand Up @@ -2191,6 +2230,7 @@ mod tests {
update_group_name_policy: FfiPermissionPolicy::Admin,
update_group_description_policy: FfiPermissionPolicy::Admin,
update_group_image_url_square_policy: FfiPermissionPolicy::Admin,
update_pinned_frame_policy: FfiPermissionPolicy::Admin,
};
assert_eq!(alix_group_permissions, expected_permission_policy_set);

Expand All @@ -2217,6 +2257,7 @@ mod tests {
update_group_name_policy: FfiPermissionPolicy::Admin,
update_group_description_policy: FfiPermissionPolicy::Admin,
update_group_image_url_square_policy: FfiPermissionPolicy::Allow,
update_pinned_frame_policy: FfiPermissionPolicy::Admin,
};
assert_eq!(alix_group_permissions, new_expected_permission_policy_set);

Expand Down
1 change: 1 addition & 0 deletions xmtp_mls/src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub const GROUP_PERMISSIONS_EXTENSION_ID: u16 = 0xff02;
pub const DEFAULT_GROUP_NAME: &str = "";
pub const DEFAULT_GROUP_DESCRIPTION: &str = "";
pub const DEFAULT_GROUP_IMAGE_URL_SQUARE: &str = "";
pub const DEFAULT_PINNED_FRAME: &str = "";

// If a metadata field name starts with this character,
// and it does not have a policy set, it is a super admin only field
Expand Down
10 changes: 8 additions & 2 deletions xmtp_mls/src/groups/group_mutable_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ use xmtp_proto::xmtp::mls::message_contents::{
};

use crate::configuration::{
DEFAULT_GROUP_DESCRIPTION, DEFAULT_GROUP_IMAGE_URL_SQUARE, DEFAULT_GROUP_NAME,
MUTABLE_METADATA_EXTENSION_ID,
DEFAULT_GROUP_DESCRIPTION, DEFAULT_GROUP_IMAGE_URL_SQUARE, DEFAULT_GROUP_NAME, DEFAULT_PINNED_FRAME, MUTABLE_METADATA_EXTENSION_ID
};

use super::GroupMetadataOptions;
Expand Down Expand Up @@ -42,6 +41,7 @@ pub enum MetadataField {
GroupName,
Description,
GroupImageUrlSquare,
PinnedFrame,
}

impl MetadataField {
Expand All @@ -50,6 +50,7 @@ impl MetadataField {
MetadataField::GroupName => "group_name",
MetadataField::Description => "description",
MetadataField::GroupImageUrlSquare => "group_image_url_square",
MetadataField::PinnedFrame => "pinned_frame",
}
}
}
Expand Down Expand Up @@ -97,6 +98,10 @@ impl GroupMutableMetadata {
opts.image_url_square
.unwrap_or_else(|| DEFAULT_GROUP_IMAGE_URL_SQUARE.to_string()),
);
attributes.insert(
MetadataField::PinnedFrame.to_string(),
opts.pinned_frame.unwrap_or_else(|| DEFAULT_PINNED_FRAME.to_string()),
);
let admin_list = vec![];
let super_admin_list = vec![creator_inbox_id.clone()];
Self {
Expand All @@ -112,6 +117,7 @@ impl GroupMutableMetadata {
MetadataField::GroupName,
MetadataField::Description,
MetadataField::GroupImageUrlSquare,
MetadataField::PinnedFrame,
]
}

Expand Down
7 changes: 7 additions & 0 deletions xmtp_mls/src/groups/intents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,13 @@ impl UpdateMetadataIntentData {
field_value: group_description,
}
}

pub fn new_update_pinned_frame(pinned_frame: String) -> Self {
Self {
field_name: MetadataField::PinnedFrame.to_string(),
field_value: pinned_frame,
}
}
}

impl From<UpdateMetadataIntentData> for Vec<u8> {
Expand Down
78 changes: 77 additions & 1 deletion xmtp_mls/src/groups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ pub struct GroupMetadataOptions {
pub name: Option<String>,
pub image_url_square: Option<String>,
pub description: Option<String>,
pub pinned_frame: Option<String>,
}

impl Clone for MlsGroup {
Expand Down Expand Up @@ -736,6 +737,41 @@ impl MlsGroup {
}
}

pub async fn update_pinned_frame<ApiClient>(
&self,
client: &Client<ApiClient>,
pinned_frame: String,
) -> Result<(), GroupError>
where
ApiClient: XmtpApi,
{
let conn = self.context.store.conn()?;
let intent_data: Vec<u8> =
UpdateMetadataIntentData::new_update_pinned_frame(pinned_frame)
.into();
let intent = conn.insert_group_intent(NewGroupIntent::new(
IntentKind::MetadataUpdate,
self.group_id.clone(),
intent_data,
))?;

self.sync_until_intent_resolved(conn, intent.id, client)
.await
}

pub fn group_pinned_frame(&self) -> Result<String, GroupError> {
let mutable_metadata = self.mutable_metadata()?;
match mutable_metadata
.attributes
.get(&MetadataField::PinnedFrame.to_string())
{
Some(pinned_frame) => Ok(pinned_frame.clone()),
None => Err(GroupError::GroupMutableMetadata(
GroupMutableMetadataError::MissingExtension,
)),
}
}

pub fn admin_list(&self) -> Result<Vec<String>, GroupError> {
let mutable_metadata = self.mutable_metadata()?;
Ok(mutable_metadata.admin_list)
Expand Down Expand Up @@ -1785,6 +1821,7 @@ mod tests {
name: Some("Group Name".to_string()),
image_url_square: Some("url".to_string()),
description: Some("group description".to_string()),
pinned_frame: Some("pinned frame".to_string()),
},
)
.unwrap();
Expand All @@ -1802,10 +1839,15 @@ mod tests {
.attributes
.get(&MetadataField::Description.to_string())
.unwrap();
let amal_group_pinned_frame: &String = binding
.attributes
.get(&MetadataField::PinnedFrame.to_string())
.unwrap();

assert_eq!(amal_group_name, "Group Name");
assert_eq!(amal_group_image_url, "url");
assert_eq!(amal_group_description, "group description");
assert_eq!(amal_group_pinned_frame, "pinned frame");
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
Expand Down Expand Up @@ -1848,7 +1890,7 @@ mod tests {
amal_group.sync(&amal).await.unwrap();

let group_mutable_metadata = amal_group.mutable_metadata().unwrap();
assert!(group_mutable_metadata.attributes.len().eq(&3));
assert!(group_mutable_metadata.attributes.len().eq(&4));
assert!(group_mutable_metadata
.attributes
.get(&MetadataField::GroupName.to_string())
Expand Down Expand Up @@ -1951,6 +1993,40 @@ mod tests {
assert_eq!(amal_group_image_url, "a url");
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_update_group_pinned_frame() {
let amal = ClientBuilder::new_test_client(&generate_local_wallet()).await;

// Create a group and verify it has the default group name
let policies = Some(PreconfiguredPolicies::AdminsOnly);
let amal_group: MlsGroup = amal
.create_group(policies, GroupMetadataOptions::default())
.unwrap();
amal_group.sync(&amal).await.unwrap();

let group_mutable_metadata = amal_group.mutable_metadata().unwrap();
assert!(group_mutable_metadata
.attributes
.get(&MetadataField::PinnedFrame.to_string())
.unwrap()
.eq(""));

// Update group name
amal_group
.update_pinned_frame(&amal, "a frame url".to_string())
.await
.unwrap();

// Verify amal group sees update
amal_group.sync(&amal).await.unwrap();
let binding = amal_group.mutable_metadata().expect("msg");
let amal_group_pinned_frame: &String = binding
.attributes
.get(&MetadataField::PinnedFrame.to_string())
.unwrap();
assert_eq!(amal_group_pinned_frame, "a frame url");
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_group_mutable_data_group_permissions() {
let amal = ClientBuilder::new_test_client(&generate_local_wallet()).await;
Expand Down

0 comments on commit 8e827c6

Please sign in to comment.