Merge pull request #7523 from hayaksi1/fix/1874-empty-formatted-body

Fall back to the message body when the formatted body has nothing to render
This commit is contained in:
Benoit Marty
2026-09-01 11:37:59 +02:00
committed by GitHub
4 changed files with 58 additions and 2 deletions
@@ -229,6 +229,25 @@ class TimelineItemContentMessageFactoryTest : RobolectricTest() {
assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(SpannedString("body"))
}
@Test
fun `test create TextMessageType with a formatted body containing only an image falls back to the body`() = runTest {
val sut = createTimelineItemContentMessageFactory()
val result = sut.create(
content = createMessageContent(
type = TextMessageType(
body = "\uD83D\uDE1C",
formatted = FormattedBody(MessageFormat.HTML, "<img src=\"mxc://matrix.org/anImage\" alt=\"\uD83D\uDE1C\" />")
)
),
senderId = A_USER_ID,
senderProfile = aProfileDetails(),
eventId = AN_EVENT_ID,
)
assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(SpannedString("\uD83D\uDE1C"))
assertThat(result.htmlDocument).isNull()
assertThat(result.plainText).isEqualTo("\uD83D\uDE1C")
}
@Test
fun `test create VideoMessageType`() = runTest {
val sut = createTimelineItemContentMessageFactory()
@@ -19,7 +19,8 @@ import org.jsoup.safety.Safelist
/**
* Converts the HTML string [FormattedBody.body] to a [Document] by parsing it.
* If the message is not formatted or the format is not [MessageFormat.HTML] we return `null`.
* If the message is not formatted, the format is not [MessageFormat.HTML], or nothing renderable is left once the
* unsupported tags have been removed, we return `null` so that the plain text body is used instead.
*
* This will also make sure mentions are prefixed with `@`.
*
@@ -44,7 +45,7 @@ fun FormattedBody.toHtmlDocument(
// Prepend `@` to mentions
fixMentions(dom, permalinkParser)
dom
dom.takeIf { it.text().isNotBlank() }
}
}
@@ -103,4 +103,28 @@ class ToHtmlDocumentTest : RobolectricTest() {
})
assertThat(document?.text()).isEqualTo("Hey Alice!")
}
@Test
fun `toHtmlDocument - returns null if the body only contains unsupported tags`() {
val body = FormattedBody(
format = MessageFormat.HTML,
body = "<img data-mx-emoticon src=\"mxc://matrix.org/anImage\" height=\"32\" width=\"32\" alt=\"\uD83D\uDE1C\" />"
)
val document = body.toHtmlDocument(permalinkParser = FakePermalinkParser())
assertThat(document).isNull()
}
@Test
fun `toHtmlDocument - returns a Document if some text survives next to unsupported tags`() {
val body = FormattedBody(
format = MessageFormat.HTML,
body = "Look at this <img src=\"mxc://matrix.org/anImage\" alt=\"cat\" />!"
)
val document = body.toHtmlDocument(permalinkParser = FakePermalinkParser())
assertThat(document?.text()).isEqualTo("Look at this !")
}
}
@@ -149,4 +149,16 @@ class ToPlainTextTest : RobolectricTest() {
)
assertThat(messageType.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo("This is the message content.")
}
@Test
fun `TextMessageType toPlainText - returns the body if the formatted one only contains an image`() {
val messageType = TextMessageType(
body = "\uD83D\uDE1C",
formatted = FormattedBody(
format = MessageFormat.HTML,
body = "<img data-mx-emoticon src=\"mxc://matrix.org/anImage\" height=\"32\" width=\"32\" alt=\"\uD83D\uDE1C\" />"
)
)
assertThat(messageType.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo("\uD83D\uDE1C")
}
}