diff --git a/CHANGELOG.md b/CHANGELOG.md index d66114c67ea..73ca624b120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Summary * Change - Android library as a module instead of submodule: [#3962](https://github.com/owncloud/android/issues/3962) * Enhancement - Koin DSL: [#3966](https://github.com/owncloud/android/pull/3966) +* Enhancement - Unit tests for datasources classes - Part 3: [#4072](https://github.com/owncloud/android/issues/4072) * Enhancement - "Apply to all" when many name conflicts arise: [#4078](https://github.com/owncloud/android/issues/4078) * Enhancement - "Share to" in oCIS accounts allows upload to any space: [#4088](https://github.com/owncloud/android/issues/4088) * Enhancement - Use invoke operator to execute usecases: [#4179](https://github.com/owncloud/android/pull/4179) @@ -32,6 +33,17 @@ Details https://github.com/owncloud/android/pull/3966 +* Enhancement - Unit tests for datasources classes - Part 3: [#4072](https://github.com/owncloud/android/issues/4072) + + Unit tests of the OCFolderBackupLocalDataSource, OCRemoteOAuthDataSource, + OCRemoteShareeDataSource, OCLocalShareDataSource, OCRemoteShareDataSource, + OCLocalSpacesDataSource, OCRemoteSpacesDataSource, OCLocalTransferDataSource, + OCLocalUserDataSource, OCRemoteUserDataSource, OCRemoteWebFingerDatasource classes + have been done and completed. + + https://github.com/owncloud/android/issues/4072 + https://github.com/owncloud/android/pull/4143 + * Enhancement - "Apply to all" when many name conflicts arise: [#4078](https://github.com/owncloud/android/issues/4078) A new dialog has been created where a checkbox has been added to be able to select all the folders diff --git a/changelog/unreleased/4143 b/changelog/unreleased/4143 new file mode 100644 index 00000000000..30b6577074e --- /dev/null +++ b/changelog/unreleased/4143 @@ -0,0 +1,8 @@ +Enhancement: Unit tests for datasources classes - Part 3 + +Unit tests of the OCFolderBackupLocalDataSource, OCRemoteOAuthDataSource, OCRemoteShareeDataSource, OCLocalShareDataSource, +OCRemoteShareDataSource, OCLocalSpacesDataSource, OCRemoteSpacesDataSource, OCLocalTransferDataSource, OCLocalUserDataSource, +OCRemoteUserDataSource, OCRemoteWebFingerDatasource classes have been done and completed. + +https://github.com/owncloud/android/issues/4072 +https://github.com/owncloud/android/pull/4143 diff --git a/owncloudApp/src/androidTest/java/com/owncloud/android/sharing/sharees/ui/SearchShareesFragmentTest.kt b/owncloudApp/src/androidTest/java/com/owncloud/android/sharing/sharees/ui/SearchShareesFragmentTest.kt index 59f3f46f890..c5384d97231 100644 --- a/owncloudApp/src/androidTest/java/com/owncloud/android/sharing/sharees/ui/SearchShareesFragmentTest.kt +++ b/owncloudApp/src/androidTest/java/com/owncloud/android/sharing/sharees/ui/SearchShareesFragmentTest.kt @@ -54,7 +54,7 @@ class SearchShareesFragmentTest { private val sharesLiveData = MutableLiveData>>>() @Before - fun init() { + fun setUp() { every { shareViewModel.shares } returns sharesLiveData stopKoin() diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt index d0577d33e23..b3bda017327 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/LocalDataSourceModule.kt @@ -34,8 +34,8 @@ import com.owncloud.android.data.capabilities.datasources.LocalCapabilitiesDataS import com.owncloud.android.data.capabilities.datasources.implementation.OCLocalCapabilitiesDataSource import com.owncloud.android.data.files.datasources.LocalFileDataSource import com.owncloud.android.data.files.datasources.implementation.OCLocalFileDataSource -import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource -import com.owncloud.android.data.folderbackup.datasources.implementation.OCFolderBackupLocalDataSource +import com.owncloud.android.data.folderbackup.datasources.LocalFolderBackupDataSource +import com.owncloud.android.data.folderbackup.datasources.implementation.OCLocalFolderBackupDataSource import com.owncloud.android.data.providers.SharedPreferencesProvider import com.owncloud.android.data.providers.implementation.OCSharedPreferencesProvider import com.owncloud.android.data.sharing.shares.datasources.LocalShareDataSource @@ -70,7 +70,7 @@ val localDataSourceModule = module { single { ScopedStorageProvider(dataFolder, androidContext()) } factory { OCLocalAuthenticationDataSource(androidContext(), get(), get(), accountType) } - factoryOf(::OCFolderBackupLocalDataSource) bind FolderBackupLocalDataSource::class + factoryOf(::OCLocalFolderBackupDataSource) bind LocalFolderBackupDataSource::class factoryOf(::OCLocalAppRegistryDataSource) bind LocalAppRegistryDataSource::class factoryOf(::OCLocalCapabilitiesDataSource) bind LocalCapabilitiesDataSource::class factoryOf(::OCLocalFileDataSource) bind LocalFileDataSource::class diff --git a/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt b/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt index 982c6619768..4c9dcfc40ac 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/providers/FileContentProvider.kt @@ -55,8 +55,8 @@ import com.owncloud.android.data.capabilities.datasources.implementation.OCLocal import com.owncloud.android.data.capabilities.datasources.implementation.OCLocalCapabilitiesDataSource.Companion.toModel import com.owncloud.android.data.capabilities.db.OCCapabilityEntity import com.owncloud.android.data.files.db.OCFileEntity -import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource -import com.owncloud.android.data.folderbackup.datasources.implementation.OCFolderBackupLocalDataSource +import com.owncloud.android.data.folderbackup.datasources.LocalFolderBackupDataSource +import com.owncloud.android.data.folderbackup.datasources.implementation.OCLocalFolderBackupDataSource import com.owncloud.android.data.migrations.CameraUploadsMigrationToRoom import com.owncloud.android.data.providers.SharedPreferencesProvider import com.owncloud.android.data.providers.implementation.OCSharedPreferencesProvider @@ -973,8 +973,8 @@ class FileContentProvider(val executors: Executors = Executors()) : ContentProvi val pictureUploadsConfiguration = migrationToRoom.getPictureUploadsConfigurationPreferences(pictureUploadsTimestamp) val videoUploadsConfiguration = migrationToRoom.getVideoUploadsConfigurationPreferences(videoUploadsTimestamp) - val backupLocalDataSource: FolderBackupLocalDataSource = - OCFolderBackupLocalDataSource(OwncloudDatabase.getDatabase(context!!).folderBackUpDao()) + val backupLocalDataSource: LocalFolderBackupDataSource = + OCLocalFolderBackupDataSource(OwncloudDatabase.getDatabase(context!!).folderBackUpDao()) // Insert camera uploads configuration in new database executors.diskIO().execute { pictureUploadsConfiguration?.let { backupLocalDataSource.saveFolderBackupConfiguration(it) } diff --git a/owncloudData/src/androidTest/java/com/owncloud/android/data/authentication/datasources/implementation/OCLocalAuthenticationDataSourceTest.kt b/owncloudData/src/androidTest/java/com/owncloud/android/data/authentication/datasources/implementation/OCLocalAuthenticationDataSourceTest.kt index a401c1a0475..a2276af7ead 100644 --- a/owncloudData/src/androidTest/java/com/owncloud/android/data/authentication/datasources/implementation/OCLocalAuthenticationDataSourceTest.kt +++ b/owncloudData/src/androidTest/java/com/owncloud/android/data/authentication/datasources/implementation/OCLocalAuthenticationDataSourceTest.kt @@ -57,7 +57,7 @@ import com.owncloud.android.testutil.OC_SECURE_SERVER_INFO_BASIC_AUTH import com.owncloud.android.testutil.OC_USER_INFO import com.owncloud.android.testutil.oauth.OC_CLIENT_REGISTRATION import io.mockk.every -import io.mockk.mockkClass +import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import org.junit.Assert.assertEquals @@ -73,11 +73,11 @@ class OCLocalAuthenticationDataSourceTest { val instantExecutorRule = InstantTaskExecutorRule() private lateinit var ocLocalAuthenticationDataSource: OCLocalAuthenticationDataSource - private val accountManager = mockkClass(AccountManager::class) + private val accountManager = mockk(relaxUnitFun = true) private val preferencesProvider = spyk() @Before - fun init() { + fun setUp() { val context = InstrumentationRegistry.getInstrumentation().targetContext ocLocalAuthenticationDataSource = OCLocalAuthenticationDataSource( @@ -86,6 +86,13 @@ class OCLocalAuthenticationDataSourceTest { preferencesProvider, OC_ACCOUNT.type ) + getAccountsByType(OC_ACCOUNT.type, arrayOf(OC_ACCOUNT)) + } + + private fun getAccountsByType(accountType: String, accounts: Array) { + every { + accountManager.getAccountsByType(accountType) + } returns accounts } @Test @@ -102,7 +109,7 @@ class OCLocalAuthenticationDataSourceTest { null ) - val newAccount = Account(OC_ACCOUNT_NAME, "owncloud") + val newAccount = Account(OC_ACCOUNT_NAME, OC_ACCOUNT.type) // One for checking if the account exists and another one for getting the new account verifyAccountsByTypeAreGot(newAccount.type, 2) @@ -115,9 +122,6 @@ class OCLocalAuthenticationDataSourceTest { @Test(expected = AccountNotNewException::class) fun addBasicAccountAlreadyExistsNoUpdate() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf(OC_ACCOUNT) // The account is already there ocLocalAuthenticationDataSource.addBasicAccount( OC_ACCOUNT_ID, @@ -131,17 +135,6 @@ class OCLocalAuthenticationDataSourceTest { @Test fun addBasicAccountAlreadyExistsUpdateSameUsername() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf(OC_ACCOUNT) // The account is already there - - every { - accountManager.setPassword(any(), any()) - } returns Unit - - every { - accountManager.setUserData(any(), any(), any()) - } returns Unit mockSelectedAccountNameInPreferences() @@ -167,10 +160,6 @@ class OCLocalAuthenticationDataSourceTest { @Test fun addBasicAccountAlreadyExistsUpdateDifferentUsername() { - every { - accountManager.setUserData(any(), any(), any()) - } returns Unit - mockSelectedAccountNameInPreferences() try { @@ -198,10 +187,6 @@ class OCLocalAuthenticationDataSourceTest { mockRegularAccountCreationFlow() mockSelectedAccountNameInPreferences() - every { - accountManager.setAuthToken(any(), any(), any()) - } returns Unit - val newAccountName = ocLocalAuthenticationDataSource.addOAuthAccount( OC_ACCOUNT_ID, OC_REDIRECTION_PATH.lastPermanentLocation, @@ -215,7 +200,7 @@ class OCLocalAuthenticationDataSourceTest { OC_CLIENT_REGISTRATION ) - val newAccount = Account(OC_ACCOUNT_NAME, "owncloud") + val newAccount = Account(OC_ACCOUNT_NAME, OC_ACCOUNT.type) // One for checking if the account exists and another one for getting the new account verifyAccountsByTypeAreGot(newAccount.type, 2) @@ -231,9 +216,6 @@ class OCLocalAuthenticationDataSourceTest { @Test(expected = AccountNotNewException::class) fun addOAuthAccountAlreadyExistsNoUpdate() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf(OC_ACCOUNT) // The account is already there ocLocalAuthenticationDataSource.addOAuthAccount( OC_ACCOUNT_ID, @@ -251,17 +233,6 @@ class OCLocalAuthenticationDataSourceTest { @Test fun addOAuthAccountAlreadyExistsUpdateSameUsername() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf(OC_ACCOUNT) // The account is already there - - every { - accountManager.setUserData(any(), any(), any()) - } returns Unit - - every { - accountManager.setAuthToken(any(), any(), any()) - } returns Unit mockSelectedAccountNameInPreferences() @@ -292,14 +263,6 @@ class OCLocalAuthenticationDataSourceTest { @Test fun addOAuthAccountAlreadyExistsUpdateDifferentUsername() { - every { - accountManager.setUserData(any(), any(), any()) - } returns Unit - - every { - accountManager.setAuthToken(any(), any(), any()) - } returns Unit - mockSelectedAccountNameInPreferences() try { @@ -337,9 +300,6 @@ class OCLocalAuthenticationDataSourceTest { @Test fun supportsOAuthOk() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf(OC_ACCOUNT) every { accountManager.getUserData(OC_ACCOUNT, KEY_SUPPORTS_OAUTH2) @@ -355,18 +315,13 @@ class OCLocalAuthenticationDataSourceTest { @Test(expected = AccountNotFoundException::class) fun supportsOAuthAccountNotFound() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf() // That account does not exist + getAccountsByType(OC_ACCOUNT.type, arrayOf())// That account does not exist ocLocalAuthenticationDataSource.supportsOAuth2(OC_ACCOUNT.name) } @Test fun getBaseUrlOk() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf(OC_ACCOUNT) every { accountManager.getUserData(OC_ACCOUNT, KEY_OC_BASE_URL) @@ -382,9 +337,7 @@ class OCLocalAuthenticationDataSourceTest { @Test(expected = AccountNotFoundException::class) fun getBaseUrlAccountNotFound() { - every { - accountManager.getAccountsByType(OC_ACCOUNT.type) - } returns arrayOf() // That account does not exist + getAccountsByType(OC_ACCOUNT.type, arrayOf()) // That account does not exist ocLocalAuthenticationDataSource.getBaseUrl(OC_ACCOUNT.name) } @@ -402,9 +355,7 @@ class OCLocalAuthenticationDataSourceTest { private fun mockRegularAccountCreationFlow() { // Step 1: Get accounts to know if the current account exists - every { - accountManager.getAccountsByType("owncloud") - } returns arrayOf() // There's no accounts yet + getAccountsByType(OC_ACCOUNT.type, arrayOf()) // There's no accounts yet // Step 2: Add new account every { diff --git a/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/OCFolderBackupRepository.kt b/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/OCFolderBackupRepository.kt index 04cd065fd7f..a88c5b00659 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/OCFolderBackupRepository.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/OCFolderBackupRepository.kt @@ -18,27 +18,27 @@ */ package com.owncloud.android.data.folderbackup -import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource +import com.owncloud.android.data.folderbackup.datasources.LocalFolderBackupDataSource import com.owncloud.android.domain.camerauploads.FolderBackupRepository import com.owncloud.android.domain.camerauploads.model.CameraUploadsConfiguration import com.owncloud.android.domain.camerauploads.model.FolderBackUpConfiguration import kotlinx.coroutines.flow.Flow class OCFolderBackupRepository( - private val folderBackupLocalDataSource: FolderBackupLocalDataSource + private val localFolderBackupDataSource: LocalFolderBackupDataSource ) : FolderBackupRepository { override fun getCameraUploadsConfiguration(): CameraUploadsConfiguration? = - folderBackupLocalDataSource.getCameraUploadsConfiguration() + localFolderBackupDataSource.getCameraUploadsConfiguration() override fun getFolderBackupConfigurationByNameAsFlow(name: String): Flow = - folderBackupLocalDataSource.getFolderBackupConfigurationByNameAsFlow(name) + localFolderBackupDataSource.getFolderBackupConfigurationByNameAsFlow(name) override fun saveFolderBackupConfiguration(folderBackUpConfiguration: FolderBackUpConfiguration) { - folderBackupLocalDataSource.saveFolderBackupConfiguration(folderBackUpConfiguration) + localFolderBackupDataSource.saveFolderBackupConfiguration(folderBackUpConfiguration) } override fun resetFolderBackupConfigurationByName(name: String) = - folderBackupLocalDataSource.resetFolderBackupConfigurationByName(name) + localFolderBackupDataSource.resetFolderBackupConfigurationByName(name) } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/FolderBackupLocalDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/LocalFolderBackupDataSource.kt similarity index 96% rename from owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/FolderBackupLocalDataSource.kt rename to owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/LocalFolderBackupDataSource.kt index 1efe4d6b68b..fcdcd1aa06f 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/FolderBackupLocalDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/LocalFolderBackupDataSource.kt @@ -22,7 +22,7 @@ import com.owncloud.android.domain.camerauploads.model.CameraUploadsConfiguratio import com.owncloud.android.domain.camerauploads.model.FolderBackUpConfiguration import kotlinx.coroutines.flow.Flow -interface FolderBackupLocalDataSource { +interface LocalFolderBackupDataSource { fun getCameraUploadsConfiguration(): CameraUploadsConfiguration? fun getFolderBackupConfigurationByNameAsFlow(name: String): Flow diff --git a/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCFolderBackupLocalDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCLocalFolderBackupDataSource.kt similarity index 82% rename from owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCFolderBackupLocalDataSource.kt rename to owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCLocalFolderBackupDataSource.kt index 1ffd5d5bd10..5af4e0a5e18 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCFolderBackupLocalDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCLocalFolderBackupDataSource.kt @@ -18,7 +18,8 @@ */ package com.owncloud.android.data.folderbackup.datasources.implementation -import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource +import androidx.annotation.VisibleForTesting +import com.owncloud.android.data.folderbackup.datasources.LocalFolderBackupDataSource import com.owncloud.android.data.folderbackup.db.FolderBackUpEntity import com.owncloud.android.data.folderbackup.db.FolderBackupDao import com.owncloud.android.domain.camerauploads.model.CameraUploadsConfiguration @@ -29,9 +30,9 @@ import com.owncloud.android.domain.camerauploads.model.UploadBehavior import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -class OCFolderBackupLocalDataSource( +class OCLocalFolderBackupDataSource( private val folderBackupDao: FolderBackupDao, -) : FolderBackupLocalDataSource { +) : LocalFolderBackupDataSource { override fun getCameraUploadsConfiguration(): CameraUploadsConfiguration? { val pictureUploadsConfiguration = folderBackupDao.getFolderBackUpConfigurationByName(pictureUploadsName) @@ -59,17 +60,22 @@ class OCFolderBackupLocalDataSource( /************************************************************************************************************** ************************************************* Mappers **************************************************** **************************************************************************************************************/ - private fun FolderBackUpEntity.toModel() = - FolderBackUpConfiguration( - accountName = accountName, - behavior = UploadBehavior.fromString(behavior), - sourcePath = sourcePath, - uploadPath = uploadPath, - wifiOnly = wifiOnly, - chargingOnly = chargingOnly, - lastSyncTimestamp = lastSyncTimestamp, - name = name - ) + + companion object { + @VisibleForTesting + fun FolderBackUpEntity.toModel() = + FolderBackUpConfiguration( + accountName = accountName, + behavior = UploadBehavior.fromString(behavior), + sourcePath = sourcePath, + uploadPath = uploadPath, + wifiOnly = wifiOnly, + chargingOnly = chargingOnly, + lastSyncTimestamp = lastSyncTimestamp, + name = name + ) + } + private fun FolderBackUpConfiguration.toEntity(): FolderBackUpEntity = FolderBackUpEntity( diff --git a/owncloudData/src/main/java/com/owncloud/android/data/spaces/datasources/implementation/OCRemoteSpacesDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/spaces/datasources/implementation/OCRemoteSpacesDataSource.kt index bb9872f4450..11f8a2b37d0 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/spaces/datasources/implementation/OCRemoteSpacesDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/spaces/datasources/implementation/OCRemoteSpacesDataSource.kt @@ -18,6 +18,7 @@ */ package com.owncloud.android.data.spaces.datasources.implementation +import androidx.annotation.VisibleForTesting import com.owncloud.android.data.ClientManager import com.owncloud.android.data.executeRemoteOperation import com.owncloud.android.data.spaces.datasources.RemoteSpacesDataSource @@ -43,48 +44,52 @@ class OCRemoteSpacesDataSource( return spacesResponse.map { it.toModel(accountName) } } - private fun SpaceResponse.toModel(accountName: String): OCSpace = - OCSpace( - accountName = accountName, - driveAlias = driveAlias, - driveType = driveType, - id = id, - lastModifiedDateTime = lastModifiedDateTime, - name = name, - owner = owner?.let { ownerResponse -> - SpaceOwner( - user = SpaceUser( - id = ownerResponse.user.id + companion object { + + @VisibleForTesting + fun SpaceResponse.toModel(accountName: String): OCSpace = + OCSpace( + accountName = accountName, + driveAlias = driveAlias, + driveType = driveType, + id = id, + lastModifiedDateTime = lastModifiedDateTime, + name = name, + owner = owner?.let { ownerResponse -> + SpaceOwner( + user = SpaceUser( + id = ownerResponse.user.id + ) + ) + }, + quota = quota?.let { quotaResponse -> + SpaceQuota( + remaining = quotaResponse.remaining, + state = quotaResponse.state, + total = quotaResponse.total, + used = quotaResponse.used, ) - ) - }, - quota = quota?.let { quotaResponse -> - SpaceQuota( - remaining = quotaResponse.remaining, - state = quotaResponse.state, - total = quotaResponse.total, - used = quotaResponse.used, - ) - }, - root = SpaceRoot( - eTag = root.eTag, - id = root.id, - webDavUrl = root.webDavUrl, - deleted = root.deleted?.let { SpaceDeleted(state = it.state) } - ), - webUrl = webUrl, - description = description, - special = special?.map { specialResponse -> - SpaceSpecial( - eTag = specialResponse.eTag, - file = SpaceFile(mimeType = specialResponse.file.mimeType), - id = specialResponse.id, - lastModifiedDateTime = specialResponse.lastModifiedDateTime, - name = specialResponse.name, - size = specialResponse.size, - specialFolder = SpaceSpecialFolder(name = specialResponse.specialFolder.name), - webDavUrl = specialResponse.webDavUrl - ) - } - ) + }, + root = SpaceRoot( + eTag = root.eTag, + id = root.id, + webDavUrl = root.webDavUrl, + deleted = root.deleted?.let { SpaceDeleted(state = it.state) } + ), + webUrl = webUrl, + description = description, + special = special?.map { specialResponse -> + SpaceSpecial( + eTag = specialResponse.eTag, + file = SpaceFile(mimeType = specialResponse.file.mimeType), + id = specialResponse.id, + lastModifiedDateTime = specialResponse.lastModifiedDateTime, + name = specialResponse.name, + size = specialResponse.size, + specialFolder = SpaceSpecialFolder(name = specialResponse.specialFolder.name), + webDavUrl = specialResponse.webDavUrl + ) + } + ) + } } diff --git a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt index 05104379ae8..dfde793f7db 100644 --- a/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt +++ b/owncloudData/src/main/java/com/owncloud/android/data/transfers/datasources/implementation/OCLocalTransferDataSource.kt @@ -20,6 +20,7 @@ package com.owncloud.android.data.transfers.datasources.implementation +import androidx.annotation.VisibleForTesting import com.owncloud.android.data.transfers.datasources.LocalTransferDataSource import com.owncloud.android.data.transfers.db.OCTransferEntity import com.owncloud.android.data.transfers.db.TransferDao @@ -143,35 +144,40 @@ class OCLocalTransferDataSource( transferDao.deleteTransfersWithStatus(TransferStatus.TRANSFER_SUCCEEDED.value) } - private fun OCTransferEntity.toModel() = OCTransfer( - id = id, - localPath = localPath, - remotePath = remotePath, - accountName = accountName, - fileSize = fileSize, - status = TransferStatus.fromValue(status), - localBehaviour = if (localBehaviour > 1) UploadBehavior.MOVE else UploadBehavior.values()[localBehaviour], - forceOverwrite = forceOverwrite, - transferEndTimestamp = transferEndTimestamp, - lastResult = lastResult?.let { TransferResult.fromValue(it) }, - createdBy = UploadEnqueuedBy.values()[createdBy], - transferId = transferId, - spaceId = spaceId, - ) - - private fun OCTransfer.toEntity() = OCTransferEntity( - localPath = localPath, - remotePath = remotePath, - accountName = accountName, - fileSize = fileSize, - status = status.value, - localBehaviour = localBehaviour.ordinal, - forceOverwrite = forceOverwrite, - transferEndTimestamp = transferEndTimestamp, - lastResult = lastResult?.value, - createdBy = createdBy.ordinal, - transferId = transferId, - spaceId = spaceId, - ).apply { this@toEntity.id?.let { this.id = it } } + + companion object { + + @VisibleForTesting + fun OCTransferEntity.toModel() = OCTransfer( + id = id, + localPath = localPath, + remotePath = remotePath, + accountName = accountName, + fileSize = fileSize, + status = TransferStatus.fromValue(status), + localBehaviour = if (localBehaviour > 1) UploadBehavior.MOVE else UploadBehavior.values()[localBehaviour], + forceOverwrite = forceOverwrite, + transferEndTimestamp = transferEndTimestamp, + lastResult = lastResult?.let { TransferResult.fromValue(it) }, + createdBy = UploadEnqueuedBy.values()[createdBy], + transferId = transferId, + spaceId = spaceId, + ) + @VisibleForTesting + fun OCTransfer.toEntity() = OCTransferEntity( + localPath = localPath, + remotePath = remotePath, + accountName = accountName, + fileSize = fileSize, + status = status.value, + localBehaviour = localBehaviour.ordinal, + forceOverwrite = forceOverwrite, + transferEndTimestamp = transferEndTimestamp, + lastResult = lastResult?.value, + createdBy = createdBy.ordinal, + transferId = transferId, + spaceId = spaceId, + ).apply { this@toEntity.id?.let { this.id = it } } + } } diff --git a/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCLocalAppRegistryDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCLocalAppRegistryDataSourceTest.kt index bc28f2cbbe1..a0c440a856e 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCLocalAppRegistryDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCLocalAppRegistryDataSourceTest.kt @@ -1,7 +1,26 @@ +/** + * ownCloud Android client application + * + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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.owncloud.android.data.appRegistry.datasources.implementation import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.owncloud.android.data.OwncloudDatabase import com.owncloud.android.data.appregistry.datasources.implementation.OCLocalAppRegistryDataSource import com.owncloud.android.data.appregistry.db.AppRegistryDao import com.owncloud.android.data.appregistry.db.AppRegistryEntity @@ -10,12 +29,14 @@ import com.owncloud.android.domain.appregistry.model.AppRegistryMimeType import com.owncloud.android.testutil.OC_ACCOUNT_NAME import com.owncloud.android.testutil.OC_APP_REGISTRY_MIMETYPE import io.mockk.every -import io.mockk.mockkClass +import io.mockk.mockk import io.mockk.verify +import kotlinx.coroutines.flow.first import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest -import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull import org.junit.Before import org.junit.Rule import org.junit.Test @@ -23,7 +44,7 @@ import org.junit.Test @ExperimentalCoroutinesApi class OCLocalAppRegistryDataSourceTest { private lateinit var ocLocalAppRegistryDataSource: OCLocalAppRegistryDataSource - private val appRegistryDao = mockkClass(AppRegistryDao::class) + private val appRegistryDao = mockk(relaxUnitFun = true) private val mimetype = "DIR" private val ocAppRegistryEntity = AppRegistryEntity( accountName = OC_ACCOUNT_NAME, @@ -42,13 +63,7 @@ class OCLocalAppRegistryDataSourceTest { val instantExecutorRule = InstantTaskExecutorRule() @Before - fun init() { - - val db = mockkClass(OwncloudDatabase::class) - - every { - db.appRegistryDao() - } returns appRegistryDao + fun setUp() { ocLocalAppRegistryDataSource = OCLocalAppRegistryDataSource( @@ -63,9 +78,8 @@ class OCLocalAppRegistryDataSourceTest { val appRegistry = ocLocalAppRegistryDataSource.getAppRegistryForMimeTypeAsStream(OC_ACCOUNT_NAME, mimetype) - appRegistry.collect { appRegistryEmitted -> - Assert.assertEquals(OC_APP_REGISTRY_MIMETYPE, appRegistryEmitted) - } + val result = appRegistry.first() + assertEquals(OC_APP_REGISTRY_MIMETYPE, result) verify(exactly = 1) { appRegistryDao.getAppRegistryForMimeType(OC_ACCOUNT_NAME, mimetype) } } @@ -77,9 +91,9 @@ class OCLocalAppRegistryDataSourceTest { val appRegistry = ocLocalAppRegistryDataSource.getAppRegistryForMimeTypeAsStream(OC_ACCOUNT_NAME, mimetype) - appRegistry.collect { appRegistryEmitted -> - Assert.assertNull(appRegistryEmitted) - } + val result = appRegistry.first() + assertNull(result) + verify(exactly = 1) { appRegistryDao.getAppRegistryForMimeType(OC_ACCOUNT_NAME, mimetype) } } @@ -90,9 +104,8 @@ class OCLocalAppRegistryDataSourceTest { val appRegistry = ocLocalAppRegistryDataSource.getAppRegistryForMimeTypeAsStream(OC_ACCOUNT_NAME, mimetype) - appRegistry.collect { appRegistryEmitted -> - Assert.assertNull(appRegistryEmitted) - } + val result = appRegistry.first() + assertNull(result) verify(exactly = 1) { appRegistryDao.getAppRegistryForMimeType(OC_ACCOUNT_NAME, mimetype) } } @@ -103,9 +116,9 @@ class OCLocalAppRegistryDataSourceTest { val appRegistry = ocLocalAppRegistryDataSource.getAppRegistryWhichAllowCreation(OC_ACCOUNT_NAME) - appRegistry.collect { appRegistryEmitted -> - Assert.assertEquals(listOf(OC_APP_REGISTRY_MIMETYPE), appRegistryEmitted) - } + val result = appRegistry.first() + assertEquals(listOf(OC_APP_REGISTRY_MIMETYPE), result) + verify(exactly = 1) { appRegistryDao.getAppRegistryWhichAllowCreation(OC_ACCOUNT_NAME) } } @@ -117,9 +130,8 @@ class OCLocalAppRegistryDataSourceTest { val appRegistry = ocLocalAppRegistryDataSource.getAppRegistryWhichAllowCreation(OC_ACCOUNT_NAME) - appRegistry.collect { listEmitted -> - Assert.assertEquals(emptyList(), listEmitted) - } + val result = appRegistry.first() + assertEquals(emptyList(), result) verify(exactly = 1) { appRegistryDao.getAppRegistryWhichAllowCreation(OC_ACCOUNT_NAME) } } @@ -133,9 +145,6 @@ class OCLocalAppRegistryDataSourceTest { ) ) - every { appRegistryDao.deleteAppRegistryForAccount(OC_ACCOUNT_NAME) } returns Unit - every { appRegistryDao.upsertAppRegistries(any()) } returns Unit - ocLocalAppRegistryDataSource.saveAppRegistryForAccount(appRegistry) verify(exactly = 1) { appRegistryDao.deleteAppRegistryForAccount(appRegistry.accountName) } @@ -163,11 +172,8 @@ class OCLocalAppRegistryDataSourceTest { @Test fun `deleteAppRegistryForAccount should delete appRegistry`() = runTest { - every { appRegistryDao.deleteAppRegistryForAccount(OC_ACCOUNT_NAME) } returns Unit - ocLocalAppRegistryDataSource.deleteAppRegistryForAccount(OC_ACCOUNT_NAME) verify(exactly = 1) { appRegistryDao.deleteAppRegistryForAccount(any()) } } - -} \ No newline at end of file +} diff --git a/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCRemoteAppRegistryDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCRemoteAppRegistryDataSourceTest.kt index c01ab18e280..58f3afb5378 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCRemoteAppRegistryDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/appRegistry/datasources/implementation/OCRemoteAppRegistryDataSourceTest.kt @@ -1,3 +1,23 @@ +/** + * ownCloud Android client application + * + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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.owncloud.android.data.appRegistry.datasources.implementation import com.owncloud.android.data.ClientManager @@ -29,7 +49,7 @@ class OCRemoteAppRegistryDataSourceTest { private val appName = "TestApp" @Before - fun init() { + fun setUp() { every { clientManager.getAppRegistryService(any()) } returns ocAppRegistryService ocRemoteAppRegistryDataSource = OCRemoteAppRegistryDataSource(clientManager) @@ -163,4 +183,4 @@ class OCRemoteAppRegistryDataSourceTest { filename = OC_FILE.fileName, ) } -} \ No newline at end of file +} diff --git a/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCLocalCapabilitiesDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCLocalCapabilitiesDataSourceTest.kt index e6c2608bd93..0815ea54ddb 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCLocalCapabilitiesDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCLocalCapabilitiesDataSourceTest.kt @@ -3,7 +3,9 @@ * * @author David González Verdugo * @author Abel García de Prada - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -51,7 +53,7 @@ class OCLocalCapabilitiesDataSourceTest { var rule: TestRule = InstantTaskExecutorRule() @Before - fun init() { + fun setUp() { ocLocalCapabilitiesDataSource = OCLocalCapabilitiesDataSource( ocCapabilityDao, diff --git a/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCRemoteCapabilitiesDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCRemoteCapabilitiesDataSourceTest.kt index 732a81f90a5..9166595be94 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCRemoteCapabilitiesDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/capabilities/datasources/OCRemoteCapabilitiesDataSourceTest.kt @@ -3,7 +3,9 @@ * * @author David González Verdugo * @author Jesús Recio - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -43,7 +45,7 @@ class OCRemoteCapabilitiesDataSourceTest { private val remoteCapabilityMapper = RemoteCapabilityMapper() @Before - fun init() { + fun setUp() { every { clientManager.getCapabilityService(any()) } returns ocCapabilityService ocRemoteCapabilitiesDataSource = diff --git a/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCLocalFileDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCLocalFileDataSourceTest.kt index e7167c66cb1..2d20f53449b 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCLocalFileDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCLocalFileDataSourceTest.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -40,6 +42,7 @@ import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals @@ -65,7 +68,7 @@ class OCLocalFileDataSourceTest { ) @Before - fun init() { + fun setUp() { dao = spyk() localDataSource = OCLocalFileDataSource(dao) } @@ -103,11 +106,9 @@ class OCLocalFileDataSourceTest { fun `getFileByIdAsFlow returns a flow of OCFile`() = runTest { every { dao.getFileByIdAsFlow(any()) } returns flowOf(DUMMY_FILE_ENTITY) - val result = localDataSource.getFileByIdAsFlow(OC_FILE.id!!) + val resultActual = localDataSource.getFileByIdAsFlow(OC_FILE.id!!).first() - result.collect { result -> - assertEquals(OC_FILE, result) - } + assertEquals(OC_FILE, resultActual) verify(exactly = 1) { dao.getFileByIdAsFlow(OC_FILE.id!!) } } @@ -116,11 +117,9 @@ class OCLocalFileDataSourceTest { fun `getFileByIdAsFlow returns null`() = runTest { every { dao.getFileByIdAsFlow(any()) } returns flowOf(null) - val result = localDataSource.getFileByIdAsFlow(DUMMY_FILE_ENTITY.id) + val result = localDataSource.getFileByIdAsFlow(DUMMY_FILE_ENTITY.id).first() - result.collect { result -> - assertNull(result) - } + assertNull(result) verify(exactly = 1) { dao.getFileByIdAsFlow(DUMMY_FILE_ENTITY.id) } } @@ -137,11 +136,9 @@ class OCLocalFileDataSourceTest { every { dao.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) } returns flowOf(ocFileAndFileSync) - val result = localDataSource.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) + val result = localDataSource.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!).first() - result.collect { emittedFileWithSyncInfo -> - assertEquals(OC_FILE_WITH_SYNC_INFO_AND_SPACE, emittedFileWithSyncInfo) - } + assertEquals(OC_FILE_WITH_SYNC_INFO_AND_SPACE, result) verify(exactly = 1) { dao.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) } } @@ -151,11 +148,9 @@ class OCLocalFileDataSourceTest { every { dao.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) } returns flowOf(null) - val result = localDataSource.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) + val result = localDataSource.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!).first() - result.collect { emittedFileWithSyncInfo -> - assertNull(emittedFileWithSyncInfo) - } + assertNull(result) verify(exactly = 1) { dao.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) } } @@ -165,11 +160,9 @@ class OCLocalFileDataSourceTest { every { dao.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) } throws Exception() - val result = localDataSource.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) + val result = localDataSource.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!).first() - result.collect { emittedFileWithSyncInfo -> - assertEquals(OC_FILE_WITH_SYNC_INFO_AND_SPACE, emittedFileWithSyncInfo) - } + assertEquals(OC_FILE_WITH_SYNC_INFO_AND_SPACE, result) verify(exactly = 1) { dao.getFileWithSyncInfoByIdAsFlow(OC_FILE.id!!) } } @@ -349,11 +342,9 @@ class OCLocalFileDataSourceTest { every { dao.getFolderContentWithSyncInfoAsFlow(any()) } returns flowOf(listOf(ocFileAndFileSync)) - val result = localDataSource.getFolderContentWithSyncInfoAsFlow(OC_FILE.id!!) + val result = localDataSource.getFolderContentWithSyncInfoAsFlow(OC_FILE.id!!).first() - result.collect { result -> - assertEquals(listOf(OC_FILE_WITH_SYNC_INFO_AND_SPACE), result) - } + assertEquals(listOf(OC_FILE_WITH_SYNC_INFO_AND_SPACE), result) verify(exactly = 1) { dao.getFolderContentWithSyncInfoAsFlow(OC_FILE.id!!) @@ -393,11 +384,9 @@ class OCLocalFileDataSourceTest { fun `getSharedByLinkWithSyncInfoForAccountAsFlow returns a flow of list of OCFileWithSyncInfo`() = runTest { every { dao.getFilesWithSyncInfoSharedByLinkAsFlow(any()) } returns flowOf(listOf(ocFileAndFileSync)) - val result = localDataSource.getSharedByLinkWithSyncInfoForAccountAsFlow(DUMMY_FILE_ENTITY.owner) + val result = localDataSource.getSharedByLinkWithSyncInfoForAccountAsFlow(DUMMY_FILE_ENTITY.owner).first() - result.collect { result -> - assertEquals(listOf(OC_FILE_WITH_SYNC_INFO_AND_SPACE), result) - } + assertEquals(listOf(OC_FILE_WITH_SYNC_INFO_AND_SPACE), result) verify(exactly = 1) { dao.getFilesWithSyncInfoSharedByLinkAsFlow(DUMMY_FILE_ENTITY.owner) @@ -417,11 +406,9 @@ class OCLocalFileDataSourceTest { fun `getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow returns a flow of list of OCFileWithSyncInfo`() = runTest { every { dao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(any()) } returns flowOf(listOf(ocFileAndFileSync)) - val result = localDataSource.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(DUMMY_FILE_ENTITY.owner) + val result = localDataSource.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(DUMMY_FILE_ENTITY.owner).first() - result.collect { result -> - assertEquals(listOf(OC_FILE_WITH_SYNC_INFO_AND_SPACE), result) - } + assertEquals(listOf(OC_FILE_WITH_SYNC_INFO_AND_SPACE), result) verify(exactly = 1) { dao.getFilesWithSyncInfoAvailableOfflineFromAccountAsFlow(DUMMY_FILE_ENTITY.owner) diff --git a/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCRemoteFileDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCRemoteFileDataSourceTest.kt index 11e6c8a7f31..3ab938da6cc 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCRemoteFileDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/file/datasources/OCRemoteFileDataSourceTest.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -82,7 +84,7 @@ class OCRemoteFileDataSourceTest { ) @Before - fun init() { + fun setUp() { every { clientManager.getFileService(any()) } returns ocFileService ocRemoteFileDataSource = OCRemoteFileDataSource(clientManager) diff --git a/owncloudData/src/test/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCLocalFolderBackupDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCLocalFolderBackupDataSourceTest.kt new file mode 100644 index 00000000000..487594e6b23 --- /dev/null +++ b/owncloudData/src/test/java/com/owncloud/android/data/folderbackup/datasources/implementation/OCLocalFolderBackupDataSourceTest.kt @@ -0,0 +1,113 @@ +/** + * ownCloud Android client application + * + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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.owncloud.android.data.folderbackup.datasources.implementation + +import com.owncloud.android.data.folderbackup.datasources.implementation.OCLocalFolderBackupDataSource.Companion.toModel +import com.owncloud.android.data.folderbackup.db.FolderBackupDao +import com.owncloud.android.domain.camerauploads.model.FolderBackUpConfiguration +import com.owncloud.android.testutil.OC_BACKUP +import com.owncloud.android.testutil.OC_BACKUP_ENTITY +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertNull +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Test + +class OCLocalFolderBackupDataSourceTest { + + private lateinit var mOcLocalFolderBackupDataSource: OCLocalFolderBackupDataSource + private val folderBackupDao = mockk(relaxed = true) + + @Before + fun setUp() { + mOcLocalFolderBackupDataSource = OCLocalFolderBackupDataSource(folderBackupDao) + } + + @Test + fun `getCameraUploadsConfiguration returns a CameraUploadsConfiguration when having valid configurations`() { + every { folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.pictureUploadsName) } returns OC_BACKUP_ENTITY + every { folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.videoUploadsName) } returns OC_BACKUP_ENTITY + + val resultCurrent = mOcLocalFolderBackupDataSource.getCameraUploadsConfiguration() + + assertEquals(OC_BACKUP_ENTITY.toModel(), resultCurrent?.pictureUploadsConfiguration) + assertEquals(OC_BACKUP_ENTITY.toModel(), resultCurrent?.videoUploadsConfiguration) + + verify(exactly = 1) { + folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.pictureUploadsName) + folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.videoUploadsName) + } + } + + @Test + fun `getCameraUploadsConfiguration returns null when there are not configurations`() { + every { folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.pictureUploadsName) } returns null + every { folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.videoUploadsName) } returns null + + val resultCurrent = mOcLocalFolderBackupDataSource.getCameraUploadsConfiguration() + + assertNull(resultCurrent) + + verify(exactly = 1) { + folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.pictureUploadsName) + folderBackupDao.getFolderBackUpConfigurationByName(FolderBackUpConfiguration.videoUploadsName) + } + } + + @Test + fun `getFolderBackupConfigurationByNameAsFlow returns a flow of CameraUploadsConfiguration when having valid configurations`() = runBlocking { + every { folderBackupDao.getFolderBackUpConfigurationByNameAsFlow(FolderBackUpConfiguration.pictureUploadsName) } returns flowOf( + OC_BACKUP_ENTITY + ) + + val resultCurrent = mOcLocalFolderBackupDataSource.getFolderBackupConfigurationByNameAsFlow(FolderBackUpConfiguration.pictureUploadsName) + + val result = resultCurrent.first() + assertEquals(OC_BACKUP_ENTITY.toModel(), result) + + verify(exactly = 1) { + folderBackupDao.getFolderBackUpConfigurationByNameAsFlow(FolderBackUpConfiguration.pictureUploadsName) + } + } + + @Test + fun `saveFolderBackupConfiguration with valid configurations saves the information`() { + mOcLocalFolderBackupDataSource.saveFolderBackupConfiguration(OC_BACKUP) + + verify(exactly = 1) { + folderBackupDao.update(OC_BACKUP_ENTITY) + } + } + + @Test + fun `resetFolderBackupConfigurationByName removes current folder backup configuration`() { + mOcLocalFolderBackupDataSource.resetFolderBackupConfigurationByName(FolderBackUpConfiguration.pictureUploadsName) + + verify(exactly = 1) { + folderBackupDao.delete(FolderBackUpConfiguration.pictureUploadsName) + } + } +} diff --git a/owncloudData/src/test/java/com/owncloud/android/data/oauth/datasources/RemoteOAuthDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/oauth/datasources/OCRemoteOAuthDataSourceTest.kt similarity index 80% rename from owncloudData/src/test/java/com/owncloud/android/data/oauth/datasources/RemoteOAuthDataSourceTest.kt rename to owncloudData/src/test/java/com/owncloud/android/data/oauth/datasources/OCRemoteOAuthDataSourceTest.kt index d774a814873..3c3dc706082 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/oauth/datasources/RemoteOAuthDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/oauth/datasources/OCRemoteOAuthDataSourceTest.kt @@ -20,10 +20,8 @@ package com.owncloud.android.data.oauth.datasources import com.owncloud.android.data.ClientManager -import com.owncloud.android.data.oauth.OC_REMOTE_CLIENT_REGISTRATION_PARAMS import com.owncloud.android.data.oauth.OC_REMOTE_CLIENT_REGISTRATION_RESPONSE import com.owncloud.android.data.oauth.OC_REMOTE_OIDC_DISCOVERY_RESPONSE -import com.owncloud.android.data.oauth.OC_REMOTE_TOKEN_REQUEST_PARAMS_ACCESS import com.owncloud.android.data.oauth.OC_REMOTE_TOKEN_RESPONSE import com.owncloud.android.data.oauth.datasources.implementation.OCRemoteOAuthDataSource import com.owncloud.android.lib.common.OwnCloudClient @@ -41,12 +39,13 @@ import com.owncloud.android.testutil.oauth.OC_TOKEN_RESPONSE import com.owncloud.android.utils.createRemoteOperationResultMock import io.mockk.every import io.mockk.mockk +import io.mockk.verify import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.Test -class RemoteOAuthDataSourceTest { +class OCRemoteOAuthDataSourceTest { private lateinit var remoteOAuthDataSource: RemoteOAuthDataSource private val clientManager: ClientManager = mockk(relaxed = true) @@ -55,7 +54,7 @@ class RemoteOAuthDataSourceTest { private val oidcService: OIDCService = mockk() @Before - fun init() { + fun setUp() { every { clientManager.getClientForAnonymousCredentials(any(), any()) } returns ocClientMocked remoteOAuthDataSource = OCRemoteOAuthDataSource( @@ -65,7 +64,7 @@ class RemoteOAuthDataSourceTest { } @Test - fun `perform oidc discovery - ok`() { + fun `performOIDCDiscovery returns a OIDCServerConfiguration`() { val oidcDiscoveryResult: RemoteOperationResult = createRemoteOperationResultMock(data = OC_REMOTE_OIDC_DISCOVERY_RESPONSE, isSuccess = true) @@ -77,19 +76,15 @@ class RemoteOAuthDataSourceTest { assertNotNull(oidcDiscovery) assertEquals(OC_OIDC_SERVER_CONFIGURATION, oidcDiscovery) - } - @Test(expected = Exception::class) - fun `perform oidc discovery - ko`() { - every { + verify(exactly = 1) { + clientManager.getClientForAnonymousCredentials(OC_SECURE_BASE_URL, false) oidcService.getOIDCServerDiscovery(ocClientMocked) - } throws Exception() - - remoteOAuthDataSource.performOIDCDiscovery(OC_SECURE_BASE_URL) + } } @Test - fun `perform token request - ok`() { + fun `performTokenRequest returns a TokenResponse`() { val tokenResponseResult: RemoteOperationResult = createRemoteOperationResultMock(data = OC_REMOTE_TOKEN_RESPONSE, isSuccess = true) @@ -101,19 +96,15 @@ class RemoteOAuthDataSourceTest { assertNotNull(tokenResponse) assertEquals(OC_TOKEN_RESPONSE, tokenResponse) - } - - @Test(expected = Exception::class) - fun `perform token request - ko`() { - every { - oidcService.performTokenRequest(ocClientMocked, OC_REMOTE_TOKEN_REQUEST_PARAMS_ACCESS) - } throws Exception() - remoteOAuthDataSource.performTokenRequest(OC_TOKEN_REQUEST_ACCESS) + verify(exactly = 1) { + clientManager.getClientForAnonymousCredentials(OC_SECURE_BASE_URL, any()) + oidcService.performTokenRequest(ocClientMocked, any()) + } } @Test - fun `register client - ok`() { + fun `registerClient returns a ClientRegistrationInfo`() { val clientRegistrationResponse: RemoteOperationResult = createRemoteOperationResultMock(data = OC_REMOTE_CLIENT_REGISTRATION_RESPONSE, isSuccess = true) @@ -125,14 +116,10 @@ class RemoteOAuthDataSourceTest { assertNotNull(clientRegistrationInfo) assertEquals(OC_CLIENT_REGISTRATION, clientRegistrationInfo) - } - @Test(expected = Exception::class) - fun `register client - ko`() { - every { - oidcService.registerClientWithRegistrationEndpoint(ocClientMocked, OC_REMOTE_CLIENT_REGISTRATION_PARAMS) - } throws Exception() - - remoteOAuthDataSource.registerClient(OC_CLIENT_REGISTRATION_REQUEST) + verify(exactly = 1) { + clientManager.getClientForAnonymousCredentials(OC_CLIENT_REGISTRATION_REQUEST.registrationEndpoint, false) + oidcService.registerClientWithRegistrationEndpoint(ocClientMocked, any()) + } } } diff --git a/owncloudData/src/test/java/com/owncloud/android/data/server/datasources/implementation/OCRemoteServerInfoDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/server/datasources/implementation/OCRemoteServerInfoDataSourceTest.kt index bfaefb85204..f0b9d7419ed 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/server/datasources/implementation/OCRemoteServerInfoDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/server/datasources/implementation/OCRemoteServerInfoDataSourceTest.kt @@ -67,7 +67,7 @@ class OCRemoteServerInfoDataSourceTest { private val authHeaderBearer = listOf(basicAuthHeader, bearerHeader) @Before - fun init() { + fun setUp() { ocRemoteServerInfoDatasource = OCRemoteServerInfoDataSource(ocServerInfoService, clientManager) every { clientManager.getClientForAnonymousCredentials(any(), any()) } returns ocClientMocked } diff --git a/owncloudData/src/test/java/com/owncloud/android/data/sharees/datasources/OCRemoteShareesDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/sharees/datasources/OCRemoteShareeDataSourceTest.kt similarity index 64% rename from owncloudData/src/test/java/com/owncloud/android/data/sharees/datasources/OCRemoteShareesDataSourceTest.kt rename to owncloudData/src/test/java/com/owncloud/android/data/sharees/datasources/OCRemoteShareeDataSourceTest.kt index 399f05b6ae1..6ee332f9af3 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/sharees/datasources/OCRemoteShareesDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/sharees/datasources/OCRemoteShareeDataSourceTest.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author David González Verdugo - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -33,6 +35,7 @@ import com.owncloud.android.testutil.OC_ACCOUNT_NAME import com.owncloud.android.utils.createRemoteOperationResultMock import io.mockk.every import io.mockk.mockk +import io.mockk.verify import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -40,15 +43,15 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test -class OCRemoteShareesDataSourceTest { +class OCRemoteShareeDataSourceTest { private lateinit var ocRemoteShareesDataSource: OCRemoteShareeDataSource private val ocShareeService: OCShareeService = mockk() private val clientManager: ClientManager = mockk() private lateinit var sharees: List @Before - fun init() { - every { clientManager.getShareeService(any()) } returns ocShareeService + fun setUp() { + every { clientManager.getShareeService(OC_ACCOUNT_NAME) } returns ocShareeService ocRemoteShareesDataSource = OCRemoteShareeDataSource(clientManager, RemoteShareeMapper()) @@ -58,94 +61,160 @@ class OCRemoteShareesDataSourceTest { ) every { - ocShareeService.getSharees("user", 1, 30) + ocShareeService.getSharees(searchString = "user", page = 1, perPage = 30) } returns getRemoteShareesOperationResult + } - // Get sharees from remote datasource + @Test + fun `getSharees returns a list of OCSharee entered as remote sharees`() { sharees = ocRemoteShareesDataSource.getSharees( "user", 1, 30, OC_ACCOUNT_NAME, ) - } - - @Test - fun `OCSharees List - ok - contains sharees entered as remote sharees`() { assertNotNull(sharees) assertEquals(5, sharees.size) + + verify(exactly = 1) { + clientManager.getShareeService(OC_ACCOUNT_NAME) + ocShareeService.getSharees(searchString = "user", page = 1, perPage = 30) + } } @Test - fun `OCSharees List - ok - contains exact user match`() { + fun `getSharees returns a list of OCSharee when contains exact user match`() { + sharees = ocRemoteShareesDataSource.getSharees( + "user", + 1, + 30, + OC_ACCOUNT_NAME, + ) + val sharee = sharees[0] assertEquals(sharee.label, "User") assertEquals(sharee.shareType, ShareType.USER) assertEquals(sharee.shareWith, "user") assertEquals(sharee.additionalInfo, "user@exact.com") assertTrue(sharee.isExactMatch) + + verify(exactly = 1) { + clientManager.getShareeService(OC_ACCOUNT_NAME) + ocShareeService.getSharees(searchString = "user", page = 1, perPage = 30) + } } @Test - fun `OCSharees List - ok - contains one user not exactly matched`() { + fun `getSharees returns a list of OCSharee when contains one user not exactly matched`() { + sharees = ocRemoteShareesDataSource.getSharees( + "user", + 1, + 30, + OC_ACCOUNT_NAME, + ) + val sharee = sharees[1] assertEquals("User 1", sharee.label) assertEquals(ShareType.USER, sharee.shareType) assertEquals("user1", sharee.shareWith) assertEquals("user1@mail.com", sharee.additionalInfo) assertFalse(sharee.isExactMatch) + + verify(exactly = 1) { + clientManager.getShareeService(OC_ACCOUNT_NAME) + ocShareeService.getSharees(searchString = "user", page = 1, perPage = 30) + } } @Test - fun `OCShares List - ok - contains one user without additional info`() { + fun `getSharees returns a list of OCSharee when contains one user without additional info`() { + sharees = ocRemoteShareesDataSource.getSharees( + "user", + 1, + 30, + OC_ACCOUNT_NAME, + ) val sharee = sharees[2] assertEquals("User 2", sharee.label) assertEquals(ShareType.USER, sharee.shareType) assertEquals("user2", sharee.shareWith) assertEquals("", sharee.additionalInfo) assertFalse(sharee.isExactMatch) + + verify(exactly = 1) { + clientManager.getShareeService(OC_ACCOUNT_NAME) + ocShareeService.getSharees(searchString = "user", page = 1, perPage = 30) + } } @Test - fun `OCShares List - ok - contains one remote user`() { + fun `getSharees returns a list of OCSharee when contains one remote user`() { + sharees = ocRemoteShareesDataSource.getSharees( + "user", + 1, + 30, + OC_ACCOUNT_NAME, + ) val sharee = sharees[3] assertEquals("Remoteuser 1", sharee.label) assertEquals(ShareType.FEDERATED, sharee.shareType) assertEquals("remoteuser1", sharee.shareWith) assertEquals("user1@remote.com", sharee.additionalInfo) assertFalse(sharee.isExactMatch) + + verify(exactly = 1) { + clientManager.getShareeService(OC_ACCOUNT_NAME) + ocShareeService.getSharees(searchString = "user", page = 1, perPage = 30) + } } @Test - fun `OCShares List - ok - contains one group`() { + fun `getSharees returns a list of OCSharee when contains one group`() { + sharees = ocRemoteShareesDataSource.getSharees( + "user", + 1, + 30, + OC_ACCOUNT_NAME, + ) + val sharee = sharees[4] assertEquals("Group 1", sharee.label) assertEquals(ShareType.GROUP, sharee.shareType) assertEquals("group1", sharee.shareWith) assertEquals("group@group.com", sharee.additionalInfo) assertFalse(sharee.isExactMatch) + + verify(exactly = 1) { + clientManager.getShareeService(OC_ACCOUNT_NAME) + ocShareeService.getSharees(searchString = "user", page = 1, perPage = 30) + } } @Test - fun `OCShares List - ok - handle empty response`() { + fun `getSharees returns a list of OCSharee when handle empty response`() { + val getRemoteShareesOperationResult = createRemoteOperationResultMock( EMPTY_REMOTE_SHAREES, true ) every { - ocShareeService.getSharees("user", 1, 30) + ocShareeService.getSharees(searchString = "user2", page = 2, perPage = 32) } returns getRemoteShareesOperationResult - // Get sharees from remote datasource val emptySharees = ocRemoteShareesDataSource.getSharees( - "user", - 1, - 30, + "user2", + 2, + 32, OC_ACCOUNT_NAME, ) assertTrue(emptySharees.isEmpty()) + + verify(exactly = 1) { + clientManager.getShareeService(OC_ACCOUNT_NAME) + ocShareeService.getSharees(searchString = "user2", page = 2, perPage = 32) + } } companion object { diff --git a/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCLocalShareDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCLocalShareDataSourceTest.kt index e213e6d812a..38f951a9122 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCLocalShareDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCLocalShareDataSourceTest.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author David González Verdugo - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -21,7 +23,6 @@ package com.owncloud.android.data.shares.datasources import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.lifecycle.MutableLiveData -import com.owncloud.android.data.OwncloudDatabase import com.owncloud.android.data.sharing.shares.datasources.implementation.OCLocalShareDataSource import com.owncloud.android.data.sharing.shares.datasources.implementation.OCLocalShareDataSource.Companion.toEntity import com.owncloud.android.data.sharing.shares.datasources.implementation.OCLocalShareDataSource.Companion.toModel @@ -34,7 +35,7 @@ import com.owncloud.android.testutil.OC_PUBLIC_SHARE import com.owncloud.android.testutil.OC_SHARE import com.owncloud.android.testutil.livedata.getLastEmittedValue import io.mockk.every -import io.mockk.mockkClass +import io.mockk.mockk import io.mockk.verify import org.junit.Assert.assertEquals import org.junit.Before @@ -43,19 +44,14 @@ import org.junit.Test class OCLocalShareDataSourceTest { private lateinit var ocLocalSharesDataSource: OCLocalShareDataSource - private val ocSharesDao = mockkClass(OCShareDao::class) + private val ocSharesDao = mockk(relaxUnitFun = true) @Rule @JvmField val instantExecutorRule = InstantTaskExecutorRule() @Before - fun init() { - val db = mockkClass(OwncloudDatabase::class) - - every { - db.shareDao() - } returns ocSharesDao + fun setUp() { ocLocalSharesDataSource = OCLocalShareDataSource( @@ -83,7 +79,7 @@ class OCLocalShareDataSourceTest { private val privateShareTypes = listOf(ShareType.USER, ShareType.GROUP, ShareType.FEDERATED) @Test - fun readLocalPrivateShares() { + fun `getSharesAsLiveData returns a list of LiveData OCShare when read local private shares`() { val privateSharesAsLiveData: MutableLiveData> = MutableLiveData() privateSharesAsLiveData.value = privateShares @@ -110,10 +106,17 @@ class OCLocalShareDataSourceTest { assertEquals(false, shares[1].isFolder) assertEquals("user.name", shares[1].shareWith) assertEquals("Nicole", shares[1].sharedWithDisplayName) + + verify(exactly = 1) { + ocSharesDao.getSharesAsLiveData( + "/Docs/doc1.doc", + "admin@server", + privateShareTypes.map { it.value }) + } } @Test - fun readLocalPrivateShare() { + fun `getShareAsLiveData read local private share returns a OCShare`() { val privateShareAsLiveData: MutableLiveData = MutableLiveData() privateShareAsLiveData.value = privateShares.first() @@ -125,10 +128,12 @@ class OCLocalShareDataSourceTest { assertEquals(false, share.isFolder) assertEquals("username", share.shareWith) assertEquals("Sophie", share.sharedWithDisplayName) + + verify(exactly = 1) { ocSharesDao.getShareAsLiveData(OC_SHARE.remoteId) } } @Test - fun insertPrivateShares() { + fun `insert private OCShare saves it correctly`() { every { ocSharesDao.insertOrReplace(privateShares[0]) } returns 10 val insertedShareId = ocLocalSharesDataSource.insert( @@ -139,10 +144,27 @@ class OCLocalShareDataSourceTest { ) ) assertEquals(10, insertedShareId) + + verify(exactly = 1) { ocSharesDao.insertOrReplace(privateShares[0]) } } @Test - fun updatePrivateShare() { + fun `insert list of private OCShares saves it correctly`() { + + val expectedValues = listOf(1, 2) + every { ocSharesDao.insertOrReplace(privateShares) } returns expectedValues + + val insertedSharesid = ocLocalSharesDataSource.insert( + privateShares.map { it.toModel() } + ) + + assertEquals(expectedValues, insertedSharesid) + + verify(exactly = 1) { ocSharesDao.insertOrReplace(privateShares) } + } + + @Test + fun `update private OCShare changes it correctly`() { every { ocSharesDao.update(privateShares[1]) } returns 3 val updatedShareId = ocLocalSharesDataSource.update( @@ -153,6 +175,8 @@ class OCLocalShareDataSourceTest { ) ) assertEquals(3, updatedShareId) + + verify(exactly = 1) { ocSharesDao.update(privateShares[1]) } } /****************************************************************************************************** @@ -175,7 +199,7 @@ class OCLocalShareDataSourceTest { ) @Test - fun readLocalPublicShares() { + fun `getSharesAsLiveData read local public shares returns a list of LiveData OCShare`() { val publicSharesAsLiveData: MutableLiveData> = MutableLiveData() publicSharesAsLiveData.value = publicShares @@ -204,10 +228,17 @@ class OCLocalShareDataSourceTest { assertEquals(true, shares[1].isFolder) assertEquals("Photos link 2", shares[1].name) assertEquals("http://server:port/s/2", shares[1].shareLink) + + verify(exactly = 1) { + ocSharesDao.getSharesAsLiveData( + "/Photos/", + "admin@server", + listOf(ShareType.PUBLIC_LINK.value)) + } } @Test - fun insertPublicShare() { + fun `insert public OCShare saves it correctly`() { every { ocSharesDao.insertOrReplace(publicShares[0]) } returns 7 val insertedShareId = ocLocalSharesDataSource.insert( @@ -219,10 +250,12 @@ class OCLocalShareDataSourceTest { ) ) assertEquals(7, insertedShareId) + + verify(exactly = 1) { ocSharesDao.insertOrReplace(publicShares[0]) } } @Test - fun insertPublicShares() { + fun `insert list of public OCShares saves it correctly`() { val expectedValues = listOf(1, 2) every { ocSharesDao.insertOrReplace(publicShares) } returns expectedValues @@ -231,10 +264,14 @@ class OCLocalShareDataSourceTest { ) assertEquals(expectedValues, retrievedValues) + + verify(exactly = 1) { ocSharesDao.insertOrReplace(publicShares) } } + + @Test - fun updatePublicShares() { + fun `update public OCShare changes it correctly`() { every { ocSharesDao.update(publicShares[1]) } returns 8 val updatedShareId = ocLocalSharesDataSource.update( @@ -246,6 +283,8 @@ class OCLocalShareDataSourceTest { ) ) assertEquals(8, updatedShareId) + + verify(exactly = 1) { ocSharesDao.update(publicShares[1]) } } /************************************************************************************************************** @@ -253,7 +292,7 @@ class OCLocalShareDataSourceTest { **************************************************************************************************************/ @Test - fun replaceShares() { + fun `replaceShares updates a list of shares correctly`() { val expectedValues = listOf(1, 2) every { ocSharesDao.replaceShares(publicShares) } returns expectedValues @@ -262,22 +301,32 @@ class OCLocalShareDataSourceTest { ) assertEquals(expectedValues, retrievedValues) + + verify(exactly = 1) { ocSharesDao.replaceShares(publicShares) } } @Test - fun deleteSharesForFile() { - every { ocSharesDao.deleteSharesForFile("file", OC_ACCOUNT_NAME) } returns Unit + fun `deleteSharesForFile removes shares related to a file`() { ocLocalSharesDataSource.deleteSharesForFile("file", OC_ACCOUNT_NAME) - verify { ocSharesDao.deleteSharesForFile("file", OC_ACCOUNT_NAME) } + verify(exactly = 1) { ocSharesDao.deleteSharesForFile("file", OC_ACCOUNT_NAME) } } @Test - fun deleteShare() { + fun `deleteShare removes a share correctly`() { every { ocSharesDao.deleteShare(OC_SHARE.remoteId) } returns 1 val deletedRows = ocLocalSharesDataSource.deleteShare(OC_SHARE.remoteId) assertEquals(1, deletedRows) + + verify(exactly = 1) { ocSharesDao.deleteShare(OC_SHARE.remoteId) } + } + @Test + fun `deleteSharesForAccount removes shares related to an account`() { + + ocLocalSharesDataSource.deleteSharesForAccount(OC_SHARE.accountOwner) + + verify(exactly = 1) { ocSharesDao.deleteSharesForAccount(OC_SHARE.accountOwner) } } } diff --git a/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCRemoteShareDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCRemoteShareDataSourceTest.kt index 613efe8cc5c..d04a7fda183 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCRemoteShareDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/shares/datasources/OCRemoteShareDataSourceTest.kt @@ -3,7 +3,9 @@ * * @author David González Verdugo * @author Jesús Recio - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -29,10 +31,12 @@ import com.owncloud.android.domain.sharing.shares.model.ShareType import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.resources.shares.ShareResponse import com.owncloud.android.lib.resources.shares.services.implementation.OCShareService +import com.owncloud.android.testutil.OC_ACCOUNT_NAME import com.owncloud.android.testutil.OC_SHARE import com.owncloud.android.utils.createRemoteOperationResultMock import io.mockk.every import io.mockk.mockk +import io.mockk.verify import org.hamcrest.CoreMatchers.notNullValue import org.hamcrest.MatcherAssert.assertThat import org.junit.Assert.assertEquals @@ -47,7 +51,7 @@ class OCRemoteShareDataSourceTest { private val clientManager: ClientManager = mockk(relaxed = true) @Before - fun init() { + fun setUp() { every { clientManager.getShareService(any()) } returns ocShareService ocRemoteShareDataSource = OCRemoteShareDataSource(clientManager, remoteShareMapper) @@ -58,7 +62,7 @@ class OCRemoteShareDataSourceTest { ******************************************************************************************************/ @Test - fun insertPrivateShare() { + fun `insert private share returns OCShare`() { val createRemoteShareOperationResult = createRemoteOperationResultMock( ShareResponse( listOf( @@ -77,7 +81,15 @@ class OCRemoteShareDataSourceTest { ) every { - ocShareService.insertShare(any(), any(), any(), any(), any(), any(), any()) + ocShareService.insertShare( + remoteFilePath = "Photos/", + shareType = com.owncloud.android.lib.resources.shares.ShareType.fromValue(ShareType.USER.value)!!, + shareWith = "user", + permissions = 1, + name = "", + password = "", + expirationDate = 0, + ) } returns createRemoteShareOperationResult // Insert share on remote datasource @@ -86,7 +98,7 @@ class OCRemoteShareDataSourceTest { shareType = ShareType.USER, shareWith = "user", permissions = 1, - accountName = "user@server" + accountName = OC_ACCOUNT_NAME ) assertThat(privateShareAdded, notNullValue()) @@ -96,10 +108,23 @@ class OCRemoteShareDataSourceTest { assertEquals("user", privateShareAdded.shareWith) assertEquals("User", privateShareAdded.sharedWithDisplayName) assertEquals(1, privateShareAdded.permissions) + + verify(exactly = 1) { + clientManager.getShareService(OC_ACCOUNT_NAME) + ocShareService.insertShare( + remoteFilePath = "Photos/", + shareType = com.owncloud.android.lib.resources.shares.ShareType.fromValue(ShareType.USER.value)!!, + shareWith = "user", + permissions = 1, + name = "", + password = "", + expirationDate = 0, + ) + } } @Test - fun updatePrivateShare() { + fun `updateShare for private share returns OCShare`() { val updateRemoteShareOperationResult = createRemoteOperationResultMock( ShareResponse( listOf( @@ -119,14 +144,20 @@ class OCRemoteShareDataSourceTest { ) every { - ocShareService.updateShare(any(), any(), any(), any(), any()) + ocShareService.updateShare( + remoteId = "3", + name = "", + password = "", + expirationDate = 0, + permissions = 17, + ) } returns updateRemoteShareOperationResult // Update share on remote datasource val privateShareUpdated = ocRemoteShareDataSource.updateShare( remoteId = "3", permissions = 17, - accountName = "user@server" + accountName = OC_ACCOUNT_NAME ) assertThat(privateShareUpdated, notNullValue()) @@ -136,6 +167,17 @@ class OCRemoteShareDataSourceTest { assertEquals("User", privateShareUpdated.sharedWithDisplayName) assertEquals(17, privateShareUpdated.permissions) assertEquals(false, privateShareUpdated.isFolder) + + verify(exactly = 1) { + clientManager.getShareService(OC_ACCOUNT_NAME) + ocShareService.updateShare( + remoteId = "3", + name = "", + password = "", + expirationDate = 0, + permissions = 17, + ) + } } /****************************************************************************************************** @@ -143,7 +185,7 @@ class OCRemoteShareDataSourceTest { ******************************************************************************************************/ @Test - fun insertPublicShare() { + fun `insert public share returns OCShare`() { val createRemoteShareOperationResult = createRemoteOperationResultMock( ShareResponse( listOf( @@ -161,7 +203,15 @@ class OCRemoteShareDataSourceTest { ) every { - ocShareService.insertShare(any(), any(), any(), any(), any(), any(), any()) + ocShareService.insertShare( + remoteFilePath = "Photos/img1.png", + shareType = com.owncloud.android.lib.resources.shares.ShareType.fromValue(ShareType.PUBLIC_LINK.value)!!, + shareWith = "", + permissions = 1, + name = "", + password = "", + expirationDate = 0 + ) } returns createRemoteShareOperationResult // Insert share on remote datasource @@ -170,7 +220,7 @@ class OCRemoteShareDataSourceTest { ShareType.PUBLIC_LINK, "", 1, - accountName = "user@server" + accountName = OC_ACCOUNT_NAME ) assertThat(publicShareAdded, notNullValue()) @@ -181,10 +231,23 @@ class OCRemoteShareDataSourceTest { assertEquals("Photos/img1.png", publicShareAdded.path) assertEquals(false, publicShareAdded.isFolder) assertEquals("http://server:port/s/112ejbhdasyd1", publicShareAdded.shareLink) + + verify(exactly = 1) { + clientManager.getShareService(OC_ACCOUNT_NAME) + ocShareService.insertShare( + remoteFilePath = "Photos/img1.png", + shareType = com.owncloud.android.lib.resources.shares.ShareType.fromValue(ShareType.PUBLIC_LINK.value)!!, + shareWith = "", + permissions = 1, + name = "", + password = "", + expirationDate = 0 + ) + } } @Test - fun updatePublicShare() { + fun `updateShare for public share returns OCShare`() { val updateRemoteShareOperationResult = createRemoteOperationResultMock( ShareResponse( listOf( @@ -204,14 +267,20 @@ class OCRemoteShareDataSourceTest { ) every { - ocShareService.updateShare(any(), any(), any(), any(), any()) + ocShareService.updateShare( + remoteId = "3", + name = "", + password = "", + expirationDate = 0, + permissions = 17, + ) } returns updateRemoteShareOperationResult // Update share on remote datasource val publicShareUpdated = ocRemoteShareDataSource.updateShare( remoteId = "3", permissions = 17, - accountName = "user@server" + accountName = OC_ACCOUNT_NAME ) assertThat(publicShareUpdated, notNullValue()) @@ -222,6 +291,17 @@ class OCRemoteShareDataSourceTest { assertEquals(2000, publicShareUpdated.expirationDate) assertEquals(1, publicShareUpdated.permissions) assertEquals("http://server:port/s/1275farv", publicShareUpdated.shareLink) + + verify(exactly = 1) { + clientManager.getShareService(OC_ACCOUNT_NAME) + ocShareService.updateShare( + remoteId = "3", + name = "", + password = "", + expirationDate = 0, + permissions = 17, + ) + } } /****************************************************************************************************** @@ -229,7 +309,7 @@ class OCRemoteShareDataSourceTest { ******************************************************************************************************/ @Test - fun readRemoteShares() { + fun `getShares returns a list of OCShare`() { val remoteShares = listOf( remoteShareMapper.toRemote( OC_SHARE.copy( @@ -279,7 +359,7 @@ class OCRemoteShareDataSourceTest { remoteFilePath = "/Documents/doc", reshares = true, subfiles = true, - accountName = "user@server" + accountName = OC_ACCOUNT_NAME ) assertEquals(4, shares.size) @@ -311,15 +391,24 @@ class OCRemoteShareDataSourceTest { assertEquals(false, groupShare.isFolder) assertEquals("family", groupShare.shareWith) assertEquals("My family", groupShare.sharedWithDisplayName) + + verify(exactly = 1) { + clientManager.getShareService(OC_ACCOUNT_NAME) + ocShareService.getShares( + remoteFilePath = "/Documents/doc", + reshares = true, + subfiles = true, + ) + } } @Test(expected = ShareNotFoundException::class) - fun insertShareFileNotFound() { + fun `insert share file not found`() { createShareOperationWithError(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND) } @Test(expected = ShareForbiddenException::class) - fun insertShareForbidden() { + fun `insert share forbidden`() { createShareOperationWithError(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN) } @@ -340,17 +429,17 @@ class OCRemoteShareDataSourceTest { ShareType.PUBLIC_LINK, "", 1, - accountName = "user@server" + accountName = OC_ACCOUNT_NAME ) } @Test(expected = ShareNotFoundException::class) - fun updateShareFileNotFound() { + fun `update share file not found`() { updateShareOperationWithError(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND) } @Test(expected = ShareForbiddenException::class) - fun updateShareForbidden() { + fun `update share forbidden`() { updateShareOperationWithError(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN) } @@ -374,7 +463,7 @@ class OCRemoteShareDataSourceTest { } @Test - fun deleteShare() { + fun `deleteShare removes a share correctly`() { val removeRemoteShareOperationResult = createRemoteOperationResultMock( Unit, isSuccess = true @@ -386,16 +475,18 @@ class OCRemoteShareDataSourceTest { ocRemoteShareDataSource.deleteShare(remoteId = "3", accountName = "user@server") - // We check there's no exception here + verify(exactly = 1) { + ocShareService.deleteShare(any()) + } } @Test(expected = ShareNotFoundException::class) - fun removeShareFileNotFound() { + fun `remove share file not found`() { deleteShareOperationWithError(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND) } @Test(expected = ShareForbiddenException::class) - fun removeShareForbidden() { + fun `remove share forbidden`() { deleteShareOperationWithError(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN) } diff --git a/owncloudData/src/test/java/com/owncloud/android/data/spaces/datasource/implementation/OCLocalSpacesDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/spaces/datasource/implementation/OCLocalSpacesDataSourceTest.kt new file mode 100644 index 00000000000..227719a7afb --- /dev/null +++ b/owncloudData/src/test/java/com/owncloud/android/data/spaces/datasource/implementation/OCLocalSpacesDataSourceTest.kt @@ -0,0 +1,251 @@ +/** + * ownCloud Android client application + * + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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.owncloud.android.data.spaces.datasource.implementation + +import com.owncloud.android.data.spaces.datasources.implementation.OCLocalSpacesDataSource +import com.owncloud.android.data.spaces.datasources.implementation.OCLocalSpacesDataSource.Companion.toEntity +import com.owncloud.android.data.spaces.datasources.implementation.OCLocalSpacesDataSource.Companion.toModel +import com.owncloud.android.data.spaces.db.SpaceSpecialEntity +import com.owncloud.android.data.spaces.db.SpacesDao +import com.owncloud.android.data.spaces.db.SpacesEntity +import com.owncloud.android.domain.spaces.model.OCSpace +import com.owncloud.android.domain.spaces.model.OCSpace.Companion.SPACE_ID_SHARES +import com.owncloud.android.testutil.OC_ACCOUNT_NAME +import com.owncloud.android.testutil.OC_SPACE_PERSONAL +import com.owncloud.android.testutil.OC_SPACE_PROJECT_WITH_IMAGE +import com.owncloud.android.testutil.SPACE_ENTITY_SHARE +import com.owncloud.android.testutil.SPACE_ENTITY_WITH_SPECIALS +import com.owncloud.android.testutil.WEB_DAV_URL +import io.mockk.Runs +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class OCLocalSpacesDataSourceTest { + + private lateinit var ocLocalSpacesDataSource: OCLocalSpacesDataSource + private val spacesDao = mockk() + + @Before + fun setUp() { + ocLocalSpacesDataSource = OCLocalSpacesDataSource(spacesDao) + } + + @Test + fun `saveSpacesForAccount inserts spaces and special spaces`() { + val spaceEntities = mutableListOf() + val spaceSpecialEntities = mutableListOf() + + listOf(OC_SPACE_PROJECT_WITH_IMAGE).forEach { spaceModel -> + spaceEntities.add(spaceModel.toEntity()) + spaceModel.special?.let { listOfSpacesSpecials -> + spaceSpecialEntities.addAll(listOfSpacesSpecials.map { it.toEntity(spaceModel.accountName, spaceModel.id) }) + } + } + + every { + spacesDao.insertOrDeleteSpaces(any(), any()) + } just Runs + + ocLocalSpacesDataSource.saveSpacesForAccount(listOf(OC_SPACE_PROJECT_WITH_IMAGE)) + + verify(exactly = 1) { + spacesDao.insertOrDeleteSpaces(spaceEntities, spaceSpecialEntities) + } + } + + @Test + fun `getPersonalSpaceForAccount by drive type returns a OCSpace`() { + every { + spacesDao.getSpacesByDriveTypeForAccount(any(), any()) + } returns listOf(OC_SPACE_PERSONAL.toEntity()) + + val resultActual = ocLocalSpacesDataSource.getPersonalSpaceForAccount(OC_ACCOUNT_NAME) + + assertEquals(OC_SPACE_PERSONAL, resultActual) + + verify(exactly = 1) { + spacesDao.getSpacesByDriveTypeForAccount(OC_ACCOUNT_NAME, setOf(OCSpace.DRIVE_TYPE_PERSONAL)) + } + } + + @Test + fun `getSharesSpaceForAccount returns a OCSpace`() { + every { + spacesDao.getSpaceByIdForAccount(SPACE_ID_SHARES, OC_ACCOUNT_NAME) + } returns SPACE_ENTITY_SHARE.space + + val resultActual = ocLocalSpacesDataSource.getSharesSpaceForAccount(OC_ACCOUNT_NAME) + + assertEquals(SPACE_ENTITY_SHARE.space.toModel(), resultActual) + + verify(exactly = 1) { + spacesDao.getSpaceByIdForAccount(SPACE_ID_SHARES, OC_ACCOUNT_NAME) + } + } + + @Test + fun `getSpacesFromEveryAccountAsStream returns a flow of OCSpace`() = runBlocking { + + every { + spacesDao.getSpacesByDriveTypeFromEveryAccountAsStream( + setOf( + OCSpace.DRIVE_TYPE_PERSONAL, + OCSpace.DRIVE_TYPE_PROJECT + ) + ) + } returns flowOf(listOf(OC_SPACE_PERSONAL.toEntity())) + + val resultActual = ocLocalSpacesDataSource.getSpacesFromEveryAccountAsStream().first() + + assertEquals(listOf(OC_SPACE_PERSONAL), resultActual) + + verify(exactly = 1) { + spacesDao.getSpacesByDriveTypeFromEveryAccountAsStream( + setOf( + OCSpace.DRIVE_TYPE_PERSONAL, + OCSpace.DRIVE_TYPE_PROJECT + ) + ) + } + } + + @Test + fun `getSpacesByDriveTypeWithSpecialsForAccountAsFlow returns a flow of OCSpace list`() = runBlocking { + + every { + spacesDao.getSpacesByDriveTypeWithSpecialsForAccountAsFlow( + OC_ACCOUNT_NAME, + setOf( + OCSpace.DRIVE_TYPE_PERSONAL, + OCSpace.DRIVE_TYPE_PROJECT + ) + ) + } returns flowOf(listOf(SPACE_ENTITY_WITH_SPECIALS)) + + val resultActual = ocLocalSpacesDataSource.getSpacesByDriveTypeWithSpecialsForAccountAsFlow( + OC_ACCOUNT_NAME, setOf( + OCSpace.DRIVE_TYPE_PERSONAL, + OCSpace.DRIVE_TYPE_PROJECT + ) + ) + + val result = resultActual.first() + assertEquals(listOf(SPACE_ENTITY_WITH_SPECIALS.toModel()), result) + + + verify(exactly = 1) { + spacesDao.getSpacesByDriveTypeWithSpecialsForAccountAsFlow( + OC_ACCOUNT_NAME, + setOf( + OCSpace.DRIVE_TYPE_PERSONAL, + OCSpace.DRIVE_TYPE_PROJECT + ) + ) + } + } + + @Test + fun `getPersonalAndProjectSpacesForAccount returns a list of OCSpace`() { + + every { + spacesDao.getSpacesByDriveTypeForAccount( + OC_ACCOUNT_NAME, + setOf( + OCSpace.DRIVE_TYPE_PERSONAL, + OCSpace.DRIVE_TYPE_PROJECT + ) + ) + } returns listOf(OC_SPACE_PERSONAL.toEntity()) + + val resultActual = ocLocalSpacesDataSource.getPersonalAndProjectSpacesForAccount(OC_ACCOUNT_NAME) + + assertEquals(listOf(OC_SPACE_PERSONAL), resultActual) + + + verify(exactly = 1) { + spacesDao.getSpacesByDriveTypeForAccount( + OC_ACCOUNT_NAME, + setOf( + OCSpace.DRIVE_TYPE_PERSONAL, + OCSpace.DRIVE_TYPE_PROJECT + ) + ) + } + } + + @Test + fun `getSpaceWithSpecialsByIdForAccount returns a OCSpace`() { + + every { + spacesDao.getSpaceWithSpecialsByIdForAccount(OC_SPACE_PERSONAL.id, OC_ACCOUNT_NAME) + } returns SPACE_ENTITY_WITH_SPECIALS + + val resultActual = ocLocalSpacesDataSource.getSpaceWithSpecialsByIdForAccount(OC_SPACE_PERSONAL.id, OC_ACCOUNT_NAME) + + assertEquals(SPACE_ENTITY_WITH_SPECIALS.toModel(), resultActual) + + verify(exactly = 1) { + spacesDao.getSpaceWithSpecialsByIdForAccount( + OC_SPACE_PERSONAL.id, OC_ACCOUNT_NAME + ) + } + } + + @Test + fun `getWebDavUrlForSpace returns a string of webDavUrl`() { + + every { + spacesDao.getWebDavUrlForSpace(OC_SPACE_PERSONAL.id, OC_ACCOUNT_NAME) + } returns WEB_DAV_URL + + val resultActual = ocLocalSpacesDataSource.getWebDavUrlForSpace(OC_SPACE_PERSONAL.id, OC_ACCOUNT_NAME) + + assertEquals(WEB_DAV_URL, resultActual) + + verify(exactly = 1) { + spacesDao.getWebDavUrlForSpace( + OC_SPACE_PERSONAL.id, OC_ACCOUNT_NAME + ) + } + } + + @Test + fun `deleteSpacesForAccount delete the space by account`() { + + every { + spacesDao.deleteSpacesForAccount(OC_ACCOUNT_NAME) + } returns Unit + + ocLocalSpacesDataSource.deleteSpacesForAccount(OC_ACCOUNT_NAME) + + verify(exactly = 1) { + spacesDao.deleteSpacesForAccount(OC_ACCOUNT_NAME) + } + } +} diff --git a/owncloudData/src/test/java/com/owncloud/android/data/spaces/datasource/implementation/OCRemoteSpacesDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/spaces/datasource/implementation/OCRemoteSpacesDataSourceTest.kt new file mode 100644 index 00000000000..1e41e0d0263 --- /dev/null +++ b/owncloudData/src/test/java/com/owncloud/android/data/spaces/datasource/implementation/OCRemoteSpacesDataSourceTest.kt @@ -0,0 +1,69 @@ +/** + * ownCloud Android client application + * + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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.owncloud.android.data.spaces.datasource.implementation + +import com.owncloud.android.data.ClientManager +import com.owncloud.android.data.spaces.datasources.implementation.OCRemoteSpacesDataSource +import com.owncloud.android.data.spaces.datasources.implementation.OCRemoteSpacesDataSource.Companion.toModel +import com.owncloud.android.lib.resources.spaces.services.OCSpacesService +import com.owncloud.android.testutil.OC_ACCOUNT_NAME +import com.owncloud.android.testutil.SPACE_RESPONSE +import com.owncloud.android.utils.createRemoteOperationResultMock +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class OCRemoteSpacesDataSourceTest { + + private lateinit var ocRemoteSpacesDataSource: OCRemoteSpacesDataSource + + private val ocSpaceService: OCSpacesService = mockk() + private val clientManager: ClientManager = mockk(relaxed = true) + + @Before + fun setUp() { + ocRemoteSpacesDataSource = OCRemoteSpacesDataSource(clientManager) + every { clientManager.getSpacesService(any()) } returns ocSpaceService + } + + @Test + fun `refreshSpacesForAccount returns a list of OCSpace`() { + val removeRemoteSpaceOperationResult = createRemoteOperationResultMock( + listOf(SPACE_RESPONSE), isSuccess = true + ) + + every { ocSpaceService.getSpaces() } returns removeRemoteSpaceOperationResult + + val resultActual = ocRemoteSpacesDataSource.refreshSpacesForAccount(OC_ACCOUNT_NAME) + + assertEquals( + listOf(SPACE_RESPONSE.toModel(OC_ACCOUNT_NAME)), resultActual + ) + + verify(exactly = 1) { + clientManager.getSpacesService(any()) + ocSpaceService.getSpaces() + } + } +} diff --git a/owncloudData/src/test/java/com/owncloud/android/data/transfers/implementation/OCLocalTransferDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/transfers/implementation/OCLocalTransferDataSourceTest.kt new file mode 100644 index 00000000000..7ff2ad0a49f --- /dev/null +++ b/owncloudData/src/test/java/com/owncloud/android/data/transfers/implementation/OCLocalTransferDataSourceTest.kt @@ -0,0 +1,324 @@ +/** + * ownCloud Android client application + * + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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.owncloud.android.data.transfers.implementation + +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource.Companion.toEntity +import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource.Companion.toModel +import com.owncloud.android.data.transfers.db.OCTransferEntity +import com.owncloud.android.data.transfers.db.TransferDao +import com.owncloud.android.domain.camerauploads.model.UploadBehavior +import com.owncloud.android.domain.transfers.model.OCTransfer +import com.owncloud.android.domain.transfers.model.TransferResult +import com.owncloud.android.domain.transfers.model.TransferStatus +import com.owncloud.android.domain.transfers.model.UploadEnqueuedBy +import com.owncloud.android.testutil.OC_ACCOUNT_NAME +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class OCLocalTransferDataSourceTest { + private lateinit var ocLocalTransferDataSource: OCLocalTransferDataSource + private val transferDao = mockk(relaxUnitFun = true) + private val id = 0L + private val ocTransfer = OCTransfer( + id = id, + localPath = "/local/path", + remotePath = "/remote/path", + accountName = OC_ACCOUNT_NAME, + fileSize = 1024L, + status = TransferStatus.TRANSFER_IN_PROGRESS, + localBehaviour = UploadBehavior.MOVE, + forceOverwrite = true, + createdBy = UploadEnqueuedBy.ENQUEUED_BY_USER + ) + + private var transferEntity: OCTransferEntity = ocTransfer.toEntity() + + @Before + fun setUp() { + + ocLocalTransferDataSource = OCLocalTransferDataSource(transferDao) + } + + @Test + fun `saveTransfer inserts it correctly`() { + val resultExpected = 1L + every { + transferDao.insertOrReplace(any()) + } returns resultExpected + + val resultActual = ocLocalTransferDataSource.saveTransfer(ocTransfer) + + assertEquals(resultExpected, resultActual) + + verify(exactly = 1) { + transferDao.insertOrReplace(ocTransfer.toEntity()) + } + } + + @Test + fun `updateTransfer changes it correctly`() { + val resultExpected = 1L + every { + transferDao.insertOrReplace(any()) + } returns resultExpected + + ocLocalTransferDataSource.updateTransfer(ocTransfer) + + verify(exactly = 1) { + transferDao.insertOrReplace(ocTransfer.toEntity()) + } + } + + @Test + fun `updateTransferStatusToInProgressById changes transfer status correctly`() { + val resultExpected = 10L + + ocLocalTransferDataSource.updateTransferStatusToInProgressById(resultExpected) + + verify(exactly = 1) { + transferDao.updateTransferStatusWithId(resultExpected, TransferStatus.TRANSFER_IN_PROGRESS.value) + } + } + + @Test + fun `updateTransferStatusToEnqueuedById changes transfer status correctly`() { + val resultExpected = 10L + + ocLocalTransferDataSource.updateTransferStatusToEnqueuedById(resultExpected) + + verify(exactly = 1) { + transferDao.updateTransferStatusWithId(resultExpected, TransferStatus.TRANSFER_QUEUED.value) + } + } + + @Test + fun `updateTransferWhenFinished changes transfer status correctly`() { + val timestamp = System.currentTimeMillis() + + ocLocalTransferDataSource.updateTransferWhenFinished(id, TransferStatus.TRANSFER_SUCCEEDED, timestamp, TransferResult.UPLOADED) + + verify(exactly = 1) { + transferDao.updateTransferWhenFinished(id, TransferStatus.TRANSFER_SUCCEEDED.value, timestamp, TransferResult.UPLOADED.value) + } + } + + @Test + fun `updateTransferLocalPath changes transfer local path correctly`() { + + ocLocalTransferDataSource.updateTransferLocalPath(id, ocTransfer.localPath) + + verify(exactly = 1) { + transferDao.updateTransferLocalPath(id, ocTransfer.localPath) + } + } + + @Test + fun `updateTransferStorageDirectoryInLocalPath changes directory correctly`() { + val oldDirectory = "oldDirectory" + val newDirectory = "newDirectory" + + ocLocalTransferDataSource.updateTransferStorageDirectoryInLocalPath(id, oldDirectory, newDirectory) + + verify(exactly = 1) { + transferDao.updateTransferStorageDirectoryInLocalPath(id, oldDirectory, newDirectory) + } + } + + @Test + fun `deleteTransferById removes it correctly`() { + + ocLocalTransferDataSource.deleteTransferById(id) + + verify(exactly = 1) { + transferDao.deleteTransferWithId(id) + } + } + + @Test + fun `deleteAllTransfersFromAccount removes all transfers correctly`() { + + ocLocalTransferDataSource.deleteAllTransfersFromAccount(OC_ACCOUNT_NAME) + + verify(exactly = 1) { + transferDao.deleteTransfersWithAccountName(OC_ACCOUNT_NAME) + } + } + + @Test + fun `getTransferById returns a OCTransfer`() { + every { + transferDao.getTransferWithId(any()) + } returns ocTransfer.toEntity() + + val actualResult = ocLocalTransferDataSource.getTransferById(id) + + assertEquals(ocTransfer, actualResult) + + verify(exactly = 1) { + transferDao.getTransferWithId(id) + } + } + + @Test + fun `getAllTransfers returns a list of OCTransfer`() { + + every { + transferDao.getAllTransfers() + } returns listOf(transferEntity) + + val actualResult = ocLocalTransferDataSource.getAllTransfers() + + assertEquals(listOf(transferEntity.toModel()), actualResult) + + verify(exactly = 1) { + transferDao.getAllTransfers() + } + } + + @Test + fun `getAllTransfersAsStream returns a flow of list of OCTransfer ordered by status`() = runBlocking { + + val transferEntityInProgress: OCTransferEntity = ocTransfer.copy(status = TransferStatus.TRANSFER_IN_PROGRESS).toEntity() + + val transferEntityQueue: OCTransferEntity = ocTransfer.copy(status = TransferStatus.TRANSFER_QUEUED).toEntity() + + val transferEntityFailed: OCTransferEntity = ocTransfer.copy(status = TransferStatus.TRANSFER_FAILED).toEntity() + + val transferEntitySucceeded: OCTransferEntity = ocTransfer.copy(status = TransferStatus.TRANSFER_SUCCEEDED).toEntity() + + val transferListRandom = listOf(transferEntityQueue, transferEntityFailed, transferEntityInProgress, transferEntitySucceeded) + + val transferQueue = ocTransfer.copy() + transferQueue.status = TransferStatus.TRANSFER_QUEUED + + val transferFailed = ocTransfer.copy() + transferFailed.status = TransferStatus.TRANSFER_FAILED + + val transferSucceeded = ocTransfer.copy() + transferSucceeded.status = TransferStatus.TRANSFER_SUCCEEDED + + val transferListOrdered = listOf(ocTransfer, transferQueue, transferFailed, transferSucceeded) + + every { + transferDao.getAllTransfersAsStream() + } returns flowOf(transferListRandom) + + val actualResult = ocLocalTransferDataSource.getAllTransfersAsStream().first() + + assertEquals(transferListOrdered, actualResult) + + verify(exactly = 1) { + transferDao.getAllTransfersAsStream() + } + } + + @Test + fun `getLastTransferFor returns a OCTransfer`() { + + every { + transferDao.getLastTransferWithRemotePathAndAccountName(ocTransfer.remotePath, OC_ACCOUNT_NAME) + } returns transferEntity + + val actualResult = ocLocalTransferDataSource.getLastTransferFor(ocTransfer.remotePath, OC_ACCOUNT_NAME) + + assertEquals(transferEntity.toModel(), actualResult) + + verify(exactly = 1) { + transferDao.getLastTransferWithRemotePathAndAccountName(ocTransfer.remotePath, OC_ACCOUNT_NAME) + } + } + + @Test + fun `getCurrentAndPendingTransfers returns a list of OCTransfer`() { + + every { + transferDao.getTransfersWithStatus(listOf(TransferStatus.TRANSFER_IN_PROGRESS.value, TransferStatus.TRANSFER_QUEUED.value)) + } returns listOf(transferEntity) + + val actualResult = ocLocalTransferDataSource.getCurrentAndPendingTransfers() + + assertEquals(listOf(transferEntity.toModel()), actualResult) + + verify(exactly = 1) { + transferDao.getTransfersWithStatus(listOf(TransferStatus.TRANSFER_IN_PROGRESS.value, TransferStatus.TRANSFER_QUEUED.value)) + } + } + + @Test + fun `getFailedTransfers returns a list of OCTransfer`() { + + every { + transferDao.getTransfersWithStatus(listOf(TransferStatus.TRANSFER_FAILED.value)) + } returns listOf(transferEntity) + + val actualResult = ocLocalTransferDataSource.getFailedTransfers() + + assertEquals(listOf(transferEntity.toModel()), actualResult) + + verify(exactly = 1) { + transferDao.getTransfersWithStatus(listOf(TransferStatus.TRANSFER_FAILED.value)) + } + } + + @Test + fun `getFinishedTransfers returns a list of OCTransfer`() { + + every { + transferDao.getTransfersWithStatus(listOf(TransferStatus.TRANSFER_SUCCEEDED.value)) + } returns listOf(transferEntity) + + val actualResult = ocLocalTransferDataSource.getFinishedTransfers() + + assertEquals(listOf(transferEntity.toModel()), actualResult) + + verify(exactly = 1) { + transferDao.getTransfersWithStatus(listOf(TransferStatus.TRANSFER_SUCCEEDED.value)) + } + } + + @Test + fun `clearFailedTransfers removes transfers correctly`() { + + ocLocalTransferDataSource.clearFailedTransfers() + + verify(exactly = 1) { + transferDao.deleteTransfersWithStatus(TransferStatus.TRANSFER_FAILED.value) + } + } + + @Test + fun `clearSuccessfulTransfers removes transfers correctly`() { + + ocLocalTransferDataSource.clearSuccessfulTransfers() + + verify(exactly = 1) { + transferDao.deleteTransfersWithStatus(TransferStatus.TRANSFER_SUCCEEDED.value) + } + } +} diff --git a/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCLocalUserDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCLocalUserDataSourceTest.kt index 15b6db7b98d..f3bb0d1e030 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCLocalUserDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCLocalUserDataSourceTest.kt @@ -2,7 +2,9 @@ * ownCloud Android client application * * @author Abel García de Prada - * Copyright (C) 2020 ownCloud GmbH. + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -22,6 +24,7 @@ package com.owncloud.android.data.user.datasources import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.owncloud.android.data.user.datasources.implementation.OCLocalUserDataSource import com.owncloud.android.data.user.datasources.implementation.OCLocalUserDataSource.Companion.toEntity +import com.owncloud.android.data.user.datasources.implementation.OCLocalUserDataSource.Companion.toModel import com.owncloud.android.data.user.db.UserDao import com.owncloud.android.testutil.OC_ACCOUNT_NAME import com.owncloud.android.testutil.OC_USER_QUOTA @@ -37,7 +40,7 @@ import org.junit.rules.TestRule class OCLocalUserDataSourceTest { private lateinit var ocLocalUserDataSource: OCLocalUserDataSource - private val ocUserQuotaDao = mockk(relaxed = true) + private val ocUserQuotaDao = mockk(relaxUnitFun = true) private val userQuotaEntity = OC_USER_QUOTA.toEntity() @@ -46,34 +49,67 @@ class OCLocalUserDataSourceTest { var rule: TestRule = InstantTaskExecutorRule() @Before - fun init() { + fun setUp() { ocLocalUserDataSource = OCLocalUserDataSource(ocUserQuotaDao) } @Test - fun getQuotaForAccount() { + fun saveQuotaForAccount() { + + ocLocalUserDataSource.saveQuotaForAccount(OC_ACCOUNT_NAME, OC_USER_QUOTA) + + verify(exactly = 1) { + ocUserQuotaDao.insertOrReplace(userQuotaEntity) + } + } + + @Test + fun `getQuotaForAccount returns a UserQuota`() { every { ocUserQuotaDao.getQuotaForAccount(any()) } returns userQuotaEntity val userQuota = ocLocalUserDataSource.getQuotaForAccount(OC_ACCOUNT_NAME) assertEquals(OC_USER_QUOTA, userQuota) + + verify(exactly = 1) { + ocUserQuotaDao.getQuotaForAccount(OC_ACCOUNT_NAME) + } } @Test - fun getQuotaForAccountNull() { + fun `getQuotaForAccount return null when dao receive null`() { every { ocUserQuotaDao.getQuotaForAccount(any()) } returns null val quotaEntity = ocLocalUserDataSource.getQuotaForAccount(OC_ACCOUNT_NAME) assertNull(quotaEntity) + + verify(exactly = 1) { + ocUserQuotaDao.getQuotaForAccount(OC_ACCOUNT_NAME) + } } @Test - fun insertQuota() { - every { ocUserQuotaDao.insertOrReplace(any()) } returns Unit + fun deleteQuotaForAccount() { - ocLocalUserDataSource.saveQuotaForAccount(OC_ACCOUNT_NAME, OC_USER_QUOTA) + ocLocalUserDataSource.deleteQuotaForAccount(OC_ACCOUNT_NAME) + + verify(exactly = 1) { + ocUserQuotaDao.deleteQuotaForAccount(OC_ACCOUNT_NAME) + } + } + + @Test + fun `getAllUserQuotas returns a list of UserQuote`() { + + every { ocUserQuotaDao.getAllUserQuotas() } returns listOf(userQuotaEntity) + + val resultActual = ocLocalUserDataSource.getAllUserQuotas() + + assertEquals(listOf(userQuotaEntity.toModel()), resultActual) - verify(exactly = 1) { ocUserQuotaDao.insertOrReplace(userQuotaEntity) } + verify(exactly = 1) { + ocUserQuotaDao.getAllUserQuotas() + } } } diff --git a/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCRemoteUserDataSourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCRemoteUserDataSourceTest.kt index fb8fcf2dcec..31f481931ad 100644 --- a/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCRemoteUserDataSourceTest.kt +++ b/owncloudData/src/test/java/com/owncloud/android/data/user/datasources/OCRemoteUserDataSourceTest.kt @@ -33,6 +33,7 @@ import com.owncloud.android.testutil.OC_USER_QUOTA import com.owncloud.android.utils.createRemoteOperationResultMock import io.mockk.every import io.mockk.mockk +import io.mockk.verify import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Before @@ -64,7 +65,7 @@ class OCRemoteUserDataSourceTest { ) @Before - fun init() { + fun setUp() { every { clientManager.getUserService(any()) } returns ocUserService ocRemoteUserDataSource = OCRemoteUserDataSource( @@ -74,7 +75,7 @@ class OCRemoteUserDataSourceTest { } @Test - fun getUserInfoOk() { + fun `getUserInfo returns UserInfo`() { val getUserInfoResult: RemoteOperationResult = createRemoteOperationResultMock(data = remoteUserInfo, isSuccess = true) @@ -86,20 +87,12 @@ class OCRemoteUserDataSourceTest { assertNotNull(userInfo) assertEquals(OC_USER_INFO, userInfo) - } - - @Test(expected = Exception::class) - fun getUserInfoException() { - every { - ocUserService.getUserInfo() - } throws Exception() - - ocRemoteUserDataSource.getUserInfo(OC_ACCOUNT_NAME) + verify(exactly = 1) { ocUserService.getUserInfo() } } @Test - fun getUserQuotaOk() { + fun `getUserQuota returns UserQuota`() { val getUserQuotaResult: RemoteOperationResult = createRemoteOperationResultMock(data = remoteQuota, isSuccess = true) @@ -111,19 +104,12 @@ class OCRemoteUserDataSourceTest { assertNotNull(userQuota) assertEquals(OC_USER_QUOTA, userQuota) - } - - @Test(expected = Exception::class) - fun getUserQuotaException() { - every { - ocUserService.getUserQuota() - } throws Exception() - ocRemoteUserDataSource.getUserQuota(OC_ACCOUNT_NAME) + verify(exactly = 1) { ocUserService.getUserQuota() } } @Test - fun getUserAvatarOk() { + fun `getUserAvatar returns UserAvatar`() { val getUserAvatarResult: RemoteOperationResult = createRemoteOperationResultMock(data = remoteAvatar, isSuccess = true) @@ -135,14 +121,8 @@ class OCRemoteUserDataSourceTest { assertNotNull(userAvatar) assertEquals(OC_USER_AVATAR, userAvatar) - } - @Test(expected = Exception::class) - fun getUserAvatarException() { - every { - ocUserService.getUserAvatar(avatarDimension) - } throws Exception() - - ocRemoteUserDataSource.getUserAvatar(OC_ACCOUNT_NAME) + verify(exactly = 1) { ocUserService.getUserAvatar(avatarDimension) } } } + diff --git a/owncloudData/src/test/java/com/owncloud/android/data/webfinger/datasource/implementation/OCRemoteWebFingerDatasourceTest.kt b/owncloudData/src/test/java/com/owncloud/android/data/webfinger/datasource/implementation/OCRemoteWebFingerDatasourceTest.kt new file mode 100644 index 00000000000..f6067dd9218 --- /dev/null +++ b/owncloudData/src/test/java/com/owncloud/android/data/webfinger/datasource/implementation/OCRemoteWebFingerDatasourceTest.kt @@ -0,0 +1,134 @@ +/** + * ownCloud Android client application + * + * @author Aitor Ballesteros Pavón + * + * Copyright (C) 2023 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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.owncloud.android.data.webfinger.datasource.implementation + +import com.owncloud.android.data.ClientManager +import com.owncloud.android.data.webfinger.datasources.implementation.OCRemoteWebFingerDatasource +import com.owncloud.android.domain.webfinger.model.WebFingerRel +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.webfinger.services.implementation.OCWebFingerService +import com.owncloud.android.testutil.OC_ACCESS_TOKEN +import com.owncloud.android.testutil.OC_ACCOUNT_ID +import com.owncloud.android.testutil.OC_SECURE_SERVER_INFO_BASIC_AUTH +import com.owncloud.android.utils.createRemoteOperationResultMock +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class OCRemoteWebFingerDatasourceTest { + + private lateinit var ocRemoteWebFingerDatasource: OCRemoteWebFingerDatasource + + private val clientManager: ClientManager = mockk(relaxed = true) + private val ownCloudClient: OwnCloudClient = mockk(relaxed = true) + private val ocWebFingerService: OCWebFingerService = mockk() + private val urls: List = listOf( + "http://webfinger.owncloud/tests/server-instance1", + "http://webfinger.owncloud/tests/server-instance2", + "http://webfinger.owncloud/tests/server-instance3", + ) + + @Before + fun setUp() { + ocRemoteWebFingerDatasource = OCRemoteWebFingerDatasource( + ocWebFingerService, + clientManager, + ) + + every { clientManager.getClientForAnonymousCredentials(OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, false) } returns ownCloudClient + + } + + @Test + fun `getInstancesFromWebFinger returns a list of web finger`() { + + val getInstancesFromWebFingerResult: RemoteOperationResult> = + createRemoteOperationResultMock(data = urls, isSuccess = true) + + every { + ocWebFingerService.getInstancesFromWebFinger( + lookupServer = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + resource = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + rel = WebFingerRel.OIDC_ISSUER_DISCOVERY.uri, + ownCloudClient, + ) + } returns getInstancesFromWebFingerResult + + val actualResult = ocRemoteWebFingerDatasource.getInstancesFromWebFinger( + lookupServer = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + rel = WebFingerRel.OIDC_ISSUER_DISCOVERY, + resource = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + ) + + assertEquals(getInstancesFromWebFingerResult.data, actualResult) + + verify(exactly = 1) { + clientManager.getClientForAnonymousCredentials(any(), false) + ocWebFingerService.getInstancesFromWebFinger( + lookupServer = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + resource = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + rel = WebFingerRel.OIDC_ISSUER_DISCOVERY.uri, + ownCloudClient, + ) + } + } + + @Test + fun `getInstancesFromAuthenticatedWebFinger returns a list of web finger`() { + + val getInstancesFromAuthenticatedWebFingerResult: RemoteOperationResult> = + createRemoteOperationResultMock(data = urls, isSuccess = true) + + every { + ocWebFingerService.getInstancesFromWebFinger( + lookupServer = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + resource = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + rel = WebFingerRel.OIDC_ISSUER_DISCOVERY.uri, + ownCloudClient, + ) + } returns getInstancesFromAuthenticatedWebFingerResult + + val actualResult = ocRemoteWebFingerDatasource.getInstancesFromAuthenticatedWebFinger( + lookupServer = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + rel = WebFingerRel.OIDC_ISSUER_DISCOVERY, + resource = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + username = OC_ACCOUNT_ID, + accessToken = OC_ACCESS_TOKEN + ) + + assertEquals(getInstancesFromAuthenticatedWebFingerResult.data, actualResult) + + verify(exactly = 1) { + ownCloudClient.credentials = any() + clientManager.getClientForAnonymousCredentials(any(), false) + ocWebFingerService.getInstancesFromWebFinger( + lookupServer = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + resource = OC_SECURE_SERVER_INFO_BASIC_AUTH.baseUrl, + rel = WebFingerRel.OIDC_ISSUER_DISCOVERY.uri, + any(), + ) + } + } +} diff --git a/owncloudDomain/src/test/java/com/owncloud/android/domain/files/usecases/GetFileWithSyncInfoByIdUseCaseTest.kt b/owncloudDomain/src/test/java/com/owncloud/android/domain/files/usecases/GetFileWithSyncInfoByIdUseCaseTest.kt index 03af700a4fc..eb4beed3cb1 100644 --- a/owncloudDomain/src/test/java/com/owncloud/android/domain/files/usecases/GetFileWithSyncInfoByIdUseCaseTest.kt +++ b/owncloudDomain/src/test/java/com/owncloud/android/domain/files/usecases/GetFileWithSyncInfoByIdUseCaseTest.kt @@ -6,6 +6,7 @@ import com.owncloud.android.testutil.OC_FILE_WITH_SYNC_INFO_AND_SPACE import io.mockk.every import io.mockk.spyk import io.mockk.verify +import kotlinx.coroutines.flow.first import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -20,20 +21,18 @@ class GetFileWithSyncInfoByIdUseCaseTest { private val useCaseParams = GetFileWithSyncInfoByIdUseCase.Params(OC_FILE.id!!) @Test - fun `get file with sync by id returns OCFileWithSyncInfo when no error`() = runTest { + fun `getFileWithSyncInfoByIdAsFlow returns OCFileWithSyncInfo when no error`() = runTest { every { repository.getFileWithSyncInfoByIdAsFlow(useCaseParams.fileId) } returns flowOf(OC_FILE_WITH_SYNC_INFO_AND_SPACE) - val useCaseResult = useCase(useCaseParams) + val useCaseResult = useCase(useCaseParams).first() - useCaseResult.collect { result -> - Assert.assertEquals(OC_FILE_WITH_SYNC_INFO_AND_SPACE, result) - } + Assert.assertEquals(OC_FILE_WITH_SYNC_INFO_AND_SPACE, useCaseResult) verify(exactly = 1) { repository.getFileWithSyncInfoByIdAsFlow(useCaseParams.fileId) } } @Test - fun `get file with sync by id returns true when repository is null`() = runTest { + fun `getFileWithSyncInfoByIdAsFlow returns true when repository is null`() = runTest { val useCaseResult = useCase(useCaseParams) every { repository.getFileWithSyncInfoByIdAsFlow(useCaseParams.fileId) } returns flowOf(null) @@ -41,16 +40,4 @@ class GetFileWithSyncInfoByIdUseCaseTest { verify(exactly = 1) { repository.getFileWithSyncInfoByIdAsFlow(useCaseParams.fileId) } } - - @Test(expected = Exception::class) - fun `get file with sync by id returns an exception`() = runTest { - every { repository.getFileWithSyncInfoByIdAsFlow(useCaseParams.fileId) } throws Exception() - - useCase(useCaseParams) - - verify(exactly = 1) { - repository.getFileWithSyncInfoByIdAsFlow(useCaseParams.fileId) - } - } - -} \ No newline at end of file +} diff --git a/owncloudTestUtil/build.gradle b/owncloudTestUtil/build.gradle index c81b34d9031..3d67e667cec 100644 --- a/owncloudTestUtil/build.gradle +++ b/owncloudTestUtil/build.gradle @@ -20,8 +20,8 @@ android { dependencies { implementation project(':owncloudDomain') + implementation project(':owncloudData') implementation project(':owncloudComLibrary') - implementation libs.kotlin.stdlib implementation libs.androidx.lifecycle.livedata.ktx } diff --git a/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCFolderBackUpConfiguration.kt b/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCFolderBackUpConfiguration.kt index dc84c660249..73a12e7d18d 100644 --- a/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCFolderBackUpConfiguration.kt +++ b/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCFolderBackUpConfiguration.kt @@ -22,6 +22,7 @@ package com.owncloud.android.testutil import com.owncloud.android.domain.camerauploads.model.FolderBackUpConfiguration import com.owncloud.android.domain.camerauploads.model.UploadBehavior +import com.owncloud.android.data.folderbackup.db.FolderBackUpEntity val OC_BACKUP = FolderBackUpConfiguration( accountName = "", @@ -33,3 +34,14 @@ val OC_BACKUP = FolderBackUpConfiguration( lastSyncTimestamp = 1542628397, name = "", ) + +val OC_BACKUP_ENTITY = FolderBackUpEntity( + accountName = "", + behavior = UploadBehavior.COPY.name, + sourcePath = "/Photos", + uploadPath = "/Photos", + wifiOnly = true, + chargingOnly = true, + lastSyncTimestamp = 1542628397, + name = "" +) diff --git a/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt b/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt index 8df42c44c3f..8953a295f5d 100644 --- a/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt +++ b/owncloudTestUtil/src/main/java/com/owncloud/android/testutil/OCSpace.kt @@ -20,7 +20,12 @@ package com.owncloud.android.testutil +import com.owncloud.android.data.spaces.db.SpaceRootEntity +import com.owncloud.android.data.spaces.db.SpaceSpecialEntity +import com.owncloud.android.data.spaces.db.SpacesEntity +import com.owncloud.android.data.spaces.db.SpacesWithSpecials import com.owncloud.android.domain.spaces.model.OCSpace +import com.owncloud.android.domain.spaces.model.OCSpace.Companion.SPACE_ID_SHARES import com.owncloud.android.domain.spaces.model.SpaceDeleted import com.owncloud.android.domain.spaces.model.SpaceFile import com.owncloud.android.domain.spaces.model.SpaceOwner @@ -29,6 +34,13 @@ import com.owncloud.android.domain.spaces.model.SpaceRoot import com.owncloud.android.domain.spaces.model.SpaceSpecial import com.owncloud.android.domain.spaces.model.SpaceSpecialFolder import com.owncloud.android.domain.spaces.model.SpaceUser +import com.owncloud.android.lib.resources.spaces.responses.QuotaResponse +import com.owncloud.android.lib.resources.spaces.responses.RootResponse +import com.owncloud.android.lib.resources.spaces.responses.SpaceResponse + +const val WEB_DAV_URL = "https://server.url/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f3805bca744-d89f-4e9c-a990-25a0d7f03fe9" + + val OC_SPACE_SPECIAL_README = SpaceSpecial( eTag = "71f78349c3598c9e431a67de5a283fc0", @@ -130,3 +142,97 @@ val OC_SPACE_PROJECT_DISABLED = OC_SPACE_PROJECT_WITH_IMAGE.copy( ), special = null ) + +val SPACE_ENTITY_WITH_SPECIALS = SpacesWithSpecials( + SpacesEntity( + accountName = OC_ACCOUNT_NAME, + driveAlias = "driveAlias", + driveType = "driveType", + id = OC_ACCOUNT_ID, + ownerId = OC_CLIENT_ID, + lastModifiedDateTime = "lastModifiedDateTime", + name = "name", + quota = null, + root = SpaceRootEntity( + eTag = "eTag", + id = "id", + webDavUrl = WEB_DAV_URL, + deleteState = "state" + ), + webUrl = "webUrl", + description = "description" + ), + listOf( + SpaceSpecialEntity( + accountName = OC_ACCOUNT_NAME, + eTag = "eTag", + fileMimeType = "fileMimeType", + id = OC_ACCOUNT_ID, + spaceId = OC_SPACE_PERSONAL.id, + lastModifiedDateTime = "lastModifiedDateTime", + name = "name", + webDavUrl = WEB_DAV_URL, + size = 100, + specialFolderName = OC_SPACE_SPECIAL_IMAGE.name + ) + ) +) + +val SPACE_ENTITY_SHARE = SpacesWithSpecials( + SpacesEntity( + accountName = OC_ACCOUNT_NAME, + driveAlias = "driveAlias", + driveType = "driveType", + id = SPACE_ID_SHARES, + ownerId = OC_CLIENT_ID, + lastModifiedDateTime = "lastModifiedDateTime", + name = "name", + quota = null, + root = SpaceRootEntity( + eTag = "eTag", + id = "id", + webDavUrl = WEB_DAV_URL, + deleteState = "state" + ), + webUrl = "webUrl", + description = "description" + ), + listOf( + SpaceSpecialEntity( + accountName = OC_ACCOUNT_NAME, + eTag = "eTag", + fileMimeType = "fileMimeType", + id = OC_ACCOUNT_ID, + spaceId = OC_SPACE_PERSONAL.id, + lastModifiedDateTime = "lastModifiedDateTime", + name = "name", + webDavUrl = WEB_DAV_URL, + size = 100, + specialFolderName = OC_SPACE_SPECIAL_IMAGE.name + ) + ) +) +val SPACE_RESPONSE = + SpaceResponse( + driveAlias = "driveAlias", + driveType = "driveType", + id = OC_ACCOUNT_ID, + lastModifiedDateTime = "lastModifiedDateTime", + name = "name", + webUrl = "webUrl", + description = "description", + owner = null, + root = RootResponse( + eTag = "eTag", + id = OC_ACCOUNT_ID, + webDavUrl = "https://server.url/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f3805bca744-d89f-4e9c-a990-25a0d7f03fe9", + deleted = null + ), + quota = QuotaResponse( + remaining = 1, + state = "state", + total = 10, + used = 1 + ), + special = null, + )