From c16bccfd3eddb6d9787ab304a4e981a6331acba0 Mon Sep 17 00:00:00 2001 From: hasibprince Date: Mon, 5 Jun 2023 12:06:01 +0600 Subject: [PATCH 1/3] Refactored FusedApi --- .../e/apps/data/fused/FusedAPIRepository.kt | 2 +- .../foundation/e/apps/data/fused/FusedApi.kt | 181 ++++++++++++++++++ .../{FusedAPIImpl.kt => FusedApiImpl.kt} | 80 ++++---- .../data/fusedDownload/FusedDownloadDAO.kt | 2 +- .../e/apps/data/updates/UpdatesManagerImpl.kt | 2 +- .../foundation/e/apps/di/RepositoryModule.kt | 6 + .../e/apps/install/pkg/PkgManagerModule.kt | 4 +- .../foundation/e/apps/FusedApiImplTest.kt | 129 ++++++------- .../e/apps/FusedApiRepositoryTest.kt | 4 +- .../e/apps/UpdateManagerImptTest.kt | 22 ++- .../installProcessor/FakeFusedDownloadDAO.kt | 17 +- .../FakeFusedManagerRepository.kt | 8 +- .../e/apps/util/LiveDataTestUtil.kt | 17 ++ 13 files changed, 342 insertions(+), 132 deletions(-) create mode 100644 app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt rename app/src/main/java/foundation/e/apps/data/fused/{FusedAPIImpl.kt => FusedApiImpl.kt} (93%) diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt index 220bf137b..f45a82870 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt @@ -38,7 +38,7 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class FusedAPIRepository @Inject constructor(private val fusedAPIImpl: FusedAPIImpl) { +class FusedAPIRepository @Inject constructor(private val fusedAPIImpl: FusedApi) { var streamBundle = StreamBundle() private set diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt new file mode 100644 index 000000000..dfd5e60f7 --- /dev/null +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt @@ -0,0 +1,181 @@ +package foundation.e.apps.data.fused + +import androidx.lifecycle.LiveData +import com.aurora.gplayapi.SearchSuggestEntry +import com.aurora.gplayapi.data.models.App +import com.aurora.gplayapi.data.models.AuthData +import com.aurora.gplayapi.data.models.StreamBundle +import com.aurora.gplayapi.data.models.StreamCluster +import foundation.e.apps.data.ResultSupreme +import foundation.e.apps.data.cleanapk.data.download.Download +import foundation.e.apps.data.enums.FilterLevel +import foundation.e.apps.data.enums.Origin +import foundation.e.apps.data.enums.ResultStatus +import foundation.e.apps.data.enums.Status +import foundation.e.apps.data.fused.data.FusedApp +import foundation.e.apps.data.fused.data.FusedCategory +import foundation.e.apps.data.fused.data.FusedHome +import foundation.e.apps.data.fused.utils.CategoryType +import foundation.e.apps.data.fusedDownload.models.FusedDownload +import retrofit2.Response + +interface FusedApi { + companion object { + const val APP_TYPE_ANY = "any" + const val APP_TYPE_OPEN = "open" + const val APP_TYPE_PWA = "pwa" + } + + /** + * Check if list in all the FusedHome is empty. + * If any list is not empty, send false. + * Else (if all lists are empty) send true. + */ + fun isFusedHomesEmpty(fusedHomes: List): Boolean + fun getApplicationCategoryPreference(): List + + suspend fun getHomeScreenData( + authData: AuthData, + ): LiveData>> + + /* + * Return three elements from the function. + * - List : List of categories. + * - String : String of application type - By default it is the value in preferences. + * In case there is any failure, for a specific type in handleAllSourcesCategories(), + * the string value is of that type. + * - ResultStatus : ResultStatus - by default is ResultStatus.OK. But in case there is a failure in + * any application category type, then it takes value of that failure. + * + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5413 + */ + suspend fun getCategoriesList( + type: CategoryType, + ): Triple, String, ResultStatus> + + /** + * Fetches search results from cleanAPK and GPlay servers and returns them + * @param query Query + * @param authData [AuthData] + * @return A livedata Pair of list of non-nullable [FusedApp] and + * a Boolean signifying if more search results are being loaded. + * Observe this livedata to display new apps as they are fetched from the network. + */ + fun getSearchResults( + query: String, + authData: AuthData + ): LiveData, Boolean>>> + + suspend fun getSearchSuggestions(query: String): List + + suspend fun getOnDemandModule( + packageName: String, + moduleName: String, + versionCode: Int, + offerType: Int + ): String? + + suspend fun updateFusedDownloadWithDownloadingInfo( + origin: Origin, + fusedDownload: FusedDownload + ) + + suspend fun getOSSDownloadInfo(id: String, version: String?): Response + + suspend fun getPWAApps(category: String): ResultSupreme> + + suspend fun getOpenSourceApps(category: String): ResultSupreme> + + suspend fun getNextStreamBundle( + homeUrl: String, + currentStreamBundle: StreamBundle, + ): ResultSupreme + + suspend fun getAdjustedFirstCluster( + streamBundle: StreamBundle, + pointer: Int = 0, + ): ResultSupreme + + suspend fun getNextStreamCluster( + currentStreamCluster: StreamCluster, + ): ResultSupreme + + suspend fun getPlayStoreApps( + browseUrl: String, + ): ResultSupreme> + + /* + * Function to search cleanapk using package name. + * Will be used to handle f-droid deeplink. + * + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 + */ + suspend fun getCleanapkAppDetails(packageName: String): Pair + + suspend fun getApplicationDetails( + packageNameList: List, + authData: AuthData, + origin: Origin + ): Pair, ResultStatus> + + /** + * Filter out apps which are restricted, whose details cannot be fetched. + * If an app is restricted, we do try to fetch the app details inside a + * try-catch block. If that fails, we remove the app, else we keep it even + * if it is restricted. + * + * Popular example: "com.skype.m2" + * + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5174 + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5131 [2] + */ + suspend fun filterRestrictedGPlayApps( + authData: AuthData, + appList: List, + ): ResultSupreme> + + /** + * Get different filter levels. + * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5720 + */ + suspend fun getAppFilterLevel(fusedApp: FusedApp, authData: AuthData?): FilterLevel + + /* + * Similar to above method but uses Aurora OSS data class "App". + */ + suspend fun getAppFilterLevel(app: App, authData: AuthData): FilterLevel + + suspend fun getApplicationDetails( + id: String, + packageName: String, + authData: AuthData, + origin: Origin + ): Pair + + /** + * Get fused app installation status. + * Applicable for both native apps and PWAs. + * + * Recommended to use this instead of [PkgManagerModule.getPackageStatus]. + */ + fun getFusedAppInstallationStatus(fusedApp: FusedApp): Status + + /** + * @return true, if any change is found, otherwise false + */ + fun isHomeDataUpdated( + newHomeData: List, + oldHomeData: List + ): Boolean + + /** + * @return returns true if there is changes in data, otherwise false + */ + fun isAnyFusedAppUpdated( + newFusedApps: List, + oldFusedApps: List + ): Boolean + + fun isAnyAppInstallStatusChanged(currentList: List): Boolean + fun isOpenSourceSelected(): Boolean +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedAPIImpl.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt similarity index 93% rename from app/src/main/java/foundation/e/apps/data/fused/FusedAPIImpl.kt rename to app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt index db60c4d7a..e25e64aa6 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedAPIImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt @@ -34,6 +34,7 @@ import com.aurora.gplayapi.data.models.StreamCluster import dagger.hilt.android.qualifiers.ApplicationContext import foundation.e.apps.R import foundation.e.apps.data.Constants.timeoutDurationInMillis +import foundation.e.apps.data.Result import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.cleanapk.CleanApkDownloadInfoFetcher import foundation.e.apps.data.cleanapk.CleanApkRetrofit @@ -52,6 +53,9 @@ import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.Type import foundation.e.apps.data.enums.isUnFiltered import foundation.e.apps.data.fdroid.FdroidWebInterface +import foundation.e.apps.data.fused.FusedApi.Companion.APP_TYPE_ANY +import foundation.e.apps.data.fused.FusedApi.Companion.APP_TYPE_OPEN +import foundation.e.apps.data.fused.FusedApi.Companion.APP_TYPE_PWA import foundation.e.apps.data.fused.data.FusedApp import foundation.e.apps.data.fused.data.FusedCategory import foundation.e.apps.data.fused.data.FusedHome @@ -81,7 +85,7 @@ typealias GplaySearchResultFlow = Flow, Boolea typealias FusedHomeDeferred = Deferred>> @Singleton -class FusedAPIImpl @Inject constructor( +class FusedApiImpl @Inject constructor( private val pkgManagerModule: PkgManagerModule, private val pwaManagerModule: PWAManagerModule, private val preferenceManagerModule: PreferenceManagerModule, @@ -90,20 +94,10 @@ class FusedAPIImpl @Inject constructor( @Named("cleanApkAppsRepository") private val cleanApkAppsRepository: CleanApkRepository, @Named("cleanApkPWARepository") private val cleanApkPWARepository: CleanApkRepository, @ApplicationContext private val context: Context -) { +) : FusedApi { companion object { private const val CATEGORY_TITLE_REPLACEABLE_CONJUNCTION = "&" - - /* - * Removing "private" access specifier to allow access in - * MainActivityViewModel.timeoutAlertDialog - * - * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5404 - */ - const val APP_TYPE_ANY = "any" - const val APP_TYPE_OPEN = "open" - const val APP_TYPE_PWA = "pwa" private const val CATEGORY_OPEN_GAMES_ID = "game_open_games" private const val CATEGORY_OPEN_GAMES_TITLE = "Open games" } @@ -113,14 +107,14 @@ class FusedAPIImpl @Inject constructor( * If any list is not empty, send false. * Else (if all lists are empty) send true. */ - fun isFusedHomesEmpty(fusedHomes: List): Boolean { + override fun isFusedHomesEmpty(fusedHomes: List): Boolean { fusedHomes.forEach { if (it.list.isNotEmpty()) return false } return true } - fun getApplicationCategoryPreference(): List { + override fun getApplicationCategoryPreference(): List { val prefs = mutableListOf() if (preferenceManagerModule.isGplaySelected()) prefs.add(APP_TYPE_ANY) if (preferenceManagerModule.isOpenSourceSelected()) prefs.add(APP_TYPE_OPEN) @@ -128,7 +122,7 @@ class FusedAPIImpl @Inject constructor( return prefs } - suspend fun getHomeScreenData( + override suspend fun getHomeScreenData( authData: AuthData, ): LiveData>> { @@ -225,7 +219,7 @@ class FusedAPIImpl @Inject constructor( * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5413 */ - suspend fun getCategoriesList( + override suspend fun getCategoriesList( type: CategoryType, ): Triple, String, ResultStatus> { val categoriesList = mutableListOf() @@ -251,7 +245,7 @@ class FusedAPIImpl @Inject constructor( * a Boolean signifying if more search results are being loaded. * Observe this livedata to display new apps as they are fetched from the network. */ - fun getSearchResults( + override fun getSearchResults( query: String, authData: AuthData ): LiveData, Boolean>>> { @@ -274,7 +268,7 @@ class FusedAPIImpl @Inject constructor( if (preferenceManagerModule.isOpenSourceSelected()) { fetchOpenSourceSearchResult( - this@FusedAPIImpl, + this@FusedApiImpl, cleanApkResults, query, searchResult, @@ -284,7 +278,7 @@ class FusedAPIImpl @Inject constructor( if (preferenceManagerModule.isPWASelected()) { fetchPWASearchResult( - this@FusedAPIImpl, + this@FusedApiImpl, query, searchResult, packageSpecificResults @@ -304,7 +298,7 @@ class FusedAPIImpl @Inject constructor( } private suspend fun fetchPWASearchResult( - fusedAPIImpl: FusedAPIImpl, + fusedAPIImpl: FusedApiImpl, query: String, searchResult: MutableList, packageSpecificResults: ArrayList @@ -358,7 +352,7 @@ class FusedAPIImpl @Inject constructor( } private suspend fun fetchOpenSourceSearchResult( - fusedAPIImpl: FusedAPIImpl, + fusedAPIImpl: FusedApiImpl, cleanApkResults: MutableList, query: String, searchResult: MutableList, @@ -490,11 +484,11 @@ class FusedAPIImpl @Inject constructor( return ResultSupreme.create(status, fusedApp) } - suspend fun getSearchSuggestions(query: String): List { + override suspend fun getSearchSuggestions(query: String): List { return gplayRepository.getSearchSuggestions(query) } - suspend fun getOnDemandModule( + override suspend fun getOnDemandModule( packageName: String, moduleName: String, versionCode: Int, @@ -514,7 +508,7 @@ class FusedAPIImpl @Inject constructor( return null } - suspend fun updateFusedDownloadWithDownloadingInfo( + override suspend fun updateFusedDownloadWithDownloadingInfo( origin: Origin, fusedDownload: FusedDownload ) { @@ -545,10 +539,10 @@ class FusedAPIImpl @Inject constructor( fusedDownload.downloadURLList = list } - suspend fun getOSSDownloadInfo(id: String, version: String?) = + override suspend fun getOSSDownloadInfo(id: String, version: String?) = (cleanApkAppsRepository as CleanApkDownloadInfoFetcher).getDownloadInfo(id, version) - suspend fun getPWAApps(category: String): ResultSupreme> { + override suspend fun getPWAApps(category: String): ResultSupreme> { val list = mutableListOf() val status = runCodeBlockWithTimeout({ val response = getPWAAppsResponse(category) @@ -562,7 +556,7 @@ class FusedAPIImpl @Inject constructor( return ResultSupreme.create(status, list) } - suspend fun getOpenSourceApps(category: String): ResultSupreme> { + override suspend fun getOpenSourceApps(category: String): ResultSupreme> { val list = mutableListOf() val status = runCodeBlockWithTimeout({ val response = getOpenSourceAppsResponse(category) @@ -576,7 +570,7 @@ class FusedAPIImpl @Inject constructor( return ResultSupreme.create(status, list) } - suspend fun getNextStreamBundle( + override suspend fun getNextStreamBundle( homeUrl: String, currentStreamBundle: StreamBundle, ): ResultSupreme { @@ -588,9 +582,9 @@ class FusedAPIImpl @Inject constructor( return ResultSupreme.create(status, streamBundle) } - suspend fun getAdjustedFirstCluster( + override suspend fun getAdjustedFirstCluster( streamBundle: StreamBundle, - pointer: Int = 0, + pointer: Int, ): ResultSupreme { var streamCluster = StreamCluster() val status = runCodeBlockWithTimeout({ @@ -600,7 +594,7 @@ class FusedAPIImpl @Inject constructor( return ResultSupreme.create(status, streamCluster) } - suspend fun getNextStreamCluster( + override suspend fun getNextStreamCluster( currentStreamCluster: StreamCluster, ): ResultSupreme { var streamCluster = StreamCluster() @@ -611,7 +605,7 @@ class FusedAPIImpl @Inject constructor( return ResultSupreme.create(status, streamCluster) } - suspend fun getPlayStoreApps( + override suspend fun getPlayStoreApps( browseUrl: String, ): ResultSupreme> { val list = mutableListOf() @@ -631,7 +625,7 @@ class FusedAPIImpl @Inject constructor( * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5509 */ - suspend fun getCleanapkAppDetails(packageName: String): Pair { + override suspend fun getCleanapkAppDetails(packageName: String): Pair { var fusedApp = FusedApp() val status = runCodeBlockWithTimeout({ val result = cleanApkAppsRepository.getSearchResult( @@ -649,7 +643,7 @@ class FusedAPIImpl @Inject constructor( return Pair(fusedApp, status) } - suspend fun getApplicationDetails( + override suspend fun getApplicationDetails( packageNameList: List, authData: AuthData, origin: Origin @@ -762,7 +756,7 @@ class FusedAPIImpl @Inject constructor( * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5174 * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5131 [2] */ - suspend fun filterRestrictedGPlayApps( + override suspend fun filterRestrictedGPlayApps( authData: AuthData, appList: List, ): ResultSupreme> { @@ -787,7 +781,7 @@ class FusedAPIImpl @Inject constructor( * Get different filter levels. * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5720 */ - suspend fun getAppFilterLevel(fusedApp: FusedApp, authData: AuthData?): FilterLevel { + override suspend fun getAppFilterLevel(fusedApp: FusedApp, authData: AuthData?): FilterLevel { if (fusedApp.package_name.isBlank()) { return FilterLevel.UNKNOWN } @@ -839,7 +833,7 @@ class FusedAPIImpl @Inject constructor( /* * Similar to above method but uses Aurora OSS data class "App". */ - suspend fun getAppFilterLevel(app: App, authData: AuthData): FilterLevel { + override suspend fun getAppFilterLevel(app: App, authData: AuthData): FilterLevel { return getAppFilterLevel(app.transformToFusedApp(), authData) } @@ -850,7 +844,7 @@ class FusedAPIImpl @Inject constructor( this.filterLevel = getAppFilterLevel(this, authData) } - suspend fun getApplicationDetails( + override suspend fun getApplicationDetails( id: String, packageName: String, authData: AuthData, @@ -1345,7 +1339,7 @@ class FusedAPIImpl @Inject constructor( * * Recommended to use this instead of [PkgManagerModule.getPackageStatus]. */ - fun getFusedAppInstallationStatus(fusedApp: FusedApp): Status { + override fun getFusedAppInstallationStatus(fusedApp: FusedApp): Status { return if (fusedApp.is_pwa) { pwaManagerModule.getPwaStatus(fusedApp) } else { @@ -1382,7 +1376,7 @@ class FusedAPIImpl @Inject constructor( /** * @return true, if any change is found, otherwise false */ - fun isHomeDataUpdated( + override fun isHomeDataUpdated( newHomeData: List, oldHomeData: List ): Boolean { @@ -1421,7 +1415,7 @@ class FusedAPIImpl @Inject constructor( /** * @return returns true if there is changes in data, otherwise false */ - fun isAnyFusedAppUpdated( + override fun isAnyFusedAppUpdated( newFusedApps: List, oldFusedApps: List ): Boolean { @@ -1439,7 +1433,7 @@ class FusedAPIImpl @Inject constructor( return false } - fun isAnyAppInstallStatusChanged(currentList: List): Boolean { + override fun isAnyAppInstallStatusChanged(currentList: List): Boolean { currentList.forEach { if (it.status == Status.INSTALLATION_ISSUE) { return@forEach @@ -1453,5 +1447,5 @@ class FusedAPIImpl @Inject constructor( return false } - fun isOpenSourceSelected() = preferenceManagerModule.isOpenSourceSelected() + override fun isOpenSourceSelected() = preferenceManagerModule.isOpenSourceSelected() } diff --git a/app/src/main/java/foundation/e/apps/data/fusedDownload/FusedDownloadDAO.kt b/app/src/main/java/foundation/e/apps/data/fusedDownload/FusedDownloadDAO.kt index 02b3fbfeb..9b3b096ef 100644 --- a/app/src/main/java/foundation/e/apps/data/fusedDownload/FusedDownloadDAO.kt +++ b/app/src/main/java/foundation/e/apps/data/fusedDownload/FusedDownloadDAO.kt @@ -25,7 +25,7 @@ interface FusedDownloadDAO { suspend fun getDownloadById(id: String): FusedDownload? @Query("SELECT * FROM fuseddownload where id = :id") - fun getDownloadFlowById(id: String): LiveData + fun getDownloadFlowById(id: String): LiveData @Update suspend fun updateDownload(fusedDownload: FusedDownload) diff --git a/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt b/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt index d537ade94..ac0a9698e 100644 --- a/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt @@ -29,7 +29,7 @@ import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.isUnFiltered import foundation.e.apps.data.faultyApps.FaultyAppRepository import foundation.e.apps.data.fdroid.FdroidRepository -import foundation.e.apps.data.fused.FusedAPIImpl.Companion.APP_TYPE_ANY +import foundation.e.apps.data.fused.FusedApi.Companion.APP_TYPE_ANY import foundation.e.apps.data.fused.FusedAPIRepository import foundation.e.apps.data.fused.data.FusedApp import foundation.e.apps.data.preference.PreferenceManagerModule diff --git a/app/src/main/java/foundation/e/apps/di/RepositoryModule.kt b/app/src/main/java/foundation/e/apps/di/RepositoryModule.kt index ddaff2849..818511a20 100644 --- a/app/src/main/java/foundation/e/apps/di/RepositoryModule.kt +++ b/app/src/main/java/foundation/e/apps/di/RepositoryModule.kt @@ -8,6 +8,8 @@ import foundation.e.apps.data.exodus.repositories.AppPrivacyInfoRepositoryImpl import foundation.e.apps.data.exodus.repositories.IAppPrivacyInfoRepository import foundation.e.apps.data.fdroid.FdroidRepository import foundation.e.apps.data.fdroid.IFdroidRepository +import foundation.e.apps.data.fused.FusedApi +import foundation.e.apps.data.fused.FusedApiImpl import foundation.e.apps.data.fusedDownload.FusedManagerImpl import foundation.e.apps.data.fusedDownload.IFusedManager import javax.inject.Singleton @@ -26,4 +28,8 @@ interface RepositoryModule { @Singleton @Binds fun getFdroidRepository(fusedManagerImpl: FdroidRepository): IFdroidRepository + + @Singleton + @Binds + fun getFusedApi(fusedApiImpl: FusedApiImpl): FusedApi } diff --git a/app/src/main/java/foundation/e/apps/install/pkg/PkgManagerModule.kt b/app/src/main/java/foundation/e/apps/install/pkg/PkgManagerModule.kt index 076c05a8f..bbb7db232 100644 --- a/app/src/main/java/foundation/e/apps/install/pkg/PkgManagerModule.kt +++ b/app/src/main/java/foundation/e/apps/install/pkg/PkgManagerModule.kt @@ -34,7 +34,7 @@ import foundation.e.apps.OpenForTesting import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.Type -import foundation.e.apps.data.fused.FusedAPIImpl +import foundation.e.apps.data.fused.FusedApi import foundation.e.apps.data.fusedDownload.models.FusedDownload import kotlinx.coroutines.DelicateCoroutinesApi import timber.log.Timber @@ -88,7 +88,7 @@ class PkgManagerModule @Inject constructor( * This method should be only used for native apps! * If you are using for any FusedApp, please consider that it can be a PWA! * - * Recommended to use: [FusedAPIImpl.getFusedAppInstallationStatus]. + * Recommended to use: [FusedApi.getFusedAppInstallationStatus]. */ fun getPackageStatus(packageName: String, versionCode: Int): Status { return if (isInstalled(packageName)) { diff --git a/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt b/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt index 69404eac1..8042e2052 100644 --- a/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt +++ b/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt @@ -20,31 +20,33 @@ package foundation.e.apps import android.content.Context import android.text.format.Formatter import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import com.aurora.gplayapi.Constants import com.aurora.gplayapi.data.models.App import com.aurora.gplayapi.data.models.AuthData import com.aurora.gplayapi.data.models.Category -import foundation.e.apps.data.cleanapk.CleanApkRetrofit import foundation.e.apps.data.cleanapk.data.categories.Categories import foundation.e.apps.data.cleanapk.data.search.Search -import foundation.e.apps.data.cleanapk.repositories.CleanAPKRepository +import foundation.e.apps.data.cleanapk.repositories.CleanApkRepository import foundation.e.apps.data.enums.FilterLevel import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Status import foundation.e.apps.data.fdroid.FdroidWebInterface -import foundation.e.apps.data.fused.FusedAPIImpl +import foundation.e.apps.data.fused.FusedApiImpl import foundation.e.apps.data.fused.data.FusedApp import foundation.e.apps.data.fused.data.FusedHome -import foundation.e.apps.data.gplay.GPlayAPIRepository +import foundation.e.apps.data.fused.utils.CategoryType +import foundation.e.apps.data.gplay.GplayStoreRepository import foundation.e.apps.install.pkg.PWAManagerModule import foundation.e.apps.install.pkg.PkgManagerModule import foundation.e.apps.util.MainCoroutineRule import foundation.e.apps.util.getOrAwaitValue import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest +import okhttp3.ResponseBody +import okhttp3.ResponseBody.Companion.toResponseBody import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -73,7 +75,7 @@ class FusedApiImplTest { @get:Rule var mainCoroutineRule = MainCoroutineRule() - private lateinit var fusedAPIImpl: FusedAPIImpl + private lateinit var fusedAPIImpl: FusedApiImpl @Mock private lateinit var pwaManagerModule: PWAManagerModule @@ -85,10 +87,13 @@ class FusedApiImplTest { private lateinit var context: Context @Mock - private lateinit var cleanApkRepository: CleanAPKRepository + private lateinit var cleanApkAppsRepository: CleanApkRepository @Mock - private lateinit var gPlayAPIRepository: GPlayAPIRepository + private lateinit var cleanApkPWARepository: CleanApkRepository + + @Mock + private lateinit var gPlayAPIRepository: GplayStoreRepository @Mock private lateinit var fdroidWebInterface: FdroidWebInterface @@ -106,13 +111,14 @@ class FusedApiImplTest { MockitoAnnotations.openMocks(this) formatterMocked = Mockito.mockStatic(Formatter::class.java) preferenceManagerModule = FakePreferenceModule(context) - fusedAPIImpl = FusedAPIImpl( - cleanApkRepository, - gPlayAPIRepository, + fusedAPIImpl = FusedApiImpl( pkgManagerModule, pwaManagerModule, preferenceManagerModule, fdroidWebInterface, + gPlayAPIRepository, + cleanApkAppsRepository, + cleanApkPWARepository, context ) } @@ -543,7 +549,7 @@ class FusedApiImplTest { price = "" ) - Mockito.`when`(gPlayAPIRepository.getAppDetails(fusedApp.package_name, AUTH_DATA)) + Mockito.`when`(gPlayAPIRepository.getAppDetails(fusedApp.package_name)) .thenReturn(App(fusedApp.package_name)) Mockito.`when`( @@ -551,7 +557,6 @@ class FusedApiImplTest { fusedApp.package_name, fusedApp.latest_version_code, fusedApp.offer_type, - AUTH_DATA ) ).thenReturn(listOf()) @@ -572,12 +577,12 @@ class FusedApiImplTest { price = "" ) - Mockito.`when`(gPlayAPIRepository.getAppDetails(fusedApp.package_name, AUTH_DATA)) + Mockito.`when`(gPlayAPIRepository.getAppDetails(fusedApp.package_name)) .thenThrow(RuntimeException()) Mockito.`when`( gPlayAPIRepository.getDownloadInfo( - fusedApp.package_name, fusedApp.latest_version_code, fusedApp.offer_type, AUTH_DATA + fusedApp.package_name, fusedApp.latest_version_code, fusedApp.offer_type ) ).thenReturn(listOf()) @@ -598,12 +603,12 @@ class FusedApiImplTest { price = "" ) - Mockito.`when`(gPlayAPIRepository.getAppDetails(fusedApp.package_name, AUTH_DATA)) + Mockito.`when`(gPlayAPIRepository.getAppDetails(fusedApp.package_name)) .thenReturn(App(fusedApp.package_name)) Mockito.`when`( gPlayAPIRepository.getDownloadInfo( - fusedApp.package_name, fusedApp.latest_version_code, fusedApp.offer_type, AUTH_DATA + fusedApp.package_name, fusedApp.latest_version_code, fusedApp.offer_type ) ).thenThrow(RuntimeException()) @@ -621,15 +626,13 @@ class FusedApiImplTest { preferenceManagerModule.isGplaySelectedFake = false Mockito.`when`( - cleanApkRepository.getCategoriesList( - eq(CleanApkRetrofit.APP_TYPE_PWA), eq(CleanApkRetrofit.APP_SOURCE_ANY) - ) + cleanApkPWARepository.getCategories() ).thenReturn(response) Mockito.`when`(context.getString(eq(R.string.pwa))).thenReturn("PWA") val categoryListResponse = - fusedAPIImpl.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + fusedAPIImpl.getCategoriesList(CategoryType.APPLICATION) assertEquals("getCategory", 3, categoryListResponse.first.size) } @@ -645,14 +648,12 @@ class FusedApiImplTest { preferenceManagerModule.isGplaySelectedFake = false Mockito.`when`( - cleanApkRepository.getCategoriesList( - eq(CleanApkRetrofit.APP_TYPE_ANY), eq(CleanApkRetrofit.APP_SOURCE_FOSS) - ) + cleanApkAppsRepository.getCategories() ).thenReturn(response) Mockito.`when`(context.getString(eq(R.string.open_source))).thenReturn("Open source") val categoryListResponse = - fusedAPIImpl.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + fusedAPIImpl.getCategoriesList(CategoryType.APPLICATION) assertEquals("getCategory", 3, categoryListResponse.first.size) } @@ -666,11 +667,11 @@ class FusedApiImplTest { preferenceManagerModule.isGplaySelectedFake = true Mockito.`when`( - gPlayAPIRepository.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + gPlayAPIRepository.getCategories(CategoryType.APPLICATION) ).thenReturn(categories) val categoryListResponse = - fusedAPIImpl.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + fusedAPIImpl.getCategoriesList(CategoryType.APPLICATION) assertEquals("getCategory", 4, categoryListResponse.first.size) } @@ -682,11 +683,11 @@ class FusedApiImplTest { preferenceManagerModule.isGplaySelectedFake = true Mockito.`when`( - gPlayAPIRepository.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + gPlayAPIRepository.getCategories(CategoryType.APPLICATION) ).thenThrow(RuntimeException()) val categoryListResponse = - fusedAPIImpl.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + fusedAPIImpl.getCategoriesList(CategoryType.APPLICATION) assertEquals("getCategory", 0, categoryListResponse.first.size) assertEquals("getCategory", ResultStatus.UNKNOWN, categoryListResponse.third) @@ -704,19 +705,15 @@ class FusedApiImplTest { val pwaResponse = Response.success(pwaCategories) Mockito.`when`( - cleanApkRepository.getCategoriesList( - eq(CleanApkRetrofit.APP_TYPE_ANY), eq(CleanApkRetrofit.APP_SOURCE_FOSS) - ) + cleanApkAppsRepository.getCategories() ).thenReturn(openSourceResponse) Mockito.`when`( - cleanApkRepository.getCategoriesList( - eq(CleanApkRetrofit.APP_TYPE_PWA), eq(CleanApkRetrofit.APP_SOURCE_ANY) - ) + cleanApkPWARepository.getCategories() ).thenReturn(pwaResponse) Mockito.`when`( - gPlayAPIRepository.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + gPlayAPIRepository.getCategories(CategoryType.APPLICATION) ).thenReturn(gplayCategories) Mockito.`when`(context.getString(eq(R.string.open_source))).thenReturn("Open source") @@ -727,7 +724,7 @@ class FusedApiImplTest { preferenceManagerModule.isGplaySelectedFake = true val categoryListResponse = - fusedAPIImpl.getCategoriesList(Category.Type.APPLICATION, AUTH_DATA) + fusedAPIImpl.getCategoriesList(CategoryType.APPLICATION) assertEquals("getCategory", 11, categoryListResponse.first.size) } @@ -758,21 +755,19 @@ class FusedApiImplTest { ) ) - val searchResult = Search(apps = appList, numberOfResults = 1, success = true) + val searchResult = Search(apps = appList, numberOfResults = 3, success = true) val packageNameSearchResponse = Response.success(searchResult) val gplayPackageResult = App("com.search.package") preferenceManagerModule.isPWASelectedFake = true preferenceManagerModule.isOpenSourceelectedFake = true preferenceManagerModule.isGplaySelectedFake = true - val gplayLivedata: LiveData, Boolean>> = MutableLiveData( - Pair( - listOf(FusedApp("a.b.c"), FusedApp("c.d.e"), FusedApp("d.e.f"), FusedApp("d.e.g")), false - ) - ) + val gplayFlow: Flow, Boolean>> = flowOf(Pair( + listOf(App("a.b.c"), App("c.d.e"), App("d.e.f"), App("d.e.g")), false + )) setupMockingSearchApp( - packageNameSearchResponse, AUTH_DATA, gplayPackageResult, gplayLivedata + packageNameSearchResponse, gplayPackageResult, gplayFlow ) val searchResultLiveData = @@ -784,52 +779,43 @@ class FusedApiImplTest { private suspend fun setupMockingSearchApp( packageNameSearchResponse: Response?, - authData: AuthData, gplayPackageResult: App, - gplayLivedata: LiveData, Boolean>>?, + gplayLivedata: Flow, Boolean>>, willThrowException: Boolean = false ) { Mockito.`when`(pwaManagerModule.getPwaStatus(any())).thenReturn(Status.UNAVAILABLE) Mockito.`when`(pkgManagerModule.getPackageStatus(any(), any())) .thenReturn(Status.UNAVAILABLE) Mockito.`when`( - cleanApkRepository.searchApps( - keyword = "com.search.package", by = "package_name" + cleanApkAppsRepository.getSearchResult( + query = "com.search.package", searchBy = "package_name" ) ).thenReturn(packageNameSearchResponse) formatterMocked.`when` { Formatter.formatFileSize(any(), any()) }.thenReturn("15MB") if (willThrowException) { - Mockito.`when`(gPlayAPIRepository.getAppDetails("com.search.package", authData)) + Mockito.`when`(gPlayAPIRepository.getAppDetails("com.search.package")) .thenThrow(RuntimeException()) } else { - Mockito.`when`(gPlayAPIRepository.getAppDetails(eq("com.search.package"), eq(authData))) + Mockito.`when`(gPlayAPIRepository.getAppDetails(eq("com.search.package"))) .thenReturn(gplayPackageResult) } - Mockito.`when`(cleanApkRepository.searchApps(keyword = "com.search.package")) + Mockito.`when`(cleanApkAppsRepository.getSearchResult(query = "com.search.package")) + .thenReturn(packageNameSearchResponse) + + Mockito.`when`(cleanApkPWARepository.getSearchResult(query = "com.search.package")) .thenReturn(packageNameSearchResponse) Mockito.`when`( - cleanApkRepository.searchApps( - keyword = "com.search.package", - type = CleanApkRetrofit.APP_TYPE_PWA, - source = CleanApkRetrofit.APP_SOURCE_ANY + cleanApkAppsRepository.getSearchResult( + query = "com.search.package" ) ).thenReturn(packageNameSearchResponse) - suspend fun replaceWithFDroid(gPlayApp: App): FusedApp { - return FusedApp(gPlayApp.id.toString(), gPlayApp.packageName) - } + Mockito.`when`(fdroidWebInterface.getFdroidApp(any())).thenReturn(Response.error(404, "".toResponseBody(null))) - Mockito.`when`( - gPlayAPIRepository.getSearchResults( - eq("com.search.package"), - eq(authData), - eq(::replaceWithFDroid) - ) - ) - .thenReturn(gplayLivedata) + Mockito.`when`(gPlayAPIRepository.getSearchResult(eq("com.search.package"),)).thenReturn(gplayLivedata) } @Test @@ -862,11 +848,12 @@ class FusedApiImplTest { val packageNameSearchResponse = Response.success(searchResult) val gplayPackageResult = App("com.search.package") - val gplayLivedata = - MutableLiveData(Pair(listOf(FusedApp("a.b.c"), FusedApp("c.d.e"), FusedApp("d.e.f")), false)) + val gplayFlow: Flow, Boolean>> = flowOf(Pair( + listOf(App("a.b.c"), App("c.d.e"), App("d.e.f"), App("d.e.g")), false + )) setupMockingSearchApp( - packageNameSearchResponse, AUTH_DATA, gplayPackageResult, gplayLivedata, true + packageNameSearchResponse, gplayPackageResult, gplayFlow, true ) preferenceManagerModule.isPWASelectedFake = false @@ -877,6 +864,6 @@ class FusedApiImplTest { fusedAPIImpl.getSearchResults("com.search.package", AUTH_DATA).getOrAwaitValue() val size = searchResultLiveData.data?.first?.size ?: -2 - assertEquals("getSearchResult", 3, size) + assertEquals("getSearchResult", 4, size) } } diff --git a/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt b/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt index 8fc89ed41..4f89a3755 100644 --- a/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt +++ b/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt @@ -17,7 +17,7 @@ package foundation.e.apps -import foundation.e.apps.data.fused.FusedAPIImpl +import foundation.e.apps.data.fused.FusedApiImpl import foundation.e.apps.data.fused.FusedAPIRepository import org.junit.Assert.assertTrue import org.junit.Before @@ -30,7 +30,7 @@ import org.mockito.kotlin.any class FusedApiRepositoryTest { private lateinit var fusedApiRepository: FusedAPIRepository @Mock - private lateinit var fusedAPIImpl: FusedAPIImpl + private lateinit var fusedAPIImpl: FusedApiImpl @Before fun setup() { diff --git a/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt b/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt index 44ceaa8cc..4e94cc262 100644 --- a/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt +++ b/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt @@ -17,6 +17,7 @@ package foundation.e.apps +import android.content.Context import android.content.pm.ApplicationInfo import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.aurora.gplayapi.data.models.AuthData @@ -25,8 +26,10 @@ import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Status import foundation.e.apps.data.faultyApps.FaultyAppRepository -import foundation.e.apps.data.fused.FusedAPIImpl +import foundation.e.apps.data.fdroid.FdroidRepository +import foundation.e.apps.data.fused.FusedApiImpl import foundation.e.apps.data.fused.FusedAPIRepository +import foundation.e.apps.data.fused.FusedApi import foundation.e.apps.data.fused.data.FusedApp import foundation.e.apps.data.updates.UpdatesManagerImpl import foundation.e.apps.install.pkg.PkgManagerModule @@ -59,14 +62,22 @@ class UpdateManagerImptTest { private lateinit var updatesManagerImpl: UpdatesManagerImpl + @Mock + private lateinit var context: Context + @Mock private lateinit var pkgManagerModule: PkgManagerModule @Mock private lateinit var fusedAPIRepository: FusedAPIRepository + private lateinit var preferenceModule: FakePreferenceModule + private lateinit var faultyAppRepository: FaultyAppRepository + @Mock + private lateinit var fdroidRepository: FdroidRepository + val authData = AuthData("e@e.email", "AtadyMsIAtadyM") val applicationInfo = mutableListOf( @@ -79,8 +90,9 @@ class UpdateManagerImptTest { fun setup() { MockitoAnnotations.openMocks(this) faultyAppRepository = FaultyAppRepository(FakeFaultyAppDao()) + preferenceModule = FakePreferenceModule(context) updatesManagerImpl = - UpdatesManagerImpl(pkgManagerModule, fusedAPIRepository, faultyAppRepository) + UpdatesManagerImpl(context, pkgManagerModule, fusedAPIRepository, faultyAppRepository, preferenceModule, fdroidRepository) } @Test @@ -296,9 +308,9 @@ class UpdateManagerImptTest { openSourceUpdates: Pair, ResultStatus>, gplayUpdates: Pair, ResultStatus>, selectedApplicationSources: List = mutableListOf( - FusedAPIImpl.APP_TYPE_ANY, - FusedAPIImpl.APP_TYPE_OPEN, - FusedAPIImpl.APP_TYPE_PWA + FusedApi.APP_TYPE_ANY, + FusedApi.APP_TYPE_OPEN, + FusedApi.APP_TYPE_PWA ) ) { Mockito.`when`(pkgManagerModule.getAllUserApps()).thenReturn(applicationInfo) diff --git a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt index f47693a50..43bb7845c 100644 --- a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt +++ b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt @@ -19,8 +19,13 @@ package foundation.e.apps.installProcessor import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.asLiveData +import androidx.lifecycle.liveData +import foundation.e.apps.data.enums.Status import foundation.e.apps.data.fusedDownload.FusedDownloadDAO import foundation.e.apps.data.fusedDownload.models.FusedDownload +import kotlinx.coroutines.flow.flow class FakeFusedDownloadDAO : FusedDownloadDAO { val fusedDownloadList = mutableListOf() @@ -41,8 +46,16 @@ class FakeFusedDownloadDAO : FusedDownloadDAO { return fusedDownloadList.find { it.id == id } } - override fun getDownloadFlowById(id: String): LiveData { - TODO("Not yet implemented") + override fun getDownloadFlowById(id: String): LiveData { + return flow { + while (true) { + val fusedDownload = fusedDownloadList.find { it.id == id } + emit(fusedDownload) + if (fusedDownload == null || fusedDownload.status == Status.INSTALLATION_ISSUE) { + break + } + } + }.asLiveData() } override suspend fun updateDownload(fusedDownload: FusedDownload) { diff --git a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt index 179b4837a..6e7cf4935 100644 --- a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt +++ b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt @@ -53,18 +53,18 @@ class FakeFusedManagerRepository( fusedDownload.downloadIdMap.replaceAll { _, _ -> true } fusedDownload.status = Status.DOWNLOADED fusedDownloadDAO.updateDownload(fusedDownload) + updateDownloadStatus(fusedDownload, Status.INSTALLING) } override suspend fun updateDownloadStatus(fusedDownload: FusedDownload, status: Status) { when (status) { Status.INSTALLING -> { + if (forceCrash) { + throw RuntimeException("test exception!") + } handleStatusInstalling(fusedDownload) } Status.INSTALLED -> { - if (forceCrash) { - throw RuntimeException() - } - fusedDownloadDAO.deleteDownload(fusedDownload) } else -> { diff --git a/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt b/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt index 58e478c34..604e4e5ce 100644 --- a/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt +++ b/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt @@ -44,6 +44,23 @@ suspend fun LiveData.getOrAwaitValue( return data as T } +//suspend fun LiveData.getOrAwaitMultipleResults( +// time: Long = 5, +// afterObserve: () -> Unit = {} +//): List { +// var data: MutableList = mutableListOf() +// val observer = Observer> { o -> +// data.addAll(o) +// print("onChanged: $o") +// } +// this.observeForever(observer) +// afterObserve.invoke() +// delay(time * 1000) +// this.removeObserver(observer) +// @Suppress("UNCHECKED_CAST") +// return data as List +//} + /** * Observes a [LiveData] until the `block` is done executing. */ -- GitLab From 9eb4a05b3f800f21a587098339e034cdf5c613a1 Mon Sep 17 00:00:00 2001 From: hasibprince Date: Mon, 5 Jun 2023 17:38:47 +0600 Subject: [PATCH 2/3] fixed appinstallprocessorTest --- .../foundation/e/apps/data/fused/FusedApi.kt | 2 +- .../e/apps/data/fused/FusedApiImpl.kt | 1 - .../e/apps/data/updates/UpdatesManagerImpl.kt | 2 +- .../foundation/e/apps/FusedApiImplTest.kt | 19 +++++++----- .../e/apps/FusedApiRepositoryTest.kt | 2 +- .../e/apps/UpdateManagerImptTest.kt | 1 - .../AppInstallProcessorTest.kt | 2 +- .../installProcessor/FakeFusedDownloadDAO.kt | 2 -- .../FakeFusedManagerRepository.kt | 12 ++++++-- .../e/apps/util/LiveDataTestUtil.kt | 30 ------------------- 10 files changed, 24 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt index dfd5e60f7..3bd46f45f 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt @@ -178,4 +178,4 @@ interface FusedApi { fun isAnyAppInstallStatusChanged(currentList: List): Boolean fun isOpenSourceSelected(): Boolean -} \ No newline at end of file +} diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt index e25e64aa6..aac230345 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt @@ -34,7 +34,6 @@ import com.aurora.gplayapi.data.models.StreamCluster import dagger.hilt.android.qualifiers.ApplicationContext import foundation.e.apps.R import foundation.e.apps.data.Constants.timeoutDurationInMillis -import foundation.e.apps.data.Result import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.cleanapk.CleanApkDownloadInfoFetcher import foundation.e.apps.data.cleanapk.CleanApkRetrofit diff --git a/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt b/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt index ac0a9698e..44f569778 100644 --- a/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt @@ -29,8 +29,8 @@ import foundation.e.apps.data.enums.Status import foundation.e.apps.data.enums.isUnFiltered import foundation.e.apps.data.faultyApps.FaultyAppRepository import foundation.e.apps.data.fdroid.FdroidRepository -import foundation.e.apps.data.fused.FusedApi.Companion.APP_TYPE_ANY import foundation.e.apps.data.fused.FusedAPIRepository +import foundation.e.apps.data.fused.FusedApi.Companion.APP_TYPE_ANY import foundation.e.apps.data.fused.data.FusedApp import foundation.e.apps.data.preference.PreferenceManagerModule import foundation.e.apps.install.pkg.PkgManagerModule diff --git a/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt b/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt index 8042e2052..13ec4be74 100644 --- a/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt +++ b/app/src/test/java/foundation/e/apps/FusedApiImplTest.kt @@ -45,7 +45,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest -import okhttp3.ResponseBody import okhttp3.ResponseBody.Companion.toResponseBody import org.junit.After import org.junit.Assert.assertEquals @@ -90,7 +89,7 @@ class FusedApiImplTest { private lateinit var cleanApkAppsRepository: CleanApkRepository @Mock - private lateinit var cleanApkPWARepository: CleanApkRepository + private lateinit var cleanApkPWARepository: CleanApkRepository @Mock private lateinit var gPlayAPIRepository: GplayStoreRepository @@ -762,9 +761,11 @@ class FusedApiImplTest { preferenceManagerModule.isPWASelectedFake = true preferenceManagerModule.isOpenSourceelectedFake = true preferenceManagerModule.isGplaySelectedFake = true - val gplayFlow: Flow, Boolean>> = flowOf(Pair( - listOf(App("a.b.c"), App("c.d.e"), App("d.e.f"), App("d.e.g")), false - )) + val gplayFlow: Flow, Boolean>> = flowOf( + Pair( + listOf(App("a.b.c"), App("c.d.e"), App("d.e.f"), App("d.e.g")), false + ) + ) setupMockingSearchApp( packageNameSearchResponse, gplayPackageResult, gplayFlow @@ -848,9 +849,11 @@ class FusedApiImplTest { val packageNameSearchResponse = Response.success(searchResult) val gplayPackageResult = App("com.search.package") - val gplayFlow: Flow, Boolean>> = flowOf(Pair( - listOf(App("a.b.c"), App("c.d.e"), App("d.e.f"), App("d.e.g")), false - )) + val gplayFlow: Flow, Boolean>> = flowOf( + Pair( + listOf(App("a.b.c"), App("c.d.e"), App("d.e.f"), App("d.e.g")), false + ) + ) setupMockingSearchApp( packageNameSearchResponse, gplayPackageResult, gplayFlow, true diff --git a/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt b/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt index 4f89a3755..8e04ce98e 100644 --- a/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt +++ b/app/src/test/java/foundation/e/apps/FusedApiRepositoryTest.kt @@ -17,8 +17,8 @@ package foundation.e.apps -import foundation.e.apps.data.fused.FusedApiImpl import foundation.e.apps.data.fused.FusedAPIRepository +import foundation.e.apps.data.fused.FusedApiImpl import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test diff --git a/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt b/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt index 4e94cc262..fb78eeeda 100644 --- a/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt +++ b/app/src/test/java/foundation/e/apps/UpdateManagerImptTest.kt @@ -27,7 +27,6 @@ import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Status import foundation.e.apps.data.faultyApps.FaultyAppRepository import foundation.e.apps.data.fdroid.FdroidRepository -import foundation.e.apps.data.fused.FusedApiImpl import foundation.e.apps.data.fused.FusedAPIRepository import foundation.e.apps.data.fused.FusedApi import foundation.e.apps.data.fused.data.FusedApp diff --git a/app/src/test/java/foundation/e/apps/installProcessor/AppInstallProcessorTest.kt b/app/src/test/java/foundation/e/apps/installProcessor/AppInstallProcessorTest.kt index 546b75869..66ad42305 100644 --- a/app/src/test/java/foundation/e/apps/installProcessor/AppInstallProcessorTest.kt +++ b/app/src/test/java/foundation/e/apps/installProcessor/AppInstallProcessorTest.kt @@ -152,7 +152,7 @@ class AppInstallProcessorTest { fakeFusedManagerRepository.forceCrash = true val finalFusedDownload = runProcessInstall(fusedDownload) - assertEquals("processInstall", Status.INSTALLATION_ISSUE, finalFusedDownload?.status) + assertTrue("processInstall", finalFusedDownload == null || fusedDownload.status == Status.INSTALLATION_ISSUE) } @Test diff --git a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt index 43bb7845c..dbec4d02e 100644 --- a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt +++ b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedDownloadDAO.kt @@ -19,9 +19,7 @@ package foundation.e.apps.installProcessor import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asLiveData -import androidx.lifecycle.liveData import foundation.e.apps.data.enums.Status import foundation.e.apps.data.fusedDownload.FusedDownloadDAO import foundation.e.apps.data.fusedDownload.models.FusedDownload diff --git a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt index 6e7cf4935..9b39077a2 100644 --- a/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt +++ b/app/src/test/java/foundation/e/apps/installProcessor/FakeFusedManagerRepository.kt @@ -37,6 +37,11 @@ class FakeFusedManagerRepository( var forceCrash = false override suspend fun downloadApp(fusedDownload: FusedDownload) { + if (forceCrash) { + System.out.println("Throwing test exception") + throw Exception("test exception!") + } + fusedDownload.status = Status.DOWNLOADING fusedDownload.downloadIdMap = mutableMapOf(Pair(341, false), Pair(342, false)) fusedDownloadDAO.updateDownload(fusedDownload) @@ -59,9 +64,6 @@ class FakeFusedManagerRepository( override suspend fun updateDownloadStatus(fusedDownload: FusedDownload, status: Status) { when (status) { Status.INSTALLING -> { - if (forceCrash) { - throw RuntimeException("test exception!") - } handleStatusInstalling(fusedDownload) } Status.INSTALLED -> { @@ -100,4 +102,8 @@ class FakeFusedManagerRepository( override fun getFusedDownloadPackageStatus(fusedDownload: FusedDownload): Status { return installationStatus } + + override suspend fun cancelDownload(fusedDownload: FusedDownload) { + fusedDownloadDAO.deleteDownload(fusedDownload) + } } diff --git a/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt b/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt index 604e4e5ce..978c43b11 100644 --- a/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt +++ b/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt @@ -43,33 +43,3 @@ suspend fun LiveData.getOrAwaitValue( @Suppress("UNCHECKED_CAST") return data as T } - -//suspend fun LiveData.getOrAwaitMultipleResults( -// time: Long = 5, -// afterObserve: () -> Unit = {} -//): List { -// var data: MutableList = mutableListOf() -// val observer = Observer> { o -> -// data.addAll(o) -// print("onChanged: $o") -// } -// this.observeForever(observer) -// afterObserve.invoke() -// delay(time * 1000) -// this.removeObserver(observer) -// @Suppress("UNCHECKED_CAST") -// return data as List -//} - -/** - * Observes a [LiveData] until the `block` is done executing. - */ -suspend fun LiveData.observeForTesting(block: suspend () -> Unit) { - val observer = Observer { } - try { - observeForever(observer) - block() - } finally { - removeObserver(observer) - } -} -- GitLab From 618f768e2cd0419d6ca4e08072e2376e31226009 Mon Sep 17 00:00:00 2001 From: hasibprince Date: Thu, 8 Jun 2023 12:26:14 +0600 Subject: [PATCH 3/3] refactor: method name --- .../java/foundation/e/apps/data/fused/FusedAPIRepository.kt | 4 ++-- app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt | 2 +- .../main/java/foundation/e/apps/data/fused/FusedApiImpl.kt | 2 +- app/src/main/java/foundation/e/apps/ui/home/HomeViewModel.kt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt index f45a82870..224fc833d 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedAPIRepository.kt @@ -82,8 +82,8 @@ class FusedAPIRepository @Inject constructor(private val fusedAPIImpl: FusedApi) return fusedAPIImpl.getHomeScreenData(authData) } - fun isFusedHomesEmpty(fusedHomes: List): Boolean { - return fusedAPIImpl.isFusedHomesEmpty(fusedHomes) + fun isHomesEmpty(fusedHomes: List): Boolean { + return fusedAPIImpl.isHomesEmpty(fusedHomes) } fun getApplicationCategoryPreference(): List { diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt index 3bd46f45f..759786cfc 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedApi.kt @@ -31,7 +31,7 @@ interface FusedApi { * If any list is not empty, send false. * Else (if all lists are empty) send true. */ - fun isFusedHomesEmpty(fusedHomes: List): Boolean + fun isHomesEmpty(fusedHomes: List): Boolean fun getApplicationCategoryPreference(): List suspend fun getHomeScreenData( diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt index aac230345..38a1bb3b2 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt @@ -106,7 +106,7 @@ class FusedApiImpl @Inject constructor( * If any list is not empty, send false. * Else (if all lists are empty) send true. */ - override fun isFusedHomesEmpty(fusedHomes: List): Boolean { + override fun isHomesEmpty(fusedHomes: List): Boolean { fusedHomes.forEach { if (it.list.isNotEmpty()) return false } diff --git a/app/src/main/java/foundation/e/apps/ui/home/HomeViewModel.kt b/app/src/main/java/foundation/e/apps/ui/home/HomeViewModel.kt index 2fbea50a8..981761b85 100644 --- a/app/src/main/java/foundation/e/apps/ui/home/HomeViewModel.kt +++ b/app/src/main/java/foundation/e/apps/ui/home/HomeViewModel.kt @@ -97,9 +97,9 @@ class HomeViewModel @Inject constructor( return fusedAPIRepository.getApplicationCategoryPreference() } - fun isFusedHomesEmpty(): Boolean { + fun isHomesEmpty(): Boolean { return homeScreenData.value?.data?.let { - fusedAPIRepository.isFusedHomesEmpty(it) + fusedAPIRepository.isHomesEmpty(it) } ?: true } -- GitLab