Media actions: add more tests
This commit is contained in:
parent
20eb2ade54
commit
730f50a433
9 changed files with 130 additions and 57 deletions
|
|
@ -123,6 +123,10 @@ class MediaViewerPresenter @AssistedInject constructor(
|
||||||
val snackbarMessage = SnackbarMessage(StringR.string.common_file_saved_on_disk_android)
|
val snackbarMessage = SnackbarMessage(StringR.string.common_file_saved_on_disk_android)
|
||||||
snackbarDispatcher.post(snackbarMessage)
|
snackbarDispatcher.post(snackbarMessage)
|
||||||
}
|
}
|
||||||
|
.onFailure {
|
||||||
|
val snackbarMessage = SnackbarMessage(mediaActionsError(it))
|
||||||
|
snackbarDispatcher.post(snackbarMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +137,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
||||||
is Async.Success -> {
|
is Async.Success -> {
|
||||||
localMediaActions.share(localMedia.state)
|
localMediaActions.share(localMedia.state)
|
||||||
.onFailure {
|
.onFailure {
|
||||||
val snackbarMessage = SnackbarMessage(openShareError(it))
|
val snackbarMessage = SnackbarMessage(mediaActionsError(it))
|
||||||
snackbarDispatcher.post(snackbarMessage)
|
snackbarDispatcher.post(snackbarMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -146,7 +150,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
||||||
is Async.Success -> {
|
is Async.Success -> {
|
||||||
localMediaActions.open(localMedia.state)
|
localMediaActions.open(localMedia.state)
|
||||||
.onFailure {
|
.onFailure {
|
||||||
val snackbarMessage = SnackbarMessage(openShareError(it))
|
val snackbarMessage = SnackbarMessage(mediaActionsError(it))
|
||||||
snackbarDispatcher.post(snackbarMessage)
|
snackbarDispatcher.post(snackbarMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -154,7 +158,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openShareError(throwable: Throwable): Int {
|
private fun mediaActionsError(throwable: Throwable): Int {
|
||||||
return if (throwable is ActivityNotFoundException) {
|
return if (throwable is ActivityNotFoundException) {
|
||||||
UtilsR.string.error_no_compatible_app_found
|
UtilsR.string.error_no_compatible_app_found
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -19,23 +19,39 @@ package io.element.android.features.messages.media
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import io.element.android.features.messages.impl.media.local.LocalMedia
|
import io.element.android.features.messages.impl.media.local.LocalMedia
|
||||||
import io.element.android.features.messages.impl.media.local.LocalMediaActions
|
import io.element.android.features.messages.impl.media.local.LocalMediaActions
|
||||||
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class FakeLocalMediaActions: LocalMediaActions {
|
class FakeLocalMediaActions(private val coroutineDispatchers: CoroutineDispatchers) : LocalMediaActions {
|
||||||
|
|
||||||
|
var shouldFail = false
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Configure() {
|
override fun Configure() {
|
||||||
//NOOP
|
//NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun saveOnDisk(localMedia: LocalMedia): Result<Unit> {
|
override suspend fun saveOnDisk(localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||||
return Result.success(Unit)
|
if (shouldFail) {
|
||||||
|
Result.failure(RuntimeException())
|
||||||
|
} else {
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun share(localMedia: LocalMedia): Result<Unit> {
|
override suspend fun share(localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||||
return Result.success(Unit)
|
if (shouldFail) {
|
||||||
|
Result.failure(RuntimeException())
|
||||||
|
} else {
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun open(localMedia: LocalMedia): Result<Unit> {
|
override suspend fun open(localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||||
return Result.success(Unit)
|
if (shouldFail) {
|
||||||
|
Result.failure(RuntimeException())
|
||||||
|
} else {
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
package io.element.android.features.messages.media.viewer
|
package io.element.android.features.messages.media.viewer
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.media3.common.MimeTypes
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
import app.cash.molecule.moleculeFlow
|
import app.cash.molecule.moleculeFlow
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
|
|
@ -32,55 +31,110 @@ import io.element.android.features.messages.media.FakeLocalMediaActions
|
||||||
import io.element.android.features.messages.media.FakeLocalMediaFactory
|
import io.element.android.features.messages.media.FakeLocalMediaFactory
|
||||||
import io.element.android.libraries.architecture.Async
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
|
||||||
import io.element.android.libraries.matrix.test.FAKE_DELAY_IN_MS
|
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaLoader
|
import io.element.android.libraries.matrix.test.media.FakeMediaLoader
|
||||||
import io.element.android.libraries.matrix.test.media.aMediaSource
|
import io.element.android.libraries.matrix.test.media.aMediaSource
|
||||||
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
private const val TESTED_MIME_TYPE = MimeTypes.IMAGE_JPEG
|
private val TESTED_MEDIA_INFO = MediaInfo(
|
||||||
private const val TESTED_MEDIA_NAME = "MediaName"
|
name = "",
|
||||||
|
mimeType = "",
|
||||||
|
formattedFileSize = ""
|
||||||
|
)
|
||||||
|
|
||||||
class MediaViewerPresenterTest {
|
class MediaViewerPresenterTest {
|
||||||
|
|
||||||
private val mockMediaUri: Uri = mockk("localMediaUri")
|
private val mockMediaUri: Uri = mockk("localMediaUri")
|
||||||
private val localMediaFactory = FakeLocalMediaFactory(mockMediaUri)
|
private val localMediaFactory = FakeLocalMediaFactory(mockMediaUri)
|
||||||
private val mediaLoader = FakeMediaLoader()
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - download media success scenario`() = runTest {
|
fun `present - download media success scenario`() = runTest {
|
||||||
val presenter = aMediaViewerPresenter()
|
val coroutineDispatchers = testCoroutineDispatchers(testScheduler, useUnconfinedTestDispatcher = false)
|
||||||
|
val mediaLoader = FakeMediaLoader(coroutineDispatchers)
|
||||||
|
val mediaActions = FakeLocalMediaActions(coroutineDispatchers)
|
||||||
|
val presenter = aMediaViewerPresenter(mediaLoader, mediaActions)
|
||||||
moleculeFlow(RecompositionClock.Immediate) {
|
moleculeFlow(RecompositionClock.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
var state = awaitItem()
|
||||||
assertThat(initialState.downloadedMedia).isEqualTo(Async.Uninitialized)
|
assertThat(state.downloadedMedia).isEqualTo(Async.Uninitialized)
|
||||||
assertThat(initialState.mediaInfo.name).isEqualTo(TESTED_MEDIA_NAME)
|
assertThat(state.mediaInfo).isEqualTo(TESTED_MEDIA_INFO)
|
||||||
val loadingState = awaitItem()
|
state = awaitItem()
|
||||||
assertThat(loadingState.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
assertThat(state.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||||
testScheduler.advanceTimeBy(FAKE_DELAY_IN_MS + 1)
|
state = awaitItem()
|
||||||
val successState = awaitItem()
|
val successData = state.downloadedMedia.dataOrNull()
|
||||||
val successData = successState.downloadedMedia.dataOrNull()
|
assertThat(state.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
||||||
assertThat(successState.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
|
||||||
assertThat(successData).isNotNull()
|
assertThat(successData).isNotNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `present - check all actions `() = runTest {
|
||||||
|
val coroutineDispatchers = testCoroutineDispatchers(testScheduler, useUnconfinedTestDispatcher = false)
|
||||||
|
val mediaLoader = FakeMediaLoader(coroutineDispatchers)
|
||||||
|
val mediaActions = FakeLocalMediaActions(coroutineDispatchers)
|
||||||
|
val presenter = aMediaViewerPresenter(mediaLoader, mediaActions)
|
||||||
|
moleculeFlow(RecompositionClock.Immediate) {
|
||||||
|
presenter.present()
|
||||||
|
}.test {
|
||||||
|
var state = awaitItem()
|
||||||
|
assertThat(state.downloadedMedia).isEqualTo(Async.Uninitialized)
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||||
|
// no state changes while media is loading
|
||||||
|
state.eventSink(MediaViewerEvents.OpenWith)
|
||||||
|
state.eventSink(MediaViewerEvents.Share)
|
||||||
|
state.eventSink(MediaViewerEvents.SaveOnDisk)
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
||||||
|
// Should succeed without change of state
|
||||||
|
state.eventSink(MediaViewerEvents.OpenWith)
|
||||||
|
// Should succeed without change of state
|
||||||
|
state.eventSink(MediaViewerEvents.Share)
|
||||||
|
state.eventSink(MediaViewerEvents.SaveOnDisk)
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNotNull()
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNull()
|
||||||
|
|
||||||
|
// Check failures
|
||||||
|
mediaActions.shouldFail = true
|
||||||
|
state.eventSink(MediaViewerEvents.OpenWith)
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNotNull()
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNull()
|
||||||
|
state.eventSink(MediaViewerEvents.Share)
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNotNull()
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNull()
|
||||||
|
state.eventSink(MediaViewerEvents.SaveOnDisk)
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNotNull()
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.snackbarMessage).isNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - download media failure then retry with success scenario`() = runTest {
|
fun `present - download media failure then retry with success scenario`() = runTest {
|
||||||
val presenter = aMediaViewerPresenter()
|
val coroutineDispatchers = testCoroutineDispatchers(testScheduler, useUnconfinedTestDispatcher = false)
|
||||||
|
val mediaLoader = FakeMediaLoader(coroutineDispatchers)
|
||||||
|
val mediaActions = FakeLocalMediaActions(coroutineDispatchers)
|
||||||
|
val presenter = aMediaViewerPresenter(mediaLoader, mediaActions)
|
||||||
moleculeFlow(RecompositionClock.Immediate) {
|
moleculeFlow(RecompositionClock.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
mediaLoader.shouldFail = true
|
mediaLoader.shouldFail = true
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.downloadedMedia).isEqualTo(Async.Uninitialized)
|
assertThat(initialState.downloadedMedia).isEqualTo(Async.Uninitialized)
|
||||||
assertThat(initialState.mediaInfo.name).isEqualTo(TESTED_MEDIA_NAME)
|
assertThat(initialState.mediaInfo).isEqualTo(TESTED_MEDIA_INFO)
|
||||||
val loadingState = awaitItem()
|
val loadingState = awaitItem()
|
||||||
assertThat(loadingState.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
assertThat(loadingState.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||||
testScheduler.advanceTimeBy(FAKE_DELAY_IN_MS)
|
|
||||||
val failureState = awaitItem()
|
val failureState = awaitItem()
|
||||||
assertThat(failureState.downloadedMedia).isInstanceOf(Async.Failure::class.java)
|
assertThat(failureState.downloadedMedia).isInstanceOf(Async.Failure::class.java)
|
||||||
mediaLoader.shouldFail = false
|
mediaLoader.shouldFail = false
|
||||||
|
|
@ -89,7 +143,6 @@ class MediaViewerPresenterTest {
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
val retryLoadingState = awaitItem()
|
val retryLoadingState = awaitItem()
|
||||||
assertThat(retryLoadingState.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
assertThat(retryLoadingState.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||||
testScheduler.advanceTimeBy(FAKE_DELAY_IN_MS)
|
|
||||||
val successState = awaitItem()
|
val successState = awaitItem()
|
||||||
val successData = successState.downloadedMedia.dataOrNull()
|
val successData = successState.downloadedMedia.dataOrNull()
|
||||||
assertThat(successState.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
assertThat(successState.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
||||||
|
|
@ -97,19 +150,19 @@ class MediaViewerPresenterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun aMediaViewerPresenter(mimeType: String = TESTED_MIME_TYPE): MediaViewerPresenter {
|
private fun aMediaViewerPresenter(
|
||||||
|
mediaLoader: FakeMediaLoader,
|
||||||
|
localMediaActions: FakeLocalMediaActions,
|
||||||
|
): MediaViewerPresenter {
|
||||||
return MediaViewerPresenter(
|
return MediaViewerPresenter(
|
||||||
inputs = MediaViewerNode.Inputs(
|
inputs = MediaViewerNode.Inputs(
|
||||||
mediaInfo = MediaInfo(name = TESTED_MEDIA_NAME,
|
mediaInfo = TESTED_MEDIA_INFO,
|
||||||
mimeType = mimeType,
|
|
||||||
formattedFileSize = "14MB"
|
|
||||||
),
|
|
||||||
mediaSource = aMediaSource(),
|
mediaSource = aMediaSource(),
|
||||||
thumbnailSource = null
|
thumbnailSource = null
|
||||||
),
|
),
|
||||||
localMediaFactory = localMediaFactory,
|
localMediaFactory = localMediaFactory,
|
||||||
mediaLoader = mediaLoader,
|
mediaLoader = mediaLoader,
|
||||||
localMediaActions = FakeLocalMediaActions(),
|
localMediaActions = localMediaActions,
|
||||||
snackbarDispatcher = SnackbarDispatcher()
|
snackbarDispatcher = SnackbarDispatcher()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
|
|
@ -60,7 +59,7 @@ fun handleSnackbarMessage(
|
||||||
val snackbarMessage by snackbarDispatcher.snackbarMessage.collectAsState(initial = null)
|
val snackbarMessage by snackbarDispatcher.snackbarMessage.collectAsState(initial = null)
|
||||||
LaunchedEffect(snackbarMessage) {
|
LaunchedEffect(snackbarMessage) {
|
||||||
if (snackbarMessage != null) {
|
if (snackbarMessage != null) {
|
||||||
launch(Dispatchers.Main) {
|
launch {
|
||||||
snackbarDispatcher.clear()
|
snackbarDispatcher.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,6 @@ dependencies {
|
||||||
api(projects.libraries.core)
|
api(projects.libraries.core)
|
||||||
api(projects.libraries.matrix.api)
|
api(projects.libraries.matrix.api)
|
||||||
api(libs.coroutines.core)
|
api(libs.coroutines.core)
|
||||||
|
implementation(libs.coroutines.test)
|
||||||
|
implementation(projects.tests.testutils)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.test
|
package io.element.android.libraries.matrix.test
|
||||||
|
|
||||||
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
@ -36,15 +37,18 @@ import io.element.android.libraries.matrix.test.pushers.FakePushersService
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
|
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
|
||||||
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
||||||
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||||
|
|
||||||
class FakeMatrixClient(
|
class FakeMatrixClient(
|
||||||
override val sessionId: SessionId = A_SESSION_ID,
|
override val sessionId: SessionId = A_SESSION_ID,
|
||||||
|
private val coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
||||||
private val userDisplayName: Result<String> = Result.success(A_USER_NAME),
|
private val userDisplayName: Result<String> = Result.success(A_USER_NAME),
|
||||||
private val userAvatarURLString: Result<String> = Result.success(AN_AVATAR_URL),
|
private val userAvatarURLString: Result<String> = Result.success(AN_AVATAR_URL),
|
||||||
override val roomSummaryDataSource: RoomSummaryDataSource = FakeRoomSummaryDataSource(),
|
override val roomSummaryDataSource: RoomSummaryDataSource = FakeRoomSummaryDataSource(),
|
||||||
override val invitesDataSource: RoomSummaryDataSource = FakeRoomSummaryDataSource(),
|
override val invitesDataSource: RoomSummaryDataSource = FakeRoomSummaryDataSource(),
|
||||||
override val mediaLoader: MatrixMediaLoader = FakeMediaLoader(),
|
override val mediaLoader: MatrixMediaLoader = FakeMediaLoader(coroutineDispatchers),
|
||||||
private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(),
|
private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(),
|
||||||
private val pushersService: FakePushersService = FakePushersService(),
|
private val pushersService: FakePushersService = FakePushersService(),
|
||||||
private val notificationService: FakeNotificationService = FakeNotificationService(),
|
private val notificationService: FakeNotificationService = FakeNotificationService(),
|
||||||
|
|
|
||||||
|
|
@ -16,40 +16,40 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.test.media
|
package io.element.android.libraries.matrix.test.media
|
||||||
|
|
||||||
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
|
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
|
||||||
import io.element.android.libraries.matrix.api.media.MediaFile
|
import io.element.android.libraries.matrix.api.media.MediaFile
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import io.element.android.libraries.matrix.test.FAKE_DELAY_IN_MS
|
import io.element.android.libraries.matrix.test.FAKE_DELAY_IN_MS
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
class FakeMediaLoader : MatrixMediaLoader {
|
class FakeMediaLoader(private val coroutineDispatchers: CoroutineDispatchers) : MatrixMediaLoader {
|
||||||
|
|
||||||
var shouldFail = false
|
var shouldFail = false
|
||||||
|
|
||||||
override suspend fun loadMediaContent(source: MediaSource): Result<ByteArray> {
|
override suspend fun loadMediaContent(source: MediaSource): Result<ByteArray> = withContext(coroutineDispatchers.io){
|
||||||
delay(FAKE_DELAY_IN_MS)
|
if (shouldFail) {
|
||||||
return if (shouldFail) {
|
|
||||||
Result.failure(RuntimeException())
|
Result.failure(RuntimeException())
|
||||||
} else {
|
} else {
|
||||||
return Result.success(ByteArray(0))
|
Result.success(ByteArray(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun loadMediaThumbnail(source: MediaSource, width: Long, height: Long): Result<ByteArray> {
|
override suspend fun loadMediaThumbnail(source: MediaSource, width: Long, height: Long): Result<ByteArray> = withContext(coroutineDispatchers.io){
|
||||||
delay(FAKE_DELAY_IN_MS)
|
if (shouldFail) {
|
||||||
return if (shouldFail) {
|
|
||||||
Result.failure(RuntimeException())
|
Result.failure(RuntimeException())
|
||||||
} else {
|
} else {
|
||||||
return Result.success(ByteArray(0))
|
Result.success(ByteArray(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun downloadMediaFile(source: MediaSource, mimeType: String?, body: String?): Result<MediaFile> {
|
override suspend fun downloadMediaFile(source: MediaSource, mimeType: String?, body: String?): Result<MediaFile> = withContext(coroutineDispatchers.io){
|
||||||
delay(FAKE_DELAY_IN_MS)
|
if (shouldFail) {
|
||||||
return if (shouldFail) {
|
|
||||||
Result.failure(RuntimeException())
|
Result.failure(RuntimeException())
|
||||||
} else {
|
} else {
|
||||||
return Result.success(FakeMediaFile(""))
|
Result.success(FakeMediaFile(""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ class MainActivity : ComponentActivity() {
|
||||||
val baseDirectory = File(applicationContext.filesDir, "sessions")
|
val baseDirectory = File(applicationContext.filesDir, "sessions")
|
||||||
|
|
||||||
RustMatrixAuthenticationService(
|
RustMatrixAuthenticationService(
|
||||||
|
context = applicationContext,
|
||||||
baseDirectory = baseDirectory,
|
baseDirectory = baseDirectory,
|
||||||
coroutineScope = Singleton.appScope,
|
coroutineScope = Singleton.appScope,
|
||||||
coroutineDispatchers = Singleton.coroutineDispatchers,
|
coroutineDispatchers = Singleton.coroutineDispatchers,
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,6 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.test.junit)
|
implementation(libs.test.junit)
|
||||||
implementation(libs.test.mockk)
|
|
||||||
implementation(libs.test.truth)
|
|
||||||
implementation(libs.test.turbine)
|
|
||||||
implementation(libs.coroutines.test)
|
implementation(libs.coroutines.test)
|
||||||
implementation(projects.libraries.matrix.test)
|
|
||||||
implementation(projects.services.appnavstate.test)
|
|
||||||
implementation(projects.services.appnavstate.test)
|
|
||||||
implementation(projects.libraries.core)
|
implementation(projects.libraries.core)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue