Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Update transfers with remote data #85

Merged
merged 6 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import com.infomaniak.multiplatform_swisstransfer.common.models.TransferDirectio
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus
import com.infomaniak.multiplatform_swisstransfer.common.utils.mapToList
import com.infomaniak.multiplatform_swisstransfer.database.controllers.TransferController
import com.infomaniak.multiplatform_swisstransfer.exceptions.NotFoundException
import com.infomaniak.multiplatform_swisstransfer.exceptions.NullPropertyException
import com.infomaniak.multiplatform_swisstransfer.network.ApiClientProvider
import com.infomaniak.multiplatform_swisstransfer.network.exceptions.ApiException
import com.infomaniak.multiplatform_swisstransfer.network.exceptions.NetworkException
Expand Down Expand Up @@ -74,6 +76,38 @@ class TransferManager internal constructor(
.flowOn(Dispatchers.IO)
}

/**
* Update all pending transfers in database, most transfers are in [TransferStatus.WAIT_VIRUS_CHECK] status.
*/
@Throws(RealmException::class, CancellationException::class)
suspend fun fetchWaitingTransfers(): Unit = withContext(Dispatchers.IO) {
transferController.getNotReadyTransfers().forEach { transfer ->
runCatching {
addTransferByLinkUUID(transfer.linkUUID, null)
}
}
}

/**
* Update the local transfer with remote api
*
* @throws RealmException An error has occurred with realm database
* @throws NotFoundException Any transfer with [transferUUID] has been found
* @throws NullPropertyException The transferDirection of the transfer found is null
*/
@Throws(RealmException::class, NotFoundException::class, NullPropertyException::class, CancellationException::class)
suspend fun fetchTransfer(transferUUID: String): Unit {
val localTransfer = transferController.getTransfer(transferUUID)
?: throw NotFoundException("No transfer found in DB with uuid = $transferUUID")
val transferDirection = localTransfer.transferDirection
?: throw NullPropertyException("the transferDirection property cannot be null")

runCatching {
val remoteTransfer = transferRepository.getTransferByLinkUUID(transferUUID).data ?: return
transferController.upsert(remoteTransfer, transferDirection)
}
}

/**
* Retrieves a [TransferUi] by linkUUID.
*
Expand Down Expand Up @@ -109,11 +143,12 @@ class TransferManager internal constructor(
UnknownException::class,
RealmException::class,
)
suspend fun addTransferByLinkUUID(linkUUID: String, uploadSession: UploadSession): Unit = withContext(Dispatchers.IO) {
suspend fun addTransferByLinkUUID(linkUUID: String, uploadSession: UploadSession?): Unit = withContext(Dispatchers.IO) {
runCatching {
addTransfer(transferRepository.getTransferByLinkUUID(linkUUID).data, TransferDirection.SENT)
}.onFailure { exception ->
when {
uploadSession == null -> return@withContext
exception is UnexpectedApiErrorFormatException && exception.bodyResponse.contains("wait_virus_check") -> {
createTransferLocally(linkUUID, uploadSession)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ class TransferController(private val realmProvider: RealmProvider) {
fun getTransfer(linkUUID: String): Transfer? = runThrowingRealm {
return realm?.query<TransferDB>("${TransferDB::linkUUID.name} == '$linkUUID'")?.first()?.find()
}

@Throws(RealmException::class)
fun getNotReadyTransfers(): List<Transfer> = runThrowingRealm {
val query = "${TransferDB.transferStatusPropertyName} != '${TransferStatus.READY.name}'"
return realm?.query<TransferDB>(query)?.find() ?: emptyList()
}
//endregion

//region Upsert data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class TransferDB() : Transfer, RealmObject {
this.container = transfer.container?.let(::ContainerDB)

this.transferDirectionValue = transferDirection.name
this.transferStatusValue = TransferStatus.READY.name
this.transferStatusValue = transfer.transferStatus?.name ?: TransferStatus.READY.name
}

constructor(linkUUID: String, uploadSession: UploadSession, transferStatus: TransferStatus) : this() {
Expand All @@ -78,5 +78,6 @@ class TransferDB() : Transfer, RealmObject {

internal companion object {
val transferDirectionPropertyName = TransferDB::transferDirectionValue.name
val transferStatusPropertyName = TransferDB::transferStatusValue.name
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.infomaniak.multiplatform_swisstransfer.database

import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferDirection
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus
import com.infomaniak.multiplatform_swisstransfer.database.controllers.TransferController
import com.infomaniak.multiplatform_swisstransfer.database.dataset.DummyTransfer
import kotlinx.coroutines.test.runTest
Expand Down Expand Up @@ -68,6 +69,14 @@ class TransferControllerTest {
canGetTransfersByDirection(TransferDirection.RECEIVED)
}

@Test
fun canGetNotReadyTransfers() = runTest {
addTwoRandomTransfersInDatabase()
val transfers = transferController.getNotReadyTransfers()
assertEquals(transfers.count(), 1)
assertEquals(transfers.first().transferStatus, TransferStatus.WAIT_VIRUS_CHECK)
}

@Test
fun canUpdateAnExistingTransfer() = runTest {
// Insert a transfer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package com.infomaniak.multiplatform_swisstransfer.database.dataset
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Container
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.File
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus

object DummyTransfer {

Expand Down Expand Up @@ -54,12 +55,14 @@ object DummyTransfer {
override var isMailSent: Boolean = true
override var downloadHost: String = "url"
override var container: Container = this@DummyTransfer.container1
override val transferStatus: TransferStatus = TransferStatus.READY
}

val transfer2 = object : Transfer by transfer1 {
override val linkUUID: String = "transfer2"
override val containerUUID: String = "container2"
override val container: Container = container2
override val transferStatus: TransferStatus = TransferStatus.WAIT_VIRUS_CHECK
}

val transfers = listOf(transfer1, transfer2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
package com.infomaniak.multiplatform_swisstransfer.network.models.transfer

import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus
import com.infomaniak.multiplatform_swisstransfer.network.serializers.DateToTimestampSerializer
import com.infomaniak.multiplatform_swisstransfer.network.serializers.IntToBooleanSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient

@Serializable
class TransferApi : Transfer {
Expand All @@ -45,4 +47,7 @@ class TransferApi : Transfer {
val downloadUrl get() = "https://$downloadHost/api/download/??QuoiFeur " // TODO: Add download method url
// https://dl-j5769qrh.swisstransfer.com/api/download/ec6bc7ac-96b3-4a6e-8d30-8e12e379d11a/97a742c9-b0f5-4fa5-b6bf-cb2c2d6bbe94
override var container: ContainerApi = ContainerApi()

@Transient
override val transferStatus: TransferStatus = TransferStatus.READY
}
Loading