chat: Fix parsing of 409/410 responses to sendMultiRecipientMessage

This commit is contained in:
Jordan Rose
2025-11-14 17:04:03 -08:00
committed by GitHub
parent 89e3d4df8f
commit 8894050176
5 changed files with 51 additions and 20 deletions

View File

@@ -1,2 +1,3 @@
v0.86.5
- chat: Fixed parsing of 409/410 responses for sendMultiRecipientMessage.

View File

@@ -123,8 +123,10 @@ class UnauthMessagesServiceTest {
[
{
"uuid": "$uuid",
"missingDevices": [4, 5],
"extraDevices": [40, 50]
"devices": {
"missingDevices": [4, 5],
"extraDevices": [40, 50]
}
}
]
""".trimIndent()
@@ -171,7 +173,9 @@ class UnauthMessagesServiceTest {
[
{
"uuid": "$uuid",
"staleDevices": [4, 5]
"devices": {
"staleDevices": [4, 5]
}
}
]
""".trimIndent()

View File

@@ -124,8 +124,10 @@ describe('UnauthMessagesService', () => {
JSON.stringify([
{
uuid,
missingDevices: [4, 5],
extraDevices: [40, 50],
devices: {
missingDevices: [4, 5],
extraDevices: [40, 50],
},
},
])
),
@@ -165,7 +167,9 @@ describe('UnauthMessagesService', () => {
JSON.stringify([
{
uuid,
staleDevices: [4, 5],
devices: {
staleDevices: [4, 5],
},
},
])
),

View File

@@ -121,10 +121,16 @@ fn parse_multi_recipient_mismatched_devices_response(
debug_assert_matches!(response.status.as_u16(), 409 | 410);
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct ParsedMismatchedDevicesEntry {
#[serde(rename = "uuid")]
service_id: String,
devices: ParsedMismatchedDevices,
}
// Note: this can be shared with the 1:1 mismatched devices response.
#[derive(serde::Deserialize, Default, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
struct ParsedMismatchedDevices {
// 409 fields
#[serde(default)]
missing_devices: Vec<u8>,
@@ -158,10 +164,19 @@ fn parse_multi_recipient_mismatched_devices_response(
.map(|entry| {
let ParsedMismatchedDevicesEntry {
service_id,
devices,
} = entry;
if devices == Default::default() {
return Err(CustomError::Unexpected {
log_safe: "no devices listed in mismatched device response".to_owned(),
});
}
let ParsedMismatchedDevices {
missing_devices,
extra_devices,
stale_devices,
} = entry;
} = devices;
Ok(MismatchedDeviceError {
account: ServiceId::parse_from_service_id_string(&service_id).ok_or_else(|| {
CustomError::Unexpected {
@@ -224,8 +239,8 @@ mod test {
#[test_case(empty(409) => matches Err(RequestError::Unexpected { .. }))]
#[test_case(json(
409, format!(r#"[
{{"uuid":"{ACI_UUID}","missingDevices":[50,60]}},
{{"uuid":"PNI:{PNI_UUID}","missingDevices":[],"extraDevices":[4,5]}}
{{"uuid":"{ACI_UUID}","devices":{{"missingDevices":[50,60]}}}},
{{"uuid":"PNI:{PNI_UUID}","devices":{{"missingDevices":[],"extraDevices":[4,5]}}}}
]"#)
) => matches Err(RequestError::Other(MrFailure::MismatchedDevices(errors))) if errors == [
MismatchedDeviceError {
@@ -243,8 +258,8 @@ mod test {
])]
#[test_case(json(
410, format!(r#"[
{{"uuid":"{ACI_UUID}","staleDevices":[4,5]}},
{{"uuid":"PNI:{PNI_UUID}","staleDevices":[]}}
{{"uuid":"{ACI_UUID}","devices":{{"staleDevices":[4,5]}}}},
{{"uuid":"PNI:{PNI_UUID}","devices":{{"staleDevices":[1]}}}}
]"#)
) => matches Err(RequestError::Other(MrFailure::MismatchedDevices(errors))) if errors == [
MismatchedDeviceError {
@@ -257,23 +272,26 @@ mod test {
account: Pni::from(Uuid::try_parse(PNI_UUID).unwrap()).into(),
missing_devices: vec![],
extra_devices: vec![],
stale_devices: vec![],
stale_devices: vec![DeviceId::new(1).unwrap()],
},
])]
#[test_case(json(
410, r#"["#
) => matches Err(RequestError::Unexpected { .. }))]
#[test_case(json(
410, format!(r#"{{"uuid":"{ACI_UUID}","staleDevices":[4,5]}}"#)
410, format!(r#"{{"uuid":"{ACI_UUID}","devices":{{"staleDevices":[4,5]}}}}"#)
) => matches Err(RequestError::Unexpected { .. }))]
#[test_case(json(
410, r#"[{"uuid":"garbage","staleDevices":[4,5]}]"#
410, format!(r#"[{{"uuid":"{ACI_UUID}","devices":{{}}}}]"#)
) => matches Err(RequestError::Unexpected { .. }))]
#[test_case(json(
410, format!(r#"{{"uuid":"{ACI_UUID}","staleDevices":[200]}}"#)
410, r#"[{"uuid":"garbage","devices":{{"staleDevices":[4,5]}}}]"#
) => matches Err(RequestError::Unexpected { .. }))]
#[test_case(json(
410, format!(r#"{{"uuid":"{ACI_UUID}","staleDevices":["4"]}}"#)
410, format!(r#"[{{"uuid":"{ACI_UUID}","devices":{{"staleDevices":[200]}}}}]"#)
) => matches Err(RequestError::Unexpected { .. }))]
#[test_case(json(
410, format!(r#"[{{"uuid":"{ACI_UUID}","devices":{{"staleDevices":["4"]}}}}]"#)
) => matches Err(RequestError::Unexpected { .. }))]
fn test_story(
response: Response,

View File

@@ -86,8 +86,10 @@ class UnauthMessagesServiceTests: UnauthChatServiceTestBase<any UnauthMessagesSe
[
{
"uuid": "\(uuid)",
"missingDevices": [4, 5],
"extraDevices": [40, 50]
"devices": {
"missingDevices": [4, 5],
"extraDevices": [40, 50]
}
}
]
""".utf8
@@ -118,7 +120,9 @@ class UnauthMessagesServiceTests: UnauthChatServiceTestBase<any UnauthMessagesSe
[
{
"uuid": "\(uuid)",
"staleDevices": [4, 5]
"devices": {
"staleDevices": [4, 5]
}
}
]
""".utf8