Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3b84fe5 authored by Hasib Prince's avatar Hasib Prince
Browse files

refactoring in order to unit test

unit test added for fusedapiimpl, fusedapirepository
refactoring homepage, applist and search fragment
parent 96099ae7
Loading
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -5,6 +5,7 @@ plugins {
    id 'org.jlleitschuh.gradle.ktlint' version '10.2.0'
    id 'org.jlleitschuh.gradle.ktlint' version '10.2.0'
    id 'androidx.navigation.safeargs.kotlin'
    id 'androidx.navigation.safeargs.kotlin'
    id 'dagger.hilt.android.plugin'
    id 'dagger.hilt.android.plugin'
    id 'kotlin-allopen'
}
}


def versionMajor = 2
def versionMajor = 2
@@ -92,6 +93,11 @@ kapt {
    correctErrorTypes true
    correctErrorTypes true
}
}


allOpen {
    // allows mocking for classes w/o directly opening them for release builds
    annotation 'foundation.e.apps.OpenClass'
}

dependencies {
dependencies {


    api "com.gitlab.AuroraOSS:gplayapi:0e224071f3"
    api "com.gitlab.AuroraOSS:gplayapi:0e224071f3"
@@ -109,6 +115,15 @@ dependencies {
    testImplementation 'junit:junit:4.13.2'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    // Optional -- Robolectric environment
    testImplementation "androidx.test:core:1.4.0"
    // Optional -- Mockito framework
    testImplementation "org.mockito:mockito-core:4.6.1"
    // Optional -- mockito-kotlin
    testImplementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
    testImplementation 'org.mockito:mockito-inline:2.13.0'




    // Coil and PhotoView
    // Coil and PhotoView
    implementation "io.coil-kt:coil:1.4.0"
    implementation "io.coil-kt:coil:1.4.0"
@@ -161,6 +176,7 @@ dependencies {
    def coroutines_version = "1.6.0"
    def coroutines_version = "1.6.0"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"


    // Room
    // Room
    def roomVersion = "2.4.1"
    def roomVersion = "2.4.1"
+32 −0
Original line number Original line Diff line number Diff line
/*
 *  Copyright (C) 2022  ECORP
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package foundation.e.apps

/**
 * This annotation allows us to open some classes for mocking purposes while they are final in
 * release builds.
 */
@Target(AnnotationTarget.ANNOTATION_CLASS)
annotation class OpenClass

/**
 * Annotate a class with [OpenForTesting] if you want it to be extendable in debug builds.
 */
@OpenClass
@Target(AnnotationTarget.CLASS)
annotation class OpenForTesting
+15 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@
package foundation.e.apps
package foundation.e.apps


import android.content.Context
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Bitmap
import android.os.Build
import android.os.Build
import android.os.SystemClock
import android.os.SystemClock
@@ -56,6 +57,7 @@ import foundation.e.apps.utils.enums.isUnFiltered
import foundation.e.apps.utils.modules.CommonUtilsModule.NETWORK_CODE_SUCCESS
import foundation.e.apps.utils.modules.CommonUtilsModule.NETWORK_CODE_SUCCESS
import foundation.e.apps.utils.modules.CommonUtilsModule.timeoutDurationInMillis
import foundation.e.apps.utils.modules.CommonUtilsModule.timeoutDurationInMillis
import foundation.e.apps.utils.modules.DataStoreModule
import foundation.e.apps.utils.modules.DataStoreModule
import foundation.e.apps.utils.modules.PWAManagerModule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withContext
@@ -71,6 +73,7 @@ class MainActivityViewModel @Inject constructor(
    private val fusedAPIRepository: FusedAPIRepository,
    private val fusedAPIRepository: FusedAPIRepository,
    private val fusedManagerRepository: FusedManagerRepository,
    private val fusedManagerRepository: FusedManagerRepository,
    private val pkgManagerModule: PkgManagerModule,
    private val pkgManagerModule: PkgManagerModule,
    private val pwaManagerModule: PWAManagerModule,
    private val ecloudRepository: EcloudRepository,
    private val ecloudRepository: EcloudRepository,
    private val blockedAppRepository: BlockedAppRepository,
    private val blockedAppRepository: BlockedAppRepository,
    private val aC2DMTask: AC2DMTask,
    private val aC2DMTask: AC2DMTask,
@@ -122,6 +125,10 @@ class MainActivityViewModel @Inject constructor(
        private var isGoogleLoginRunning = false
        private var isGoogleLoginRunning = false
    }
    }


    fun getUser(): User {
        return User.valueOf(userType.value ?: User.UNAVAILABLE.name)
    }

    private fun setFirstTokenFetchTime() {
    private fun setFirstTokenFetchTime() {
        if (firstAuthDataFetchTime == 0L) {
        if (firstAuthDataFetchTime == 0L) {
            firstAuthDataFetchTime = SystemClock.uptimeMillis()
            firstAuthDataFetchTime = SystemClock.uptimeMillis()
@@ -631,4 +638,12 @@ class MainActivityViewModel @Inject constructor(
    fun getAppNameByPackageName(packageName: String): String {
    fun getAppNameByPackageName(packageName: String): String {
        return pkgManagerModule.getAppNameFromPackageName(packageName)
        return pkgManagerModule.getAppNameFromPackageName(packageName)
    }
    }

    fun getLaunchIntentForPackageName(packageName: String): Intent? {
        return pkgManagerModule.getLaunchIntent(packageName)
    }

    fun launchPwa(fusedApp: FusedApp) {
        pwaManagerModule.launchPwa(fusedApp)
    }
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@


package foundation.e.apps.api.cleanapk
package foundation.e.apps.api.cleanapk


import foundation.e.apps.OpenForTesting
import foundation.e.apps.api.cleanapk.data.app.Application
import foundation.e.apps.api.cleanapk.data.app.Application
import foundation.e.apps.api.cleanapk.data.categories.Categories
import foundation.e.apps.api.cleanapk.data.categories.Categories
import foundation.e.apps.api.cleanapk.data.download.Download
import foundation.e.apps.api.cleanapk.data.download.Download
@@ -26,6 +27,7 @@ import foundation.e.apps.api.cleanapk.data.search.Search
import retrofit2.Response
import retrofit2.Response
import javax.inject.Inject
import javax.inject.Inject


@OpenForTesting
class CleanAPKRepository @Inject constructor(
class CleanAPKRepository @Inject constructor(
    private val cleanAPKInterface: CleanAPKInterface,
    private val cleanAPKInterface: CleanAPKInterface,
    private val cleanApkAppDetailApi: CleanApkAppDetailApi
    private val cleanApkAppDetailApi: CleanApkAppDetailApi
+71 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ import foundation.e.apps.api.fused.data.FusedHome
import foundation.e.apps.api.fused.data.Ratings
import foundation.e.apps.api.fused.data.Ratings
import foundation.e.apps.api.fused.utils.CategoryUtils
import foundation.e.apps.api.fused.utils.CategoryUtils
import foundation.e.apps.api.gplay.GPlayAPIRepository
import foundation.e.apps.api.gplay.GPlayAPIRepository
import foundation.e.apps.home.model.HomeChildFusedAppDiffUtil
import foundation.e.apps.manager.database.fusedDownload.FusedDownload
import foundation.e.apps.manager.database.fusedDownload.FusedDownload
import foundation.e.apps.manager.pkg.PkgManagerModule
import foundation.e.apps.manager.pkg.PkgManagerModule
import foundation.e.apps.utils.enums.AppTag
import foundation.e.apps.utils.enums.AppTag
@@ -1260,4 +1261,74 @@ class FusedAPIImpl @Inject constructor(
        }
        }
        return list
        return list
    }
    }

    /**
     * @return true, if any change is found, otherwise false
     */
    fun isHomeDataUpdated(
        newHomeData: List<FusedHome>,
        oldHomeData: List<FusedHome>
    ): Boolean {
        if (newHomeData.size != oldHomeData.size) {
            return true
        }

        oldHomeData.forEach {
            val fusedHome = newHomeData[oldHomeData.indexOf(it)]
            if (!it.title.contentEquals(fusedHome.title) || !areFusedAppsUpdated(it, fusedHome)) {
                return true
            }
        }
        return false
    }

    private fun areFusedAppsUpdated(
        oldFusedHome: FusedHome,
        newFusedHome: FusedHome,
    ): Boolean {
        val fusedAppDiffUtil = HomeChildFusedAppDiffUtil()

        oldFusedHome.list.forEach { oldFusedApp ->
            val indexOfOldFusedApp = oldFusedHome.list.indexOf(oldFusedApp)
            val fusedApp = newFusedHome.list[indexOfOldFusedApp]
            if (!fusedAppDiffUtil.areContentsTheSame(oldFusedApp, fusedApp)) {
                return false
            }
        }
        return true
    }

    /**
     * @return returns true if there is changes in data, otherwise false
     */
    fun isAnyFusedAppUpdated(
        newFusedApps: List<FusedApp>,
        oldFusedApps: List<FusedApp>
    ): Boolean {
        val fusedAppDiffUtil = HomeChildFusedAppDiffUtil()
        if (newFusedApps.size != oldFusedApps.size) {
            return true
        }

        newFusedApps.forEach {
            val indexOfNewFusedApp = newFusedApps.indexOf(it)
            if (!fusedAppDiffUtil.areContentsTheSame(it, oldFusedApps[indexOfNewFusedApp])) {
                return true
            }
        }
        return false
    }

    fun isAnyAppInstallStatusChanged(currentList: List<FusedApp>): Boolean {
        currentList.forEach {
            if (it.status == Status.INSTALLATION_ISSUE) {
                return@forEach
            }
            val currentAppStatus = pkgManagerModule.getPackageStatus(it.package_name, it.latest_version_code)
            if (it.status != currentAppStatus) {
                return true
            }
        }
        return false
    }
}
}
Loading