Skip to content
Snippets Groups Projects
Unverified Commit 6f751761 authored by Matthias Urhahn's avatar Matthias Urhahn Committed by GitHub
Browse files

Show current env when launching app (DEV) (#1515)


* On flavor "deviceForTesters" show a toast to tell the testers/devs which environment is currently activated.

* Add unit tests for new "Current env: ..." toast.

Co-authored-by: default avatarRalf Gehrer <ralfgehrer@users.noreply.github.com>
parent 0fa4ccd9
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ import android.content.Intent ...@@ -5,6 +5,7 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
...@@ -19,10 +20,14 @@ import de.rki.coronawarnapp.storage.LocalData ...@@ -19,10 +20,14 @@ import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.ui.base.startActivitySafely import de.rki.coronawarnapp.ui.base.startActivitySafely
import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
import de.rki.coronawarnapp.util.BackgroundPrioritization import de.rki.coronawarnapp.util.BackgroundPrioritization
import de.rki.coronawarnapp.util.CWADebug
import de.rki.coronawarnapp.util.ConnectivityHelper import de.rki.coronawarnapp.util.ConnectivityHelper
import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.util.DialogHelper
import de.rki.coronawarnapp.util.device.PowerManagement import de.rki.coronawarnapp.util.device.PowerManagement
import de.rki.coronawarnapp.util.di.AppInjector import de.rki.coronawarnapp.util.di.AppInjector
import de.rki.coronawarnapp.util.ui.observe2
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
import de.rki.coronawarnapp.worker.BackgroundWorkScheduler import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
...@@ -47,6 +52,12 @@ class MainActivity : AppCompatActivity(), HasAndroidInjector { ...@@ -47,6 +52,12 @@ class MainActivity : AppCompatActivity(), HasAndroidInjector {
@Inject lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any> @Inject lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>
override fun androidInjector(): AndroidInjector<Any> = dispatchingAndroidInjector override fun androidInjector(): AndroidInjector<Any> = dispatchingAndroidInjector
@Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
private val vm: MainActivityViewModel by cwaViewModels(
ownerProducer = { viewModelStore },
factoryProducer = { viewModelFactory }
)
private val FragmentManager.currentNavigationFragment: Fragment? private val FragmentManager.currentNavigationFragment: Fragment?
get() = primaryNavigationFragment?.childFragmentManager?.fragments?.first() get() = primaryNavigationFragment?.childFragmentManager?.fragments?.first()
...@@ -76,6 +87,12 @@ class MainActivity : AppCompatActivity(), HasAndroidInjector { ...@@ -76,6 +87,12 @@ class MainActivity : AppCompatActivity(), HasAndroidInjector {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
settingsViewModel = ViewModelProviders.of(this).get(SettingsViewModel::class.java) settingsViewModel = ViewModelProviders.of(this).get(SettingsViewModel::class.java)
if (CWADebug.isDeviceForTestersBuild) {
vm.showEnvironmentHint.observe2(this) {
Toast.makeText(this, "Current environment: $it", Toast.LENGTH_SHORT).show()
}
}
} }
/** /**
......
package de.rki.coronawarnapp.ui.main package de.rki.coronawarnapp.ui.main
import dagger.Binds
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import dagger.multibindings.IntoMap
import de.rki.coronawarnapp.ui.interoperability.InteroperabilityConfigurationFragment import de.rki.coronawarnapp.ui.interoperability.InteroperabilityConfigurationFragment
import de.rki.coronawarnapp.ui.interoperability.InteroperabilityConfigurationFragmentModule import de.rki.coronawarnapp.ui.interoperability.InteroperabilityConfigurationFragmentModule
import de.rki.coronawarnapp.ui.main.home.HomeFragmentModule import de.rki.coronawarnapp.ui.main.home.HomeFragmentModule
...@@ -11,6 +13,9 @@ import de.rki.coronawarnapp.ui.settings.SettingsResetFragment ...@@ -11,6 +13,9 @@ import de.rki.coronawarnapp.ui.settings.SettingsResetFragment
import de.rki.coronawarnapp.ui.settings.SettingsResetModule import de.rki.coronawarnapp.ui.settings.SettingsResetModule
import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionFragmentModule import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionFragmentModule
import de.rki.coronawarnapp.ui.tracing.details.RiskDetailsFragmentModule import de.rki.coronawarnapp.ui.tracing.details.RiskDetailsFragmentModule
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
@Module( @Module(
includes = [ includes = [
...@@ -34,4 +39,11 @@ abstract class MainActivityModule { ...@@ -34,4 +39,11 @@ abstract class MainActivityModule {
@ContributesAndroidInjector(modules = [SettingsResetModule::class]) @ContributesAndroidInjector(modules = [SettingsResetModule::class])
abstract fun settingsResetScreen(): SettingsResetFragment abstract fun settingsResetScreen(): SettingsResetFragment
@Binds
@IntoMap
@CWAViewModelKey(MainActivityViewModel::class)
abstract fun mainActivityViewModel(
factory: MainActivityViewModel.Factory
): CWAViewModelFactory<out CWAViewModel>
} }
package de.rki.coronawarnapp.ui.main
import com.squareup.inject.assisted.AssistedInject
import de.rki.coronawarnapp.environment.EnvironmentSetup
import de.rki.coronawarnapp.util.CWADebug
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import de.rki.coronawarnapp.util.ui.SingleLiveEvent
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
class MainActivityViewModel @AssistedInject constructor(
dispatcherProvider: DispatcherProvider,
private val environmentSetup: EnvironmentSetup
) : CWAViewModel(
dispatcherProvider = dispatcherProvider
) {
val showEnvironmentHint = SingleLiveEvent<String>()
init {
if (CWADebug.isDeviceForTestersBuild) {
launch {
val current = environmentSetup.currentEnvironment
if (current != EnvironmentSetup.Type.PRODUCTION) {
showEnvironmentHint.postValue(current.rawKey)
}
}
}
}
@AssistedInject.Factory
interface Factory : SimpleCWAViewModelFactory<MainActivityViewModel>
}
package de.rki.coronawarnapp.main
import de.rki.coronawarnapp.environment.EnvironmentSetup
import de.rki.coronawarnapp.ui.main.MainActivityViewModel
import de.rki.coronawarnapp.util.CWADebug
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import io.mockk.clearAllMocks
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockkObject
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import testhelpers.BaseTest
import testhelpers.TestDispatcherProvider
import testhelpers.extensions.CoroutinesTestExtension
import testhelpers.extensions.InstantExecutorExtension
@ExtendWith(InstantExecutorExtension::class, CoroutinesTestExtension::class)
class MainActivityViewModelTest : BaseTest() {
@MockK lateinit var environmentSetup: EnvironmentSetup
@BeforeEach
fun setup() {
MockKAnnotations.init(this)
mockkObject(CWADebug)
}
@AfterEach
fun teardown() {
clearAllMocks()
}
private fun createInstance(): MainActivityViewModel = MainActivityViewModel(
dispatcherProvider = TestDispatcherProvider,
environmentSetup = environmentSetup
)
@Test
fun `environment toast is visible test environments`() {
every { CWADebug.isDeviceForTestersBuild } returns true
every { environmentSetup.currentEnvironment } returns EnvironmentSetup.Type.DEV
val vm = createInstance()
vm.showEnvironmentHint.value shouldBe EnvironmentSetup.Type.DEV.rawKey
}
@Test
fun `environment toast is only visible in deviceForTesters flavor`() {
every { CWADebug.isDeviceForTestersBuild } returns false
every { environmentSetup.currentEnvironment } returns EnvironmentSetup.Type.DEV
val vm = createInstance()
vm.showEnvironmentHint.value shouldBe null
}
@Test
fun `environment toast is not visible in production`() {
every { CWADebug.isDeviceForTestersBuild } returns true
every { environmentSetup.currentEnvironment } returns EnvironmentSetup.Type.PRODUCTION
val vm = createInstance()
vm.showEnvironmentHint.value shouldBe null
}
}
...@@ -11,7 +11,6 @@ import de.rki.coronawarnapp.ui.main.home.TracingHeaderState ...@@ -11,7 +11,6 @@ import de.rki.coronawarnapp.ui.main.home.TracingHeaderState
import de.rki.coronawarnapp.ui.tracing.card.TracingCardState import de.rki.coronawarnapp.ui.tracing.card.TracingCardState
import de.rki.coronawarnapp.ui.tracing.card.TracingCardStateProvider import de.rki.coronawarnapp.ui.tracing.card.TracingCardStateProvider
import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel
import de.rki.coronawarnapp.util.security.EncryptionErrorResetTool import de.rki.coronawarnapp.util.security.EncryptionErrorResetTool
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations
...@@ -39,7 +38,6 @@ class HomeFragmentViewModelTest : BaseTest() { ...@@ -39,7 +38,6 @@ class HomeFragmentViewModelTest : BaseTest() {
@MockK lateinit var context: Context @MockK lateinit var context: Context
@MockK lateinit var errorResetTool: EncryptionErrorResetTool @MockK lateinit var errorResetTool: EncryptionErrorResetTool
@MockK lateinit var settingsViewModel: SettingsViewModel @MockK lateinit var settingsViewModel: SettingsViewModel
@MockK lateinit var submissionViewModel: SubmissionViewModel
@MockK lateinit var tracingCardStateProvider: TracingCardStateProvider @MockK lateinit var tracingCardStateProvider: TracingCardStateProvider
@MockK lateinit var submissionCardsStateProvider: SubmissionCardsStateProvider @MockK lateinit var submissionCardsStateProvider: SubmissionCardsStateProvider
@MockK lateinit var tracingRepository: TracingRepository @MockK lateinit var tracingRepository: TracingRepository
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment