API modules do not need to setup dependency injection.

Move the implementation to the impl modules.
This commit is contained in:
Benoit Marty 2025-11-12 16:03:00 +01:00 committed by Benoit Marty
parent 9eb66afd87
commit b3ec256dfa
43 changed files with 620 additions and 405 deletions

View file

@ -1,5 +1,3 @@
import extension.setupDependencyInjection
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2023, 2024 New Vector Ltd.
@ -16,8 +14,6 @@ android {
namespace = "io.element.android.features.cachecleaner.api"
}
setupDependencyInjection()
dependencies {
implementation(projects.libraries.architecture)
implementation(libs.androidx.startup)

View file

@ -97,6 +97,7 @@ dependencies {
testImplementation(projects.libraries.matrixuiTest)
testImplementation(projects.libraries.push.test)
testImplementation(projects.services.analytics.test)
testImplementation(projects.services.appnavstate.impl)
testImplementation(projects.services.appnavstate.test)
testImplementation(projects.services.toolbox.test)
}

View file

@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.test.widget.FakeMatrixWidgetDriver
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -86,7 +87,7 @@ class DefaultCallWidgetProviderTest {
// No room from the client
givenGetRoomResult(A_ROOM_ID, null)
}
val activeRoomsHolder = ActiveRoomsHolder().apply {
val activeRoomsHolder = DefaultActiveRoomsHolder().apply {
// A current active room with the same room id
addRoom(
FakeJoinedRoom(
@ -130,7 +131,7 @@ class DefaultCallWidgetProviderTest {
matrixClientProvider: MatrixClientProvider = FakeMatrixClientProvider(),
appPreferencesStore: AppPreferencesStore = InMemoryAppPreferencesStore(),
callWidgetSettingsProvider: CallWidgetSettingsProvider = FakeCallWidgetSettingsProvider(),
activeRoomsHolder: ActiveRoomsHolder = ActiveRoomsHolder(),
activeRoomsHolder: ActiveRoomsHolder = DefaultActiveRoomsHolder(),
) = DefaultCallWidgetProvider(
matrixClientsProvider = matrixClientProvider,
appPreferencesStore = appPreferencesStore,

View file

@ -89,6 +89,7 @@ dependencies {
testImplementation(projects.services.analytics.test)
testImplementation(projects.services.toolbox.test)
testImplementation(projects.libraries.featureflag.test)
testImplementation(projects.libraries.mediaupload.impl)
testImplementation(projects.libraries.mediaupload.test)
testImplementation(projects.libraries.mediapickers.test)
testImplementation(projects.libraries.permissions.test)

View file

@ -37,7 +37,7 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaSenderFactory
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
import io.element.android.libraries.mediaupload.api.allFiles
import io.element.android.libraries.preferences.api.store.VideoCompressionPreset
@ -56,7 +56,7 @@ class AttachmentsPreviewPresenter(
@Assisted private val onDoneListener: OnDoneListener,
@Assisted private val timelineMode: Timeline.Mode,
@Assisted private val inReplyToEventId: EventId?,
mediaSenderFactory: MediaSender.Factory,
mediaSenderFactory: MediaSenderFactory,
private val permalinkBuilder: PermalinkBuilder,
private val temporaryUriDeleter: TemporaryUriDeleter,
private val mediaOptimizationSelectorPresenterFactory: MediaOptimizationSelectorPresenter.Factory,

View file

@ -61,7 +61,7 @@ import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
import io.element.android.libraries.matrix.ui.messages.reply.map
import io.element.android.libraries.mediapickers.api.PickerProvider
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaSenderFactory
import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory
import io.element.android.libraries.permissions.api.PermissionsEvents
import io.element.android.libraries.permissions.api.PermissionsPresenter
@ -107,7 +107,7 @@ class MessageComposerPresenter(
private val mediaPickerProvider: PickerProvider,
private val sessionPreferencesStore: SessionPreferencesStore,
private val localMediaFactory: LocalMediaFactory,
private val mediaSenderFactory: MediaSender.Factory,
mediaSenderFactory: MediaSenderFactory,
private val snackbarDispatcher: SnackbarDispatcher,
private val analyticsService: AnalyticsService,
private val locationService: LocationService,

View file

@ -32,7 +32,7 @@ import io.element.android.features.messages.api.timeline.voicemessages.composer.
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaSenderFactory
import io.element.android.libraries.permissions.api.PermissionsEvents
import io.element.android.libraries.permissions.api.PermissionsPresenter
import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent
@ -57,7 +57,7 @@ class DefaultVoiceMessageComposerPresenter(
@Assisted private val timelineMode: Timeline.Mode,
private val voiceRecorder: VoiceRecorder,
private val analyticsService: AnalyticsService,
mediaSenderFactory: MediaSender.Factory,
mediaSenderFactory: MediaSenderFactory,
private val player: VoiceMessageComposerPlayer,
private val messageComposerContext: MessageComposerContext,
permissionsPresenterFactory: PermissionsPresenter.Factory

View file

@ -78,7 +78,6 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID_2
import io.element.android.libraries.matrix.test.A_THREAD_ID
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
@ -166,6 +165,7 @@ class MessagesPresenterTest {
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventOrTransactionId -> Result.success(true) }
val toggleReactionFailure =
lambdaRecorder { _: String, _: EventOrTransactionId -> Result.failure<Boolean>(IllegalStateException("Failed to send reaction")) }
val addRecentEmojiResult = lambdaRecorder { _: String -> Result.success(Unit) }
val timeline = FakeTimeline().apply {
this.toggleReactionLambda = toggleReactionSuccess
@ -184,7 +184,8 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(
timeline = timeline,
joinedRoom = room,
coroutineDispatchers = coroutineDispatchers
addRecentEmoji = AddRecentEmoji { addRecentEmojiResult(it) },
coroutineDispatchers = coroutineDispatchers,
)
presenter.testWithLifecycleOwner {
skipItems(1)
@ -201,6 +202,7 @@ class MessagesPresenterTest {
assert(toggleReactionFailure)
.isCalledOnce()
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
addRecentEmojiResult.assertions().isCalledOnce().with(value("👍"))
}
}
@ -212,7 +214,9 @@ class MessagesPresenterTest {
toggle = !toggle
Result.success(toggle)
}
val addRecentEmoji = lambdaRecorder { _: String ->
Result.success(Unit)
}
val timeline = FakeTimeline().apply {
this.toggleReactionLambda = toggleReactionSuccess
}
@ -230,6 +234,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(
timeline = timeline,
joinedRoom = room,
addRecentEmoji = AddRecentEmoji { addRecentEmoji(it) },
coroutineDispatchers = coroutineDispatchers
)
presenter.testWithLifecycleOwner {
@ -244,6 +249,7 @@ class MessagesPresenterTest {
listOf(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId())),
)
skipItems(1)
addRecentEmoji.assertions().isCalledOnce().with(value("👍"))
}
}
@ -1196,10 +1202,12 @@ class MessagesPresenterTest {
)
presenter.testWithLifecycleOwner {
val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(
action = TimelineItemAction.ReplyInThread,
event = aMessageEvent(threadInfo = TimelineItemThreadInfo.ThreadResponse(A_THREAD_ID))
))
initialState.eventSink(
MessagesEvents.HandleAction(
action = TimelineItemAction.ReplyInThread,
event = aMessageEvent(threadInfo = TimelineItemThreadInfo.ThreadResponse(A_THREAD_ID))
)
)
awaitItem()
openThreadLambda.assertions().isCalledOnce().with(value(A_THREAD_ID), value(null))
}
@ -1216,14 +1224,16 @@ class MessagesPresenterTest {
)
presenter.testWithLifecycleOwner {
val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(
action = TimelineItemAction.ReplyInThread,
event = aMessageEvent(
// The event id will be used as the thread id instead
eventId = AN_EVENT_ID,
threadInfo = null,
initialState.eventSink(
MessagesEvents.HandleAction(
action = TimelineItemAction.ReplyInThread,
event = aMessageEvent(
// The event id will be used as the thread id instead
eventId = AN_EVENT_ID,
threadInfo = null,
)
)
))
)
awaitItem()
openThreadLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID.toThreadId()), value(null))
}
@ -1334,7 +1344,7 @@ class MessagesPresenterTest {
encryptionService: FakeEncryptionService = FakeEncryptionService(),
featureFlagService: FakeFeatureFlagService = FakeFeatureFlagService(),
actionListEventSink: (ActionListEvents) -> Unit = {},
addRecentEmoji: AddRecentEmoji = AddRecentEmoji(FakeMatrixClient(), testCoroutineDispatchers()),
addRecentEmoji: AddRecentEmoji = AddRecentEmoji { _ -> lambdaError() },
markAsFullyRead: MarkAsFullyRead = FakeMarkAsFullyRead(),
): MessagesPresenter {
return MessagesPresenter(

View file

@ -41,8 +41,9 @@ import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaSenderFactory
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
import io.element.android.libraries.mediaupload.impl.DefaultMediaSender
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
import io.element.android.libraries.mediaviewer.api.aVideoMediaInfo
import io.element.android.libraries.mediaviewer.api.anApkMediaInfo
@ -601,17 +602,15 @@ class AttachmentsPreviewPresenterTest {
return AttachmentsPreviewPresenter(
attachment = aMediaAttachment(localMedia),
onDoneListener = onDoneListener,
mediaSenderFactory = object : MediaSender.Factory {
override fun create(timelineMode: Timeline.Mode): MediaSender {
return MediaSender(
preProcessor = mediaPreProcessor,
room = room,
timelineMode = timelineMode,
mediaOptimizationConfigProvider = {
MediaOptimizationConfig(compressImages = true, videoCompressionPreset = VideoCompressionPreset.STANDARD)
}
)
}
mediaSenderFactory = MediaSenderFactory { timelineMode ->
DefaultMediaSender(
preProcessor = mediaPreProcessor,
room = room,
timelineMode = timelineMode,
mediaOptimizationConfigProvider = {
MediaOptimizationConfig(compressImages = true, videoCompressionPreset = VideoCompressionPreset.STANDARD)
}
)
},
permalinkBuilder = permalinkBuilder,
temporaryUriDeleter = temporaryUriDeleter,

View file

@ -21,7 +21,6 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.test.AN_EXCEPTION
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.mediaupload.api.MaxUploadSizeProvider
import io.element.android.libraries.mediaviewer.api.aVideoMediaInfo
import io.element.android.libraries.mediaviewer.api.anImageMediaInfo
@ -206,7 +205,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
@Test
fun `present - max upload size will default to 100MB if we can't get it`() = runTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter(
maxUploadSizeProvider = MaxUploadSizeProvider(FakeMatrixClient(getMaxUploadSizeResult = { Result.failure(AN_EXCEPTION) }))
maxUploadSizeProvider = MaxUploadSizeProvider { Result.failure(AN_EXCEPTION) }
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -233,9 +232,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
private fun createDefaultMediaOptimizationSelectorPresenter(
localMedia: LocalMedia = aLocalMedia(mockMediaUrl, aVideoMediaInfo()),
maxUploadSizeProvider: MaxUploadSizeProvider = MaxUploadSizeProvider(
FakeMatrixClient(getMaxUploadSizeResult = { Result.success(1_000L) }),
),
maxUploadSizeProvider: MaxUploadSizeProvider = MaxUploadSizeProvider { Result.success(1_000L) },
sessionPreferencesStore: InMemorySessionPreferencesStore = InMemorySessionPreferencesStore(),
featureFlagService: FakeFeatureFlagService = FakeFeatureFlagService(mapOf(FeatureFlags.SelectableMediaQuality.key to true)),
mediaExtractorFactory: FakeVideoMetadataExtractorFactory = FakeVideoMetadataExtractorFactory(),

View file

@ -75,8 +75,9 @@ import io.element.android.libraries.mediapickers.api.PickerProvider
import io.element.android.libraries.mediapickers.test.FakePickerProvider
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaSenderFactory
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
import io.element.android.libraries.mediaupload.impl.DefaultMediaSender
import io.element.android.libraries.mediaupload.test.FakeMediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaFactory
@ -1551,20 +1552,18 @@ class MessageComposerPresenterTest {
mediaPickerProvider = pickerProvider,
sessionPreferencesStore = sessionPreferencesStore,
localMediaFactory = localMediaFactory,
mediaSenderFactory = object : MediaSender.Factory {
override fun create(timelineMode: Timeline.Mode): MediaSender {
return MediaSender(
preProcessor = mediaPreProcessor,
room = room,
timelineMode = timelineMode,
mediaOptimizationConfigProvider = {
MediaOptimizationConfig(
mediaSenderFactory = MediaSenderFactory { timelineMode ->
DefaultMediaSender(
preProcessor = mediaPreProcessor,
room = room,
timelineMode = timelineMode,
mediaOptimizationConfigProvider = {
MediaOptimizationConfig(
compressImages = true,
videoCompressionPreset = VideoCompressionPreset.STANDARD
)
}
)
}
}
)
},
snackbarDispatcher = snackbarDispatcher,
analyticsService = analyticsService,

View file

@ -30,7 +30,7 @@ import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.impl.DefaultMediaSender
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
import io.element.android.libraries.permissions.api.PermissionsPresenter
import io.element.android.libraries.permissions.api.aPermissionsState
@ -75,7 +75,7 @@ class VoiceMessageComposerPresenterTest {
},
)
private val mediaPreProcessor = FakeMediaPreProcessor().apply { givenAudioResult() }
private val mediaSender = MediaSender(
private val mediaSender = DefaultMediaSender(
preProcessor = mediaPreProcessor,
room = joinedRoom,
timelineMode = Timeline.Mode.Live,
@ -668,11 +668,7 @@ class VoiceMessageComposerPresenterTest {
timelineMode = Timeline.Mode.Live,
voiceRecorder = voiceRecorder,
analyticsService = analyticsService,
mediaSenderFactory = object : MediaSender.Factory {
override fun create(timelineMode: Timeline.Mode): MediaSender {
return mediaSender
}
},
mediaSenderFactory = { mediaSender },
player = VoiceMessageComposerPlayer(FakeMediaPlayer(), this),
messageComposerContext = messageComposerContext,
permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter),

View file

@ -25,4 +25,5 @@ dependencies {
implementation(projects.libraries.voicerecorder.test)
implementation(projects.services.analytics.test)
implementation(projects.tests.testutils)
implementation(projects.libraries.mediaupload.impl)
}

View file

@ -15,6 +15,7 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.impl.DefaultMediaSender
import io.element.android.libraries.mediaupload.test.FakeMediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory
@ -24,7 +25,7 @@ import kotlinx.coroutines.CoroutineScope
class FakeDefaultVoiceMessageComposerPresenterFactory(
private val sessionCoroutineScope: CoroutineScope,
private val mediaSender: MediaSender = MediaSender(
private val mediaSender: MediaSender = DefaultMediaSender(
preProcessor = FakeMediaPreProcessor(),
room = FakeJoinedRoom(),
timelineMode = Timeline.Mode.Live,
@ -37,11 +38,7 @@ class FakeDefaultVoiceMessageComposerPresenterFactory(
timelineMode = timelineMode,
voiceRecorder = FakeVoiceRecorder(),
analyticsService = FakeAnalyticsService(),
mediaSenderFactory = object : MediaSender.Factory {
override fun create(timelineMode: Timeline.Mode): MediaSender {
return mediaSender
}
},
mediaSenderFactory = { mediaSender },
player = VoiceMessageComposerPlayer(
mediaPlayer = FakeMediaPlayer(),
sessionCoroutineScope = sessionCoroutineScope,

View file

@ -115,6 +115,7 @@ dependencies {
testImplementation(projects.libraries.indicator.test)
testImplementation(projects.libraries.pushproviders.test)
testImplementation(projects.libraries.sessionStorage.test)
testImplementation(projects.services.appnavstate.impl)
testImplementation(projects.services.analytics.test)
testImplementation(projects.services.toolbox.test)
}

View file

@ -19,7 +19,7 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.push.test.FakePushService
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder
import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.lambda.value
import io.element.android.tests.testutils.testCoroutineDispatchers
@ -34,7 +34,7 @@ import org.robolectric.RobolectricTestRunner
class DefaultClearCacheUseCaseTest {
@Test
fun `execute clear cache should do all the expected tasks`() = runTest {
val activeRoomsHolder = ActiveRoomsHolder().apply { addRoom(FakeJoinedRoom()) }
val activeRoomsHolder = DefaultActiveRoomsHolder().apply { addRoom(FakeJoinedRoom()) }
val clearCacheLambda = lambdaRecorder<Unit> { }
val matrixClient = FakeMatrixClient(
sessionId = A_SESSION_ID,

View file

@ -48,4 +48,5 @@ dependencies {
testImplementation(projects.libraries.mediaupload.test)
testImplementation(projects.libraries.preferences.test)
testImplementation(projects.libraries.roomselect.test)
testImplementation(projects.services.appnavstate.impl)
}

View file

@ -23,10 +23,8 @@ import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaSenderRoomFactory
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@ -39,7 +37,7 @@ class SharePresenter(
private val sessionCoroutineScope: CoroutineScope,
private val shareIntentHandler: ShareIntentHandler,
private val matrixClient: MatrixClient,
private val mediaPreProcessor: MediaPreProcessor,
private val mediaSenderRoomFactory: MediaSenderRoomFactory,
private val activeRoomsHolder: ActiveRoomsHolder,
private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider,
) : Presenter<ShareState> {
@ -88,12 +86,7 @@ class SharePresenter(
roomIds
.map { roomId ->
val room = getJoinedRoom(roomId) ?: return@map false
val mediaSender = MediaSender(
preProcessor = mediaPreProcessor,
room = room,
timelineMode = Timeline.Mode.Live,
mediaOptimizationConfigProvider = mediaOptimizationConfigProvider,
)
val mediaSender = mediaSenderRoomFactory.create(room = room)
filesToShare
.map { fileToShare ->
val result = mediaSender.sendMedia(

View file

@ -17,18 +17,17 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.media.FileInfo
import io.element.android.libraries.matrix.test.A_MESSAGE
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.api.MediaSenderRoomFactory
import io.element.android.libraries.mediaupload.test.FakeMediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
import io.element.android.libraries.mediaupload.test.FakeMediaSender
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.lambdaRecorder
import kotlinx.coroutines.test.TestScope
@ -37,7 +36,6 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import java.io.File
@RunWith(RobolectricTestRunner::class)
class SharePresenterTest {
@ -121,18 +119,16 @@ class SharePresenterTest {
@Test
fun `present - send media ok`() = runTest {
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val sendMediaResult = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
val joinedRoom = FakeJoinedRoom(
liveTimeline = FakeTimeline().apply {
sendFileLambda = sendFileResult
},
liveTimeline = FakeTimeline(),
)
val matrixClient = FakeMatrixClient().apply {
givenGetRoomResult(A_ROOM_ID, joinedRoom)
}
val mediaSender = FakeMediaSender(
sendMediaResult = sendMediaResult,
)
val presenter = createSharePresenter(
matrixClient = matrixClient,
shareIntentHandler = FakeShareIntentHandler { _, onFile, _ ->
@ -144,7 +140,8 @@ class SharePresenterTest {
)
)
)
}
},
mediaSenderRoomFactory = MediaSenderRoomFactory { mediaSender },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -156,7 +153,7 @@ class SharePresenterTest {
val success = awaitItem()
assertThat(success.shareAction.isSuccess()).isTrue()
assertThat(success.shareAction).isEqualTo(AsyncAction.Success(listOf(A_ROOM_ID)))
sendFileResult.assertions().isCalledOnce()
sendMediaResult.assertions().isCalledOnce()
}
}
}
@ -165,17 +162,17 @@ internal fun TestScope.createSharePresenter(
intent: Intent = Intent(),
shareIntentHandler: ShareIntentHandler = FakeShareIntentHandler(),
matrixClient: MatrixClient = FakeMatrixClient(),
mediaPreProcessor: MediaPreProcessor = FakeMediaPreProcessor(),
activeRoomsHolder: ActiveRoomsHolder = ActiveRoomsHolder(),
mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
activeRoomsHolder: ActiveRoomsHolder = DefaultActiveRoomsHolder(),
mediaSenderRoomFactory: MediaSenderRoomFactory = MediaSenderRoomFactory { FakeMediaSender() },
mediaOptimizationConfigProvider: MediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
): SharePresenter {
return SharePresenter(
intent = intent,
sessionCoroutineScope = this,
shareIntentHandler = shareIntentHandler,
matrixClient = matrixClient,
mediaPreProcessor = mediaPreProcessor,
activeRoomsHolder = activeRoomsHolder,
mediaSenderRoomFactory = mediaSenderRoomFactory,
mediaOptimizationConfigProvider = mediaOptimizationConfigProvider,
)
}