Loading app/src/test/java/foundation/e/apps/data/login/repository/AuthenticatorRepositoryTest.kt 0 → 100644 +121 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.login.repository import android.content.Context import androidx.test.core.app.ApplicationProvider import com.aurora.gplayapi.data.models.AuthData import com.google.common.truth.Truth.assertThat import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.enums.User import foundation.e.apps.data.login.core.AuthObject import foundation.e.apps.data.login.core.StoreAuthResult import foundation.e.apps.data.login.core.StoreAuthenticator import foundation.e.apps.data.login.core.StoreType import foundation.e.apps.data.preference.AppLoungeDataStore import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config(sdk = [30]) class AuthenticatorRepositoryTest { @Test fun getGPlayAuthOrThrow_returnsStoredAuth() = runTest { val authData = AuthData(email = "user@example.com") val appLoungeDataStore = createDataStore() appLoungeDataStore.saveAuthData(authData) val repository = AuthenticatorRepository(emptyList(), appLoungeDataStore) val result = repository.getGPlayAuthOrThrow() assertThat(result).isEqualTo(authData) } @Test fun fetchAuthObjects_logsOutAndPersistsAuthData() = runTest { val authData = AuthData(email = "user@example.com") val authObject = AuthObject.GPlayAuth(ResultSupreme.Success(authData), User.GOOGLE) val storeResult = StoreAuthResult(authObject, authData) val appLoungeDataStore = createDataStore() val playAuthenticator = mockk<StoreAuthenticator>() val inactiveAuthenticator = mockk<StoreAuthenticator>() every { playAuthenticator.storeType } returns StoreType.PLAY_STORE every { inactiveAuthenticator.storeType } returns StoreType.CLEAN_APK every { playAuthenticator.isStoreActive() } returns true every { inactiveAuthenticator.isStoreActive() } returns false coEvery { playAuthenticator.logout() } returns Unit coEvery { playAuthenticator.login() } returns storeResult val repository = AuthenticatorRepository(listOf(playAuthenticator, inactiveAuthenticator), appLoungeDataStore) val result = repository.fetchAuthObjects(listOf(StoreType.PLAY_STORE)) assertThat(result).containsExactly(authObject) coVerify { playAuthenticator.logout() } assertThat(appLoungeDataStore.getAuthData()).isEqualTo(authData) } @Test fun getValidatedAuthData_returnsErrorWhenMissingPlayStoreAuthenticator() = runTest { val appLoungeDataStore = createDataStore() val cleanApkAuthenticator = mockk<StoreAuthenticator>() every { cleanApkAuthenticator.storeType } returns StoreType.CLEAN_APK val repository = AuthenticatorRepository(listOf(cleanApkAuthenticator), appLoungeDataStore) val result = repository.getValidatedAuthData() assertThat(result).isInstanceOf(ResultSupreme.Error::class.java) } @Test fun getValidatedAuthData_logsOutAndPersistsAuthData() = runTest { val authData = AuthData(email = "user@example.com") val authObject = AuthObject.GPlayAuth(ResultSupreme.Success(authData), User.GOOGLE) val storeResult = StoreAuthResult(authObject, authData) val appLoungeDataStore = createDataStore() val playAuthenticator = mockk<StoreAuthenticator>() every { playAuthenticator.storeType } returns StoreType.PLAY_STORE coEvery { playAuthenticator.logout() } returns Unit coEvery { playAuthenticator.login() } returns storeResult val repository = AuthenticatorRepository(listOf(playAuthenticator), appLoungeDataStore) val result = repository.getValidatedAuthData() assertThat(result).isInstanceOf(ResultSupreme.Success::class.java) coVerify { playAuthenticator.logout() } assertThat(appLoungeDataStore.getAuthData()).isEqualTo(authData) } private fun createDataStore(): AppLoungeDataStore { val context = ApplicationProvider.getApplicationContext<Context>() val json = Json { ignoreUnknownKeys = true } return AppLoungeDataStore(context, json) } } app/src/test/java/foundation/e/apps/install/updates/UpdatesWorkerTest.kt 0 → 100644 +149 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.install.updates import android.app.NotificationManager import android.content.Context import android.content.SharedPreferences import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.os.Build import androidx.work.Data import androidx.work.WorkerParameters import com.aurora.gplayapi.data.models.AuthData import com.google.common.truth.Truth.assertThat import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.blockedApps.BlockedAppRepository import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.User import foundation.e.apps.data.gitlab.SystemAppsUpdatesRepository import foundation.e.apps.data.login.core.AuthObject import foundation.e.apps.data.login.core.StoreAuthResult import foundation.e.apps.data.login.core.StoreAuthenticator import foundation.e.apps.data.login.core.StoreType import foundation.e.apps.data.login.repository.AuthenticatorRepository import foundation.e.apps.data.login.state.LoginState import foundation.e.apps.data.preference.AppLoungeDataStore import foundation.e.apps.data.updates.UpdatesManagerRepository import foundation.e.apps.install.workmanager.AppInstallProcessor import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config(sdk = [Build.VERSION_CODES.N]) class UpdatesWorkerTest { @Test fun doWork_retriesUpdatesAfterAuthRefresh() = runTest { val dataStoreContext = RuntimeEnvironment.getApplication() val workerContext = mock<Context>() val sharedPreferences = mock<SharedPreferences>() val connectivityManager = mock<ConnectivityManager>() val network = mock<Network>() val networkCapabilities = mock<NetworkCapabilities>() val notificationManager = mock<NotificationManager>() val params = mock<WorkerParameters>() val updatesManagerRepository = mock<UpdatesManagerRepository>() val appLoungeDataStore = createDataStore(dataStoreContext) val storeAuthenticator = mockk<StoreAuthenticator>() val authenticatorRepository = AuthenticatorRepository(listOf(storeAuthenticator), appLoungeDataStore) val appInstallProcessor = mock<AppInstallProcessor>() val blockedAppRepository = mock<BlockedAppRepository>() val systemAppsUpdatesRepository = mock<SystemAppsUpdatesRepository>() val authData = AuthData(email = "user@example.com") val applications = listOf<Application>() val inputData = Data.Builder() .putBoolean(UpdatesWorker.IS_AUTO_UPDATE, false) .build() whenever(workerContext.applicationContext).thenReturn(workerContext) whenever(workerContext.getSharedPreferences(any(), any())).thenReturn(sharedPreferences) whenever(workerContext.getString(any())).thenReturn("key") whenever(workerContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(connectivityManager) whenever(workerContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager) whenever(workerContext.checkSelfPermission(any())).thenReturn(android.content.pm.PackageManager.PERMISSION_GRANTED) whenever(connectivityManager.activeNetwork).thenReturn(network) whenever(connectivityManager.getNetworkCapabilities(network)).thenReturn(networkCapabilities) whenever(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)).thenReturn(true) whenever(sharedPreferences.getBoolean(any(), any())).thenReturn(true) appLoungeDataStore.destroyCredentials() appLoungeDataStore.saveUserType(User.GOOGLE) appLoungeDataStore.saveAuthData(authData) val user = appLoungeDataStore.getUser() val loginState = appLoungeDataStore.getLoginState() assertThat(user).isEqualTo(User.GOOGLE) assertThat(loginState).isEqualTo(LoginState.AVAILABLE) every { storeAuthenticator.storeType } returns StoreType.PLAY_STORE every { storeAuthenticator.isStoreActive() } returns true coEvery { storeAuthenticator.logout() } returns Unit coEvery { storeAuthenticator.login() } returns StoreAuthResult( AuthObject.GPlayAuth(ResultSupreme.Success(authData), User.GOOGLE), authData ) whenever(params.inputData).thenReturn(inputData) whenever(updatesManagerRepository.getUpdates()).thenReturn( Pair(applications, ResultStatus.RETRY), Pair(applications, ResultStatus.OK) ) whenever(updatesManagerRepository.getUpdatesOSS()).thenReturn(Pair(applications, ResultStatus.OK)) whenever(systemAppsUpdatesRepository.fetchUpdatableSystemApps(true)).thenReturn(Unit) val worker = UpdatesWorker( workerContext, params, updatesManagerRepository, appLoungeDataStore, authenticatorRepository, appInstallProcessor, blockedAppRepository, systemAppsUpdatesRepository ) worker.doWork() verify(updatesManagerRepository, times(2)).getUpdates() coVerify { storeAuthenticator.login() } } private fun createDataStore(context: Context): AppLoungeDataStore { val json = kotlinx.serialization.json.Json { ignoreUnknownKeys = true } return AppLoungeDataStore(context, json) } } Loading
app/src/test/java/foundation/e/apps/data/login/repository/AuthenticatorRepositoryTest.kt 0 → 100644 +121 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.login.repository import android.content.Context import androidx.test.core.app.ApplicationProvider import com.aurora.gplayapi.data.models.AuthData import com.google.common.truth.Truth.assertThat import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.enums.User import foundation.e.apps.data.login.core.AuthObject import foundation.e.apps.data.login.core.StoreAuthResult import foundation.e.apps.data.login.core.StoreAuthenticator import foundation.e.apps.data.login.core.StoreType import foundation.e.apps.data.preference.AppLoungeDataStore import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config(sdk = [30]) class AuthenticatorRepositoryTest { @Test fun getGPlayAuthOrThrow_returnsStoredAuth() = runTest { val authData = AuthData(email = "user@example.com") val appLoungeDataStore = createDataStore() appLoungeDataStore.saveAuthData(authData) val repository = AuthenticatorRepository(emptyList(), appLoungeDataStore) val result = repository.getGPlayAuthOrThrow() assertThat(result).isEqualTo(authData) } @Test fun fetchAuthObjects_logsOutAndPersistsAuthData() = runTest { val authData = AuthData(email = "user@example.com") val authObject = AuthObject.GPlayAuth(ResultSupreme.Success(authData), User.GOOGLE) val storeResult = StoreAuthResult(authObject, authData) val appLoungeDataStore = createDataStore() val playAuthenticator = mockk<StoreAuthenticator>() val inactiveAuthenticator = mockk<StoreAuthenticator>() every { playAuthenticator.storeType } returns StoreType.PLAY_STORE every { inactiveAuthenticator.storeType } returns StoreType.CLEAN_APK every { playAuthenticator.isStoreActive() } returns true every { inactiveAuthenticator.isStoreActive() } returns false coEvery { playAuthenticator.logout() } returns Unit coEvery { playAuthenticator.login() } returns storeResult val repository = AuthenticatorRepository(listOf(playAuthenticator, inactiveAuthenticator), appLoungeDataStore) val result = repository.fetchAuthObjects(listOf(StoreType.PLAY_STORE)) assertThat(result).containsExactly(authObject) coVerify { playAuthenticator.logout() } assertThat(appLoungeDataStore.getAuthData()).isEqualTo(authData) } @Test fun getValidatedAuthData_returnsErrorWhenMissingPlayStoreAuthenticator() = runTest { val appLoungeDataStore = createDataStore() val cleanApkAuthenticator = mockk<StoreAuthenticator>() every { cleanApkAuthenticator.storeType } returns StoreType.CLEAN_APK val repository = AuthenticatorRepository(listOf(cleanApkAuthenticator), appLoungeDataStore) val result = repository.getValidatedAuthData() assertThat(result).isInstanceOf(ResultSupreme.Error::class.java) } @Test fun getValidatedAuthData_logsOutAndPersistsAuthData() = runTest { val authData = AuthData(email = "user@example.com") val authObject = AuthObject.GPlayAuth(ResultSupreme.Success(authData), User.GOOGLE) val storeResult = StoreAuthResult(authObject, authData) val appLoungeDataStore = createDataStore() val playAuthenticator = mockk<StoreAuthenticator>() every { playAuthenticator.storeType } returns StoreType.PLAY_STORE coEvery { playAuthenticator.logout() } returns Unit coEvery { playAuthenticator.login() } returns storeResult val repository = AuthenticatorRepository(listOf(playAuthenticator), appLoungeDataStore) val result = repository.getValidatedAuthData() assertThat(result).isInstanceOf(ResultSupreme.Success::class.java) coVerify { playAuthenticator.logout() } assertThat(appLoungeDataStore.getAuthData()).isEqualTo(authData) } private fun createDataStore(): AppLoungeDataStore { val context = ApplicationProvider.getApplicationContext<Context>() val json = Json { ignoreUnknownKeys = true } return AppLoungeDataStore(context, json) } }
app/src/test/java/foundation/e/apps/install/updates/UpdatesWorkerTest.kt 0 → 100644 +149 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.install.updates import android.app.NotificationManager import android.content.Context import android.content.SharedPreferences import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.os.Build import androidx.work.Data import androidx.work.WorkerParameters import com.aurora.gplayapi.data.models.AuthData import com.google.common.truth.Truth.assertThat import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.blockedApps.BlockedAppRepository import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.User import foundation.e.apps.data.gitlab.SystemAppsUpdatesRepository import foundation.e.apps.data.login.core.AuthObject import foundation.e.apps.data.login.core.StoreAuthResult import foundation.e.apps.data.login.core.StoreAuthenticator import foundation.e.apps.data.login.core.StoreType import foundation.e.apps.data.login.repository.AuthenticatorRepository import foundation.e.apps.data.login.state.LoginState import foundation.e.apps.data.preference.AppLoungeDataStore import foundation.e.apps.data.updates.UpdatesManagerRepository import foundation.e.apps.install.workmanager.AppInstallProcessor import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config(sdk = [Build.VERSION_CODES.N]) class UpdatesWorkerTest { @Test fun doWork_retriesUpdatesAfterAuthRefresh() = runTest { val dataStoreContext = RuntimeEnvironment.getApplication() val workerContext = mock<Context>() val sharedPreferences = mock<SharedPreferences>() val connectivityManager = mock<ConnectivityManager>() val network = mock<Network>() val networkCapabilities = mock<NetworkCapabilities>() val notificationManager = mock<NotificationManager>() val params = mock<WorkerParameters>() val updatesManagerRepository = mock<UpdatesManagerRepository>() val appLoungeDataStore = createDataStore(dataStoreContext) val storeAuthenticator = mockk<StoreAuthenticator>() val authenticatorRepository = AuthenticatorRepository(listOf(storeAuthenticator), appLoungeDataStore) val appInstallProcessor = mock<AppInstallProcessor>() val blockedAppRepository = mock<BlockedAppRepository>() val systemAppsUpdatesRepository = mock<SystemAppsUpdatesRepository>() val authData = AuthData(email = "user@example.com") val applications = listOf<Application>() val inputData = Data.Builder() .putBoolean(UpdatesWorker.IS_AUTO_UPDATE, false) .build() whenever(workerContext.applicationContext).thenReturn(workerContext) whenever(workerContext.getSharedPreferences(any(), any())).thenReturn(sharedPreferences) whenever(workerContext.getString(any())).thenReturn("key") whenever(workerContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(connectivityManager) whenever(workerContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager) whenever(workerContext.checkSelfPermission(any())).thenReturn(android.content.pm.PackageManager.PERMISSION_GRANTED) whenever(connectivityManager.activeNetwork).thenReturn(network) whenever(connectivityManager.getNetworkCapabilities(network)).thenReturn(networkCapabilities) whenever(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)).thenReturn(true) whenever(sharedPreferences.getBoolean(any(), any())).thenReturn(true) appLoungeDataStore.destroyCredentials() appLoungeDataStore.saveUserType(User.GOOGLE) appLoungeDataStore.saveAuthData(authData) val user = appLoungeDataStore.getUser() val loginState = appLoungeDataStore.getLoginState() assertThat(user).isEqualTo(User.GOOGLE) assertThat(loginState).isEqualTo(LoginState.AVAILABLE) every { storeAuthenticator.storeType } returns StoreType.PLAY_STORE every { storeAuthenticator.isStoreActive() } returns true coEvery { storeAuthenticator.logout() } returns Unit coEvery { storeAuthenticator.login() } returns StoreAuthResult( AuthObject.GPlayAuth(ResultSupreme.Success(authData), User.GOOGLE), authData ) whenever(params.inputData).thenReturn(inputData) whenever(updatesManagerRepository.getUpdates()).thenReturn( Pair(applications, ResultStatus.RETRY), Pair(applications, ResultStatus.OK) ) whenever(updatesManagerRepository.getUpdatesOSS()).thenReturn(Pair(applications, ResultStatus.OK)) whenever(systemAppsUpdatesRepository.fetchUpdatableSystemApps(true)).thenReturn(Unit) val worker = UpdatesWorker( workerContext, params, updatesManagerRepository, appLoungeDataStore, authenticatorRepository, appInstallProcessor, blockedAppRepository, systemAppsUpdatesRepository ) worker.doWork() verify(updatesManagerRepository, times(2)).getUpdates() coVerify { storeAuthenticator.login() } } private fun createDataStore(context: Context): AppLoungeDataStore { val json = kotlinx.serialization.json.Json { ignoreUnknownKeys = true } return AppLoungeDataStore(context, json) } }