From 381f2c8823318bd3925faccc01dd1996239bc722 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:41:56 +0200 Subject: [PATCH 01/24] network: Handle transfer by url or linkUuid --- .../network/repositories/TransferRepository.kt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt index f20d035f..e0cfaa59 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt @@ -25,6 +25,7 @@ import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnknownApiE import com.infomaniak.multiplatform_swisstransfer.network.models.ApiResponse import com.infomaniak.multiplatform_swisstransfer.network.models.transfer.TransferApi import com.infomaniak.multiplatform_swisstransfer.network.requests.TransferRequest +import com.infomaniak.multiplatform_swisstransfer.network.utils.ApiRoutes import io.ktor.client.HttpClient import kotlinx.serialization.json.Json import kotlin.coroutines.cancellation.CancellationException @@ -45,5 +46,16 @@ class TransferRepository internal constructor(private val transferRequest: Trans NetworkException::class, UnknownException::class, ) - suspend fun getTransfer(linkUuid: String): ApiResponse = transferRequest.getTransfer(linkUuid) + suspend fun getTransferByLinkUuid(linkUuid: String): ApiResponse = transferRequest.getTransfer(linkUuid) + + @Throws( + CancellationException::class, + ApiException::class, + UnknownApiException::class, + NetworkException::class, + UnknownException::class, + ) + suspend fun getTransferByUrl(url: String): ApiResponse { + return transferRequest.getTransfer(url.substringAfter(ApiRoutes.baseUrl)) + } } From 76108c48cac4c4ac541f689eb2023dbe392653f8 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:43:16 +0200 Subject: [PATCH 02/24] database: Cast a Transfer to TransferDB --- .../database/models/transfers/ContainerDB.kt | 20 ++++++++++++++++++- .../database/models/transfers/FileDB.kt | 18 ++++++++++++++++- .../database/models/transfers/TransferDB.kt | 17 +++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/ContainerDB.kt b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/ContainerDB.kt index 0b1ce1c1..43910d01 100644 --- a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/ContainerDB.kt +++ b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/ContainerDB.kt @@ -18,12 +18,13 @@ package com.infomaniak.multiplatform_swisstransfer.database.models.transfers import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Container +import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.File import io.realm.kotlin.ext.realmListOf import io.realm.kotlin.types.RealmList import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey -class ContainerDB : Container>, RealmObject { +class ContainerDB() : Container>, RealmObject { @PrimaryKey override var uuid: String = "" override var duration: Long = 0L @@ -41,4 +42,21 @@ class ContainerDB : Container>, RealmObject { // @SerialName("WSUser") // TODO: What's this ? // val wsUser: JsonElement? override var files: RealmList = realmListOf() + + constructor(container: Container>) : this() { + this.uuid = container.uuid + this.duration = container.duration + this.createdDateTimestamp = container.createdDateTimestamp + this.expiredDateTimestamp = container.expiredDateTimestamp + this.numberOfFiles = container.numberOfFiles + this.message = container.message + this.needPassword = container.needPassword + this.language = container.language + this.sizeUploaded = container.sizeUploaded + this.deletedDateTimestamp = container.deletedDateTimestamp + this.swiftVersion = container.swiftVersion + this.downloadLimit = container.downloadLimit + this.source = container.source + this.files = container.files.mapTo(realmListOf()) { FileDB(it) } + } } diff --git a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/FileDB.kt b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/FileDB.kt index 316b94dd..c4b555f5 100644 --- a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/FileDB.kt +++ b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/FileDB.kt @@ -21,7 +21,7 @@ import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Fi import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey -class FileDB : File, RealmObject { +class FileDB() : File, RealmObject { @PrimaryKey override var containerUuid: String = "" override var uuid: String = "" @@ -36,4 +36,20 @@ class FileDB : File, RealmObject { override var receivedSizeInBytes: Long = 0L override var path: String? = "" override var thumbnailPath: String? = "" + + constructor(file: File) : this() { + this.containerUuid = file.containerUuid + this.uuid = file.uuid + this.fileName = file.fileName + this.fileSizeInBytes = file.fileSizeInBytes + this.downloadCounter = file.downloadCounter + this.createdDateTimestamp = file.createdDateTimestamp + this.expiredDateTimestamp = file.expiredDateTimestamp + this.eVirus = file.eVirus + this.deletedDate = file.deletedDate + this.mimeType = file.mimeType + this.receivedSizeInBytes = file.receivedSizeInBytes + this.path = file.path + this.thumbnailPath = file.thumbnailPath + } } diff --git a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/TransferDB.kt b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/TransferDB.kt index 6f6b2456..7a681a70 100644 --- a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/TransferDB.kt +++ b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/models/transfers/TransferDB.kt @@ -17,11 +17,13 @@ */ package com.infomaniak.multiplatform_swisstransfer.database.models.transfers +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 io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.PrimaryKey -class TransferDB : Transfer, RealmObject { +class TransferDB() : Transfer, RealmObject { @PrimaryKey override var linkUuid: String = "" override var containerUuid: String = "" @@ -32,4 +34,17 @@ class TransferDB : Transfer, RealmObject { override var isMailSent: Boolean = false override var downloadHost: String = "" override var container: ContainerDB? = null + + @Suppress("UNCHECKED_CAST") + constructor(transfer: Transfer<*>) : this() { + this.linkUuid = transfer.linkUuid + this.containerUuid = transfer.containerUuid + this.downloadCounterCredit = transfer.downloadCounterCredit + this.createdDateTimestamp = transfer.createdDateTimestamp + this.expiredDateTimestamp = transfer.expiredDateTimestamp + this.hasBeenDownloadedOneTime = transfer.hasBeenDownloadedOneTime + this.isMailSent = transfer.isMailSent + this.downloadHost = transfer.downloadHost + this.container = ContainerDB(transfer.container as Container>) + } } From 1d61eee72c9a6b5321ae4dcc264916f793640faa Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:44:29 +0200 Subject: [PATCH 03/24] database: Get and upsert a Transfer --- .../cache/setting/TransfersController.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransfersController.kt b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransfersController.kt index b1c8dd73..b6608602 100644 --- a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransfersController.kt +++ b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransfersController.kt @@ -17,12 +17,19 @@ */ package com.infomaniak.multiplatform_swisstransfer.database.cache.setting +import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer import com.infomaniak.multiplatform_swisstransfer.database.RealmProvider import com.infomaniak.multiplatform_swisstransfer.database.models.transfers.TransferDB +import io.realm.kotlin.UpdatePolicy import io.realm.kotlin.ext.query import io.realm.kotlin.query.RealmResults +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.mapLatest import kotlin.coroutines.cancellation.CancellationException +@OptIn(ExperimentalCoroutinesApi::class) class TransfersController(private val realmProvider: RealmProvider) { private val realm by lazy { realmProvider.realmTransfers } @@ -30,6 +37,21 @@ class TransfersController(private val realmProvider: RealmProvider) { //region Get data @Throws(IllegalArgumentException::class, CancellationException::class) fun getTransfers(): RealmResults? = realm?.query()?.find() + + @Throws(IllegalArgumentException::class, CancellationException::class) + fun getTransfersFlow(): Flow> = getTransfers()?.asFlow()?.mapLatest { it.list } ?: emptyFlow() + + fun getTransfer(linkUuid: String): TransferDB? { + return realm?.query("${TransferDB::linkUuid.name} == '$linkUuid'")?.first()?.find() + } + //endregion + + //region Upsert data + suspend fun upsert(transfer: Transfer<*>) { + realm?.write { + this.copyToRealm(TransferDB(transfer), UpdatePolicy.ALL) + } + } //endregion //region Update data From a4d82a279e949707d861e13c59f1bb5b9f562b01 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:45:11 +0200 Subject: [PATCH 04/24] database: Add unit test for TransferController --- .../database/RealmProvider.kt | 7 ++- .../database/TransferControllerTest.kt | 57 +++++++++++++++++++ .../database/dataset/DummyTransfer.kt | 55 ++++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt create mode 100644 STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt diff --git a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/RealmProvider.kt b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/RealmProvider.kt index aaa75cba..fe92f754 100644 --- a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/RealmProvider.kt +++ b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/RealmProvider.kt @@ -32,8 +32,8 @@ class RealmProvider { var realmTransfers: Realm? = null private set - fun openRealmTransfers(userId: Int) { - realmTransfers = Realm.open(realmTransfersConfiguration(userId)) + fun openRealmTransfers(userId: Int, inMemory: Boolean = false) { + realmTransfers = Realm.open(realmTransfersConfiguration(userId, inMemory)) } fun closeRealmAppSettings() { @@ -64,9 +64,10 @@ class RealmProvider { .name("Uploads") .build() - private fun realmTransfersConfiguration(userId: Int) = RealmConfiguration + private fun realmTransfersConfiguration(userId: Int, inMemory: Boolean) = RealmConfiguration .Builder(schema = setOf(TransferDB::class, ContainerDB::class, FileDB::class)) .name(transferRealmName(userId)) + .apply { if (inMemory) inMemory() } .build() private fun transferRealmName(userId: Int) = "Transfers-$userId" diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt new file mode 100644 index 00000000..149a9811 --- /dev/null +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -0,0 +1,57 @@ +/* + * Infomaniak SwissTransfer - Multiplatform + * Copyright (C) 2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.multiplatform_swisstransfer.database + +import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransfersController +import com.infomaniak.multiplatform_swisstransfer.database.dataset.DummyTransfer +import kotlinx.coroutines.runBlocking +import kotlin.test.* + +class TransferControllerTest { + + private val realmProvider = RealmProvider().apply { openRealmTransfers(userId = 0, inMemory = true) } + private val transferController = TransfersController(realmProvider) + + @AfterTest + fun removeData() { + runBlocking { transferController.removeData() } + } + + @Test + fun canCreateTransfer() = runBlocking { + val transfer = DummyTransfer.transfer + transferController.upsert(transfer) + val realmTransfer = transferController.getTransfer(transfer.linkUuid) + assertNotNull(realmTransfer) + assertEquals(transfer.container.uuid, realmTransfer.container?.uuid) + assertEquals(transfer.container.files.count(), realmTransfer.container?.files?.count()) + } + + @Test + fun realmTransferListIsEmpty() { + assertTrue(transferController.getTransfers()?.isEmpty() == true) + } + + @Test + fun canGetFrom() = runBlocking { + val transfer = DummyTransfer.transfer + transferController.upsert(transfer) + val transfers = transferController.getTransfers() + assertEquals(1, transfers?.count()) + } +} diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt new file mode 100644 index 00000000..d2d76080 --- /dev/null +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt @@ -0,0 +1,55 @@ +/* + * Infomaniak SwissTransfer - Multiplatform + * Copyright (C) 2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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 + +object DummyTransfer { + + private val containerTest = object : Container> { + override var uuid: String = "transfer1Container" + override var duration: Long = 0 + override var createdDateTimestamp: Long = 0 + override var expiredDateTimestamp: Long = 0 + override var numberOfFiles: Int = 0 + override var message: String? = null + override var needPassword: Boolean = false + override var language: String = "language" + override var sizeUploaded: Long = 0 + override var deletedDateTimestamp: Long? = null + override var swiftVersion: Int = 0 + override var downloadLimit: Int = 0 + override var source: String = "source" + override var files: List = emptyList() + } + + val transfer = object : Transfer>> { + override var linkUuid: String = "transferLinkUuid1" + override var containerUuid: String = "containerUuid" + override var downloadCounterCredit: Int = 0 + override var createdDateTimestamp: Long = 0 + override var expiredDateTimestamp: Long = 0 + override var hasBeenDownloadedOneTime: Boolean = false + override var isMailSent: Boolean = true + override var downloadHost: String = "url" + override var container: Container> = containerTest + } + +} From 4dda277ba47fb11fc4d804a3abf91218ea48a549 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:45:27 +0200 Subject: [PATCH 05/24] database: Remove useless test class --- .../database/Test.kt | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/Test.kt diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/Test.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/Test.kt deleted file mode 100644 index a5cbe330..00000000 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/Test.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Infomaniak SwissTransfer - Multiplatform - * Copyright (C) 2024 Infomaniak Network SA - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.infomaniak.multiplatform_swisstransfer.database - -import kotlin.test.Test -import kotlin.test.assertEquals - -class CommonGreetingTest { - - @Test - fun testExample() { - assertEquals(4, 2 + 2, "Check for correct addition") - } -} From 76f2fe15361a6471270bdda908dfe484fb1ee65b Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:46:16 +0200 Subject: [PATCH 06/24] core: Handle transfers with transferManager --- .../SwissTransferInjection.kt | 2 +- .../managers/TransferManager.kt | 49 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt index 1b74fa34..21dad4c4 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt @@ -52,7 +52,7 @@ class SwissTransferInjection { private val transfersController by lazy { TransfersController(realmProvider) } /** A manager used to orchestrate Transfers operations. */ - val transferManager by lazy { TransferManager(realmProvider, apiClientProvider) } + val transferManager by lazy { TransferManager(apiClientProvider, transfersController, transferRepository) } /** A manager used to orchestrate AppSettings operations. */ val appSettingsManager by lazy { AppSettingsManager(appSettingsController) } diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt index fea0dc66..19ca0ff1 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt @@ -17,8 +17,19 @@ */ package com.infomaniak.multiplatform_swisstransfer.managers -import com.infomaniak.multiplatform_swisstransfer.database.RealmProvider +import com.infomaniak.multiplatform_swisstransfer.common.exceptions.UnknownException +import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer +import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransfersController import com.infomaniak.multiplatform_swisstransfer.network.ApiClientProvider +import com.infomaniak.multiplatform_swisstransfer.network.exceptions.ApiException +import com.infomaniak.multiplatform_swisstransfer.network.exceptions.NetworkException +import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnknownApiException +import com.infomaniak.multiplatform_swisstransfer.network.models.transfer.TransferApi +import com.infomaniak.multiplatform_swisstransfer.network.repositories.TransferRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.flow.flowOn +import kotlin.coroutines.cancellation.CancellationException /** * TransferManager is responsible for orchestrating data transfer operations @@ -32,8 +43,40 @@ import com.infomaniak.multiplatform_swisstransfer.network.ApiClientProvider * @property clientProvider The provider for creating and configuring HTTP clients for API communication. */ class TransferManager internal constructor( - private val realmProvider: RealmProvider, private val clientProvider: ApiClientProvider, + private val transfersController: TransfersController, + private val transferRepository: TransferRepository, ) { - // TODO: Implement here + + val transfers get() = transfersController.getTransfersFlow().flowOn(Dispatchers.IO) + + @Throws( + CancellationException::class, + ApiException::class, + UnknownApiException::class, + NetworkException::class, + UnknownException::class, + ) + suspend fun addTransferByLinkUuid(linkUuid: String) { + addTransfer(transferRepository.getTransferByLinkUuid(linkUuid).data) + } + + @Throws( + CancellationException::class, + ApiException::class, + UnknownApiException::class, + NetworkException::class, + UnknownException::class, + ) + suspend fun addTransferByUrl(url: String) { + addTransfer(transferRepository.getTransferByUrl(url).data) + } + + private suspend fun addTransfer(transferApi: TransferApi?) { + runCatching { + transfersController.upsert(transferApi as Transfer<*>) + }.onFailure { + throw UnknownException(it) + } + } } From b7297224b9aa333876eb01a7b5b132122a9d2476 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:48:02 +0200 Subject: [PATCH 07/24] refactor: Rename TransfersController into TransferController --- .../multiplatform_swisstransfer/SwissTransferInjection.kt | 8 ++++---- .../managers/AccountManager.kt | 8 ++++---- .../managers/TransferManager.kt | 8 ++++---- .../{TransfersController.kt => TransferController.kt} | 2 +- .../database/TransferControllerTest.kt | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) rename STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/{TransfersController.kt => TransferController.kt} (97%) diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt index 21dad4c4..6b22432a 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/SwissTransferInjection.kt @@ -19,7 +19,7 @@ package com.infomaniak.multiplatform_swisstransfer import com.infomaniak.multiplatform_swisstransfer.database.RealmProvider import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.AppSettingsController -import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransfersController +import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransferController import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.UploadController import com.infomaniak.multiplatform_swisstransfer.managers.AccountManager import com.infomaniak.multiplatform_swisstransfer.managers.AppSettingsManager @@ -49,14 +49,14 @@ class SwissTransferInjection { private val appSettingsController by lazy { AppSettingsController(realmProvider) } private val uploadController by lazy { UploadController(realmProvider) } - private val transfersController by lazy { TransfersController(realmProvider) } + private val transferController by lazy { TransferController(realmProvider) } /** A manager used to orchestrate Transfers operations. */ - val transferManager by lazy { TransferManager(apiClientProvider, transfersController, transferRepository) } + val transferManager by lazy { TransferManager(apiClientProvider, transferController, transferRepository) } /** A manager used to orchestrate AppSettings operations. */ val appSettingsManager by lazy { AppSettingsManager(appSettingsController) } /** A manager used to orchestrate Accounts operations. */ - val accountManager by lazy { AccountManager(appSettingsController, uploadController, transfersController, realmProvider) } + val accountManager by lazy { AccountManager(appSettingsController, uploadController, transferController, realmProvider) } } diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/AccountManager.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/AccountManager.kt index cadde6f8..ce41b108 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/AccountManager.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/AccountManager.kt @@ -19,7 +19,7 @@ package com.infomaniak.multiplatform_swisstransfer.managers import com.infomaniak.multiplatform_swisstransfer.database.RealmProvider import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.AppSettingsController -import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransfersController +import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransferController import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.UploadController /** @@ -27,13 +27,13 @@ import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.UploadC * * @property appSettingsController The controller for managing AppSettings operations. * @property uploadController The controller for managing Upload operations. - * @property transfersController The controller for managing Transfers operation. + * @property transferController The controller for managing Transfers operation. * @property realmProvider The provider for managing Realm database operations. */ class AccountManager internal constructor( private val appSettingsController: AppSettingsController, private val uploadController: UploadController, - private val transfersController: TransfersController, + private val transferController: TransferController, private val realmProvider: RealmProvider, ) { @@ -54,7 +54,7 @@ class AccountManager internal constructor( appSettingsController.removeData() uploadController.removeData() - transfersController.removeData() + transferController.removeData() realmProvider.closeAllRealms() } diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt index 19ca0ff1..eed1e419 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt @@ -19,7 +19,7 @@ package com.infomaniak.multiplatform_swisstransfer.managers import com.infomaniak.multiplatform_swisstransfer.common.exceptions.UnknownException import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer -import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransfersController +import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransferController import com.infomaniak.multiplatform_swisstransfer.network.ApiClientProvider import com.infomaniak.multiplatform_swisstransfer.network.exceptions.ApiException import com.infomaniak.multiplatform_swisstransfer.network.exceptions.NetworkException @@ -44,11 +44,11 @@ import kotlin.coroutines.cancellation.CancellationException */ class TransferManager internal constructor( private val clientProvider: ApiClientProvider, - private val transfersController: TransfersController, + private val transferController: TransferController, private val transferRepository: TransferRepository, ) { - val transfers get() = transfersController.getTransfersFlow().flowOn(Dispatchers.IO) + val transfers get() = transferController.getTransfersFlow().flowOn(Dispatchers.IO) @Throws( CancellationException::class, @@ -74,7 +74,7 @@ class TransferManager internal constructor( private suspend fun addTransfer(transferApi: TransferApi?) { runCatching { - transfersController.upsert(transferApi as Transfer<*>) + transferController.upsert(transferApi as Transfer<*>) }.onFailure { throw UnknownException(it) } diff --git a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransfersController.kt b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransferController.kt similarity index 97% rename from STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransfersController.kt rename to STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransferController.kt index b6608602..b8801fb4 100644 --- a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransfersController.kt +++ b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransferController.kt @@ -30,7 +30,7 @@ import kotlinx.coroutines.flow.mapLatest import kotlin.coroutines.cancellation.CancellationException @OptIn(ExperimentalCoroutinesApi::class) -class TransfersController(private val realmProvider: RealmProvider) { +class TransferController(private val realmProvider: RealmProvider) { private val realm by lazy { realmProvider.realmTransfers } diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt index 149a9811..73a87784 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -17,7 +17,7 @@ */ package com.infomaniak.multiplatform_swisstransfer.database -import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransfersController +import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransferController import com.infomaniak.multiplatform_swisstransfer.database.dataset.DummyTransfer import kotlinx.coroutines.runBlocking import kotlin.test.* @@ -25,7 +25,7 @@ import kotlin.test.* class TransferControllerTest { private val realmProvider = RealmProvider().apply { openRealmTransfers(userId = 0, inMemory = true) } - private val transferController = TransfersController(realmProvider) + private val transferController = TransferController(realmProvider) @AfterTest fun removeData() { From 7dbd102c8253f8b96e2cee7ec264f7addc2570f3 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:52:30 +0200 Subject: [PATCH 08/24] refactor: Update kDoc and add Dispatches.IO --- .../managers/TransferManager.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt index eed1e419..7e783a97 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt @@ -29,6 +29,7 @@ import com.infomaniak.multiplatform_swisstransfer.network.repositories.TransferR import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.withContext import kotlin.coroutines.cancellation.CancellationException /** @@ -39,8 +40,9 @@ import kotlin.coroutines.cancellation.CancellationException * smooth and efficient data transfers, providing a centralized management point * for transfer-related activities. * - * @property realmProvider The provider for managing Realm database operations. * @property clientProvider The provider for creating and configuring HTTP clients for API communication. + * @property transferController The provider for transfer data from database. + * @property transferRepository The provider for transfer data from api. */ class TransferManager internal constructor( private val clientProvider: ApiClientProvider, @@ -57,7 +59,7 @@ class TransferManager internal constructor( NetworkException::class, UnknownException::class, ) - suspend fun addTransferByLinkUuid(linkUuid: String) { + suspend fun addTransferByLinkUuid(linkUuid: String) = withContext(Dispatchers.IO) { addTransfer(transferRepository.getTransferByLinkUuid(linkUuid).data) } @@ -68,7 +70,7 @@ class TransferManager internal constructor( NetworkException::class, UnknownException::class, ) - suspend fun addTransferByUrl(url: String) { + suspend fun addTransferByUrl(url: String) = withContext(Dispatchers.IO) { addTransfer(transferRepository.getTransferByUrl(url).data) } From 861483f92414c5fede34a9835381674ced8eddad Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 12:54:19 +0200 Subject: [PATCH 09/24] refactor: Update Core README --- STCore/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/STCore/README.md b/STCore/README.md index 8f947cd3..d6bdc6e9 100644 --- a/STCore/README.md +++ b/STCore/README.md @@ -59,8 +59,7 @@ centralized access point to orchestrate transfer operations. - **Type**: `TransferManager` - **Description**: - - `transferManager` is a lazily initialized property that provides a manager to orchestrate all transfer operations. It - uses `realmProvider` and `apiClientProvider` to configure and manage Transfers efficiently. + - `transferManager` is a lazily initialized property that provides a manager to orchestrate all transfer operations. - **Usage Example**: ```kotlin From 11181413b05972fe14f616742f5d13759e979849 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 13:06:48 +0200 Subject: [PATCH 10/24] feat: Sort transfers by created date --- .../database/cache/setting/TransferController.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransferController.kt b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransferController.kt index b8801fb4..78498aa0 100644 --- a/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransferController.kt +++ b/STDatabase/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/database/cache/setting/TransferController.kt @@ -23,6 +23,7 @@ import com.infomaniak.multiplatform_swisstransfer.database.models.transfers.Tran import io.realm.kotlin.UpdatePolicy import io.realm.kotlin.ext.query import io.realm.kotlin.query.RealmResults +import io.realm.kotlin.query.Sort import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow @@ -36,7 +37,9 @@ class TransferController(private val realmProvider: RealmProvider) { //region Get data @Throws(IllegalArgumentException::class, CancellationException::class) - fun getTransfers(): RealmResults? = realm?.query()?.find() + fun getTransfers(): RealmResults? { + return realm?.query()?.sort(TransferDB::createdDateTimestamp.name, Sort.DESCENDING)?.find() + } @Throws(IllegalArgumentException::class, CancellationException::class) fun getTransfersFlow(): Flow> = getTransfers()?.asFlow()?.mapLatest { it.list } ?: emptyFlow() From ecc67629c019c229e9fdb11d600fadedb987ecf3 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 13:32:25 +0200 Subject: [PATCH 11/24] refactor: Rename canGetFrom into canGetTransfers --- .../database/TransferControllerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt index 73a87784..a3c2d1fc 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -48,7 +48,7 @@ class TransferControllerTest { } @Test - fun canGetFrom() = runBlocking { + fun canGetTransfers() = runBlocking { val transfer = DummyTransfer.transfer transferController.upsert(transfer) val transfers = transferController.getTransfers() From 54271046076f4b0e3abf20719bdff4ba3e505dfb Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 13:32:55 +0200 Subject: [PATCH 12/24] refactor: Add 'L' at end of 0 if needed --- .../database/dataset/DummyTransfer.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt index d2d76080..a22ab9a1 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/dataset/DummyTransfer.kt @@ -25,14 +25,14 @@ object DummyTransfer { private val containerTest = object : Container> { override var uuid: String = "transfer1Container" - override var duration: Long = 0 - override var createdDateTimestamp: Long = 0 - override var expiredDateTimestamp: Long = 0 + override var duration: Long = 0L + override var createdDateTimestamp: Long = 0L + override var expiredDateTimestamp: Long = 0L override var numberOfFiles: Int = 0 override var message: String? = null override var needPassword: Boolean = false override var language: String = "language" - override var sizeUploaded: Long = 0 + override var sizeUploaded: Long = 0L override var deletedDateTimestamp: Long? = null override var swiftVersion: Int = 0 override var downloadLimit: Int = 0 @@ -44,8 +44,8 @@ object DummyTransfer { override var linkUuid: String = "transferLinkUuid1" override var containerUuid: String = "containerUuid" override var downloadCounterCredit: Int = 0 - override var createdDateTimestamp: Long = 0 - override var expiredDateTimestamp: Long = 0 + override var createdDateTimestamp: Long = 0L + override var expiredDateTimestamp: Long = 0L override var hasBeenDownloadedOneTime: Boolean = false override var isMailSent: Boolean = true override var downloadHost: String = "url" From c565e11a605131a11b04ce208c9789a824cb0fef Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 15:28:07 +0200 Subject: [PATCH 13/24] fix: Realm for unit tests --- .../database/TransferControllerTest.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt index a3c2d1fc..8fd5b8be 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -24,12 +24,19 @@ import kotlin.test.* class TransferControllerTest { - private val realmProvider = RealmProvider().apply { openRealmTransfers(userId = 0, inMemory = true) } - private val transferController = TransferController(realmProvider) + private lateinit var realmProvider: RealmProvider + private lateinit var transferController: TransferController + + @BeforeTest + fun setup() { + realmProvider = RealmProvider().apply { openRealmTransfers(userId = 0, inMemory = true) } + transferController = TransferController(realmProvider) + } @AfterTest - fun removeData() { - runBlocking { transferController.removeData() } + fun tearDown() = runBlocking { + transferController.removeData() + realmProvider.closeRealmTransfers() } @Test @@ -37,7 +44,7 @@ class TransferControllerTest { val transfer = DummyTransfer.transfer transferController.upsert(transfer) val realmTransfer = transferController.getTransfer(transfer.linkUuid) - assertNotNull(realmTransfer) + assertNotNull(realmTransfer, "The transfer cannot be null") assertEquals(transfer.container.uuid, realmTransfer.container?.uuid) assertEquals(transfer.container.files.count(), realmTransfer.container?.files?.count()) } From 54b956dc6ed095869638919dd1dd5bcec2d7d6d7 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 16:29:59 +0200 Subject: [PATCH 14/24] test: Support for Coroutines in Database module --- STDatabase/build.gradle.kts | 1 + .../database/TransferControllerTest.kt | 8 ++++---- gradle/libs.versions.toml | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/STDatabase/build.gradle.kts b/STDatabase/build.gradle.kts index 416301b1..dff5c922 100644 --- a/STDatabase/build.gradle.kts +++ b/STDatabase/build.gradle.kts @@ -15,6 +15,7 @@ kotlin { } commonTest.dependencies { implementation(libs.kotlin.test) + implementation(libs.kotlinx.coroutines.test) } } } diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt index 8fd5b8be..f6067ea4 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -19,7 +19,7 @@ package com.infomaniak.multiplatform_swisstransfer.database import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.TransferController import com.infomaniak.multiplatform_swisstransfer.database.dataset.DummyTransfer -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlin.test.* class TransferControllerTest { @@ -34,13 +34,13 @@ class TransferControllerTest { } @AfterTest - fun tearDown() = runBlocking { + fun tearDown() = runTest { transferController.removeData() realmProvider.closeRealmTransfers() } @Test - fun canCreateTransfer() = runBlocking { + fun canCreateTransfer() = runTest { val transfer = DummyTransfer.transfer transferController.upsert(transfer) val realmTransfer = transferController.getTransfer(transfer.linkUuid) @@ -55,7 +55,7 @@ class TransferControllerTest { } @Test - fun canGetTransfers() = runBlocking { + fun canGetTransfers() = runTest { val transfer = DummyTransfer.transfer transferController.upsert(transfer) val transfers = transferController.getTransfers() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c5a789e5..c98fcd02 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,6 +25,7 @@ realm-base = { module = "io.realm.kotlin:library-base", version.ref = "realm" } skie-gradle-plugin = { module = "co.touchlab.skie:gradle-plugin-api", version.ref = "skie" } #Test kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } [plugins] androidLibrary = { id = "com.android.library", version.ref = "agp" } From 015d6e0b631b841e84da6305dfbaaa445b951703 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 17:07:53 +0200 Subject: [PATCH 15/24] test: Can remove a transfer from database --- .../database/TransferControllerTest.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt index f6067ea4..221e4595 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -49,6 +49,13 @@ class TransferControllerTest { assertEquals(transfer.container.files.count(), realmTransfer.container?.files?.count()) } + @Test + fun canRemoveTransfers() = runTest { + transferController.upsert(DummyTransfer.transfer) + transferController.removeData() + assertEquals(0, transferController.getTransfers()?.count()) + } + @Test fun realmTransferListIsEmpty() { assertTrue(transferController.getTransfers()?.isEmpty() == true) From 693c9470aaaaf0af222732acfc086c7ee3260c4c Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 17:22:52 +0200 Subject: [PATCH 16/24] test(Database): Add more messages --- .../database/TransferControllerTest.kt | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt index 221e4595..30c87d44 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -45,20 +45,7 @@ class TransferControllerTest { transferController.upsert(transfer) val realmTransfer = transferController.getTransfer(transfer.linkUuid) assertNotNull(realmTransfer, "The transfer cannot be null") - assertEquals(transfer.container.uuid, realmTransfer.container?.uuid) - assertEquals(transfer.container.files.count(), realmTransfer.container?.files?.count()) - } - - @Test - fun canRemoveTransfers() = runTest { - transferController.upsert(DummyTransfer.transfer) - transferController.removeData() - assertEquals(0, transferController.getTransfers()?.count()) - } - - @Test - fun realmTransferListIsEmpty() { - assertTrue(transferController.getTransfers()?.isEmpty() == true) + assertEquals(transfer.container.uuid, realmTransfer.container?.uuid, "The container is missing") } @Test @@ -66,6 +53,13 @@ class TransferControllerTest { val transfer = DummyTransfer.transfer transferController.upsert(transfer) val transfers = transferController.getTransfers() - assertEquals(1, transfers?.count()) + assertEquals(1, transfers?.count(), "The transfer list must contain 1 item") + } + + @Test + fun canRemoveTransfers() = runTest { + transferController.upsert(DummyTransfer.transfer) + transferController.removeData() + assertEquals(0, transferController.getTransfers()?.count(), "The transfers table must be empty") } } From bdff78eb4d5bceb144896687d1b75fdb75a665d7 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Thu, 10 Oct 2024 17:50:39 +0200 Subject: [PATCH 17/24] core: Add kDoc for TransferManager --- .../managers/TransferManager.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt index 7e783a97..cfb5324d 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt @@ -50,8 +50,29 @@ class TransferManager internal constructor( private val transferRepository: TransferRepository, ) { + /** + * The `Flow` of [transfers] is used to receive updates for new transfers added in database. + * @see addTransferByLinkUuid + * @see addTransferByUrl + */ val transfers get() = transferController.getTransfersFlow().flowOn(Dispatchers.IO) + /** + * Retrieves a transfer using the provided link UUID and saves it to the database. + * + * This function is typically used after a transfer has been uploaded. Once the upload is complete, + * a `linkUuid` is returned, which must be passed to this function to retrieve the corresponding transfer. + * After retrieving the transfer, it is saved to the database. + * + * @see transfers + * + * @param linkUuid The UUID corresponding to the uploaded transfer link. + * @throws CancellationException If the operation is cancelled. + * @throws ApiException If there is an error related to the API during transfer retrieval. + * @throws UnknownApiException If an unknown error occurs while interacting with the API. + * @throws NetworkException If there is a network issue during the transfer retrieval. + * @throws UnknownException For any other unexpected errors that occur during the process. + */ @Throws( CancellationException::class, ApiException::class, @@ -63,6 +84,22 @@ class TransferManager internal constructor( addTransfer(transferRepository.getTransferByLinkUuid(linkUuid).data) } + /** + * Retrieves a transfer using the provided URL and saves it to the database. + * + * This function is used when a transfer URL is available. The provided `url` is used to retrieve + * the corresponding transfer, and after the transfer is successfully retrieved, it is saved to + * the database. + * + * @see transfers + * + * @param url The URL associated with the transfer to retrieve. + * @throws CancellationException If the operation is cancelled. + * @throws ApiException If there is an error related to the API during transfer retrieval. + * @throws UnknownApiException If an unknown error occurs while interacting with the API. + * @throws NetworkException If there is a network issue during the transfer retrieval. + * @throws UnknownException For any other unexpected errors that occur during the process. + */ @Throws( CancellationException::class, ApiException::class, From ee9bda3b3b65a6fef67a2f9c183eb0057b01aa80 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Fri, 11 Oct 2024 14:39:19 +0200 Subject: [PATCH 18/24] test: Can Update an existing transfer --- .../database/TransferControllerTest.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt index 30c87d44..d14efa19 100644 --- a/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt +++ b/STDatabase/src/commonTest/kotlin/com/infomaniak/multiplatform_swisstransfer/database/TransferControllerTest.kt @@ -17,6 +17,9 @@ */ package com.infomaniak.multiplatform_swisstransfer.database +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.database.cache.setting.TransferController import com.infomaniak.multiplatform_swisstransfer.database.dataset.DummyTransfer import kotlinx.coroutines.test.runTest @@ -56,6 +59,25 @@ class TransferControllerTest { assertEquals(1, transfers?.count(), "The transfer list must contain 1 item") } + @Test + fun canUpdateAnExistingTransfer() = runTest { + // Insert a transfer + val transfer1 = DummyTransfer.transfer + transferController.upsert(transfer1) + val realmTransfer1 = transferController.getTransfer(transfer1.linkUuid) + assertNotNull(realmTransfer1) + + // Update the transfer + val transfer2 = object : Transfer>> by transfer1 { + override var containerUuid: String = "transfer2" + } + transferController.upsert(transfer2) + val realmTransfers = transferController.getTransfers() + assertNotNull(realmTransfers) + assertEquals(1, realmTransfers.count()) + assertEquals(transfer2.containerUuid, realmTransfers.first().containerUuid) + } + @Test fun canRemoveTransfers() = runTest { transferController.upsert(DummyTransfer.transfer) From ada87a95bf47d233fcbe371806098e4f89fc62e3 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Fri, 11 Oct 2024 14:40:10 +0200 Subject: [PATCH 19/24] Update STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt Co-authored-by: Gibran Chevalley <32095402+LunarX@users.noreply.github.com> --- .../network/repositories/TransferRepository.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt index e0cfaa59..4ab6327d 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt @@ -56,6 +56,8 @@ class TransferRepository internal constructor(private val transferRequest: Trans UnknownException::class, ) suspend fun getTransferByUrl(url: String): ApiResponse { - return transferRequest.getTransfer(url.substringAfter(ApiRoutes.baseUrl)) + return transferRequest.getTransfer(extractUuid(url)) } + + private fun extractUuid(url: String) = url.substringAfter(ApiRoutes.baseUrl) } From 2d345798ff3d685d53b130c048f5e798a8098c3e Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Fri, 11 Oct 2024 15:07:34 +0200 Subject: [PATCH 20/24] refactor: Rename UnknownApiException in UnexpectedApiErrorFormatException --- .../managers/TransferManager.kt | 14 +++++++------- .../network/ApiClientProvider.kt | 6 +++--- .../network/exceptions/ContainerErrorsException.kt | 10 +++++----- .../network/exceptions/EmailValidationException.kt | 10 +++++----- ...ion.kt => UnexpectedApiErrorFormatException.kt} | 2 +- .../network/repositories/TransferRepository.kt | 6 +++--- .../network/repositories/UploadRepository.kt | 14 +++++++------- 7 files changed, 31 insertions(+), 31 deletions(-) rename STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/{UnknownApiException.kt => UnexpectedApiErrorFormatException.kt} (87%) diff --git a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt index cfb5324d..467bd2ac 100644 --- a/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt +++ b/STCore/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/managers/TransferManager.kt @@ -23,7 +23,7 @@ import com.infomaniak.multiplatform_swisstransfer.database.cache.setting.Transfe import com.infomaniak.multiplatform_swisstransfer.network.ApiClientProvider import com.infomaniak.multiplatform_swisstransfer.network.exceptions.ApiException import com.infomaniak.multiplatform_swisstransfer.network.exceptions.NetworkException -import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnknownApiException +import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnexpectedApiErrorFormatException import com.infomaniak.multiplatform_swisstransfer.network.models.transfer.TransferApi import com.infomaniak.multiplatform_swisstransfer.network.repositories.TransferRepository import kotlinx.coroutines.Dispatchers @@ -69,14 +69,14 @@ class TransferManager internal constructor( * @param linkUuid The UUID corresponding to the uploaded transfer link. * @throws CancellationException If the operation is cancelled. * @throws ApiException If there is an error related to the API during transfer retrieval. - * @throws UnknownApiException If an unknown error occurs while interacting with the API. + * @throws UnexpectedApiErrorFormatException Unparsable api error response. * @throws NetworkException If there is a network issue during the transfer retrieval. - * @throws UnknownException For any other unexpected errors that occur during the process. + * @throws UnknownException Any error not already handled by the above ones. */ @Throws( CancellationException::class, ApiException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, NetworkException::class, UnknownException::class, ) @@ -96,14 +96,14 @@ class TransferManager internal constructor( * @param url The URL associated with the transfer to retrieve. * @throws CancellationException If the operation is cancelled. * @throws ApiException If there is an error related to the API during transfer retrieval. - * @throws UnknownApiException If an unknown error occurs while interacting with the API. + * @throws UnexpectedApiErrorFormatException Unparsable api error response. * @throws NetworkException If there is a network issue during the transfer retrieval. - * @throws UnknownException For any other unexpected errors that occur during the process. + * @throws UnknownException Any error not already handled by the above ones. */ @Throws( CancellationException::class, ApiException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, NetworkException::class, UnknownException::class, ) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/ApiClientProvider.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/ApiClientProvider.kt index e7fc6bc5..4306c407 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/ApiClientProvider.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/ApiClientProvider.kt @@ -20,7 +20,7 @@ package com.infomaniak.multiplatform_swisstransfer.network import com.infomaniak.multiplatform_swisstransfer.common.exceptions.UnknownException import com.infomaniak.multiplatform_swisstransfer.network.exceptions.ApiException import com.infomaniak.multiplatform_swisstransfer.network.exceptions.NetworkException -import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnknownApiException +import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnexpectedApiErrorFormatException import com.infomaniak.multiplatform_swisstransfer.network.models.ApiError import io.ktor.client.HttpClient import io.ktor.client.HttpClientConfig @@ -79,14 +79,14 @@ class ApiClientProvider internal constructor(engine: HttpClientEngineFactory<*>? val apiError = json.decodeFromString(bodyResponse) throw ApiException(apiError.errorCode, apiError.message) }.onFailure { - throw UnknownApiException(statusCode, bodyResponse) + throw UnexpectedApiErrorFormatException(statusCode, bodyResponse) } } } handleResponseExceptionWithRequest { cause, _ -> when (cause) { is IOException -> throw NetworkException("Network error: ${cause.message}") - is ApiException, is UnknownApiException -> throw cause + is ApiException, is UnexpectedApiErrorFormatException -> throw cause else -> throw UnknownException(cause) } } diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ContainerErrorsException.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ContainerErrorsException.kt index 3012a6a9..45392b6d 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ContainerErrorsException.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ContainerErrorsException.kt @@ -61,7 +61,7 @@ sealed class ContainerErrorsException(val statusCode: Int, errorMessage: String) internal companion object { /** - * Extension function to convert an instance of [UnknownApiException] to a more specific exception + * Extension function to convert an instance of [UnexpectedApiErrorFormatException] to a more specific exception * based on its HTTP status code. * * This function maps the status codes to specific exceptions as follows: @@ -70,13 +70,13 @@ sealed class ContainerErrorsException(val statusCode: Int, errorMessage: String) * - 404: [DailyTransferLimitReachedException] * - 422: [CaptchaNotValidException] * - 429: [TooManyCodesGeneratedException] - * - Other status codes: The original [UnknownApiException] instance + * - Other status codes: The original [UnexpectedApiErrorFormatException] instance * - * @receiver An instance of [UnknownApiException]. + * @receiver An instance of [UnexpectedApiErrorFormatException]. * @return An instance of [Exception] which can be one of the specific exceptions mentioned above, - * or the original [UnknownApiException] if the status code does not match any predefined values. + * or the original [UnexpectedApiErrorFormatException] if the status code does not match any predefined values. */ - fun UnknownApiException.toContainerErrorsException(): Exception { + fun UnexpectedApiErrorFormatException.toContainerErrorsException(): Exception { return when (statusCode) { 401 -> EmailValidationRequired() 403 -> DomainBlockedException() diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/EmailValidationException.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/EmailValidationException.kt index c2cc0cb9..6e9fc4cb 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/EmailValidationException.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/EmailValidationException.kt @@ -36,18 +36,18 @@ sealed class EmailValidationException(statusCode: Int) : ApiException(statusCode internal companion object { /** - * Extension function to convert an instance of [UnknownApiException] to a specific + * Extension function to convert an instance of [UnexpectedApiErrorFormatException] to a specific * [EmailValidationException] based on its HTTP status code. * * This function maps the status codes to specific exceptions as follows: * - 401: [InvalidPasswordException] - * - Other status codes: The original [UnknownApiException] instance + * - Other status codes: The original [UnexpectedApiErrorFormatException] instance * - * @receiver An instance of [UnknownApiException]. + * @receiver An instance of [UnexpectedApiErrorFormatException]. * @return An instance of [EmailValidationException] which can be [InvalidPasswordException] - * or the original [UnknownApiException] if the status code does not match any predefined values. + * or the original [UnexpectedApiErrorFormatException] if the status code does not match any predefined values. */ - fun UnknownApiException.toEmailValidationException() = when (statusCode) { + fun UnexpectedApiErrorFormatException.toEmailValidationException() = when (statusCode) { 401 -> InvalidPasswordException() else -> this } diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnknownApiException.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnexpectedApiErrorFormatException.kt similarity index 87% rename from STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnknownApiException.kt rename to STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnexpectedApiErrorFormatException.kt index 14f61df4..5c0d9f11 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnknownApiException.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnexpectedApiErrorFormatException.kt @@ -17,4 +17,4 @@ */ package com.infomaniak.multiplatform_swisstransfer.network.exceptions -class UnknownApiException(val statusCode: Int, val bodyResponse: String) : Exception(bodyResponse) +class UnexpectedApiErrorFormatException(val statusCode: Int, val bodyResponse: String) : Exception(bodyResponse) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt index 4ab6327d..289f1bd9 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/TransferRepository.kt @@ -21,7 +21,7 @@ import com.infomaniak.multiplatform_swisstransfer.common.exceptions.UnknownExcep import com.infomaniak.multiplatform_swisstransfer.network.ApiClientProvider import com.infomaniak.multiplatform_swisstransfer.network.exceptions.ApiException import com.infomaniak.multiplatform_swisstransfer.network.exceptions.NetworkException -import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnknownApiException +import com.infomaniak.multiplatform_swisstransfer.network.exceptions.UnexpectedApiErrorFormatException import com.infomaniak.multiplatform_swisstransfer.network.models.ApiResponse import com.infomaniak.multiplatform_swisstransfer.network.models.transfer.TransferApi import com.infomaniak.multiplatform_swisstransfer.network.requests.TransferRequest @@ -42,7 +42,7 @@ class TransferRepository internal constructor(private val transferRequest: Trans @Throws( CancellationException::class, ApiException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, NetworkException::class, UnknownException::class, ) @@ -51,7 +51,7 @@ class TransferRepository internal constructor(private val transferRequest: Trans @Throws( CancellationException::class, ApiException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, NetworkException::class, UnknownException::class, ) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/UploadRepository.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/UploadRepository.kt index 1e2d29f2..9fa743e7 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/UploadRepository.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/repositories/UploadRepository.kt @@ -48,14 +48,14 @@ class UploadRepository internal constructor(private val uploadRequest: UploadReq ContainerErrorsException::class, ApiException::class, NetworkException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, UnknownException::class, ) suspend fun initUpload(initUploadBody: InitUploadBody): InitUploadResponseApi { return runCatching { uploadRequest.initUpload(initUploadBody) }.getOrElse { exception -> - if (exception is UnknownApiException) { + if (exception is UnexpectedApiErrorFormatException) { throw exception.toContainerErrorsException() } else { throw exception @@ -68,14 +68,14 @@ class UploadRepository internal constructor(private val uploadRequest: UploadReq EmailValidationException::class, ApiException::class, NetworkException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, UnknownException::class, ) suspend fun verifyEmailCode(verifyEmailCodeBody: VerifyEmailCodeBody): AuthorEmailToken { return runCatching { uploadRequest.verifyEmailCode(verifyEmailCodeBody) }.getOrElse { exception -> - if (exception is UnknownApiException) { + if (exception is UnexpectedApiErrorFormatException) { throw exception.toEmailValidationException() } else { throw exception @@ -87,7 +87,7 @@ class UploadRepository internal constructor(private val uploadRequest: UploadReq CancellationException::class, ApiException::class, NetworkException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, UnknownException::class, ) suspend fun resendEmailCode(resendEmailCodeBody: ResendEmailCodeBody): Boolean { @@ -97,7 +97,7 @@ class UploadRepository internal constructor(private val uploadRequest: UploadReq @Throws( CancellationException::class, ApiException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, NetworkException::class, UnknownException::class, ) @@ -115,7 +115,7 @@ class UploadRepository internal constructor(private val uploadRequest: UploadReq @Throws( CancellationException::class, ApiException::class, - UnknownApiException::class, + UnexpectedApiErrorFormatException::class, NetworkException::class, UnknownException::class, ) From 3fe5973c9862a5bd9b9f84d3ab060292f25ee9e2 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Fri, 11 Oct 2024 17:02:45 +0200 Subject: [PATCH 21/24] chore: Add kDoc for ApiException --- .../network/exceptions/ApiException.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ApiException.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ApiException.kt index a12def30..5b1f2696 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ApiException.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/ApiException.kt @@ -17,4 +17,13 @@ */ package com.infomaniak.multiplatform_swisstransfer.network.exceptions +/** + * Thrown when an API call fails due to an error identified by a specific error code. + * + * This exception is used to represent errors returned by an API, with an associated error code + * and message describing the problem. + * + * @param errorCode The specific error code returned by the API. + * @param errorMessage The detailed error message explaining the cause of the failure. + */ open class ApiException(val errorCode: Int, errorMessage: String) : Exception(errorMessage) From 7ff7f94a8cd216fc356b831a834366754c99f845 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Fri, 11 Oct 2024 17:03:06 +0200 Subject: [PATCH 22/24] chore: Add kDoc for UnexpectedApiErrorFormatException --- .../exceptions/UnexpectedApiErrorFormatException.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnexpectedApiErrorFormatException.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnexpectedApiErrorFormatException.kt index 5c0d9f11..40ae2094 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnexpectedApiErrorFormatException.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/UnexpectedApiErrorFormatException.kt @@ -17,4 +17,13 @@ */ package com.infomaniak.multiplatform_swisstransfer.network.exceptions +/** + * Thrown when an API call returns an error in an unexpected format that cannot be parsed. + * + * This exception indicates that the API response format is different from what was expected, + * preventing proper parsing of the error details. + * + * @param statusCode The HTTP status code returned by the API. + * @param bodyResponse The raw response body from the API that could not be parsed. + */ class UnexpectedApiErrorFormatException(val statusCode: Int, val bodyResponse: String) : Exception(bodyResponse) From 87a3856513cd4d9a747474c2f301f5ac750e89a9 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Fri, 11 Oct 2024 17:09:10 +0200 Subject: [PATCH 23/24] chore: Add kDoc for NetworkException --- .../network/exceptions/NetworkException.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt index c4f588ad..31254a1d 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt @@ -19,4 +19,12 @@ package com.infomaniak.multiplatform_swisstransfer.network.exceptions import io.ktor.utils.io.errors.IOException +/** + * Thrown when a network-related error occurs, such as connectivity issues or timeouts. + * + * This exception is used to represent errors that occur during network operations, + * typically indicating problems with the connection, DNS resolution, or other network failures. + * + * @param message A detailed message describing the network error. + */ class NetworkException(message: String) : IOException(message) From c5e0ebc41764dd44b931158a4413561efc765a41 Mon Sep 17 00:00:00 2001 From: Abdourahamane Boinaidi Date: Tue, 15 Oct 2024 09:58:34 +0200 Subject: [PATCH 24/24] refactor: Update NetworkException kDoc --- .../network/exceptions/NetworkException.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt index 31254a1d..f894dc9e 100644 --- a/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt +++ b/STNetwork/src/commonMain/kotlin/com/infomaniak/multiplatform_swisstransfer/network/exceptions/NetworkException.kt @@ -22,9 +22,6 @@ import io.ktor.utils.io.errors.IOException /** * Thrown when a network-related error occurs, such as connectivity issues or timeouts. * - * This exception is used to represent errors that occur during network operations, - * typically indicating problems with the connection, DNS resolution, or other network failures. - * * @param message A detailed message describing the network error. */ class NetworkException(message: String) : IOException(message)