Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions native/swift/Sources/wordpress-api/WPComExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ public extension BotConversation {
return false
}
}

public extension SupportAttachment {
var dimensions: AttachmentDimensions? {
getAttachmentDimensions(attachment: self)
}
}
135 changes: 131 additions & 4 deletions wp_api/src/wp_com/support_tickets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub struct SupportAttachment {
pub content_type: String,
pub size: u64,
pub url: String,
pub metadata: HashMap<String, AttachmentMetadataValue>,
pub metadata: HashMap<AttachmentMetadataKey, AttachmentMetadataValue>,
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Enum)]
Expand All @@ -75,12 +75,25 @@ pub enum SupportMessageAuthor {
SupportAgent(SupportAgentIdentity),
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Enum, strum_macros::Display)]
#[strum(serialize_all = "snake_case")]
#[derive(
Debug,
Hash,
PartialEq,
Eq,
Serialize,
Deserialize,
uniffi::Enum,
strum_macros::Display,
strum_macros::EnumString,
)]
pub enum AttachmentMetadataKey {
#[serde(alias = "width")]
Width,
#[serde(alias = "height")]
Height,
Other(String),
#[serde(untagged)]
#[strum(default)]
Custom(String),
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Enum)]
Expand All @@ -91,6 +104,40 @@ pub enum AttachmentMetadataValue {
Boolean(bool),
}

impl AttachmentMetadataValue {
pub fn get_number(&self) -> Option<u64> {
match self {
AttachmentMetadataValue::Number(number) => Some(*number),
_ => None,
}
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
pub struct AttachmentDimensions {
pub width: u64,
pub height: u64,
}

#[uniffi::export]
pub fn get_attachment_dimensions(attachment: &SupportAttachment) -> Option<AttachmentDimensions> {
let metadata = &attachment.metadata;

let width = metadata
.get(&AttachmentMetadataKey::Width)
.and_then(|v| v.get_number());
let height = metadata
.get(&AttachmentMetadataKey::Height)
.and_then(|v| v.get_number());

if let Some(width) = width
&& let Some(height) = height
{
return Some(AttachmentDimensions { width, height });
}

None
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
pub struct SupportAgentIdentity {
pub id: u64,
Expand Down Expand Up @@ -126,6 +173,7 @@ impl std::fmt::Display for ConversationId {
#[cfg(test)]
mod tests {
use super::*;
use rstest::*;

#[test]
fn test_support_conversation_deserialization() {
Expand All @@ -142,4 +190,83 @@ mod tests {
serde_json::from_str(json).expect("Failed to deserialize support conversation list");
assert_eq!(conversation_list.len(), 11);
}

#[test]
fn test_support_conversation_with_attachments_deserialization() {
let json = include_str!(
"../../tests/wpcom/support_tickets/single-conversation-with-attachments.json"
);
let conversation: SupportConversation =
serde_json::from_str(json).expect("Failed to deserialize support conversation");
assert_eq!(conversation.messages.len(), 1);
assert_eq!(conversation.messages[0].attachments.len(), 2);
assert_eq!(
conversation.messages[0].attachments[0].filename,
"sample-image-1.jpg"
);
assert_eq!(
conversation.messages[0].attachments[0].content_type,
"image/jpeg"
);
assert_eq!(conversation.messages[0].attachments[0].size, 123456);
assert_eq!(
conversation.messages[0].attachments[0].url,
"https://example.com/attachments/token/token1/?name=sample-image-1.jpg"
);

let dimensions =
get_attachment_dimensions(&conversation.messages[0].attachments[0]).unwrap();

assert_eq!(dimensions.width, 1000);
assert_eq!(dimensions.height, 800);

assert_eq!(
conversation.messages[0].attachments[1].filename,
"sample-image-2.jpg"
);
assert_eq!(
conversation.messages[0].attachments[1].content_type,
"image/jpeg"
);
assert_eq!(conversation.messages[0].attachments[1].size, 654321);
assert_eq!(
conversation.messages[0].attachments[1].url,
"https://example.com/attachments/token/token2/?name=sample-image-2.jpg"
);

let dimensions =
get_attachment_dimensions(&conversation.messages[0].attachments[1]).unwrap();
assert_eq!(dimensions.width, 2000);
assert_eq!(dimensions.height, 1600);
}

#[test]
fn test_attachment_metadata_key_custom_deserialization() {
let json = r#"{"Custom": "test"}"#;
let metadata: HashMap<AttachmentMetadataKey, AttachmentMetadataValue> =
serde_json::from_str(json).expect("Failed to deserialize attachment metadata");
assert_eq!(metadata.len(), 1);
}

#[rstest]
#[case(AttachmentMetadataKey::Width, "Width")]
#[case(AttachmentMetadataKey::Height, "Height")]
#[case(
AttachmentMetadataKey::Custom(String::from("testlowercase")),
"testlowercase"
)]
#[case(
AttachmentMetadataKey::Custom(String::from("testWithCamelCase")),
"testWithCamelCase"
)]
#[case(
AttachmentMetadataKey::Custom(String::from("test_with_snake_case")),
"test_with_snake_case"
)]
fn test_attachment_metadata_key_to_string(
#[case] key: AttachmentMetadataKey,
#[case] expected_str: &str,
) {
assert_eq!(key.to_string(), expected_str);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"id": 10000001,
"title": "Test Ticket",
"description": "Redacted for privacy",
"status": "new",
"messages": [
{
"id": 20000001,
"content": "Redacted for privacy",
"role": "user",
"author": {
"id": 30000001,
"name": "Test User",
"email": "test.user@example.com"
},
"author_is_current_user": true,
"created_at": "2025-10-27T21:30:43+00:00",
"attachments": [
{
"id": 40000001,
"filename": "sample-image-1.jpg",
"content_type": "image/jpeg",
"size": 123456,
"url": "https://example.com/attachments/token/token1/?name=sample-image-1.jpg",
"metadata": {
"width": 1000,
"height": 800
}
},
{
"id": 40000002,
"filename": "sample-image-2.jpg",
"content_type": "image/jpeg",
"size": 654321,
"url": "https://example.com/attachments/token/token2/?name=sample-image-2.jpg",
"metadata": {
"width": 2000,
"height": 1600
}
}
]
}
],
"created_at": "2025-10-27T21:30:43+00:00",
"updated_at": "2025-10-27T21:30:43+00:00"
}