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")) 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 @Test
fun `test create VideoMessageType`() = runTest { fun `test create VideoMessageType`() = runTest {
val sut = createTimelineItemContentMessageFactory() val sut = createTimelineItemContentMessageFactory()
@@ -19,7 +19,8 @@ import org.jsoup.safety.Safelist
/** /**
* Converts the HTML string [FormattedBody.body] to a [Document] by parsing it. * 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 `@`. * This will also make sure mentions are prefixed with `@`.
* *
@@ -44,7 +45,7 @@ fun FormattedBody.toHtmlDocument(
// Prepend `@` to mentions // Prepend `@` to mentions
fixMentions(dom, permalinkParser) fixMentions(dom, permalinkParser)
dom dom.takeIf { it.text().isNotBlank() }
} }
} }
@@ -103,4 +103,28 @@ class ToHtmlDocumentTest : RobolectricTest() {
}) })
assertThat(document?.text()).isEqualTo("Hey Alice!") 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.") 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")
}
} }