Fetches the remote draft right before sending

The remote attachments are added to the local ones in order to avoid
sending failures wherein the attachments on the BE are different than
the ones on the client side.

MAILAND-3070
This commit is contained in:
Maciej Surmacz 2023-07-05 13:19:22 +02:00
parent 983828438d
commit a7ddf1f4ea
3 changed files with 26 additions and 5 deletions

View File

@ -24,6 +24,8 @@ import androidx.annotation.WorkerThread
import androidx.lifecycle.LiveData
import androidx.room.Transaction
import ch.protonmail.android.activities.messageDetails.IntentExtrasData
import ch.protonmail.android.api.ProtonMailApiManager
import ch.protonmail.android.api.interceptors.UserIdTag
import ch.protonmail.android.api.models.DatabaseProvider
import ch.protonmail.android.api.models.User
import ch.protonmail.android.attachments.DownloadEmbeddedAttachmentsWorker
@ -71,7 +73,8 @@ class MessageDetailsRepository @Inject constructor(
private val userManager: UserManager,
private val databaseProvider: DatabaseProvider,
private val attachmentsWorker: DownloadEmbeddedAttachmentsWorker.Enqueuer,
private val labelRepository: LabelRepository
private val labelRepository: LabelRepository,
private val protonMailApiManager: ProtonMailApiManager
) {
private var requestedUserId: UserId? = null
@ -92,7 +95,8 @@ class MessageDetailsRepository @Inject constructor(
attachmentsWorker: DownloadEmbeddedAttachmentsWorker.Enqueuer,
labelRepository: LabelRepository,
@Assisted userId: UserId,
) : this(applicationContext, userManager, databaseProvider, attachmentsWorker, labelRepository) {
protonMailApiManager: ProtonMailApiManager
) : this(applicationContext, userManager, databaseProvider, attachmentsWorker, labelRepository, protonMailApiManager) {
requestedUserId = userId
}
@ -346,6 +350,9 @@ class MessageDetailsRepository @Inject constructor(
fun findAllPendingUploadsAsync(): LiveData<List<PendingUpload>> =
pendingActionDao.findAllPendingUploadsAsync()
suspend fun getRemoteMessageDetails(messageId: String, userId: UserId): Message =
protonMailApiManager.fetchMessageDetails(messageId, UserIdTag(userId)).message
@AssistedInject.Factory
interface AssistedFactory {

View File

@ -68,6 +68,7 @@ import ch.protonmail.android.data.local.model.Message
import ch.protonmail.android.pendingaction.data.worker.CleanUpPendingSendWorker
import ch.protonmail.android.usecase.compose.SaveDraft
import ch.protonmail.android.usecase.compose.SaveDraftResult
import ch.protonmail.android.utils.TryWithRetry
import ch.protonmail.android.utils.notifier.UserNotifier
import ch.protonmail.android.worker.repository.WorkerRepository
import dagger.assisted.Assisted
@ -115,7 +116,8 @@ class SendMessageWorker @AssistedInject constructor(
private val userNotifier: UserNotifier,
private val databaseProvider: DatabaseProvider,
private val workerRepository: WorkerRepository,
private val getCleanUpPendingSendWorkName: CleanUpPendingSendWorker.ProvideUniqueName
private val getCleanUpPendingSendWorkName: CleanUpPendingSendWorker.ProvideUniqueName,
private val tryWithRetry: TryWithRetry
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
@ -145,7 +147,7 @@ class SendMessageWorker @AssistedInject constructor(
is SaveDraftResult.Success -> {
val messageId = result.draftId
Timber.i("Send Message Worker saved draft successfully for messageId $messageId")
val savedDraftMessage = messageDetailsRepository.findMessageById(messageId).first()
val savedDraftMessage = getRefreshedDraft(messageId, userId)
?: return retryOrFail(userId, SavedDraftMessageNotFound, message)
Timber.d("Send Message Worker fetching send preferences for messageId $messageId")
@ -202,6 +204,16 @@ class SendMessageWorker @AssistedInject constructor(
}
}
private suspend fun getRefreshedDraft(messageId: String, userId: UserId): Message? {
val localDraft = messageDetailsRepository.findMessageById(messageId).first() ?: return null
tryWithRetry {
messageDetailsRepository.getRemoteMessageDetails(messageId, userId)
}.map { remoteDraft ->
localDraft.attachments = localDraft.attachments.plus(remoteDraft.attachments)
}
return localDraft
}
private suspend fun handleSendMessageResponse(
userId: UserId,
messageId: String,

View File

@ -57,6 +57,7 @@ import ch.protonmail.android.testdata.UserTestData.userId
import ch.protonmail.android.testdata.WorkerTestData
import ch.protonmail.android.usecase.compose.SaveDraft
import ch.protonmail.android.usecase.compose.SaveDraftResult
import ch.protonmail.android.utils.TryWithRetry
import ch.protonmail.android.utils.notifier.UserNotifier
import ch.protonmail.android.worker.repository.WorkerRepository
import io.mockk.Called
@ -142,7 +143,8 @@ class SendMessageWorkerTest : CoroutinesTest by CoroutinesTest() {
userNotifier = userNotifier,
databaseProvider = databaseProvider,
workerRepository = workerRepository,
getCleanUpPendingSendWorkName = provideUniqueCleanUpName
getCleanUpPendingSendWorkName = provideUniqueCleanUpName,
tryWithRetry = TryWithRetry()
)
@Test