From 7249c1eb9a853a51785183134e46b8985c0c7810 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Thu, 29 May 2025 15:43:53 +0530 Subject: [PATCH 1/9] added version check --- app/build.gradle | 1 + .../android/GroundApplication.kt | 4 ++ .../android/GroundApplicationModule.kt | 11 ++++++ .../groundplatform/android/MainActivity.kt | 38 +++++++++++++++++++ .../xml/firebase_remote_config_defaults.xml | 28 ++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 app/src/main/res/xml/firebase_remote_config_defaults.xml diff --git a/app/build.gradle b/app/build.gradle index 872cc71c1a..f967029d73 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -245,6 +245,7 @@ dependencies { implementation 'com.google.firebase:firebase-messaging' implementation 'com.google.firebase:firebase-messaging-directboot' implementation 'com.google.firebase:firebase-messaging-ktx' + implementation 'com.google.firebase:firebase-config' // Hilt implementation "com.google.dagger:hilt-android:$project.hiltVersion" diff --git a/app/src/main/java/org/groundplatform/android/GroundApplication.kt b/app/src/main/java/org/groundplatform/android/GroundApplication.kt index 3813cf7735..1f9a255a8b 100644 --- a/app/src/main/java/org/groundplatform/android/GroundApplication.kt +++ b/app/src/main/java/org/groundplatform/android/GroundApplication.kt @@ -21,6 +21,7 @@ import android.util.Log import androidx.hilt.work.HiltWorkerFactory import androidx.multidex.MultiDexApplication import androidx.work.Configuration +import com.google.firebase.remoteconfig.FirebaseRemoteConfig import dagger.hilt.android.HiltAndroidApp import javax.inject.Inject import org.groundplatform.android.Config.isReleaseBuild @@ -31,6 +32,7 @@ class GroundApplication : MultiDexApplication(), Configuration.Provider { @Inject lateinit var crashReportingTree: CrashReportingTree @Inject lateinit var workerFactory: HiltWorkerFactory + @Inject lateinit var remoteConfig: FirebaseRemoteConfig override val workManagerConfiguration: Configuration get() = Configuration.Builder().setWorkerFactory(workerFactory).build() @@ -44,6 +46,8 @@ class GroundApplication : MultiDexApplication(), Configuration.Provider { // Log failures when trying to do work in the UI thread. setStrictMode() } + remoteConfig.setDefaultsAsync(R.xml.firebase_remote_config_defaults) + remoteConfig.fetchAndActivate() } private fun setStrictMode() { diff --git a/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt b/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt index c876ecbe2a..7f79b357e1 100644 --- a/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt +++ b/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt @@ -18,6 +18,10 @@ package org.groundplatform.android import android.content.Context import android.content.res.Resources import com.google.android.gms.common.GoogleApiAvailability +import com.google.firebase.Firebase +import com.google.firebase.remoteconfig.FirebaseRemoteConfig +import com.google.firebase.remoteconfig.remoteConfig +import com.google.firebase.remoteconfig.remoteConfigSettings import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -43,4 +47,11 @@ object GroundApplicationModule { } @Provides fun provideLocale() = Locale.getDefault() + + @Provides + @Singleton + fun provideFirebaseRemoteConfig(): FirebaseRemoteConfig = + Firebase.remoteConfig.apply { + setConfigSettingsAsync(remoteConfigSettings { minimumFetchIntervalInSeconds = 3600 }) + } } diff --git a/app/src/main/java/org/groundplatform/android/MainActivity.kt b/app/src/main/java/org/groundplatform/android/MainActivity.kt index 9edc52cff4..41fbe6989e 100644 --- a/app/src/main/java/org/groundplatform/android/MainActivity.kt +++ b/app/src/main/java/org/groundplatform/android/MainActivity.kt @@ -16,6 +16,7 @@ package org.groundplatform.android import android.app.AlertDialog +import android.content.ActivityNotFoundException import android.content.Intent import android.net.Uri import android.os.Bundle @@ -31,8 +32,10 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import androidx.navigation.NavDirections import androidx.navigation.fragment.NavHostFragment +import com.google.firebase.remoteconfig.FirebaseRemoteConfig import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject +import kotlin.compareTo import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch @@ -58,6 +61,7 @@ class MainActivity : AbstractActivity() { @Inject lateinit var activityStreams: ActivityStreams @Inject lateinit var viewModelFactory: ViewModelFactory @Inject lateinit var userRepository: UserRepository + @Inject lateinit var remoteConfig: FirebaseRemoteConfig private lateinit var viewModel: MainViewModel private lateinit var navHostFragment: NavHostFragment @@ -197,6 +201,7 @@ class MainActivity : AbstractActivity() { override fun onResume() { super.onResume() viewModel.checkAuthStatus() + checkForUpdate() } /** Override up button behavior to use Navigation Components back stack. */ @@ -261,4 +266,37 @@ class MainActivity : AbstractActivity() { navigate(action) } } + + private fun checkForUpdate() { + val forceUpdate = remoteConfig.getBoolean("force_update") + val latestVersion = remoteConfig.getLong("latest_version_code").toInt() + val currentVersion = BuildConfig.VERSION_CODE + println(" --- $forceUpdate $latestVersion $currentVersion") + if (forceUpdate && currentVersion < latestVersion) { + showForceUpdateDialog() + } + } + + private fun showForceUpdateDialog() { + AlertDialog.Builder(this) + .setTitle("Update Required") + .setMessage("A new version of the app is available. Please update to continue using the app.") + .setCancelable(false) + .setPositiveButton("Update") { dialog, _ -> + val appPackageName = packageName + try { + startActivity( + Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$appPackageName")) + ) + } catch (e: ActivityNotFoundException) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse("https://play.google.com/store/apps/details?id=$appPackageName"), + ) + ) + } + } + .show() + } } diff --git a/app/src/main/res/xml/firebase_remote_config_defaults.xml b/app/src/main/res/xml/firebase_remote_config_defaults.xml new file mode 100644 index 0000000000..917dca874f --- /dev/null +++ b/app/src/main/res/xml/firebase_remote_config_defaults.xml @@ -0,0 +1,28 @@ + + + + + + + force_update + true + + + latest_version_code + 14916 + + From 8cce75dc2cb7a2a24a564a33b1db0997a2bf06c5 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Thu, 29 May 2025 15:45:35 +0530 Subject: [PATCH 2/9] nit fix --- app/src/main/java/org/groundplatform/android/MainActivity.kt | 2 +- app/src/main/res/xml/firebase_remote_config_defaults.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/groundplatform/android/MainActivity.kt b/app/src/main/java/org/groundplatform/android/MainActivity.kt index 41fbe6989e..b7175a3a59 100644 --- a/app/src/main/java/org/groundplatform/android/MainActivity.kt +++ b/app/src/main/java/org/groundplatform/android/MainActivity.kt @@ -271,7 +271,7 @@ class MainActivity : AbstractActivity() { val forceUpdate = remoteConfig.getBoolean("force_update") val latestVersion = remoteConfig.getLong("latest_version_code").toInt() val currentVersion = BuildConfig.VERSION_CODE - println(" --- $forceUpdate $latestVersion $currentVersion") + if (forceUpdate && currentVersion < latestVersion) { showForceUpdateDialog() } diff --git a/app/src/main/res/xml/firebase_remote_config_defaults.xml b/app/src/main/res/xml/firebase_remote_config_defaults.xml index 917dca874f..2856efb4eb 100644 --- a/app/src/main/res/xml/firebase_remote_config_defaults.xml +++ b/app/src/main/res/xml/firebase_remote_config_defaults.xml @@ -19,10 +19,10 @@ force_update - true + false latest_version_code - 14916 + 14914 From c6d246e5ba9ff4338a3e5a3743b0ddd2bcf73ac6 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Mon, 2 Jun 2025 11:50:19 +0530 Subject: [PATCH 3/9] update strings --- .../main/java/org/groundplatform/android/MainActivity.kt | 8 ++++---- app/src/main/res/values-es/strings.xml | 4 ++++ app/src/main/res/values-fr/strings.xml | 4 ++++ app/src/main/res/values-pt/strings.xml | 4 ++++ app/src/main/res/values/strings.xml | 4 ++++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/groundplatform/android/MainActivity.kt b/app/src/main/java/org/groundplatform/android/MainActivity.kt index b7175a3a59..6aa9b11cb4 100644 --- a/app/src/main/java/org/groundplatform/android/MainActivity.kt +++ b/app/src/main/java/org/groundplatform/android/MainActivity.kt @@ -35,7 +35,6 @@ import androidx.navigation.fragment.NavHostFragment import com.google.firebase.remoteconfig.FirebaseRemoteConfig import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -import kotlin.compareTo import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch @@ -279,16 +278,17 @@ class MainActivity : AbstractActivity() { private fun showForceUpdateDialog() { AlertDialog.Builder(this) - .setTitle("Update Required") - .setMessage("A new version of the app is available. Please update to continue using the app.") + .setTitle(R.string.dialog_title_update_required) + .setMessage(R.string.dialog_message_update_required) .setCancelable(false) - .setPositiveButton("Update") { dialog, _ -> + .setPositiveButton(R.string.dialog_button_update) { dialog, _ -> val appPackageName = packageName try { startActivity( Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$appPackageName")) ) } catch (e: ActivityNotFoundException) { + Timber.e("Not able to open play store: $e") startActivity( Intent( Intent.ACTION_VIEW, diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 231ce4e27f..77e05eda38 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -210,4 +210,8 @@ Clara Área: %1$.2f m² + + Actualización requerida + Hay una nueva versión de la aplicación disponible. Por favor, actualiza para seguir usando la aplicación. + Actualizar diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 05674724cb..4a03203c92 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -209,4 +209,8 @@ Claire Surface: %1$.2f m² + + Mise à jour requise + Une nouvelle version de l’application est disponible. Veuillez mettre à jour pour continuer à utiliser l’application. + Mettre à jour diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 57ecb64061..d5e3caa124 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -211,4 +211,8 @@ Clara Área: %1$.2f m² + + Atualização necessária + Uma nova versão do aplicativo está disponível. Atualize para continuar usando o aplicativo. + Atualizar diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a732971f2f..e413ce0bbc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -210,4 +210,8 @@ 255 characters max Area: %1$.2f m² + + Update Required + A new version of the app is available. Please update to continue using the app. + Update From f60004ee439615a5de4f7b966472c44a7b549d80 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Mon, 2 Jun 2025 12:35:46 +0530 Subject: [PATCH 4/9] firebase fix --- .../groundplatform/android/GroundApplicationModule.kt | 10 ++++++++-- .../java/org/groundplatform/android/MainActivity.kt | 6 ++---- .../java/org/groundplatform/android/MainViewModel.kt | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt b/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt index 7f79b357e1..b6aa9af0c0 100644 --- a/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt +++ b/app/src/main/java/org/groundplatform/android/GroundApplicationModule.kt @@ -19,6 +19,7 @@ import android.content.Context import android.content.res.Resources import com.google.android.gms.common.GoogleApiAvailability import com.google.firebase.Firebase +import com.google.firebase.FirebaseApp import com.google.firebase.remoteconfig.FirebaseRemoteConfig import com.google.firebase.remoteconfig.remoteConfig import com.google.firebase.remoteconfig.remoteConfigSettings @@ -50,8 +51,13 @@ object GroundApplicationModule { @Provides @Singleton - fun provideFirebaseRemoteConfig(): FirebaseRemoteConfig = - Firebase.remoteConfig.apply { + fun provideFirebaseRemoteConfig(@ApplicationContext context: Context): FirebaseRemoteConfig { + if (FirebaseApp.getApps(context).isEmpty()) { + FirebaseApp.initializeApp(context) + } + + return Firebase.remoteConfig.apply { setConfigSettingsAsync(remoteConfigSettings { minimumFetchIntervalInSeconds = 3600 }) } + } } diff --git a/app/src/main/java/org/groundplatform/android/MainActivity.kt b/app/src/main/java/org/groundplatform/android/MainActivity.kt index 6aa9b11cb4..02becf0ed8 100644 --- a/app/src/main/java/org/groundplatform/android/MainActivity.kt +++ b/app/src/main/java/org/groundplatform/android/MainActivity.kt @@ -32,7 +32,6 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import androidx.navigation.NavDirections import androidx.navigation.fragment.NavHostFragment -import com.google.firebase.remoteconfig.FirebaseRemoteConfig import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.filterNotNull @@ -60,7 +59,6 @@ class MainActivity : AbstractActivity() { @Inject lateinit var activityStreams: ActivityStreams @Inject lateinit var viewModelFactory: ViewModelFactory @Inject lateinit var userRepository: UserRepository - @Inject lateinit var remoteConfig: FirebaseRemoteConfig private lateinit var viewModel: MainViewModel private lateinit var navHostFragment: NavHostFragment @@ -267,8 +265,8 @@ class MainActivity : AbstractActivity() { } private fun checkForUpdate() { - val forceUpdate = remoteConfig.getBoolean("force_update") - val latestVersion = remoteConfig.getLong("latest_version_code").toInt() + val forceUpdate = viewModel.remoteConfig.getBoolean("force_update") + val latestVersion = viewModel.remoteConfig.getLong("latest_version_code").toInt() val currentVersion = BuildConfig.VERSION_CODE if (forceUpdate && currentVersion < latestVersion) { diff --git a/app/src/main/java/org/groundplatform/android/MainViewModel.kt b/app/src/main/java/org/groundplatform/android/MainViewModel.kt index e0d0e537fb..7448a9e2a3 100644 --- a/app/src/main/java/org/groundplatform/android/MainViewModel.kt +++ b/app/src/main/java/org/groundplatform/android/MainViewModel.kt @@ -20,6 +20,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.google.android.gms.auth.api.signin.GoogleSignInStatusCodes.SIGN_IN_CANCELLED import com.google.android.gms.common.api.ApiException +import com.google.firebase.remoteconfig.FirebaseRemoteConfig import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.MutableSharedFlow @@ -55,6 +56,7 @@ constructor( private val reactivateLastSurvey: ReactivateLastSurveyUseCase, @IoDispatcher private val ioDispatcher: CoroutineDispatcher, private val authenticationManager: AuthenticationManager, + val remoteConfig: FirebaseRemoteConfig, ) : AbstractViewModel() { private val _navigationRequests: MutableSharedFlow = MutableSharedFlow() From f769a78c751661d904e983ed8bcae3bb5cfd4e73 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Wed, 4 Jun 2025 21:15:01 +0530 Subject: [PATCH 5/9] moved to value 0 --- app/src/main/res/xml/firebase_remote_config_defaults.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/xml/firebase_remote_config_defaults.xml b/app/src/main/res/xml/firebase_remote_config_defaults.xml index 2856efb4eb..a148df13ac 100644 --- a/app/src/main/res/xml/firebase_remote_config_defaults.xml +++ b/app/src/main/res/xml/firebase_remote_config_defaults.xml @@ -23,6 +23,6 @@ latest_version_code - 14914 + 0 From da916d472c8b03ea139a8c50cf1413e83d7fd214 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Wed, 4 Jun 2025 22:38:39 +0530 Subject: [PATCH 6/9] moved to viewmodel --- .../org/groundplatform/android/MainActivity.kt | 14 +++----------- .../org/groundplatform/android/MainViewModel.kt | 6 ++++++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/groundplatform/android/MainActivity.kt b/app/src/main/java/org/groundplatform/android/MainActivity.kt index 02becf0ed8..0b971405b0 100644 --- a/app/src/main/java/org/groundplatform/android/MainActivity.kt +++ b/app/src/main/java/org/groundplatform/android/MainActivity.kt @@ -198,7 +198,9 @@ class MainActivity : AbstractActivity() { override fun onResume() { super.onResume() viewModel.checkAuthStatus() - checkForUpdate() + if (viewModel.shouldForceUpdate()) { + showForceUpdateDialog() + } } /** Override up button behavior to use Navigation Components back stack. */ @@ -264,16 +266,6 @@ class MainActivity : AbstractActivity() { } } - private fun checkForUpdate() { - val forceUpdate = viewModel.remoteConfig.getBoolean("force_update") - val latestVersion = viewModel.remoteConfig.getLong("latest_version_code").toInt() - val currentVersion = BuildConfig.VERSION_CODE - - if (forceUpdate && currentVersion < latestVersion) { - showForceUpdateDialog() - } - } - private fun showForceUpdateDialog() { AlertDialog.Builder(this) .setTitle(R.string.dialog_title_update_required) diff --git a/app/src/main/java/org/groundplatform/android/MainViewModel.kt b/app/src/main/java/org/groundplatform/android/MainViewModel.kt index 7448a9e2a3..878a29b2a0 100644 --- a/app/src/main/java/org/groundplatform/android/MainViewModel.kt +++ b/app/src/main/java/org/groundplatform/android/MainViewModel.kt @@ -140,4 +140,10 @@ constructor( /** Returns true if the user has already accepted the Terms of Service. */ private fun isTosAccepted(): Boolean = termsOfServiceRepository.isTermsOfServiceAccepted + + fun shouldForceUpdate(currentVersion: Int = BuildConfig.VERSION_CODE): Boolean { + val forceUpdate = remoteConfig.getBoolean("force_update") + val latestVersion = remoteConfig.getLong("latest_version_code") + return forceUpdate && currentVersion.toLong() < latestVersion + } } From 02bacfcf8bd4f1f6b9c347b2fa05ad4aa49ecec9 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Thu, 5 Jun 2025 07:33:48 +0530 Subject: [PATCH 7/9] nit fixes --- .../android/GroundApplication.kt | 19 +++++++++++++++++-- .../groundplatform/android/MainActivity.kt | 2 +- .../groundplatform/android/MainViewModel.kt | 4 ++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/groundplatform/android/GroundApplication.kt b/app/src/main/java/org/groundplatform/android/GroundApplication.kt index 1f9a255a8b..5ccfd649f7 100644 --- a/app/src/main/java/org/groundplatform/android/GroundApplication.kt +++ b/app/src/main/java/org/groundplatform/android/GroundApplication.kt @@ -46,8 +46,7 @@ class GroundApplication : MultiDexApplication(), Configuration.Provider { // Log failures when trying to do work in the UI thread. setStrictMode() } - remoteConfig.setDefaultsAsync(R.xml.firebase_remote_config_defaults) - remoteConfig.fetchAndActivate() + initiateRemoteConfig() } private fun setStrictMode() { @@ -58,6 +57,22 @@ class GroundApplication : MultiDexApplication(), Configuration.Provider { StrictMode.setVmPolicy(VmPolicy.Builder().detectLeakedSqlLiteObjects().penaltyLog().build()) } + /** + * Initializes Firebase Remote Config by setting default values from the provided XML file and + * fetching remote values to activate them for use in the app. + * + * This method: + * - Sets default values using `firebase_remote_config_defaults.xml` + * - Asynchronously fetches the latest Remote Config values from Firebase + * - Immediately activates the fetched values + * + * Call this during app startup to ensure Remote Config values are available. + */ + private fun initiateRemoteConfig() { + remoteConfig.setDefaultsAsync(R.xml.firebase_remote_config_defaults) + remoteConfig.fetchAndActivate() + } + /** Reports any error with priority more than "info" to Crashlytics. */ class CrashReportingTree @Inject diff --git a/app/src/main/java/org/groundplatform/android/MainActivity.kt b/app/src/main/java/org/groundplatform/android/MainActivity.kt index 0b971405b0..fca53c5d0e 100644 --- a/app/src/main/java/org/groundplatform/android/MainActivity.kt +++ b/app/src/main/java/org/groundplatform/android/MainActivity.kt @@ -198,7 +198,7 @@ class MainActivity : AbstractActivity() { override fun onResume() { super.onResume() viewModel.checkAuthStatus() - if (viewModel.shouldForceUpdate()) { + if (viewModel.isAppUpdateAvailable()) { showForceUpdateDialog() } } diff --git a/app/src/main/java/org/groundplatform/android/MainViewModel.kt b/app/src/main/java/org/groundplatform/android/MainViewModel.kt index 878a29b2a0..7cab5ebf24 100644 --- a/app/src/main/java/org/groundplatform/android/MainViewModel.kt +++ b/app/src/main/java/org/groundplatform/android/MainViewModel.kt @@ -56,7 +56,7 @@ constructor( private val reactivateLastSurvey: ReactivateLastSurveyUseCase, @IoDispatcher private val ioDispatcher: CoroutineDispatcher, private val authenticationManager: AuthenticationManager, - val remoteConfig: FirebaseRemoteConfig, + private val remoteConfig: FirebaseRemoteConfig, ) : AbstractViewModel() { private val _navigationRequests: MutableSharedFlow = MutableSharedFlow() @@ -141,7 +141,7 @@ constructor( /** Returns true if the user has already accepted the Terms of Service. */ private fun isTosAccepted(): Boolean = termsOfServiceRepository.isTermsOfServiceAccepted - fun shouldForceUpdate(currentVersion: Int = BuildConfig.VERSION_CODE): Boolean { + fun isAppUpdateAvailable(currentVersion: Int = BuildConfig.VERSION_CODE): Boolean { val forceUpdate = remoteConfig.getBoolean("force_update") val latestVersion = remoteConfig.getLong("latest_version_code") return forceUpdate && currentVersion.toLong() < latestVersion From b765497a70e13cce294c0f63327c251988cb3b05 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Wed, 11 Jun 2025 13:22:34 +0530 Subject: [PATCH 8/9] excetion check log --- .../android/MainActivityTest.kt | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/src/test/java/org/groundplatform/android/MainActivityTest.kt b/app/src/test/java/org/groundplatform/android/MainActivityTest.kt index fb4ea75fce..cc7c5c4bc4 100644 --- a/app/src/test/java/org/groundplatform/android/MainActivityTest.kt +++ b/app/src/test/java/org/groundplatform/android/MainActivityTest.kt @@ -47,14 +47,22 @@ class MainActivityTest : BaseHiltTest() { @Test fun signInProgressDialog_whenSigningIn_isDisplayed() = runWithTestDispatcher { - Robolectric.buildActivity(MainActivity::class.java).use { controller -> - controller.setup() // Moves Activity to RESUMED state - activity = controller.get() - - fakeAuthenticationManager.setState(SignInState.SigningIn) - advanceUntilIdle() - - assertThat(ShadowProgressDialog.getLatestDialog().isShowing).isTrue() + try { + Robolectric.buildActivity(MainActivity::class.java).use { controller -> + controller.setup() // Moves Activity to RESUMED state + activity = controller.get() + + advanceUntilIdle() + + fakeAuthenticationManager.setState(SignInState.SigningIn) + advanceUntilIdle() + + assertThat(ShadowProgressDialog.getLatestDialog().isShowing).isTrue() + } + } catch (e: Exception) { + println("Caught exception: ${e.message}") + e.printStackTrace() + throw e } } From cb724e11e904cbc5b82e49a6cd6909717c0e02e9 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Thu, 12 Jun 2025 22:11:41 +0530 Subject: [PATCH 9/9] catch to log --- .../android/MainActivityTest.kt | 110 +++++++++++------- 1 file changed, 68 insertions(+), 42 deletions(-) diff --git a/app/src/test/java/org/groundplatform/android/MainActivityTest.kt b/app/src/test/java/org/groundplatform/android/MainActivityTest.kt index cc7c5c4bc4..b08fa5a0fd 100644 --- a/app/src/test/java/org/groundplatform/android/MainActivityTest.kt +++ b/app/src/test/java/org/groundplatform/android/MainActivityTest.kt @@ -68,76 +68,102 @@ class MainActivityTest : BaseHiltTest() { @Test fun signInProgressDialog_whenSignedOutAfterSignInState_isNotDisplayed() = runWithTestDispatcher { - Robolectric.buildActivity(MainActivity::class.java).use { controller -> - controller.setup() // Moves Activity to RESUMED state - activity = controller.get() + try { + Robolectric.buildActivity(MainActivity::class.java).use { controller -> + controller.setup() // Moves Activity to RESUMED state + activity = controller.get() - fakeAuthenticationManager.setState(SignInState.SigningIn) - fakeAuthenticationManager.setState(SignInState.SignedOut) - advanceUntilIdle() + fakeAuthenticationManager.setState(SignInState.SigningIn) + fakeAuthenticationManager.setState(SignInState.SignedOut) + advanceUntilIdle() - assertThat(ShadowProgressDialog.getLatestDialog().isShowing).isFalse() + assertThat(ShadowProgressDialog.getLatestDialog().isShowing).isFalse() + } + } catch (e: Exception) { + println("Caught exception: ${e.message}") + e.printStackTrace() + throw e } } @Test fun signInErrorDialog_isDisplayed() = runWithTestDispatcher { - Robolectric.buildActivity(MainActivity::class.java).use { controller -> - controller.setup() // Moves Activity to RESUMED state - activity = controller.get() - - fakeAuthenticationManager.setState( - SignInState.Error( - error = - FirebaseFirestoreException("error", FirebaseFirestoreException.Code.PERMISSION_DENIED) + try { + Robolectric.buildActivity(MainActivity::class.java).use { controller -> + controller.setup() // Moves Activity to RESUMED state + activity = controller.get() + + fakeAuthenticationManager.setState( + SignInState.Error( + error = + FirebaseFirestoreException("error", FirebaseFirestoreException.Code.PERMISSION_DENIED) + ) ) - ) - advanceUntilIdle() + advanceUntilIdle() - assertThat(ShadowProgressDialog.getLatestDialog().isShowing).isTrue() + assertThat(ShadowProgressDialog.getLatestDialog().isShowing).isTrue() + } + } catch (e: Exception) { + println("Caught exception: ${e.message}") + e.printStackTrace() + throw e } } @Test fun launchAppWithSurveyId_loggedInUser_ActivitySurvey() = runWithTestDispatcher { - val uri = Uri.parse("https://groundplatform.org/survey/surveyId") - val intent = Intent(Intent.ACTION_VIEW, uri) + try { + val uri = Uri.parse("https://groundplatform.org/survey/surveyId") + val intent = Intent(Intent.ACTION_VIEW, uri) - Robolectric.buildActivity(MainActivity::class.java, intent).use { controller -> - controller.setup() - activity = controller.get() + Robolectric.buildActivity(MainActivity::class.java, intent).use { controller -> + controller.setup() + activity = controller.get() - val navHost = - activity.supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment - val navController = navHost.navController + val navHost = + activity.supportFragmentManager.findFragmentById(R.id.nav_host_fragment) + as NavHostFragment + val navController = navHost.navController - fakeAuthenticationManager.setState(SignInState.SignedIn(FakeData.USER)) - advanceUntilIdle() + fakeAuthenticationManager.setState(SignInState.SignedIn(FakeData.USER)) + advanceUntilIdle() - assertThat(navController.currentDestination?.id).isEqualTo(R.id.surveySelectorFragment) + assertThat(navController.currentDestination?.id).isEqualTo(R.id.surveySelectorFragment) - assertThat(navController.currentBackStackEntry?.arguments?.getString("surveyId")) - .isEqualTo("surveyId") + assertThat(navController.currentBackStackEntry?.arguments?.getString("surveyId")) + .isEqualTo("surveyId") + } + } catch (e: Exception) { + println("Caught exception: ${e.message}") + e.printStackTrace() + throw e } } @Test fun launchAppWithSurveyId_needLogin_ShowLoginIn() = runWithTestDispatcher { - val uri = Uri.parse("https://groundplatform.org/survey/surveyId") - val intent = Intent(Intent.ACTION_VIEW, uri) + try { + val uri = Uri.parse("https://groundplatform.org/survey/surveyId") + val intent = Intent(Intent.ACTION_VIEW, uri) - Robolectric.buildActivity(MainActivity::class.java, intent).use { controller -> - controller.setup() - activity = controller.get() + Robolectric.buildActivity(MainActivity::class.java, intent).use { controller -> + controller.setup() + activity = controller.get() - val navHost = - activity.supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment - val navController = navHost.navController + val navHost = + activity.supportFragmentManager.findFragmentById(R.id.nav_host_fragment) + as NavHostFragment + val navController = navHost.navController - fakeAuthenticationManager.setState(SignInState.SignedOut) - advanceUntilIdle() + fakeAuthenticationManager.setState(SignInState.SignedOut) + advanceUntilIdle() - assertThat(navController.currentDestination?.id).isEqualTo(R.id.sign_in_fragment) + assertThat(navController.currentDestination?.id).isEqualTo(R.id.sign_in_fragment) + } + } catch (e: Exception) { + println("Caught exception: ${e.message}") + e.printStackTrace() + throw e } } }