From a476544761b427f7388ab5fbbbbf3e0b105a59be Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 14 Nov 2022 12:01:29 +0100 Subject: [PATCH] Fix some quoted messages having 'null' message bodies (#7532) * Fix some quoted messages having 'null' message bodies --- changelog.d/7530.sdk | 1 + .../room/send/LocalEchoEventFactory.kt | 65 +++-- .../room/send/LocalEchoEventFactoryTests.kt | 241 ++++++++++++++++++ .../sdk/test/fakes/FakeClipboardManager.kt | 37 +++ .../sdk/test/fakes/FakeConnectivityManager.kt | 44 ++++ .../android/sdk/test/fakes/FakeContext.kt | 84 ++++++ .../sdk/test/fakes/FakeNetworkCapabilities.kt | 32 +++ .../session/content/FakeThumbnailExtractor.kt | 24 ++ .../permalinks/FakePermalinkFactory.kt | 24 ++ .../room/send/FakeLocalEchoRepository.kt | 24 ++ .../session/room/send/FakeMarkdownParser.kt | 32 +++ .../room/send/FakeWaveFormSanitizer.kt | 24 ++ .../room/send/pills/FakeTextPillsUtils.kt | 24 ++ 13 files changed, 631 insertions(+), 25 deletions(-) create mode 100644 changelog.d/7530.sdk create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactoryTests.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeClipboardManager.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeConnectivityManager.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeContext.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeNetworkCapabilities.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/content/FakeThumbnailExtractor.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/permalinks/FakePermalinkFactory.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeLocalEchoRepository.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeMarkdownParser.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeWaveFormSanitizer.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/pills/FakeTextPillsUtils.kt diff --git a/changelog.d/7530.sdk b/changelog.d/7530.sdk new file mode 100644 index 0000000000..4cea35f44b --- /dev/null +++ b/changelog.d/7530.sdk @@ -0,0 +1 @@ +Fix a bug that caused messages with no formatted text to be quoted as "null". diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index 7d8605c2bd..55ba78c2a5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -804,20 +804,12 @@ internal class LocalEchoEventFactory @Inject constructor( additionalContent: Content? = null, ): Event { val messageContent = quotedEvent.getLastMessageContent() - val textMsg = if (messageContent is MessageContentWithFormattedBody) { - messageContent.formattedBody - } else { - messageContent?.body - } - val quoteText = legacyRiotQuoteText(textMsg, text) - val quoteFormattedText = "
$textMsg
$formattedText" - + val formattedQuotedText = (messageContent as? MessageContentWithFormattedBody)?.formattedBody + val textContent = createQuoteTextContent(messageContent?.body, formattedQuotedText, text, formattedText, autoMarkdown) return if (rootThreadEventId != null) { createMessageEvent( roomId, - markdownParser - .parse(quoteText, force = true, advanced = autoMarkdown).copy(formattedText = quoteFormattedText) - .toThreadTextContent( + textContent.toThreadTextContent( rootThreadEventId = rootThreadEventId, latestThreadEventId = localEchoRepository.getLatestThreadEvent(rootThreadEventId), msgType = MessageType.MSGTYPE_TEXT @@ -827,31 +819,54 @@ internal class LocalEchoEventFactory @Inject constructor( } else { createFormattedTextEvent( roomId, - markdownParser.parse(quoteText, force = true, advanced = autoMarkdown).copy(formattedText = quoteFormattedText), + textContent, MessageType.MSGTYPE_TEXT, additionalContent, ) } } - private fun legacyRiotQuoteText(quotedText: String?, myText: String): String { - val messageParagraphs = quotedText?.split("\n\n".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray() - return buildString { - if (messageParagraphs != null) { - for (i in messageParagraphs.indices) { - if (messageParagraphs[i].isNotBlank()) { - append("> ") - append(messageParagraphs[i]) - } + private fun createQuoteTextContent( + quotedText: String?, + formattedQuotedText: String?, + text: String, + formattedText: String?, + autoMarkdown: Boolean + ): TextContent { + val currentFormattedText = formattedText ?: if (autoMarkdown) { + val parsed = markdownParser.parse(text, force = true, advanced = true) + // If formattedText == text, formattedText is returned as null + parsed.formattedText ?: parsed.text + } else { + text + } + val processedFormattedQuotedText = formattedQuotedText ?: quotedText - if (i != messageParagraphs.lastIndex) { - append("\n\n") - } + val plainTextBody = buildString { + val plainMessageParagraphs = quotedText?.split("\n\n".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray().orEmpty() + plainMessageParagraphs.forEachIndexed { index, paragraph -> + if (paragraph.isNotBlank()) { + append("> ") + append(paragraph) + } + + if (index != plainMessageParagraphs.lastIndex) { + append("\n\n") } } append("\n\n") - append(myText) + append(text) } + val formattedTextBody = buildString { + if (!processedFormattedQuotedText.isNullOrBlank()) { + append("
") + append(processedFormattedQuotedText) + append("
") + } + append("
") + append(currentFormattedText) + } + return TextContent(plainTextBody, formattedTextBody) } companion object { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactoryTests.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactoryTests.kt new file mode 100644 index 0000000000..b30428e5e1 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactoryTests.kt @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.send + +import org.amshove.kluent.internal.assertEquals +import org.junit.Before +import org.junit.Test +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.EditAggregatedSummary +import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary +import org.matrix.android.sdk.api.session.room.model.message.MessageContent +import org.matrix.android.sdk.api.session.room.model.message.MessageContentWithFormattedBody +import org.matrix.android.sdk.api.session.room.sender.SenderInfo +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.api.util.TextContent +import org.matrix.android.sdk.test.fakes.FakeClock +import org.matrix.android.sdk.test.fakes.FakeContext +import org.matrix.android.sdk.test.fakes.internal.session.content.FakeThumbnailExtractor +import org.matrix.android.sdk.test.fakes.internal.session.permalinks.FakePermalinkFactory +import org.matrix.android.sdk.test.fakes.internal.session.room.send.FakeLocalEchoRepository +import org.matrix.android.sdk.test.fakes.internal.session.room.send.FakeMarkdownParser +import org.matrix.android.sdk.test.fakes.internal.session.room.send.FakeWaveFormSanitizer +import org.matrix.android.sdk.test.fakes.internal.session.room.send.pills.FakeTextPillsUtils + +@Suppress("MaxLineLength") +class LocalEchoEventFactoryTests { + + companion object { + internal const val A_USER_ID_1 = "@user_1:matrix.org" + internal const val A_ROOM_ID = "!sUeOGZKsBValPTUMax:matrix.org" + internal const val AN_EVENT_ID = "\$vApgexcL8Vfh-WxYKsFKCDooo67ttbjm3TiVKXaWijU" + internal const val AN_EPOCH = 1655210176L + + val A_START_EVENT = Event( + type = EventType.STATE_ROOM_CREATE, + eventId = AN_EVENT_ID, + originServerTs = 1652435922563, + senderId = A_USER_ID_1, + roomId = A_ROOM_ID + ) + } + + private val fakeContext = FakeContext() + private val fakeMarkdownParser = FakeMarkdownParser() + private val fakeTextPillsUtils = FakeTextPillsUtils() + private val fakeThumbnailExtractor = FakeThumbnailExtractor() + private val fakeWaveFormSanitizer = FakeWaveFormSanitizer() + private val fakeLocalEchoRepository = FakeLocalEchoRepository() + private val fakePermalinkFactory = FakePermalinkFactory() + private val fakeClock = FakeClock() + + private val localEchoEventFactory = LocalEchoEventFactory( + context = fakeContext.instance, + userId = A_USER_ID_1, + markdownParser = fakeMarkdownParser.instance, + textPillsUtils = fakeTextPillsUtils.instance, + thumbnailExtractor = fakeThumbnailExtractor.instance, + waveformSanitizer = fakeWaveFormSanitizer.instance, + localEchoRepository = fakeLocalEchoRepository.instance, + permalinkFactory = fakePermalinkFactory.instance, + clock = fakeClock + ) + + @Before + fun setup() { + fakeClock.givenEpoch(AN_EPOCH) + fakeMarkdownParser.givenBoldMarkdown() + } + + @Test + fun `given a null quotedText, when a quote event is created, then the result message should only contain the new text after new lines`() { + val event = createTimelineEvent(null, null) + val quotedContent = localEchoEventFactory.createQuotedTextEvent( + roomId = A_ROOM_ID, + quotedEvent = event, + text = "Text", + formattedText = null, + autoMarkdown = false, + rootThreadEventId = null, + additionalContent = null, + ).content.toModel() + assertEquals("\n\nText", quotedContent?.body) + assertEquals("
Text", (quotedContent as? MessageContentWithFormattedBody)?.formattedBody) + } + + @Test + fun `given a plain text quoted message, when a quote event is created, then the result message should contain both the quoted and new text`() { + val event = createTimelineEvent("Quoted", null) + val quotedContent = localEchoEventFactory.createQuotedTextEvent( + roomId = A_ROOM_ID, + quotedEvent = event, + text = "Text", + formattedText = null, + autoMarkdown = false, + rootThreadEventId = null, + additionalContent = null, + ).content.toModel() + assertEquals("> Quoted\n\nText", quotedContent?.body) + assertEquals("
Quoted

Text", (quotedContent as? MessageContentWithFormattedBody)?.formattedBody) + } + + @Test + fun `given a formatted text quoted message, when a quote event is created, then the result message should contain both the formatted quote and new text`() { + val event = createTimelineEvent("Quoted", "Quoted") + val quotedContent = localEchoEventFactory.createQuotedTextEvent( + roomId = A_ROOM_ID, + quotedEvent = event, + text = "Text", + formattedText = null, + autoMarkdown = false, + rootThreadEventId = null, + additionalContent = null, + ).content.toModel() + // This still uses the plain text version + assertEquals("> Quoted\n\nText", quotedContent?.body) + // This one has the formatted one + assertEquals("
Quoted

Text", (quotedContent as? MessageContentWithFormattedBody)?.formattedBody) + } + + @Test + fun `given formatted text quoted message and new message, when a quote event is created, then the result message should contain both the formatted quote and new formatted text`() { + val event = createTimelineEvent("Quoted", "Quoted") + val quotedContent = localEchoEventFactory.createQuotedTextEvent( + roomId = A_ROOM_ID, + quotedEvent = event, + text = "Text", + formattedText = "Formatted text", + autoMarkdown = false, + rootThreadEventId = null, + additionalContent = null, + ).content.toModel() + // This still uses the plain text version + assertEquals("> Quoted\n\nText", quotedContent?.body) + // This one has the formatted one + assertEquals( + "
Quoted

Formatted text", + (quotedContent as? MessageContentWithFormattedBody)?.formattedBody + ) + } + + @Test + fun `given formatted text quoted message and new message with autoMarkdown, when a quote event is created, then the result message should contain both the formatted quote and new formatted text, not the markdown processed text`() { + val event = createTimelineEvent("Quoted", "Quoted") + val quotedContent = localEchoEventFactory.createQuotedTextEvent( + roomId = A_ROOM_ID, + quotedEvent = event, + text = "Text", + formattedText = "Formatted text", + autoMarkdown = true, + rootThreadEventId = null, + additionalContent = null, + ).content.toModel() + // This still uses the plain text version + assertEquals("> Quoted\n\nText", quotedContent?.body) + // This one has the formatted one + assertEquals( + "
Quoted

Formatted text", + (quotedContent as? MessageContentWithFormattedBody)?.formattedBody + ) + } + + @Test + fun `given a formatted text quoted message and a new message with autoMarkdown, when a quote event is created, then the result message should contain both the formatted quote and new processed formatted text`() { + val event = createTimelineEvent("Quoted", "Quoted") + val quotedContent = localEchoEventFactory.createQuotedTextEvent( + roomId = A_ROOM_ID, + quotedEvent = event, + text = "**Text**", + formattedText = null, + autoMarkdown = true, + rootThreadEventId = null, + additionalContent = null, + ).content.toModel() + // This still uses the markdown text version + assertEquals("> Quoted\n\n**Text**", quotedContent?.body) + // This one has the formatted one + assertEquals( + "
Quoted

Text", + (quotedContent as? MessageContentWithFormattedBody)?.formattedBody + ) + } + + @Test + fun `given a plain text quoted message and a new message with autoMarkdown, when a quote event is created, then the result message should the plain text quote and new processed formatted text`() { + val event = createTimelineEvent("Quoted", null) + val quotedContent = localEchoEventFactory.createQuotedTextEvent( + roomId = A_ROOM_ID, + quotedEvent = event, + text = "**Text**", + formattedText = null, + autoMarkdown = true, + rootThreadEventId = null, + additionalContent = null, + ).content.toModel() + // This still uses the markdown text version + assertEquals("> Quoted\n\n**Text**", quotedContent?.body) + // This one has the formatted one + assertEquals( + "
Quoted

Text", + (quotedContent as? MessageContentWithFormattedBody)?.formattedBody + ) + } + + private fun createTimelineEvent(quotedText: String?, formattedQuotedText: String?): TimelineEvent { + val textContent = quotedText?.let { + TextContent( + quotedText, + formattedQuotedText + ).toMessageTextContent().toContent() + } + return TimelineEvent( + root = A_START_EVENT, + localId = 1234, + eventId = AN_EVENT_ID, + displayIndex = 0, + senderInfo = SenderInfo(A_USER_ID_1, A_USER_ID_1, true, null), + annotations = if (textContent != null) { + EventAnnotationsSummary( + editSummary = EditAggregatedSummary(latestContent = textContent, emptyList(), emptyList()) + ) + } else null + ) + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeClipboardManager.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeClipboardManager.kt new file mode 100644 index 0000000000..bce8b41aa9 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeClipboardManager.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes + +import android.content.ClipData +import android.content.ClipboardManager +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.runs +import io.mockk.verify + +class FakeClipboardManager { + val instance = mockk() + + fun givenSetPrimaryClip() { + every { instance.setPrimaryClip(any()) } just runs + } + + fun verifySetPrimaryClip(clipData: ClipData) { + verify { instance.setPrimaryClip(clipData) } + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeConnectivityManager.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeConnectivityManager.kt new file mode 100644 index 0000000000..5c3a245c51 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeConnectivityManager.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes + +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkCapabilities +import io.mockk.every +import io.mockk.mockk + +class FakeConnectivityManager { + val instance = mockk() + + fun givenNoActiveConnection() { + every { instance.activeNetwork } returns null + } + + fun givenHasActiveConnection() { + val network = mockk() + every { instance.activeNetwork } returns network + + val networkCapabilities = FakeNetworkCapabilities() + networkCapabilities.givenTransports( + NetworkCapabilities.TRANSPORT_CELLULAR, + NetworkCapabilities.TRANSPORT_WIFI, + NetworkCapabilities.TRANSPORT_VPN + ) + every { instance.getNetworkCapabilities(network) } returns networkCapabilities.instance + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeContext.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeContext.kt new file mode 100644 index 0000000000..966c6a1bb2 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeContext.kt @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes + +import android.content.ClipboardManager +import android.content.ContentResolver +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.Uri +import android.os.ParcelFileDescriptor +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.runs +import java.io.OutputStream + +class FakeContext( + private val contentResolver: ContentResolver = mockk() +) { + + val instance = mockk() + + init { + every { instance.contentResolver } returns contentResolver + every { instance.applicationContext } returns instance + } + + fun givenFileDescriptor(uri: Uri, mode: String, factory: () -> ParcelFileDescriptor?) { + val fileDescriptor = factory() + every { contentResolver.openFileDescriptor(uri, mode, null) } returns fileDescriptor + } + + fun givenSafeOutputStreamFor(uri: Uri): OutputStream { + val outputStream = mockk(relaxed = true) + every { contentResolver.openOutputStream(uri, "wt") } returns outputStream + return outputStream + } + + fun givenMissingSafeOutputStreamFor(uri: Uri) { + every { contentResolver.openOutputStream(uri, "wt") } returns null + } + + fun givenNoConnection() { + val connectivityManager = FakeConnectivityManager() + connectivityManager.givenNoActiveConnection() + givenService(Context.CONNECTIVITY_SERVICE, ConnectivityManager::class.java, connectivityManager.instance) + } + + fun givenService(name: String, klass: Class, service: T) { + every { instance.getSystemService(name) } returns service + every { instance.getSystemService(klass) } returns service + } + + fun givenHasConnection() { + val connectivityManager = FakeConnectivityManager() + connectivityManager.givenHasActiveConnection() + givenService(Context.CONNECTIVITY_SERVICE, ConnectivityManager::class.java, connectivityManager.instance) + } + + fun givenStartActivity(intent: Intent) { + every { instance.startActivity(intent) } just runs + } + + fun givenClipboardManager(): FakeClipboardManager { + val fakeClipboardManager = FakeClipboardManager() + givenService(Context.CLIPBOARD_SERVICE, ClipboardManager::class.java, fakeClipboardManager.instance) + return fakeClipboardManager + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeNetworkCapabilities.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeNetworkCapabilities.kt new file mode 100644 index 0000000000..c630b94d47 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeNetworkCapabilities.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes + +import android.net.NetworkCapabilities +import io.mockk.every +import io.mockk.mockk + +class FakeNetworkCapabilities { + val instance = mockk() + + fun givenTransports(vararg type: Int) { + every { instance.hasTransport(any()) } answers { + val input = it.invocation.args.first() as Int + type.contains(input) + } + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/content/FakeThumbnailExtractor.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/content/FakeThumbnailExtractor.kt new file mode 100644 index 0000000000..b541d24161 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/content/FakeThumbnailExtractor.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes.internal.session.content + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor + +class FakeThumbnailExtractor { + internal val instance = mockk() +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/permalinks/FakePermalinkFactory.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/permalinks/FakePermalinkFactory.kt new file mode 100644 index 0000000000..3d7e85424e --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/permalinks/FakePermalinkFactory.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes.internal.session.permalinks + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory + +class FakePermalinkFactory { + internal val instance = mockk() +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeLocalEchoRepository.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeLocalEchoRepository.kt new file mode 100644 index 0000000000..b10d13824b --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeLocalEchoRepository.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes.internal.session.room.send + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository + +class FakeLocalEchoRepository { + internal val instance = mockk() +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeMarkdownParser.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeMarkdownParser.kt new file mode 100644 index 0000000000..a27c9284e7 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeMarkdownParser.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes.internal.session.room.send + +import io.mockk.every +import io.mockk.mockk +import org.matrix.android.sdk.api.util.TextContent +import org.matrix.android.sdk.internal.session.room.send.MarkdownParser + +class FakeMarkdownParser { + internal val instance = mockk() + fun givenBoldMarkdown() { + every { instance.parse(any(), any(), any()) } answers { + val text = arg(0) + TextContent(text, "${text.replace("*", "")}") + } + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeWaveFormSanitizer.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeWaveFormSanitizer.kt new file mode 100644 index 0000000000..052ddf7831 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/FakeWaveFormSanitizer.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes.internal.session.room.send + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.room.send.WaveFormSanitizer + +class FakeWaveFormSanitizer { + internal val instance = mockk() +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/pills/FakeTextPillsUtils.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/pills/FakeTextPillsUtils.kt new file mode 100644 index 0000000000..0d783d6628 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/session/room/send/pills/FakeTextPillsUtils.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes.internal.session.room.send.pills + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils + +class FakeTextPillsUtils { + internal val instance = mockk() +}